职工福利功能优化
This commit is contained in:
@@ -38,6 +38,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
@@ -270,10 +271,12 @@ public class SysFileServiceImpl extends BaseServiceImpl<Sys_file> implements Sys
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
HtmlSaveOptions saveOptions = new HtmlSaveOptions();
|
HtmlSaveOptions saveOptions = new HtmlSaveOptions();
|
||||||
|
// Aspose输出和字节流读取必须固定使用UTF-8,避免不同服务器的JVM默认编码导致中文乱码。
|
||||||
|
saveOptions.setEncoding(StandardCharsets.UTF_8);
|
||||||
saveOptions.setExportImagesAsBase64(true);
|
saveOptions.setExportImagesAsBase64(true);
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
doc.save(bos, saveOptions);
|
doc.save(bos, saveOptions);
|
||||||
String htmlContent = Jsoup.parse(bos.toString()).body().html();
|
String htmlContent = Jsoup.parse(bos.toString(StandardCharsets.UTF_8)).body().html();
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile(IMG_BASE64_PATTERN, Pattern.CASE_INSENSITIVE);
|
Pattern pattern = Pattern.compile(IMG_BASE64_PATTERN, Pattern.CASE_INSENSITIVE);
|
||||||
Matcher matcher = pattern.matcher(htmlContent);
|
Matcher matcher = pattern.matcher(htmlContent);
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ public class WelfareMineController {
|
|||||||
END AS isChoose,
|
END AS isChoose,
|
||||||
GROUP_CONCAT(DISTINCT wuso.optionName ,'(',wus.selectNum,'份)') AS gist_list,
|
GROUP_CONCAT(DISTINCT wuso.optionName ,'(',wus.selectNum,'份)') AS gist_list,
|
||||||
MAX(wus.selectTime) AS selectTime,
|
MAX(wus.selectTime) AS selectTime,
|
||||||
MAX(wus.deliveryDate) AS deliveryDate,
|
|
||||||
wus.receiveAddress,
|
wus.receiveAddress,
|
||||||
wl.userId
|
wl.userId
|
||||||
FROM
|
FROM
|
||||||
@@ -98,7 +97,6 @@ public class WelfareMineController {
|
|||||||
wpus.receiveAddress,
|
wpus.receiveAddress,
|
||||||
wpso.optionName,
|
wpso.optionName,
|
||||||
wpus.selectNum,
|
wpus.selectNum,
|
||||||
wpus.deliveryDate,
|
|
||||||
wpus.remark,
|
wpus.remark,
|
||||||
wpus.userSign,
|
wpus.userSign,
|
||||||
wpus.courierNumber,
|
wpus.courierNumber,
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.budwk.app.zhgh.welfare.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.zhgh.welfare.service.WelfareProjectService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 福利通知附件查看入口。
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@Ok("json:full")
|
||||||
|
@At("/platform/welfare/notice")
|
||||||
|
@Api(tags = "福利通知")
|
||||||
|
public class WelfareNoticeController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private WelfareProjectService projectService;
|
||||||
|
|
||||||
|
@At("detail")
|
||||||
|
@Ok("beetl:/platform/zhghh5/welfare/notice/detail.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("福利通知附件详情页")
|
||||||
|
public void detail() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询福利通知附件详情。
|
||||||
|
*
|
||||||
|
* @param id 福利项目 ID
|
||||||
|
* @return JSON 结果,data 中包含项目名称、文件名称、下载地址和 PDF 预览地址
|
||||||
|
*/
|
||||||
|
@At("detailData")
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("查询福利通知附件详情")
|
||||||
|
public Result detailData(@Valid String id) {
|
||||||
|
if (StrUtil.isBlank(id)) {
|
||||||
|
return Result.error("福利项目ID不能为空");
|
||||||
|
}
|
||||||
|
return Result.success(projectService.getNoticeAttachmentInfo(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,7 +57,6 @@ public class WelfareUserSelectController {
|
|||||||
ELSE 0
|
ELSE 0
|
||||||
END AS isChoose,
|
END AS isChoose,
|
||||||
wus.selectTime,
|
wus.selectTime,
|
||||||
MAX(wus.deliveryDate) AS deliveryDate,
|
|
||||||
MAX(wus.remark) AS remark,
|
MAX(wus.remark) AS remark,
|
||||||
GROUP_CONCAT(DISTINCT wuso.optionName ,'(',wus.selectNum,'份)') AS gist_list,
|
GROUP_CONCAT(DISTINCT wuso.optionName ,'(',wus.selectNum,'份)') AS gist_list,
|
||||||
wus.receiveAddress
|
wus.receiveAddress
|
||||||
|
|||||||
@@ -207,6 +207,14 @@ public class WelfareProject extends BaseModel implements SysHomeConvert {
|
|||||||
@ColDefine(type = ColType.VARCHAR, width = 200)
|
@ColDefine(type = ColType.VARCHAR, width = 200)
|
||||||
private String cover;
|
private String cover;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 福利通知附件下载地址,只允许关联一个 Word 文件。
|
||||||
|
*/
|
||||||
|
@Column
|
||||||
|
@Comment("福利通知附件")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 200)
|
||||||
|
private String noticeAttachment;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("是否全年生日蛋糕卷")
|
@Comment("是否全年生日蛋糕卷")
|
||||||
@ColDefine(type = ColType.BOOLEAN)
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.budwk.app.zhgh.welfare.service;
|
|||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
||||||
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
|
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -25,6 +26,14 @@ public interface WelfareProjectService extends BaseService<WelfareProject> {
|
|||||||
*/
|
*/
|
||||||
List<WelfareProject> listHistoryProject();
|
List<WelfareProject> listHistoryProject();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询福利通知详情页需要的项目和附件信息。
|
||||||
|
*
|
||||||
|
* @param projectId 福利项目 ID
|
||||||
|
* @return 包含 projectName、fileId、fileName、suffix、attachmentUrl 和 previewUrl 的详情数据;未上传附件时文件字段为空
|
||||||
|
*/
|
||||||
|
NutMap getNoticeAttachmentInfo(String projectId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验福利选择是否保留系统默认福利。
|
* 校验福利选择是否保留系统默认福利。
|
||||||
*
|
*
|
||||||
@@ -44,11 +53,10 @@ public interface WelfareProjectService extends BaseService<WelfareProject> {
|
|||||||
String validateGroupSelectionQuantity(String projectId, WelfareUserSelection[] selections);
|
String validateGroupSelectionQuantity(String projectId, WelfareUserSelection[] selections);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验福利选择附加信息。配送时间为必填项,必须按日期粒度不早于本次选择时间;
|
* 校验福利选择附加信息。同一次提交的全部福利项必须使用相同备注,配送时间字段已停用。
|
||||||
* 同一次提交的全部福利项必须使用相同配送时间和备注。
|
|
||||||
*
|
*
|
||||||
* @param selections 用户提交的福利选择数组,每项需包含 deliveryDate,可选包含 remark
|
* @param selections 用户提交的福利选择数组,每项可包含 remark
|
||||||
* @param selectTime 后端生成的本次选择时间,用于防止客户端伪造日期
|
* @param selectTime 后端生成的本次选择时间,保留该参数以兼容现有调用接口
|
||||||
* @return 校验通过返回 {@code null},否则返回可直接展示的错误提示
|
* @return 校验通过返回 {@code null},否则返回可直接展示的错误提示
|
||||||
*/
|
*/
|
||||||
String validateSelectionAdditionalInfo(WelfareUserSelection[] selections, Date selectTime);
|
String validateSelectionAdditionalInfo(WelfareUserSelection[] selections, Date selectTime);
|
||||||
|
|||||||
+7
-1
@@ -15,11 +15,17 @@ public interface WelfareSelectionSituationService extends BaseService<WelfareLis
|
|||||||
* 根据选择情况页面的全部查询条件发送钉钉消息。
|
* 根据选择情况页面的全部查询条件发送钉钉消息。
|
||||||
*
|
*
|
||||||
* @param pageForm 查询条件,包含项目、福利选项、人员信息、组织范围及选择状态
|
* @param pageForm 查询条件,包含项目、福利选项、人员信息、组织范围及选择状态
|
||||||
* @param messageContent 纯文本消息内容,不应包含HTML标签或富文本样式
|
* @param messageContent 纯文本消息内容,不应包含HTML标签或富文本样式;发送前会补充福利通知详情地址
|
||||||
* @return 实际提交到钉钉消息渠道的去重人员数量
|
* @return 实际提交到钉钉消息渠道的去重人员数量
|
||||||
*/
|
*/
|
||||||
int sendDingTalkMessage(WelfareSelectionSituationPageForm pageForm, String messageContent);
|
int sendDingTalkMessage(WelfareSelectionSituationPageForm pageForm, String messageContent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按选择情况页面的查询条件导出人员选择明细。
|
||||||
|
*
|
||||||
|
* @param pageForm 页面查询条件,包含项目、福利选项、姓名、工号、组织范围、人员类型和选择状态
|
||||||
|
* @param response HTTP响应,返回包含快递单号和签字图片的XLSX文件流
|
||||||
|
*/
|
||||||
void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
||||||
void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
public interface WelfareUserEvaluationService extends BaseService<WelfareUserEvaluation> {
|
public interface WelfareUserEvaluationService extends BaseService<WelfareUserEvaluation> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验当前用户是否已到福利配送日期。只有存在选择记录、全部记录已设置配送日期,且当前日期
|
* 校验当前用户是否已经选择福利且项目活动已经结束。活动结束时间以福利项目的
|
||||||
* 不早于配送日期时才允许打开或提交评价。
|
* choiceTimeEnd 为准,PC、移动端与接口提交使用同一规则。
|
||||||
*
|
*
|
||||||
* @param projectId 福利项目ID
|
* @param projectId 福利项目ID
|
||||||
* @param userId 当前登录用户ID
|
* @param userId 当前登录用户ID
|
||||||
|
|||||||
+83
-19
@@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
import com.budwk.app.sys.models.Sys_home_activity;
|
import com.budwk.app.sys.models.Sys_home_activity;
|
||||||
|
import com.budwk.app.sys.models.Sys_file;
|
||||||
import com.budwk.app.sys.models.Sys_user;
|
import com.budwk.app.sys.models.Sys_user;
|
||||||
import com.budwk.app.zhgh.welfare.model.WelfareList;
|
import com.budwk.app.zhgh.welfare.model.WelfareList;
|
||||||
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
||||||
@@ -79,6 +80,25 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
return dao().query(WelfareProject.class, Cnd.NEW().desc(WelfareProject::getYear).desc(WelfareProject::getChoiceTimeStart));
|
return dao().query(WelfareProject.class, Cnd.NEW().desc(WelfareProject::getYear).desc(WelfareProject::getChoiceTimeStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NutMap getNoticeAttachmentInfo(String projectId) {
|
||||||
|
WelfareProject project = fetch(projectId);
|
||||||
|
if (project == null) {
|
||||||
|
throw new IllegalArgumentException("福利项目不存在");
|
||||||
|
}
|
||||||
|
NutMap result = NutMap.NEW().addv("projectName", project.getName());
|
||||||
|
if (StrUtil.isBlank(project.getNoticeAttachment())) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Sys_file noticeFile = resolveNoticeAttachmentFile(project.getNoticeAttachment());
|
||||||
|
return result
|
||||||
|
.addv("fileId", noticeFile.getId())
|
||||||
|
.addv("fileName", noticeFile.getName())
|
||||||
|
.addv("suffix", noticeFile.getSuffix())
|
||||||
|
.addv("attachmentUrl", noticeFile.getDownloadPath())
|
||||||
|
.addv("previewUrl", "/platform/sys/file/convertPDF?id=" + noticeFile.getId());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String validateSystemDefaultOptionSelection(String projectId, WelfareUserSelection[] selections) {
|
public String validateSystemDefaultOptionSelection(String projectId, WelfareUserSelection[] selections) {
|
||||||
List<WelfareProjectSubjectOption> systemDefaultOptions = dao().query(WelfareProjectSubjectOption.class,
|
List<WelfareProjectSubjectOption> systemDefaultOptions = dao().query(WelfareProjectSubjectOption.class,
|
||||||
@@ -182,8 +202,8 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验一次选择提交中的配送日期和备注。日期比较统一截断到当天零点,允许选择当天配送;
|
* 校验一次选择提交中的备注。配送时间字段已停用,新提交数据统一清空该字段;
|
||||||
* 多项福利的附加信息必须一致,避免同一次选择产生互相冲突的评价开放时间。
|
* 多项福利的备注必须一致,避免同一次选择出现互相冲突的附加信息。
|
||||||
*
|
*
|
||||||
* @param selections 当前提交的福利选择数据
|
* @param selections 当前提交的福利选择数据
|
||||||
* @param selectTime 后端生成的选择时间
|
* @param selectTime 后端生成的选择时间
|
||||||
@@ -194,30 +214,23 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
if (selections == null || selections.length == 0) {
|
if (selections == null || selections.length == 0) {
|
||||||
return "请至少选择一项福利";
|
return "请至少选择一项福利";
|
||||||
}
|
}
|
||||||
Date selectionDate = DateUtil.beginOfDay(selectTime == null ? new Date() : selectTime);
|
|
||||||
Date submittedDeliveryDate = null;
|
|
||||||
String submittedRemark = null;
|
String submittedRemark = null;
|
||||||
|
boolean firstSelection = true;
|
||||||
for (WelfareUserSelection selection : selections) {
|
for (WelfareUserSelection selection : selections) {
|
||||||
if (selection == null || selection.getDeliveryDate() == null) {
|
if (selection == null) {
|
||||||
return "请选择配送时间";
|
return "福利选择数据不能为空";
|
||||||
}
|
|
||||||
Date deliveryDate = DateUtil.beginOfDay(selection.getDeliveryDate());
|
|
||||||
if (deliveryDate.before(selectionDate)) {
|
|
||||||
return "配送时间不能早于选择时间";
|
|
||||||
}
|
|
||||||
if (submittedDeliveryDate == null) {
|
|
||||||
submittedDeliveryDate = deliveryDate;
|
|
||||||
submittedRemark = StrUtil.trim(selection.getRemark());
|
|
||||||
} else if (!submittedDeliveryDate.equals(deliveryDate)) {
|
|
||||||
return "同一次选择的配送时间必须一致";
|
|
||||||
} else if (!Objects.equals(submittedRemark, StrUtil.trim(selection.getRemark()))) {
|
|
||||||
return "同一次选择的备注必须一致";
|
|
||||||
}
|
}
|
||||||
String remark = StrUtil.trim(selection.getRemark());
|
String remark = StrUtil.trim(selection.getRemark());
|
||||||
|
if (firstSelection) {
|
||||||
|
submittedRemark = remark;
|
||||||
|
firstSelection = false;
|
||||||
|
} else if (!Objects.equals(submittedRemark, remark)) {
|
||||||
|
return "同一次选择的备注必须一致";
|
||||||
|
}
|
||||||
if (remark != null && remark.length() > 200) {
|
if (remark != null && remark.length() > 200) {
|
||||||
return "备注不能超过200字";
|
return "备注不能超过200字";
|
||||||
}
|
}
|
||||||
selection.setDeliveryDate(deliveryDate);
|
selection.setDeliveryDate(null);
|
||||||
selection.setRemark(remark);
|
selection.setRemark(remark);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -257,6 +270,7 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void saveProject(WelfareProject project) {
|
public void saveProject(WelfareProject project) {
|
||||||
|
normalizeNoticeAttachment(project);
|
||||||
// 保存前根据福利选项分组去重并校验选择数量范围,防止非法 JSON 配置进入数据库。
|
// 保存前根据福利选项分组去重并校验选择数量范围,防止非法 JSON 配置进入数据库。
|
||||||
normalizeGroupSelectionConfigs(project);
|
normalizeGroupSelectionConfigs(project);
|
||||||
// 插入项目
|
// 插入项目
|
||||||
@@ -272,6 +286,7 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void updateProject(WelfareProject project) {
|
public void updateProject(WelfareProject project) {
|
||||||
|
normalizeNoticeAttachment(project);
|
||||||
// 修改项目时同样归一化分组配置,确保新增、编辑两条保存链路规则一致。
|
// 修改项目时同样归一化分组配置,确保新增、编辑两条保存链路规则一致。
|
||||||
normalizeGroupSelectionConfigs(project);
|
normalizeGroupSelectionConfigs(project);
|
||||||
// 更新项目
|
// 更新项目
|
||||||
@@ -325,6 +340,55 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
dao().clear(Sys_home_activity.class, Cnd.where("id", "=", id));
|
dao().clear(Sys_home_activity.class, Cnd.where("id", "=", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验福利通知附件数量和真实文件类型,并将提交地址归一化为系统文件下载地址。
|
||||||
|
*
|
||||||
|
* @param project 待保存的福利项目,noticeAttachment 应为单个系统文件下载地址
|
||||||
|
*/
|
||||||
|
private void normalizeNoticeAttachment(WelfareProject project) {
|
||||||
|
String attachment = StrUtil.trim(project.getNoticeAttachment());
|
||||||
|
if (StrUtil.isBlank(attachment)) {
|
||||||
|
project.setNoticeAttachment(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attachment.contains(",")) {
|
||||||
|
throw new IllegalArgumentException("福利通知附件只能上传一个文件");
|
||||||
|
}
|
||||||
|
Sys_file noticeFile = resolveNoticeAttachmentFile(attachment);
|
||||||
|
String suffix = StrUtil.blankToDefault(noticeFile.getSuffix(), "").toLowerCase(Locale.ROOT);
|
||||||
|
if (!"doc".equals(suffix) && !"docx".equals(suffix)) {
|
||||||
|
throw new IllegalArgumentException("福利通知附件只能上传Word文件");
|
||||||
|
}
|
||||||
|
project.setNoticeAttachment(noticeFile.getDownloadPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从系统下载地址解析文件 ID,并确认文件记录真实存在。
|
||||||
|
*
|
||||||
|
* @param attachment 系统文件下载地址,格式为 /platform/sys/file/download?id=文件ID
|
||||||
|
* @return 对应的系统文件记录
|
||||||
|
*/
|
||||||
|
private Sys_file resolveNoticeAttachmentFile(String attachment) {
|
||||||
|
int idIndex = attachment.indexOf("id=");
|
||||||
|
if (idIndex < 0) {
|
||||||
|
throw new IllegalArgumentException("福利通知附件地址无效");
|
||||||
|
}
|
||||||
|
String fileId = attachment.substring(idIndex + 3);
|
||||||
|
int parameterIndex = fileId.indexOf('&');
|
||||||
|
if (parameterIndex >= 0) {
|
||||||
|
fileId = fileId.substring(0, parameterIndex);
|
||||||
|
}
|
||||||
|
fileId = fileId.trim();
|
||||||
|
if (StrUtil.isBlank(fileId)) {
|
||||||
|
throw new IllegalArgumentException("福利通知附件地址无效");
|
||||||
|
}
|
||||||
|
Sys_file noticeFile = dao().fetch(Sys_file.class, fileId);
|
||||||
|
if (noticeFile == null) {
|
||||||
|
throw new IllegalArgumentException("福利通知附件文件不存在,请重新上传");
|
||||||
|
}
|
||||||
|
return noticeFile;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据福利选项中的非空分组生成最终配置数组,并校验最小、最大选择数量。
|
* 根据福利选项中的非空分组生成最终配置数组,并校验最小、最大选择数量。
|
||||||
* 最大选择数量为 0 时表示不限,不参与最小值与最大值的大小比较。
|
* 最大选择数量为 0 时表示不限,不参与最小值与最大值的大小比较。
|
||||||
|
|||||||
+91
-2
@@ -14,6 +14,7 @@ import com.budwk.app.base.exception.BaseException;
|
|||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
import com.budwk.app.base.sms.SmsService;
|
import com.budwk.app.base.sms.SmsService;
|
||||||
|
import com.budwk.app.web.commons.base.Globals;
|
||||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||||
import com.budwk.app.base.utils.PageUtil;
|
import com.budwk.app.base.utils.PageUtil;
|
||||||
import com.budwk.app.sys.models.Sys_file;
|
import com.budwk.app.sys.models.Sys_file;
|
||||||
@@ -21,6 +22,7 @@ import com.budwk.app.sys.services.SysFileService;
|
|||||||
import com.budwk.app.sys.utils.SysFileMinIoUtil;
|
import com.budwk.app.sys.utils.SysFileMinIoUtil;
|
||||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
|
import com.budwk.app.zhgh.welfare.model.WelfareCourierNumber;
|
||||||
import com.budwk.app.zhgh.welfare.model.WelfareList;
|
import com.budwk.app.zhgh.welfare.model.WelfareList;
|
||||||
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
||||||
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
|
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
|
||||||
@@ -75,7 +77,6 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
GROUP_CONCAT(DISTINCT t3.optionName ,'(',t2.selectNum,'份)') AS selectedOptions,
|
GROUP_CONCAT(DISTINCT t3.optionName ,'(',t2.selectNum,'份)') AS selectedOptions,
|
||||||
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
|
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
|
||||||
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
|
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
|
||||||
MAX(t2.deliveryDate) AS deliveryDate,
|
|
||||||
t4.username AS userName,
|
t4.username AS userName,
|
||||||
t4.loginname AS loginName,
|
t4.loginname AS loginName,
|
||||||
t4.sex,
|
t4.sex,
|
||||||
@@ -143,7 +144,16 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
}
|
}
|
||||||
|
|
||||||
String title = project.getName() + "-福利通知";
|
String title = project.getName() + "-福利通知";
|
||||||
boolean success = smsService.sendMsg("6", loginNames, null, title, plainContent, null, null);
|
String detailUrl = StrUtil.removeSuffix(Globals.AppDomain, "/")
|
||||||
|
+ "/platform/welfare/notice/detail?id=" + project.getId();
|
||||||
|
String detailLine = "查看详情:" + detailUrl;
|
||||||
|
// 移除前端预置的详情行后统一追加到正文末尾,既避免重复链接,也保证最终消息排版一致。
|
||||||
|
String messageBody = Arrays.stream(plainContent.split("\\R"))
|
||||||
|
.filter(line -> !line.trim().startsWith("查看详情:"))
|
||||||
|
.collect(Collectors.joining("\n"))
|
||||||
|
.trim();
|
||||||
|
String sendContent = StrUtil.isBlank(messageBody) ? detailLine : messageBody + "\n" + detailLine;
|
||||||
|
boolean success = smsService.sendMsg("6", loginNames, null, title, sendContent, detailUrl, detailUrl);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw new BaseException("钉钉消息发送失败,请检查消息发送配置或稍后重试");
|
throw new BaseException("钉钉消息发送失败,请检查消息发送配置或稍后重试");
|
||||||
}
|
}
|
||||||
@@ -190,12 +200,15 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
t1.id,
|
t1.id,
|
||||||
|
t1.userId,
|
||||||
t1.welfareUnionName,
|
t1.welfareUnionName,
|
||||||
t1.welfareUnitName,
|
t1.welfareUnitName,
|
||||||
GROUP_CONCAT(DISTINCT t3.optionName,'(',t2.selectNum,'份)') AS selectedOptions,
|
GROUP_CONCAT(DISTINCT t3.optionName,'(',t2.selectNum,'份)') AS selectedOptions,
|
||||||
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
|
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
|
||||||
GROUP_CONCAT(DISTINCT t2.userName) AS userName2,
|
GROUP_CONCAT(DISTINCT t2.userName) AS userName2,
|
||||||
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
|
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
|
||||||
|
GROUP_CONCAT(DISTINCT t2.courierNumber) AS legacyCourierNumber,
|
||||||
|
MAX(t2.userSign) AS userSign,
|
||||||
t4.username AS userName,
|
t4.username AS userName,
|
||||||
t4.loginname AS loginName,
|
t4.loginname AS loginName,
|
||||||
t4.sex
|
t4.sex
|
||||||
@@ -244,6 +257,8 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
cnd.groupBy("t1.id");
|
cnd.groupBy("t1.id");
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
List<NutMap> list = listMap(sql);
|
List<NutMap> list = listMap(sql);
|
||||||
|
fillExportCourierNumbers(list, pageForm);
|
||||||
|
list.forEach(this::fillExportUserSign);
|
||||||
|
|
||||||
// 项目
|
// 项目
|
||||||
WelfareProject project = dao().fetch(WelfareProject.class, pageForm.getProjectId());
|
WelfareProject project = dao().fetch(WelfareProject.class, pageForm.getProjectId());
|
||||||
@@ -263,6 +278,13 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
if(project.getProvideMode() == 3){
|
if(project.getProvideMode() == 3){
|
||||||
entities.add(new ExcelExportEntity("收货地址", "receiveAddress", 40));
|
entities.add(new ExcelExportEntity("收货地址", "receiveAddress", 40));
|
||||||
}
|
}
|
||||||
|
ExcelExportEntity courierNumberEntity = new ExcelExportEntity("快递单号", "courierNumber", 30);
|
||||||
|
courierNumberEntity.setWrap(true);
|
||||||
|
entities.add(courierNumberEntity);
|
||||||
|
ExcelExportEntity userSignEntity = new ExcelExportEntity("签字信息", "userSignBytes", 20);
|
||||||
|
userSignEntity.setType(2);
|
||||||
|
userSignEntity.setExportImageType(2);
|
||||||
|
entities.add(userSignEntity);
|
||||||
|
|
||||||
// 设置导出参数
|
// 设置导出参数
|
||||||
ExportParams exportParams = new ExportParams();
|
ExportParams exportParams = new ExportParams();
|
||||||
@@ -275,6 +297,73 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量补充选择情况导出的快递单号。
|
||||||
|
* 当前数据从快递单号表读取;历史数据仍兼容选择记录中的旧快递单号字段。
|
||||||
|
*
|
||||||
|
* @param rows 选择情况导出行,每行必须包含userId,处理后增加courierNumber文本字段
|
||||||
|
* @param pageForm 页面查询条件;welfareOptionId不为空时只导出所选套餐对应的快递单号
|
||||||
|
*/
|
||||||
|
private void fillExportCourierNumbers(List<NutMap> rows, WelfareSelectionSituationPageForm pageForm) {
|
||||||
|
List<String> userIds = rows.stream()
|
||||||
|
.map(row -> row.getString("userId"))
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.distinct()
|
||||||
|
.toList();
|
||||||
|
if (userIds.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cnd courierCondition = Cnd.where(WelfareCourierNumber::getWelfareId, "=", pageForm.getProjectId())
|
||||||
|
.and(WelfareCourierNumber::getSelectUserId, "in", userIds)
|
||||||
|
.andEX(WelfareCourierNumber::getSelectOptionId, "=", pageForm.getWelfareOptionId());
|
||||||
|
courierCondition.asc(WelfareCourierNumber::getCreatedAt);
|
||||||
|
Map<String, List<WelfareCourierNumber>> courierNumbersByUser = dao()
|
||||||
|
.query(WelfareCourierNumber.class, courierCondition)
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.groupingBy(WelfareCourierNumber::getSelectUserId));
|
||||||
|
|
||||||
|
for (NutMap row : rows) {
|
||||||
|
LinkedHashSet<String> courierNumbers = courierNumbersByUser
|
||||||
|
.getOrDefault(row.getString("userId"), Collections.emptyList())
|
||||||
|
.stream()
|
||||||
|
.map(WelfareCourierNumber::getCourierNumber)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
|
String legacyCourierNumber = row.getString("legacyCourierNumber");
|
||||||
|
if (StrUtil.isNotBlank(legacyCourierNumber)) {
|
||||||
|
Arrays.stream(legacyCourierNumber.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.forEach(courierNumbers::add);
|
||||||
|
}
|
||||||
|
row.put("courierNumber", String.join("、", courierNumbers));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将签字文件路径转换为选择情况Excel可识别的图片字节。
|
||||||
|
* 文件记录缺失或文件读取失败时保留空白签字列,避免单个历史文件影响整份导出。
|
||||||
|
*
|
||||||
|
* @param row 选择情况导出行,输入userSign文件路径,输出userSignBytes图片字节
|
||||||
|
*/
|
||||||
|
private void fillExportUserSign(NutMap row) {
|
||||||
|
String userSignPath = row.getString("userSign");
|
||||||
|
if (StrUtil.isBlank(userSignPath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Sys_file file = dao().fetch(Sys_file.class, Cnd.where(Sys_file::getDownloadPath, "=", userSignPath));
|
||||||
|
if (file == null) {
|
||||||
|
log.warn("选择情况导出未找到签字文件记录,userId={}, userSign={}", row.getString("userId"), userSignPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
row.put("userSignBytes", SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("选择情况导出签字文件读取失败,userId={}", row.getString("userId"), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
|
public void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -4,7 +4,6 @@ import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
|||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.exception.BaseException;
|
import com.budwk.app.base.exception.BaseException;
|
||||||
@@ -59,8 +58,8 @@ public class WelfareUserEvaluationServiceImpl extends BaseServiceImpl<WelfareUse
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 评价开放时间以后端福利选择记录为准,避免客户端隐藏按钮后仍可直接调用评价接口。
|
* 评价开放时间以后端福利项目活动结束时间为准,避免客户端隐藏按钮后仍可直接调用评价接口。
|
||||||
* 配送时间按日期粒度比较,到达配送日期当天即可评价。
|
* 当前用户必须已经存在福利选择记录,且当前时间达到 choiceTimeEnd 才允许评价。
|
||||||
*
|
*
|
||||||
* @param projectId 福利项目ID
|
* @param projectId 福利项目ID
|
||||||
* @param userId 当前登录用户ID
|
* @param userId 当前登录用户ID
|
||||||
@@ -77,14 +76,15 @@ public class WelfareUserEvaluationServiceImpl extends BaseServiceImpl<WelfareUse
|
|||||||
if (selections.isEmpty()) {
|
if (selections.isEmpty()) {
|
||||||
return "当前项目暂无可评价的福利选择";
|
return "当前项目暂无可评价的福利选择";
|
||||||
}
|
}
|
||||||
Date currentDate = DateUtil.beginOfDay(new Date());
|
WelfareProject project = dao().fetch(WelfareProject.class, projectId);
|
||||||
for (WelfareUserSelection selection : selections) {
|
if (project == null) {
|
||||||
if (selection.getDeliveryDate() == null) {
|
return "福利项目不存在";
|
||||||
return "当前福利尚未设置配送时间,暂不能评价";
|
}
|
||||||
}
|
if (project.getChoiceTimeEnd() == null) {
|
||||||
if (currentDate.before(DateUtil.beginOfDay(selection.getDeliveryDate()))) {
|
return "当前福利未设置活动结束时间,暂不能评价";
|
||||||
return "配送时间未到,暂不能评价";
|
}
|
||||||
}
|
if (new Date().before(project.getChoiceTimeEnd())) {
|
||||||
|
return "福利活动尚未结束,暂不能评价";
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
-- 补充旧版疗休养已完成移植、但未写入新版菜单表的两个 PC 端入口。
|
||||||
|
-- 使用 permission 做幂等判断,脚本可重复执行。
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
|
||||||
|
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt,
|
||||||
|
delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'8a691f4623db4d82927668b05d10b401',
|
||||||
|
parent_menu.id,
|
||||||
|
CONCAT(
|
||||||
|
parent_menu.path,
|
||||||
|
LPAD(
|
||||||
|
IFNULL((
|
||||||
|
SELECT MAX(CAST(RIGHT(child.path, 4) AS UNSIGNED))
|
||||||
|
FROM sys_menu child
|
||||||
|
WHERE child.parentId = parent_menu.id
|
||||||
|
), 0) + 1,
|
||||||
|
4,
|
||||||
|
'0'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'线路成团结果通知',
|
||||||
|
'Line Group Result Notice',
|
||||||
|
'menu',
|
||||||
|
'/platform/recuperation/lineStatistics',
|
||||||
|
'data-pjax',
|
||||||
|
'',
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
'recuperation.lineStatistics',
|
||||||
|
'查询线路报名统计并发送成团或未成团通知',
|
||||||
|
IFNULL((
|
||||||
|
SELECT MAX(child.location)
|
||||||
|
FROM sys_menu child
|
||||||
|
WHERE child.parentId = parent_menu.id
|
||||||
|
), parent_menu.location) + 1,
|
||||||
|
0,
|
||||||
|
'',
|
||||||
|
UNIX_TIMESTAMP(NOW()) * 1000,
|
||||||
|
'',
|
||||||
|
UNIX_TIMESTAMP(NOW()) * 1000,
|
||||||
|
0,
|
||||||
|
'PC',
|
||||||
|
parent_menu.moduleId,
|
||||||
|
NULL,
|
||||||
|
'x',
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
FROM sys_menu parent_menu
|
||||||
|
WHERE parent_menu.permission = 'recuperation'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM (SELECT id FROM sys_menu WHERE permission = 'recuperation.lineStatistics') existing_menu
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
|
||||||
|
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt,
|
||||||
|
delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'3074a944a1554982835793d1c164183f',
|
||||||
|
parent_menu.id,
|
||||||
|
CONCAT(
|
||||||
|
parent_menu.path,
|
||||||
|
LPAD(
|
||||||
|
IFNULL((
|
||||||
|
SELECT MAX(CAST(RIGHT(child.path, 4) AS UNSIGNED))
|
||||||
|
FROM sys_menu child
|
||||||
|
WHERE child.parentId = parent_menu.id
|
||||||
|
), 0) + 1,
|
||||||
|
4,
|
||||||
|
'0'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'省内灵活组团查询',
|
||||||
|
'Flexible Group Query',
|
||||||
|
'menu',
|
||||||
|
'/platform/recuperation/flexibleGroupQuery',
|
||||||
|
'data-pjax',
|
||||||
|
'',
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
'recuperation.flexibleGroupQuery',
|
||||||
|
'查询省内灵活组团、团队及报名人员',
|
||||||
|
IFNULL((
|
||||||
|
SELECT MAX(child.location)
|
||||||
|
FROM sys_menu child
|
||||||
|
WHERE child.parentId = parent_menu.id
|
||||||
|
), parent_menu.location) + 1,
|
||||||
|
0,
|
||||||
|
'',
|
||||||
|
UNIX_TIMESTAMP(NOW()) * 1000,
|
||||||
|
'',
|
||||||
|
UNIX_TIMESTAMP(NOW()) * 1000,
|
||||||
|
0,
|
||||||
|
'PC',
|
||||||
|
parent_menu.moduleId,
|
||||||
|
NULL,
|
||||||
|
's',
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
FROM sys_menu parent_menu
|
||||||
|
WHERE parent_menu.permission = 'recuperation'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM (SELECT id FROM sys_menu WHERE permission = 'recuperation.flexibleGroupQuery') existing_menu
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 系统管理员默认拥有补充菜单权限,其他业务角色可在角色管理中按需分配。
|
||||||
|
INSERT INTO sys_role_menu (roleId, menuId)
|
||||||
|
SELECT role_info.id, menu_info.id
|
||||||
|
FROM sys_role role_info
|
||||||
|
JOIN sys_menu menu_info ON menu_info.permission IN (
|
||||||
|
'recuperation.lineStatistics',
|
||||||
|
'recuperation.flexibleGroupQuery'
|
||||||
|
)
|
||||||
|
LEFT JOIN sys_role_menu role_menu
|
||||||
|
ON role_menu.roleId = role_info.id
|
||||||
|
AND role_menu.menuId = menu_info.id
|
||||||
|
WHERE role_info.code = 'SYSADMIN'
|
||||||
|
AND role_menu.roleId IS NULL;
|
||||||
@@ -319,6 +319,18 @@ layout("/layouts/platform.html"){
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<el-form-item label="福利通知附件" prop="noticeAttachment">
|
||||||
|
<file-upload
|
||||||
|
:value.sync="formData.noticeAttachment"
|
||||||
|
:upload_number="1"
|
||||||
|
accept=".doc,.docx"
|
||||||
|
upload_mode="file"
|
||||||
|
upload_text="上传福利通知附件"
|
||||||
|
upload_result_category="interval"
|
||||||
|
upload_result_type="url"
|
||||||
|
></file-upload>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="封面图片" prop="cover">
|
<el-form-item label="封面图片" prop="cover">
|
||||||
<file-upload
|
<file-upload
|
||||||
:value.sync="formData.cover"
|
:value.sync="formData.cover"
|
||||||
@@ -485,6 +497,7 @@ layout("/layouts/platform.html"){
|
|||||||
noticePushMode: 1,
|
noticePushMode: 1,
|
||||||
groupRequired: false,
|
groupRequired: false,
|
||||||
groupSelectionConfigs: [],
|
groupSelectionConfigs: [],
|
||||||
|
noticeAttachment: "",
|
||||||
options: [],
|
options: [],
|
||||||
welfareProjectSubjects: [],
|
welfareProjectSubjects: [],
|
||||||
flexibleGifts: [{}]
|
flexibleGifts: [{}]
|
||||||
|
|||||||
@@ -43,12 +43,10 @@ const welfareOption = {
|
|||||||
|
|
||||||
<el-table-column align="center" header-align="center" label="系统默认选择" width="140">
|
<el-table-column align="center" header-align="center" label="系统默认选择" width="140">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-radio
|
<el-checkbox
|
||||||
v-model="systemDefaultOption"
|
:value="!!row.isSystemDefault"
|
||||||
:label="row"
|
@change="setSystemDefault(row, $event)">
|
||||||
@change="setSystemDefault(row)">
|
</el-checkbox>
|
||||||
|
|
||||||
</el-radio>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
@@ -170,7 +168,6 @@ const welfareOption = {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
welfareList: [],
|
welfareList: [],
|
||||||
systemDefaultOption: null,
|
|
||||||
localGroupRequired: false,
|
localGroupRequired: false,
|
||||||
descriptionDialog: {
|
descriptionDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
@@ -187,10 +184,6 @@ const welfareOption = {
|
|||||||
created() {
|
created() {
|
||||||
this.welfareList = this.value ? JSON.parse(JSON.stringify(this.value)) : [];
|
this.welfareList = this.value ? JSON.parse(JSON.stringify(this.value)) : [];
|
||||||
this.localGroupRequired = Boolean(this.groupRequired);
|
this.localGroupRequired = Boolean(this.groupRequired);
|
||||||
this.systemDefaultOption = this.welfareList.find((item) => item.isSystemDefault) || null;
|
|
||||||
if (this.systemDefaultOption) {
|
|
||||||
this.setSystemDefault(this.systemDefaultOption);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
@@ -298,22 +291,16 @@ const welfareOption = {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 每个福利项目只允许配置一个系统默认选项,保存时会随福利选项一并提交。
|
// 每个福利选项独立维护系统默认状态,支持同时勾选多个选项或取消已有勾选。
|
||||||
setSystemDefault(defaultOption) {
|
setSystemDefault(option, selected) {
|
||||||
this.welfareList.forEach((item) => {
|
this.$set(option, 'isSystemDefault', selected);
|
||||||
this.$set(item, 'isSystemDefault', item === defaultOption);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteOption(index) {
|
deleteOption(index) {
|
||||||
this.$confirm('确认删除该福利选项?', '提示', {
|
this.$confirm('确认删除该福利选项?', '提示', {
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const deletedOption = this.welfareList[index];
|
|
||||||
this.welfareList.splice(index, 1);
|
this.welfareList.splice(index, 1);
|
||||||
if (this.systemDefaultOption === deletedOption) {
|
|
||||||
this.systemDefaultOption = null;
|
|
||||||
}
|
|
||||||
this.updateSortNumbers();
|
this.updateSortNumbers();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -442,7 +429,7 @@ const welfareOption = {
|
|||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.welfare-option .el-radio__label {
|
.welfare-option .el-checkbox__label {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,11 +135,6 @@ layout("/layouts/platform.html"){
|
|||||||
<span v-else>暂无</span>
|
<span v-else>暂无</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template scope="{row}" v-else-if="column.prop=='deliveryDate'">
|
|
||||||
<span v-if="row.deliveryDate">{{$moment(row.deliveryDate).format('YYYY-MM-DD')}}</span>
|
|
||||||
<span v-else>暂无</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template scope="{row}" v-else-if="column.prop=='remark'">
|
<template scope="{row}" v-else-if="column.prop=='remark'">
|
||||||
<span v-if="row.remark">{{row.remark}}</span>
|
<span v-if="row.remark">{{row.remark}}</span>
|
||||||
<span v-else>暂无</span>
|
<span v-else>暂无</span>
|
||||||
@@ -224,7 +219,6 @@ layout("/layouts/platform.html"){
|
|||||||
{ prop: "choiceTime", label: "选择时间" },
|
{ prop: "choiceTime", label: "选择时间" },
|
||||||
{ prop: "isChoose", label: "是否选择" },
|
{ prop: "isChoose", label: "是否选择" },
|
||||||
{ prop: "gist_list", label: "所选福利" },
|
{ prop: "gist_list", label: "所选福利" },
|
||||||
{ prop: "deliveryDate", label: "配送时间" },
|
|
||||||
{ prop: "remark", label: "备注" }
|
{ prop: "remark", label: "备注" }
|
||||||
// { prop: "receiveAddress", label: "收货地址" }
|
// { prop: "receiveAddress", label: "收货地址" }
|
||||||
],
|
],
|
||||||
@@ -289,15 +283,15 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配送日期到达后才显示评价入口;没有配送日期的历史数据不允许评价。
|
* 用户已选择福利且活动结束后显示评价入口。
|
||||||
* @param row 福利项目列表行,deliveryDate 为 yyyy-MM-dd 日期
|
* @param row 福利项目列表行,choiceTimeEnd 为活动结束时间
|
||||||
* @return {boolean} 当前日期达到配送日期时返回 true
|
* @return {boolean} 当前时间达到活动结束时间时返回 true
|
||||||
*/
|
*/
|
||||||
canEvaluate(row) {
|
canEvaluate(row) {
|
||||||
if (!row.isChoose || !row.deliveryDate) {
|
if (!row.isChoose || !row.choiceTimeEnd) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return this.$moment().startOf("day").valueOf() >= this.$moment(row.deliveryDate).startOf("day").valueOf()
|
return this.$moment().valueOf() >= this.$moment(row.choiceTimeEnd).valueOf()
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -172,19 +172,6 @@ const optionSelect = {
|
|||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item prop="deliveryDate" label="配送时间">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="contactForm.deliveryDate"
|
|
||||||
type="date"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
format="yyyy-MM-dd"
|
|
||||||
placeholder="请选择配送时间"
|
|
||||||
:picker-options="deliveryDatePickerOptions"
|
|
||||||
style="width: 100%">
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item prop="remark" label="备注">
|
<el-form-item prop="remark" label="备注">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -285,7 +272,6 @@ const optionSelect = {
|
|||||||
receiveAddress: "",
|
receiveAddress: "",
|
||||||
userName: "", // 收货人
|
userName: "", // 收货人
|
||||||
userSign: "",
|
userSign: "",
|
||||||
deliveryDate: "", // 配送日期,按 yyyy-MM-dd 提交
|
|
||||||
remark: "" // 用户自选和管理员代选共用的选择备注
|
remark: "" // 用户自选和管理员代选共用的选择备注
|
||||||
},
|
},
|
||||||
contactRules: {
|
contactRules: {
|
||||||
@@ -299,15 +285,8 @@ const optionSelect = {
|
|||||||
message: "请输入正确的手机号码",
|
message: "请输入正确的手机号码",
|
||||||
trigger: "blur"
|
trigger: "blur"
|
||||||
}
|
}
|
||||||
],
|
|
||||||
deliveryDate: [
|
|
||||||
{required: true, message: "请选择配送时间", trigger: "change"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
deliveryDatePickerOptions: {
|
|
||||||
// 配送日期按天校验,选择当天允许提交。
|
|
||||||
disabledDate: (time) => time.getTime() < new Date().setHours(0, 0, 0, 0)
|
|
||||||
},
|
|
||||||
addressOptions: []
|
addressOptions: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -447,7 +426,6 @@ const optionSelect = {
|
|||||||
receiveAddress: "",
|
receiveAddress: "",
|
||||||
userName: "",
|
userName: "",
|
||||||
userSign: "",
|
userSign: "",
|
||||||
deliveryDate: "",
|
|
||||||
remark: ""
|
remark: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,8 +482,6 @@ const optionSelect = {
|
|||||||
// 本人选择按字段回退到登录人信息;代选只使用目标人员已有选择数据。
|
// 本人选择按字段回退到登录人信息;代选只使用目标人员已有选择数据。
|
||||||
this.$set(this.contactForm, "mobile", firstSelection.mobile || (!this.isProxySelect ? currentUser.mobile || "" : ""))
|
this.$set(this.contactForm, "mobile", firstSelection.mobile || (!this.isProxySelect ? currentUser.mobile || "" : ""))
|
||||||
this.$set(this.contactForm, "userName", firstSelection.userName || (!this.isProxySelect ? currentUser.username || "" : ""))
|
this.$set(this.contactForm, "userName", firstSelection.userName || (!this.isProxySelect ? currentUser.username || "" : ""))
|
||||||
this.$set(this.contactForm, "deliveryDate", this.userSelection[0].deliveryDate
|
|
||||||
? this.$moment(this.userSelection[0].deliveryDate).format("YYYY-MM-DD") : "")
|
|
||||||
this.$set(this.contactForm, "remark", this.userSelection[0].remark || "")
|
this.$set(this.contactForm, "remark", this.userSelection[0].remark || "")
|
||||||
} else {
|
} else {
|
||||||
if (this.isProxySelect) {
|
if (this.isProxySelect) {
|
||||||
@@ -640,7 +616,6 @@ const optionSelect = {
|
|||||||
userName: this.showReceivingContact ? this.contactForm.userName : "",
|
userName: this.showReceivingContact ? this.contactForm.userName : "",
|
||||||
userSign: this.contactForm.userSign,
|
userSign: this.contactForm.userSign,
|
||||||
receiveAddress: this.showReceivingContact ? this.contactForm.receiveAddress : "",
|
receiveAddress: this.showReceivingContact ? this.contactForm.receiveAddress : "",
|
||||||
deliveryDate: this.contactForm.deliveryDate,
|
|
||||||
remark: this.contactForm.remark
|
remark: this.contactForm.remark
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -655,7 +630,6 @@ const optionSelect = {
|
|||||||
userName: this.showReceivingContact ? this.contactForm.userName : "",
|
userName: this.showReceivingContact ? this.contactForm.userName : "",
|
||||||
userSign: this.contactForm.userSign,
|
userSign: this.contactForm.userSign,
|
||||||
receiveAddress: this.showReceivingContact ? this.contactForm.receiveAddress : "",
|
receiveAddress: this.showReceivingContact ? this.contactForm.receiveAddress : "",
|
||||||
deliveryDate: this.contactForm.deliveryDate,
|
|
||||||
remark: this.contactForm.remark
|
remark: this.contactForm.remark
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,11 +88,11 @@ layout("/layouts/platform.html"){
|
|||||||
></dict-select>
|
></dict-select>
|
||||||
</search-item>
|
</search-item>
|
||||||
|
|
||||||
<search-item label="人员分类">
|
<!-- <search-item label="人员分类">-->
|
||||||
<el-select clearable filterable placeholder="请选择人员分类" style="width: 100%" v-model="pageForm.aidFundMemberUserType">
|
<!-- <el-select clearable filterable placeholder="请选择人员分类" style="width: 100%" v-model="pageForm.aidFundMemberUserType">-->
|
||||||
<el-option :key="item.code" :label="item.name" :value="item.code" v-for="item in aidFundMemberUserTypeOptions"></el-option>
|
<!-- <el-option :key="item.code" :label="item.name" :value="item.code" v-for="item in aidFundMemberUserTypeOptions"></el-option>-->
|
||||||
</el-select>
|
<!-- </el-select>-->
|
||||||
</search-item>
|
<!-- </search-item>-->
|
||||||
</search>
|
</search>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@@ -224,7 +224,6 @@ layout("/layouts/platform.html"){
|
|||||||
{ prop: "welfareUnionName", label: "所属工会", sortable: true },
|
{ prop: "welfareUnionName", label: "所属工会", sortable: true },
|
||||||
{ prop: "welfareUnitName", label: "所属单位", sortable: true },
|
{ prop: "welfareUnitName", label: "所属单位", sortable: true },
|
||||||
{ prop: "selectedOptions", label: "所选福利", sortable: true },
|
{ prop: "selectedOptions", label: "所选福利", sortable: true },
|
||||||
{ prop: "deliveryDate", label: "配送时间", sortable: true },
|
|
||||||
{ prop: "mobile", label: "联系电话", sortable: true }
|
{ prop: "mobile", label: "联系电话", sortable: true }
|
||||||
],
|
],
|
||||||
optionSelectVisible: false,
|
optionSelectVisible: false,
|
||||||
@@ -239,6 +238,13 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
noticeDetailUrl() {
|
||||||
|
if (!this.pageForm.projectId) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
const appDomain = typeof APP_DOMAIN !== "undefined" && APP_DOMAIN ? APP_DOMAIN : window.location.origin
|
||||||
|
return appDomain.replace(/\/+$/, "") + "/platform/welfare/notice/detail?id=" + encodeURIComponent(this.pageForm.projectId)
|
||||||
|
},
|
||||||
welfareOptions() {
|
welfareOptions() {
|
||||||
if (this.pageForm.projectId) {
|
if (this.pageForm.projectId) {
|
||||||
return this.projectOptions.find((item) => item.id === this.pageForm.projectId)?.options
|
return this.projectOptions.find((item) => item.id === this.pageForm.projectId)?.options
|
||||||
@@ -312,7 +318,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.$message.warning("请先选择福利项目")
|
this.$message.warning("请先选择福利项目")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$set(this.messageDialog, "messageContent", "")
|
this.$set(this.messageDialog, "messageContent", "查看详情:" + this.noticeDetailUrl)
|
||||||
this.$set(this.messageDialog, "visible", true)
|
this.$set(this.messageDialog, "visible", true)
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs.messageForm) {
|
if (this.$refs.messageForm) {
|
||||||
@@ -338,7 +344,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.$message.warning("请输入有效的消息内容")
|
this.$message.warning("请输入有效的消息内容")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.messageSending = true
|
this.$set(this, "messageSending", true)
|
||||||
this.$axios.post("/platform/welfare/selection/situation/sendMessage", {
|
this.$axios.post("/platform/welfare/selection/situation/sendMessage", {
|
||||||
pageForm: JSON.stringify(this.pageForm),
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
messageContent: messageContent
|
messageContent: messageContent
|
||||||
@@ -350,67 +356,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.$message.error(res.msg)
|
this.$message.error(res.msg)
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.messageSending = false
|
this.$set(this, "messageSending", false)
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 按当前页面全部查询条件导出签收单模版,后台会再次叠加登录人的数据权限。
|
|
||||||
exportReceiveTemplate() {
|
|
||||||
if (!this.pageForm.projectId) {
|
|
||||||
this.$message.warning("请先选择福利项目")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$downLoad("/platform/welfare/selection/situation/exportReceiveTemplate", {
|
|
||||||
pageForm: JSON.stringify(this.pageForm)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 打开发送窗口时清空上次编辑内容,实际接收人由后台按当前查询条件重新计算。
|
|
||||||
openMessageDialog() {
|
|
||||||
if (!this.pageForm.projectId) {
|
|
||||||
this.$message.warning("请先选择福利项目")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$set(this.messageDialog, "messageContent", "")
|
|
||||||
this.$set(this.messageDialog, "visible", true)
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (this.$refs.messageForm) {
|
|
||||||
this.$refs.messageForm.clearValidate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
closeMessageDialog(done) {
|
|
||||||
this.$set(this.messageDialog, "visible", false)
|
|
||||||
if (typeof done === "function") {
|
|
||||||
done()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
sendMessage() {
|
|
||||||
this.$refs.messageForm.validate((valid) => {
|
|
||||||
if (!valid) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const messageContent = (this.messageDialog.messageContent || "").trim()
|
|
||||||
if (!messageContent) {
|
|
||||||
this.$message.warning("请输入有效的消息内容")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.messageSending = true
|
|
||||||
this.$axios.post("/platform/welfare/selection/situation/sendMessage", {
|
|
||||||
pageForm: JSON.stringify(this.pageForm),
|
|
||||||
messageContent: messageContent
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.$message.success(res.msg)
|
|
||||||
this.closeMessageDialog()
|
|
||||||
} else {
|
|
||||||
this.$message.error(res.msg)
|
|
||||||
}
|
|
||||||
}).finally(() => {
|
|
||||||
this.messageSending = false
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1351,15 +1351,15 @@ layout("/layouts/platform_h5.html"){
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配送日期到达后才显示移动端评价入口;历史记录未设置配送日期时保持隐藏。
|
* 当前用户已选择福利且项目活动结束后显示移动端评价入口。
|
||||||
* @param row 我的福利列表行,deliveryDate 为 yyyy-MM-dd 日期
|
* @param row 我的福利列表行,choiceTimeEnd 为活动结束时间
|
||||||
* @return {boolean} 当前日期达到配送日期时返回 true
|
* @return {boolean} 当前时间达到活动结束时间时返回 true
|
||||||
*/
|
*/
|
||||||
canEvaluate(row) {
|
canEvaluate(row) {
|
||||||
if (!row || !row.deliveryDate) {
|
if (!row || !row.isChoose || !row.choiceTimeEnd) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return this.$moment().startOf("day").valueOf() >= this.$moment(row.deliveryDate).startOf("day").valueOf()
|
return this.$moment().valueOf() >= this.$moment(row.choiceTimeEnd).valueOf()
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform_h5.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.welfare-notice-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f7f8fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welfare-notice-card {
|
||||||
|
margin: 12px;
|
||||||
|
padding: 14px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welfare-notice-title {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: #323233;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welfare-notice-viewer {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100vh - 150px);
|
||||||
|
border: 0;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welfare-notice-empty {
|
||||||
|
padding: 50px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app" v-cloak class="welfare-notice-page" v-loading="pageLoading">
|
||||||
|
<van-nav-bar title="福利通知" left-text="返回" left-arrow fixed placeholder @click-left="back"></van-nav-bar>
|
||||||
|
<div class="welfare-notice-card" v-if="notice.fileId">
|
||||||
|
<div class="welfare-notice-title">{{notice.projectName}}</div>
|
||||||
|
<iframe class="welfare-notice-viewer" :src="viewerUrl" :title="notice.fileName"></iframe>
|
||||||
|
<van-button block type="primary" plain @click="download">下载原文件</van-button>
|
||||||
|
</div>
|
||||||
|
<van-empty v-else-if="!pageLoading" class="welfare-notice-empty" description="暂无福利通知附件"></van-empty>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script nonce="${cspNonce!}">
|
||||||
|
new Vue({
|
||||||
|
el: "#app",
|
||||||
|
data() {
|
||||||
|
const query = new URLSearchParams(window.location.search)
|
||||||
|
return {
|
||||||
|
projectId: query.get("id") || "",
|
||||||
|
notice: {},
|
||||||
|
pageLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
viewerUrl() {
|
||||||
|
if (!this.notice.previewUrl) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return "/assets/platform/plugins/pdfJs/web/viewer.html?file=" + encodeURIComponent(this.notice.previewUrl)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
back() {
|
||||||
|
window.history.back()
|
||||||
|
},
|
||||||
|
loadNotice() {
|
||||||
|
this.$set(this, "pageLoading", true)
|
||||||
|
this.$axios.post("/platform/welfare/notice/detailData", {id: this.projectId}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$set(this, "notice", res.data || {})
|
||||||
|
} else {
|
||||||
|
this.$toast.fail(res.msg)
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.$set(this, "pageLoading", false)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
download() {
|
||||||
|
if (this.notice.attachmentUrl) {
|
||||||
|
window.location.href = this.notice.attachmentUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadNotice()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -918,16 +918,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
maxlength="11"
|
maxlength="11"
|
||||||
required
|
required
|
||||||
></van-field>
|
></van-field>
|
||||||
<van-field
|
|
||||||
v-model="formData.deliveryDate"
|
|
||||||
label="配送时间"
|
|
||||||
placeholder="请选择配送时间"
|
|
||||||
readonly
|
|
||||||
clickable
|
|
||||||
is-link
|
|
||||||
@click="openDeliveryCalendar"
|
|
||||||
required
|
|
||||||
></van-field>
|
|
||||||
<van-field
|
<van-field
|
||||||
v-model="formData.remark"
|
v-model="formData.remark"
|
||||||
label="备注"
|
label="备注"
|
||||||
@@ -990,20 +980,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
</div>
|
</div>
|
||||||
</van-popup>
|
</van-popup>
|
||||||
|
|
||||||
<!-- 配送日期使用 Vant 日历快捷选择,点击日期后立即确认;弹层同步接入全局历史栈。 -->
|
|
||||||
<van-calendar
|
|
||||||
v-model="showDeliveryCalendar"
|
|
||||||
title="选择配送时间"
|
|
||||||
type="single"
|
|
||||||
color="#1989fa"
|
|
||||||
:show-confirm="false"
|
|
||||||
:close-on-click-overlay="false"
|
|
||||||
:min-date="deliveryCalendarMinDate"
|
|
||||||
:default-date="deliveryCalendarDefaultDate"
|
|
||||||
@confirm="confirmDeliveryDate"
|
|
||||||
@close="handleHistoryLayerComponentClose('delivery-calendar')">
|
|
||||||
</van-calendar>
|
|
||||||
|
|
||||||
<!-- 选项详情弹窗 -->
|
<!-- 选项详情弹窗 -->
|
||||||
<van-action-sheet v-model="showOptionDetailDialog" class="welfare-detail-sheet"
|
<van-action-sheet v-model="showOptionDetailDialog" class="welfare-detail-sheet"
|
||||||
:style="{ height: '78%' }" :close-on-click-overlay="true"
|
:style="{ height: '78%' }" :close-on-click-overlay="true"
|
||||||
@@ -1051,8 +1027,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
projectId: "",
|
projectId: "",
|
||||||
selectedRadioId: "", // 单选模式下选中的选项ID
|
selectedRadioId: "", // 单选模式下选中的选项ID
|
||||||
showConfirmDialog: false,
|
showConfirmDialog: false,
|
||||||
showDeliveryCalendar: false, // 配送日期日历弹层
|
|
||||||
deliveryCalendarDefaultDate: new Date(), // 日历打开时默认定位的日期
|
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
hasSubmittedBefore: false, // 是否之前提交过
|
hasSubmittedBefore: false, // 是否之前提交过
|
||||||
showOptionDetailDialog: false, // 选项详情弹窗
|
showOptionDetailDialog: false, // 选项详情弹窗
|
||||||
@@ -1065,7 +1039,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
address: "",// 收货地址
|
address: "",// 收货地址
|
||||||
receiveAddress: "", // 确认后的完整收货地址
|
receiveAddress: "", // 确认后的完整收货地址
|
||||||
userName: "",//收货人
|
userName: "",//收货人
|
||||||
deliveryDate: "", // 配送日期,按 yyyy-MM-dd 提交
|
|
||||||
remark: "" // 用户选择备注
|
remark: "" // 用户选择备注
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1077,11 +1050,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
|
||||||
// Vant 日历最小可选日期为当天零点,允许用户选择当天配送。
|
|
||||||
deliveryCalendarMinDate() {
|
|
||||||
return this.$moment().startOf("day").toDate()
|
|
||||||
},
|
|
||||||
|
|
||||||
// 系统默认福利必须被保留,管理端限制每个项目最多配置一个。
|
// 系统默认福利必须被保留,管理端限制每个项目最多配置一个。
|
||||||
systemDefaultOption() {
|
systemDefaultOption() {
|
||||||
if (!this.projectInfo.options) return null
|
if (!this.projectInfo.options) return null
|
||||||
@@ -1142,7 +1110,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
return Math.max(0, this.selectionLimit - this.selectedCount)
|
return Math.max(0, this.selectionLimit - this.selectedCount)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 意向选择不采集收货人、联系电话和收货地址,配送时间及备注仍按原业务要求保留。
|
// 意向选择不采集收货人、联系电话和收货地址,备注仍按原业务要求保留。
|
||||||
showReceivingContact() {
|
showReceivingContact() {
|
||||||
return Number(this.projectInfo.provideMode) !== 2
|
return Number(this.projectInfo.provideMode) !== 2
|
||||||
},
|
},
|
||||||
@@ -1174,7 +1142,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
// 根据浏览器历史中的弹层栈统一显示或关闭弹框,保证返回键与页面状态一致。
|
// 根据浏览器历史中的弹层栈统一显示或关闭弹框,保证返回键与页面状态一致。
|
||||||
syncHistoryLayerStack(stack) {
|
syncHistoryLayerStack(stack) {
|
||||||
this.showConfirmDialog = stack.includes("confirm")
|
this.showConfirmDialog = stack.includes("confirm")
|
||||||
this.$set(this, "showDeliveryCalendar", stack.includes("delivery-calendar"))
|
|
||||||
this.showAddressPopup = stack.includes("address")
|
this.showAddressPopup = stack.includes("address")
|
||||||
this.showOptionDetailDialog = stack.includes("detail")
|
this.showOptionDetailDialog = stack.includes("detail")
|
||||||
},
|
},
|
||||||
@@ -1212,36 +1179,10 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
setHistoryLayerVisible(layerName, visible) {
|
setHistoryLayerVisible(layerName, visible) {
|
||||||
if (layerName === "confirm") this.showConfirmDialog = visible
|
if (layerName === "confirm") this.showConfirmDialog = visible
|
||||||
if (layerName === "delivery-calendar") this.$set(this, "showDeliveryCalendar", visible)
|
|
||||||
if (layerName === "address") this.showAddressPopup = visible
|
if (layerName === "address") this.showAddressPopup = visible
|
||||||
if (layerName === "detail") this.showOptionDetailDialog = visible
|
if (layerName === "detail") this.showOptionDetailDialog = visible
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开配送日期日历。已有 deliveryDate 时定位到该日期,否则默认定位当天;无返回值。
|
|
||||||
* 日历作为确认选择弹层的下一层历史记录,系统返回键只关闭日历。
|
|
||||||
*/
|
|
||||||
openDeliveryCalendar() {
|
|
||||||
const selectedDate = this.formData.deliveryDate
|
|
||||||
? this.$moment(this.formData.deliveryDate, "YYYY-MM-DD").toDate()
|
|
||||||
: new Date()
|
|
||||||
// 历史配送日期早于今天时定位到今天,避免默认日期超出日历可选范围。
|
|
||||||
const defaultDate = this.$moment(selectedDate).startOf("day").valueOf()
|
|
||||||
< this.$moment().startOf("day").valueOf() ? new Date() : selectedDate
|
|
||||||
this.$set(this, "deliveryCalendarDefaultDate", defaultDate)
|
|
||||||
this.openHistoryLayer("delivery-calendar")
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 快捷选中配送日期。date 为 van-calendar 返回的 Date,写入 yyyy-MM-dd 字符串后同步回退日历历史;无返回值。
|
|
||||||
*
|
|
||||||
* @param date Vant 日历当前选中的日期
|
|
||||||
*/
|
|
||||||
confirmDeliveryDate(date) {
|
|
||||||
this.$set(this.formData, "deliveryDate", this.$moment(date).format("YYYY-MM-DD"))
|
|
||||||
this.closeHistoryLayer("delivery-calendar")
|
|
||||||
},
|
|
||||||
|
|
||||||
optionRankText(option) {
|
optionRankText(option) {
|
||||||
if (option.rankNo) {
|
if (option.rankNo) {
|
||||||
return "本次福利排行榜第" + option.rankNo + "名"
|
return "本次福利排行榜第" + option.rankNo + "名"
|
||||||
@@ -1387,10 +1328,8 @@ layout("/layouts/platform_h5.html"){
|
|||||||
this.userSelection = resp.data
|
this.userSelection = resp.data
|
||||||
this.hasSubmittedBefore = this.userSelection.length > 0
|
this.hasSubmittedBefore = this.userSelection.length > 0
|
||||||
|
|
||||||
// 配送时间和备注属于整次选择,统一从首条选择记录回显。
|
// 备注属于整次选择,统一从首条选择记录回显。
|
||||||
if (this.userSelection && this.userSelection.length > 0) {
|
if (this.userSelection && this.userSelection.length > 0) {
|
||||||
this.$set(this.formData, "deliveryDate", this.userSelection[0].deliveryDate
|
|
||||||
? this.$moment(this.userSelection[0].deliveryDate).format("YYYY-MM-DD") : "")
|
|
||||||
this.$set(this.formData, "remark", this.userSelection[0].remark || "")
|
this.$set(this.formData, "remark", this.userSelection[0].remark || "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1543,11 +1482,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 配送时间是评价开放依据,提交前必须确保不早于当前选择日期。
|
|
||||||
if (!this.validateDeliveryDate()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isSubmitting) return
|
if (this.isSubmitting) return
|
||||||
this.isSubmitting = true
|
this.isSubmitting = true
|
||||||
|
|
||||||
@@ -1568,7 +1502,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
selectNum: 1,
|
selectNum: 1,
|
||||||
mobile: this.showReceivingContact ? this.formData.mobile : "",
|
mobile: this.showReceivingContact ? this.formData.mobile : "",
|
||||||
userName: this.showReceivingContact ? this.formData.userName : "",
|
userName: this.showReceivingContact ? this.formData.userName : "",
|
||||||
deliveryDate: this.formData.deliveryDate,
|
|
||||||
remark: this.formData.remark
|
remark: this.formData.remark
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1581,7 +1514,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
selectNum: option.selectNum,
|
selectNum: option.selectNum,
|
||||||
mobile: this.showReceivingContact ? this.formData.mobile : "",
|
mobile: this.showReceivingContact ? this.formData.mobile : "",
|
||||||
userName: this.showReceivingContact ? this.formData.userName : "",
|
userName: this.showReceivingContact ? this.formData.userName : "",
|
||||||
deliveryDate: this.formData.deliveryDate,
|
|
||||||
remark: this.formData.remark
|
remark: this.formData.remark
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -1653,26 +1585,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验配送日期。deliveryDate 应传 yyyy-MM-dd,返回布尔值表示是否允许继续提交。
|
|
||||||
* 日期按天比较,配送日期等于选择当天时允许提交。
|
|
||||||
*
|
|
||||||
* @return {boolean} 配送日期有效返回 true,否则提示错误并返回 false
|
|
||||||
*/
|
|
||||||
validateDeliveryDate() {
|
|
||||||
if (!this.formData.deliveryDate) {
|
|
||||||
this.$toast.fail("请选择配送时间")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const deliveryDate = this.$moment(this.formData.deliveryDate).startOf("day").valueOf()
|
|
||||||
const currentDate = this.$moment().startOf("day").valueOf()
|
|
||||||
if (deliveryDate < currentDate) {
|
|
||||||
this.$toast.fail("配送时间不能早于选择时间")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
|
|
||||||
// 提交选择
|
// 提交选择
|
||||||
submitSelection() {
|
submitSelection() {
|
||||||
if (!this.hasSelection) {
|
if (!this.hasSelection) {
|
||||||
|
|||||||
@@ -505,10 +505,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-icon name="clock-o"></van-icon>
|
<van-icon name="clock-o"></van-icon>
|
||||||
<span>选择时间:未设置</span>
|
<span>选择时间:未设置</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="welfare-list-card__time" v-if="Number(row.isChoose) === 1">
|
|
||||||
<van-icon name="logistics"></van-icon>
|
|
||||||
<span>配送时间:{{ row.deliveryDate ? $moment(row.deliveryDate).format('YYYY-MM-DD') : '暂无' }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="welfare-list-card__time" v-if="Number(row.isChoose) === 1 && row.remark">
|
<div class="welfare-list-card__time" v-if="Number(row.isChoose) === 1 && row.remark">
|
||||||
<van-icon name="notes-o"></van-icon>
|
<van-icon name="notes-o"></van-icon>
|
||||||
<span>备注:{{ row.remark }}</span>
|
<span>备注:{{ row.remark }}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user