职工福利功能优化

This commit is contained in:
2026-09-06 15:48:25 +08:00
parent c0d9636e1f
commit b87567230f
21 changed files with 536 additions and 269 deletions
@@ -38,6 +38,7 @@ import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Base64;
@@ -270,10 +271,12 @@ public class SysFileServiceImpl extends BaseServiceImpl<Sys_file> implements Sys
}
}
HtmlSaveOptions saveOptions = new HtmlSaveOptions();
// Aspose输出和字节流读取必须固定使用UTF-8,避免不同服务器的JVM默认编码导致中文乱码。
saveOptions.setEncoding(StandardCharsets.UTF_8);
saveOptions.setExportImagesAsBase64(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
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);
Matcher matcher = pattern.matcher(htmlContent);
@@ -60,7 +60,6 @@ public class WelfareMineController {
END AS isChoose,
GROUP_CONCAT(DISTINCT wuso.optionName ,'',wus.selectNum,'份)') AS gist_list,
MAX(wus.selectTime) AS selectTime,
MAX(wus.deliveryDate) AS deliveryDate,
wus.receiveAddress,
wl.userId
FROM
@@ -98,7 +97,6 @@ public class WelfareMineController {
wpus.receiveAddress,
wpso.optionName,
wpus.selectNum,
wpus.deliveryDate,
wpus.remark,
wpus.userSign,
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
END AS isChoose,
wus.selectTime,
MAX(wus.deliveryDate) AS deliveryDate,
MAX(wus.remark) AS remark,
GROUP_CONCAT(DISTINCT wuso.optionName ,'',wus.selectNum,'份)') AS gist_list,
wus.receiveAddress
@@ -207,6 +207,14 @@ public class WelfareProject extends BaseModel implements SysHomeConvert {
@ColDefine(type = ColType.VARCHAR, width = 200)
private String cover;
/**
* 福利通知附件下载地址,只允许关联一个 Word 文件。
*/
@Column
@Comment("福利通知附件")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String noticeAttachment;
@Column
@Comment("是否全年生日蛋糕卷")
@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.zhgh.welfare.model.WelfareProject;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.List;
@@ -25,6 +26,14 @@ public interface WelfareProjectService extends BaseService<WelfareProject> {
*/
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);
/**
* 校验福利选择附加信息。配送时间为必填项,必须按日期粒度不早于本次选择时间;
* 同一次提交的全部福利项必须使用相同配送时间和备注。
* 校验福利选择附加信息。同一次提交的全部福利项必须使用相同备注,配送时间字段已停用。
*
* @param selections 用户提交的福利选择数组,每项需包含 deliveryDate,可选包含 remark
* @param selectTime 后端生成的本次选择时间,用于防止客户端伪造日期
* @param selections 用户提交的福利选择数组,每项包含 remark
* @param selectTime 后端生成的本次选择时间,保留该参数以兼容现有调用接口
* @return 校验通过返回 {@code null},否则返回可直接展示的错误提示
*/
String validateSelectionAdditionalInfo(WelfareUserSelection[] selections, Date selectTime);
@@ -15,11 +15,17 @@ public interface WelfareSelectionSituationService extends BaseService<WelfareLis
* 根据选择情况页面的全部查询条件发送钉钉消息。
*
* @param pageForm 查询条件,包含项目、福利选项、人员信息、组织范围及选择状态
* @param messageContent 纯文本消息内容,不应包含HTML标签或富文本样式
* @param messageContent 纯文本消息内容,不应包含HTML标签或富文本样式;发送前会补充福利通知详情地址
* @return 实际提交到钉钉消息渠道的去重人员数量
*/
int sendDingTalkMessage(WelfareSelectionSituationPageForm pageForm, String messageContent);
/**
* 按选择情况页面的查询条件导出人员选择明细。
*
* @param pageForm 页面查询条件,包含项目、福利选项、姓名、工号、组织范围、人员类型和选择状态
* @param response HTTP响应,返回包含快递单号和签字图片的XLSX文件流
*/
void exportXlsx(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> {
/**
* 校验当前用户是否已到福利配送日期。只有存在选择记录、全部记录已设置配送日期,且当前日期
* 不早于配送日期时才允许打开或提交评价
* 校验当前用户是否已经选择福利且项目活动已经结束。活动结束时间以福利项目的
* choiceTimeEnd 为准,PC、移动端与接口提交使用同一规则
*
* @param projectId 福利项目ID
* @param userId 当前登录用户ID
@@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
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.zhgh.welfare.model.WelfareList;
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));
}
@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
public String validateSystemDefaultOptionSelection(String projectId, WelfareUserSelection[] selections) {
List<WelfareProjectSubjectOption> systemDefaultOptions = dao().query(WelfareProjectSubjectOption.class,
@@ -182,8 +202,8 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
}
/**
* 校验一次选择提交中的配送日期和备注。日期比较统一截断到当天零点,允许选择当天配送
* 多项福利的附加信息必须一致,避免同一次选择产生互相冲突的评价开放时间
* 校验一次选择提交中的备注。配送时间字段已停用,新提交数据统一清空该字段
* 多项福利的备注必须一致,避免同一次选择出现互相冲突的附加信息
*
* @param selections 当前提交的福利选择数据
* @param selectTime 后端生成的选择时间
@@ -194,30 +214,23 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
if (selections == null || selections.length == 0) {
return "请至少选择一项福利";
}
Date selectionDate = DateUtil.beginOfDay(selectTime == null ? new Date() : selectTime);
Date submittedDeliveryDate = null;
String submittedRemark = null;
boolean firstSelection = true;
for (WelfareUserSelection selection : selections) {
if (selection == null || selection.getDeliveryDate() == null) {
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 "同一次选择的备注必须一致";
if (selection == null) {
return "福利选择数据不能为空";
}
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) {
return "备注不能超过200字";
}
selection.setDeliveryDate(deliveryDate);
selection.setDeliveryDate(null);
selection.setRemark(remark);
}
return null;
@@ -257,6 +270,7 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
@Override
@Aop(TransAop.READ_COMMITTED)
public void saveProject(WelfareProject project) {
normalizeNoticeAttachment(project);
// 保存前根据福利选项分组去重并校验选择数量范围,防止非法 JSON 配置进入数据库。
normalizeGroupSelectionConfigs(project);
// 插入项目
@@ -272,6 +286,7 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
@Override
@Aop(TransAop.READ_COMMITTED)
public void updateProject(WelfareProject project) {
normalizeNoticeAttachment(project);
// 修改项目时同样归一化分组配置,确保新增、编辑两条保存链路规则一致。
normalizeGroupSelectionConfigs(project);
// 更新项目
@@ -325,6 +340,55 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
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 时表示不限,不参与最小值与最大值的大小比较。
@@ -14,6 +14,7 @@ import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
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.PageUtil;
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.web.commons.auth.utils.AuthUtil;
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.WelfareProject;
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 t2.mobile) AS mobile,
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
MAX(t2.deliveryDate) AS deliveryDate,
t4.username AS userName,
t4.loginname AS loginName,
t4.sex,
@@ -143,7 +144,16 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
}
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) {
throw new BaseException("钉钉消息发送失败,请检查消息发送配置或稍后重试");
}
@@ -190,12 +200,15 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
Sql sql = Sqls.create("""
SELECT
t1.id,
t1.userId,
t1.welfareUnionName,
t1.welfareUnitName,
GROUP_CONCAT(DISTINCT t3.optionName,'',t2.selectNum,'份)') AS selectedOptions,
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
GROUP_CONCAT(DISTINCT t2.userName) AS userName2,
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
GROUP_CONCAT(DISTINCT t2.courierNumber) AS legacyCourierNumber,
MAX(t2.userSign) AS userSign,
t4.username AS userName,
t4.loginname AS loginName,
t4.sex
@@ -244,6 +257,8 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
cnd.groupBy("t1.id");
sql.setCondition(cnd);
List<NutMap> list = listMap(sql);
fillExportCourierNumbers(list, pageForm);
list.forEach(this::fillExportUserSign);
// 项目
WelfareProject project = dao().fetch(WelfareProject.class, pageForm.getProjectId());
@@ -263,6 +278,13 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
if(project.getProvideMode() == 3){
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();
@@ -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
public void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
@@ -4,7 +4,6 @@ import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
@@ -59,8 +58,8 @@ public class WelfareUserEvaluationServiceImpl extends BaseServiceImpl<WelfareUse
}
/**
* 评价开放时间以后端福利选择记录为准,避免客户端隐藏按钮后仍可直接调用评价接口。
* 配送时间按日期粒度比较,到达配送日期当天即可评价。
* 评价开放时间以后端福利项目活动结束时间为准,避免客户端隐藏按钮后仍可直接调用评价接口。
* 当前用户必须已经存在福利选择记录,且当前时间达到 choiceTimeEnd 才允许评价。
*
* @param projectId 福利项目ID
* @param userId 当前登录用户ID
@@ -77,14 +76,15 @@ public class WelfareUserEvaluationServiceImpl extends BaseServiceImpl<WelfareUse
if (selections.isEmpty()) {
return "当前项目暂无可评价的福利选择";
}
Date currentDate = DateUtil.beginOfDay(new Date());
for (WelfareUserSelection selection : selections) {
if (selection.getDeliveryDate() == null) {
return "当前福利尚未设置配送时间,暂不能评价";
}
if (currentDate.before(DateUtil.beginOfDay(selection.getDeliveryDate()))) {
return "配送时间未到,暂不能评价";
}
WelfareProject project = dao().fetch(WelfareProject.class, projectId);
if (project == null) {
return "福利项目不存在";
}
if (project.getChoiceTimeEnd() == null) {
return "当前福利未设置活动结束时间,暂不能评价";
}
if (new Date().before(project.getChoiceTimeEnd())) {
return "福利活动尚未结束,暂不能评价";
}
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>
</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">
<file-upload
:value.sync="formData.cover"
@@ -485,6 +497,7 @@ layout("/layouts/platform.html"){
noticePushMode: 1,
groupRequired: false,
groupSelectionConfigs: [],
noticeAttachment: "",
options: [],
welfareProjectSubjects: [],
flexibleGifts: [{}]
@@ -43,12 +43,10 @@ const welfareOption = {
<el-table-column align="center" header-align="center" label="系统默认选择" width="140">
<template slot-scope="{row}">
<el-radio
v-model="systemDefaultOption"
:label="row"
@change="setSystemDefault(row)">
&nbsp;
</el-radio>
<el-checkbox
:value="!!row.isSystemDefault"
@change="setSystemDefault(row, $event)">
</el-checkbox>
</template>
</el-table-column>
@@ -170,7 +168,6 @@ const welfareOption = {
data() {
return {
welfareList: [],
systemDefaultOption: null,
localGroupRequired: false,
descriptionDialog: {
visible: false,
@@ -187,10 +184,6 @@ const welfareOption = {
created() {
this.welfareList = this.value ? JSON.parse(JSON.stringify(this.value)) : [];
this.localGroupRequired = Boolean(this.groupRequired);
this.systemDefaultOption = this.welfareList.find((item) => item.isSystemDefault) || null;
if (this.systemDefaultOption) {
this.setSystemDefault(this.systemDefaultOption);
}
},
watch: {
@@ -298,22 +291,16 @@ const welfareOption = {
return true;
},
// 每个福利项目只允许配置一个系统默认选项,保存时会随福利选项一并提交
setSystemDefault(defaultOption) {
this.welfareList.forEach((item) => {
this.$set(item, 'isSystemDefault', item === defaultOption);
});
// 每个福利选项独立维护系统默认状态,支持同时勾选多个选项或取消已有勾选
setSystemDefault(option, selected) {
this.$set(option, 'isSystemDefault', selected);
},
deleteOption(index) {
this.$confirm('确认删除该福利选项?', '提示', {
type: 'warning'
}).then(() => {
const deletedOption = this.welfareList[index];
this.welfareList.splice(index, 1);
if (this.systemDefaultOption === deletedOption) {
this.systemDefaultOption = null;
}
this.updateSortNumbers();
});
},
@@ -442,7 +429,7 @@ const welfareOption = {
transform: translate(-50%, -50%);
}
.welfare-option .el-radio__label {
.welfare-option .el-checkbox__label {
padding-left: 0;
}
@@ -135,11 +135,6 @@ layout("/layouts/platform.html"){
<span v-else>暂无</span>
</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'">
<span v-if="row.remark">{{row.remark}}</span>
<span v-else>暂无</span>
@@ -224,7 +219,6 @@ layout("/layouts/platform.html"){
{ prop: "choiceTime", label: "选择时间" },
{ prop: "isChoose", label: "是否选择" },
{ prop: "gist_list", label: "所选福利" },
{ prop: "deliveryDate", label: "配送时间" },
{ prop: "remark", label: "备注" }
// { prop: "receiveAddress", label: "收货地址" }
],
@@ -289,15 +283,15 @@ layout("/layouts/platform.html"){
},
/**
* 配送日期到达后才显示评价入口;没有配送日期的历史数据不允许评价
* @param row 福利项目列表行,deliveryDate 为 yyyy-MM-dd 日期
* @return {boolean} 当前日期达到配送日期时返回 true
* 用户已选择福利且活动结束后显示评价入口
* @param row 福利项目列表行,choiceTimeEnd 为活动结束时间
* @return {boolean} 当前时间达到活动结束时间时返回 true
*/
canEvaluate(row) {
if (!row.isChoose || !row.deliveryDate) {
if (!row.isChoose || !row.choiceTimeEnd) {
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-form-item>
</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-form-item prop="remark" label="备注">
<el-input
@@ -285,7 +272,6 @@ const optionSelect = {
receiveAddress: "",
userName: "", // 收货人
userSign: "",
deliveryDate: "", // 配送日期,按 yyyy-MM-dd 提交
remark: "" // 用户自选和管理员代选共用的选择备注
},
contactRules: {
@@ -299,15 +285,8 @@ const optionSelect = {
message: "请输入正确的手机号码",
trigger: "blur"
}
],
deliveryDate: [
{required: true, message: "请选择配送时间", trigger: "change"}
]
},
deliveryDatePickerOptions: {
// 配送日期按天校验,选择当天允许提交。
disabledDate: (time) => time.getTime() < new Date().setHours(0, 0, 0, 0)
},
addressOptions: []
}
},
@@ -447,7 +426,6 @@ const optionSelect = {
receiveAddress: "",
userName: "",
userSign: "",
deliveryDate: "",
remark: ""
}
@@ -504,8 +482,6 @@ const optionSelect = {
// 本人选择按字段回退到登录人信息;代选只使用目标人员已有选择数据。
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, "deliveryDate", this.userSelection[0].deliveryDate
? this.$moment(this.userSelection[0].deliveryDate).format("YYYY-MM-DD") : "")
this.$set(this.contactForm, "remark", this.userSelection[0].remark || "")
} else {
if (this.isProxySelect) {
@@ -640,7 +616,6 @@ const optionSelect = {
userName: this.showReceivingContact ? this.contactForm.userName : "",
userSign: this.contactForm.userSign,
receiveAddress: this.showReceivingContact ? this.contactForm.receiveAddress : "",
deliveryDate: this.contactForm.deliveryDate,
remark: this.contactForm.remark
}
]
@@ -655,7 +630,6 @@ const optionSelect = {
userName: this.showReceivingContact ? this.contactForm.userName : "",
userSign: this.contactForm.userSign,
receiveAddress: this.showReceivingContact ? this.contactForm.receiveAddress : "",
deliveryDate: this.contactForm.deliveryDate,
remark: this.contactForm.remark
}))
}
@@ -88,11 +88,11 @@ layout("/layouts/platform.html"){
></dict-select>
</search-item>
<search-item label="人员分类">
<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-select>
</search-item>
<!-- <search-item label="人员分类">-->
<!-- <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-select>-->
<!-- </search-item>-->
</search>
</el-card>
@@ -224,7 +224,6 @@ layout("/layouts/platform.html"){
{ prop: "welfareUnionName", label: "所属工会", sortable: true },
{ prop: "welfareUnitName", label: "所属单位", sortable: true },
{ prop: "selectedOptions", label: "所选福利", sortable: true },
{ prop: "deliveryDate", label: "配送时间", sortable: true },
{ prop: "mobile", label: "联系电话", sortable: true }
],
optionSelectVisible: false,
@@ -239,6 +238,13 @@ layout("/layouts/platform.html"){
}
},
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() {
if (this.pageForm.projectId) {
return this.projectOptions.find((item) => item.id === this.pageForm.projectId)?.options
@@ -312,7 +318,7 @@ layout("/layouts/platform.html"){
this.$message.warning("请先选择福利项目")
return
}
this.$set(this.messageDialog, "messageContent", "")
this.$set(this.messageDialog, "messageContent", "查看详情:" + this.noticeDetailUrl)
this.$set(this.messageDialog, "visible", true)
this.$nextTick(() => {
if (this.$refs.messageForm) {
@@ -338,7 +344,7 @@ layout("/layouts/platform.html"){
this.$message.warning("请输入有效的消息内容")
return
}
this.messageSending = true
this.$set(this, "messageSending", true)
this.$axios.post("/platform/welfare/selection/situation/sendMessage", {
pageForm: JSON.stringify(this.pageForm),
messageContent: messageContent
@@ -350,67 +356,7 @@ layout("/layouts/platform.html"){
this.$message.error(res.msg)
}
}).finally(() => {
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
this.$set(this, "messageSending", false)
})
})
},
@@ -1351,15 +1351,15 @@ layout("/layouts/platform_h5.html"){
},
/**
* 配送日期到达后才显示移动端评价入口;历史记录未设置配送日期时保持隐藏
* @param row 我的福利列表行,deliveryDate 为 yyyy-MM-dd 日期
* @return {boolean} 当前日期达到配送日期时返回 true
* 当前用户已选择福利且项目活动结束后显示移动端评价入口
* @param row 我的福利列表行,choiceTimeEnd 为活动结束时间
* @return {boolean} 当前时间达到活动结束时间时返回 true
*/
canEvaluate(row) {
if (!row || !row.deliveryDate) {
if (!row || !row.isChoose || !row.choiceTimeEnd) {
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"
required
></van-field>
<van-field
v-model="formData.deliveryDate"
label="配送时间"
placeholder="请选择配送时间"
readonly
clickable
is-link
@click="openDeliveryCalendar"
required
></van-field>
<van-field
v-model="formData.remark"
label="备注"
@@ -990,20 +980,6 @@ layout("/layouts/platform_h5.html"){
</div>
</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"
:style="{ height: '78%' }" :close-on-click-overlay="true"
@@ -1051,8 +1027,6 @@ layout("/layouts/platform_h5.html"){
projectId: "",
selectedRadioId: "", // 单选模式下选中的选项ID
showConfirmDialog: false,
showDeliveryCalendar: false, // 配送日期日历弹层
deliveryCalendarDefaultDate: new Date(), // 日历打开时默认定位的日期
isSubmitting: false,
hasSubmittedBefore: false, // 是否之前提交过
showOptionDetailDialog: false, // 选项详情弹窗
@@ -1065,7 +1039,6 @@ layout("/layouts/platform_h5.html"){
address: "",// 收货地址
receiveAddress: "", // 确认后的完整收货地址
userName: "",//收货人
deliveryDate: "", // 配送日期,按 yyyy-MM-dd 提交
remark: "" // 用户选择备注
},
@@ -1077,11 +1050,6 @@ layout("/layouts/platform_h5.html"){
computed: {
// Vant 日历最小可选日期为当天零点,允许用户选择当天配送。
deliveryCalendarMinDate() {
return this.$moment().startOf("day").toDate()
},
// 系统默认福利必须被保留,管理端限制每个项目最多配置一个。
systemDefaultOption() {
if (!this.projectInfo.options) return null
@@ -1142,7 +1110,7 @@ layout("/layouts/platform_h5.html"){
return Math.max(0, this.selectionLimit - this.selectedCount)
},
// 意向选择不采集收货人、联系电话和收货地址,配送时间及备注仍按原业务要求保留。
// 意向选择不采集收货人、联系电话和收货地址,备注仍按原业务要求保留。
showReceivingContact() {
return Number(this.projectInfo.provideMode) !== 2
},
@@ -1174,7 +1142,6 @@ layout("/layouts/platform_h5.html"){
// 根据浏览器历史中的弹层栈统一显示或关闭弹框,保证返回键与页面状态一致。
syncHistoryLayerStack(stack) {
this.showConfirmDialog = stack.includes("confirm")
this.$set(this, "showDeliveryCalendar", stack.includes("delivery-calendar"))
this.showAddressPopup = stack.includes("address")
this.showOptionDetailDialog = stack.includes("detail")
},
@@ -1212,36 +1179,10 @@ layout("/layouts/platform_h5.html"){
setHistoryLayerVisible(layerName, visible) {
if (layerName === "confirm") this.showConfirmDialog = visible
if (layerName === "delivery-calendar") this.$set(this, "showDeliveryCalendar", visible)
if (layerName === "address") this.showAddressPopup = 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) {
if (option.rankNo) {
return "本次福利排行榜第" + option.rankNo + "名"
@@ -1387,10 +1328,8 @@ layout("/layouts/platform_h5.html"){
this.userSelection = resp.data
this.hasSubmittedBefore = 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 || "")
}
@@ -1543,11 +1482,6 @@ layout("/layouts/platform_h5.html"){
return
}
// 配送时间是评价开放依据,提交前必须确保不早于当前选择日期。
if (!this.validateDeliveryDate()) {
return
}
if (this.isSubmitting) return
this.isSubmitting = true
@@ -1568,7 +1502,6 @@ layout("/layouts/platform_h5.html"){
selectNum: 1,
mobile: this.showReceivingContact ? this.formData.mobile : "",
userName: this.showReceivingContact ? this.formData.userName : "",
deliveryDate: this.formData.deliveryDate,
remark: this.formData.remark
}
]
@@ -1581,7 +1514,6 @@ layout("/layouts/platform_h5.html"){
selectNum: option.selectNum,
mobile: this.showReceivingContact ? this.formData.mobile : "",
userName: this.showReceivingContact ? this.formData.userName : "",
deliveryDate: this.formData.deliveryDate,
remark: this.formData.remark
}))
}
@@ -1653,26 +1585,6 @@ layout("/layouts/platform_h5.html"){
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() {
if (!this.hasSelection) {
@@ -505,10 +505,6 @@ layout("/layouts/platform_h5.html"){
<van-icon name="clock-o"></van-icon>
<span>选择时间:未设置</span>
</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">
<van-icon name="notes-o"></van-icon>
<span>备注:{{ row.remark }}</span>