Merge remote-tracking branch 'origin/main'
This commit is contained in:
+8
@@ -106,6 +106,14 @@ public class WelfareSelectionSituationController {
|
|||||||
situationService.exportXlsx(pageForm, response);
|
situationService.exportXlsx(pageForm, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("welfare.selection.situation")
|
||||||
|
@Ok("void")
|
||||||
|
@ApiOperation("导出Excel")
|
||||||
|
public void receiveXlsx(@Valid @Param("pageForm") WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
|
||||||
|
situationService.receiveXlsx(pageForm, response);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
public Result getMobileByUserId(String userId) {
|
public Result getMobileByUserId(String userId) {
|
||||||
|
|||||||
@@ -12,5 +12,6 @@ public interface WelfareSelectionSituationService extends BaseService<WelfareLis
|
|||||||
Pagination pageData(WelfareSelectionSituationPageForm pageForm);
|
Pagination pageData(WelfareSelectionSituationPageForm pageForm);
|
||||||
|
|
||||||
void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
||||||
|
void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-6
@@ -16,13 +16,12 @@ import org.nutz.dao.Sqls;
|
|||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +41,7 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
@Override
|
@Override
|
||||||
public WelfareProject projectInfo(String projectId) {
|
public WelfareProject projectInfo(String projectId) {
|
||||||
WelfareProject project = fetch(projectId);
|
WelfareProject project = fetch(projectId);
|
||||||
fetchLinks(project, "options",Cnd.NEW().asc("optionSort"));
|
fetchLinks(project, "options", Cnd.NEW().asc("optionSort"));
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,9 +62,27 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
|
|||||||
public void updateProject(WelfareProject project) {
|
public void updateProject(WelfareProject project) {
|
||||||
// 更新项目
|
// 更新项目
|
||||||
update(project);
|
update(project);
|
||||||
dao().clear(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", project.getId()));
|
List<WelfareProjectSubjectOption> optionList = dao().query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", project.getId()));
|
||||||
|
List<String> dbOptionIds = optionList.stream()
|
||||||
|
.map(WelfareProjectSubjectOption::getId)
|
||||||
|
.toList();
|
||||||
|
// 2. 获取 project 中的所有选项 ID(注意 null 安全)
|
||||||
|
List<String> projectOptionIds = project.getOptions() == null ?
|
||||||
|
Collections.emptyList() :
|
||||||
|
project.getOptions().stream()
|
||||||
|
.map(WelfareProjectSubjectOption::getId)
|
||||||
|
.filter(Objects::nonNull) // 避免 null id
|
||||||
|
.toList();
|
||||||
|
// 3. 找出需要删除的 ID:在 db 中但不在 project 中
|
||||||
|
List<String> toDeleteIds = dbOptionIds.stream()
|
||||||
|
.filter(id -> !projectOptionIds.contains(id))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 4. 批量删除
|
||||||
|
if (!toDeleteIds.isEmpty()) {
|
||||||
|
dao().clear(WelfareProjectSubjectOption.class,
|
||||||
|
Cnd.where(WelfareProjectSubjectOption::getId, "in", toDeleteIds));
|
||||||
|
}
|
||||||
|
|
||||||
// 新增或更新选项
|
|
||||||
for (WelfareProjectSubjectOption option : project.getOptions()) {
|
for (WelfareProjectSubjectOption option : project.getOptions()) {
|
||||||
option.setWelfareId(project.getId());
|
option.setWelfareId(project.getId());
|
||||||
dao().insertOrUpdate(option);
|
dao().insertOrUpdate(option);
|
||||||
|
|||||||
+99
-4
@@ -1,33 +1,45 @@
|
|||||||
package com.budwk.app.zhgh.welfare.service.impl;
|
package com.budwk.app.zhgh.welfare.service.impl;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.entity.ImageEntity;
|
||||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
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.afterturn.easypoi.excel.export.ExcelExportService;
|
||||||
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.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.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.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.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.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.param.WelfareSelectionSituationPageForm;
|
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
|
||||||
import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService;
|
import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.ArrayList;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.List;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@IocBean(args = {"refer:dao"})
|
@IocBean(args = {"refer:dao"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -36,6 +48,9 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
super(dao);
|
super(dao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SysFileService sysFileService;
|
||||||
@Override
|
@Override
|
||||||
public Pagination pageData(WelfareSelectionSituationPageForm pageForm) {
|
public Pagination pageData(WelfareSelectionSituationPageForm pageForm) {
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
@@ -46,7 +61,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
t1.welfareUnionName,
|
t1.welfareUnionName,
|
||||||
t1.welfareUnitName,
|
t1.welfareUnitName,
|
||||||
t1.welfareUnitId,
|
t1.welfareUnitId,
|
||||||
GROUP_CONCAT(DISTINCT t3.optionName) 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,
|
||||||
t4.username AS userName,
|
t4.username AS userName,
|
||||||
@@ -105,7 +120,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
t1.id,
|
t1.id,
|
||||||
t1.welfareUnionName,
|
t1.welfareUnionName,
|
||||||
t1.welfareUnitName,
|
t1.welfareUnitName,
|
||||||
GROUP_CONCAT(DISTINCT t3.optionName) 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,
|
||||||
t4.username AS userName,
|
t4.username AS userName,
|
||||||
@@ -183,4 +198,84 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
|||||||
log.error("导出Excel失败", e);
|
log.error("导出Excel失败", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
|
||||||
|
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
t1.*,
|
||||||
|
t2.userSign,
|
||||||
|
t3.username userName,
|
||||||
|
t3.loginname loginName,
|
||||||
|
GROUP_CONCAT(DISTINCT t2.selectOptionId) AS selectOptionIds
|
||||||
|
FROM
|
||||||
|
welfare_list t1
|
||||||
|
LEFT JOIN welfare_project_user_selection t2 ON t2.welfareId = t1.projectId
|
||||||
|
AND t2.selectUserId = t1.userId
|
||||||
|
LEFT JOIN sys_user t3 ON t3.id = t1.userId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.and("t1.projectId", "=", pageForm.getProjectId());
|
||||||
|
cnd.groupBy("t1.id");
|
||||||
|
cnd.asc("t1.welfareUnitId");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
List<NutMap> list = listMap(sql);
|
||||||
|
List<WelfareProjectSubjectOption> optionList = dao().query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", pageForm.getProjectId()).asc("optionSort"));
|
||||||
|
|
||||||
|
for (NutMap map : list) {
|
||||||
|
if (map.get("selectOptionIds") != null){
|
||||||
|
String[] selectOptionIds = map.getString("selectOptionIds").split(",");
|
||||||
|
for (WelfareProjectSubjectOption option : optionList) {
|
||||||
|
if(Arrays.asList(selectOptionIds).contains(option.getId())){
|
||||||
|
map.put(option.getOptionName(), "√");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (map.get("userSign") != null){
|
||||||
|
try {
|
||||||
|
Sys_file file = dao().fetch(Sys_file.class, Cnd.where(Sys_file::getDownloadPath, "=", map.getString("userSign")));
|
||||||
|
byte[] userSignBytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath());
|
||||||
|
map.put("userSign", userSignBytes);
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error("下载图片失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> safeList = list.stream().map(nutMap -> {
|
||||||
|
Map<String, Object> map = new HashMap<>(nutMap);
|
||||||
|
return map;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
// 分组
|
||||||
|
Map<String, List<Map<String, Object>>> listMap = safeList.stream()
|
||||||
|
.collect(Collectors.groupingBy(n -> (String) n.get("welfareUnionName")));
|
||||||
|
|
||||||
|
// 构建 Excel 列
|
||||||
|
List<ExcelExportEntity> entities = new ArrayList<>();
|
||||||
|
entities.add(new ExcelExportEntity("工号", "loginName", 20));
|
||||||
|
entities.add(new ExcelExportEntity("姓名", "userName", 20));
|
||||||
|
optionList.forEach(option -> {
|
||||||
|
entities.add(new ExcelExportEntity(option.getOptionName(), option.getOptionName(), 20));
|
||||||
|
});
|
||||||
|
ExcelExportEntity userSignEntity = new ExcelExportEntity("签字", "userSign", 20);
|
||||||
|
userSignEntity.setType(2);
|
||||||
|
userSignEntity.setExportImageType(2);
|
||||||
|
entities.add(userSignEntity);
|
||||||
|
|
||||||
|
// 导出
|
||||||
|
Workbook workbook = new HSSFWorkbook();
|
||||||
|
listMap.forEach((k, v) -> {
|
||||||
|
ExcelExportService service = new ExcelExportService();
|
||||||
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setSheetName(k);
|
||||||
|
exportParams.setType(ExcelType.HSSF);
|
||||||
|
service.createSheetForMap(workbook, exportParams, entities, v);
|
||||||
|
});
|
||||||
|
|
||||||
|
CommonDownloadUtil.download("领取表.xls", workbook, response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+54
-11
@@ -97,11 +97,12 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
|||||||
|
|
||||||
for (NutMap union : mapUnions) {
|
for (NutMap union : mapUnions) {
|
||||||
// 福利人数
|
// 福利人数
|
||||||
long teacherSum = welfareSelectionList.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId", "").equals(union.getString("id"))).count();
|
long teacherSum = welfareSelectionList.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId", "").equals(union.getString("id"))).count();
|
||||||
union.put("teacherSum", teacherSum);
|
union.put("teacherSum", teacherSum);
|
||||||
|
|
||||||
|
|
||||||
// 已选人数
|
// 已选人数
|
||||||
long selectedNum = welfareSelectionList.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId", "").equals(union.getString("id")) && v.getBoolean("has_selected")).count();
|
long selectedNum = welfareSelectionList.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId", "").equals(union.getString("id")) && v.getBoolean("has_selected")).count();
|
||||||
union.put("selectedNum", selectedNum);
|
union.put("selectedNum", selectedNum);
|
||||||
|
|
||||||
// 未选人数
|
// 未选人数
|
||||||
@@ -109,8 +110,25 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
|||||||
|
|
||||||
// 各选项的选择人数
|
// 各选项的选择人数
|
||||||
for (WelfareProjectSubjectOption option : welfareOptions) {
|
for (WelfareProjectSubjectOption option : welfareOptions) {
|
||||||
long count = userSelections.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId").equals(union.getString("id")) && StrUtil.isNotBlank(v.getString("selectOptionId")) && v.getString("selectOptionId").equals(option.getId())).map(v -> v.getString("selectUserId")).distinct().count();
|
int total = userSelections.stream()
|
||||||
union.put(option.getId(), count);
|
.filter(v ->
|
||||||
|
StrUtil.isNotBlank(v.getString("welfareUnionId"))
|
||||||
|
&& v.getString("welfareUnionId").equals(union.getString("id"))
|
||||||
|
&& StrUtil.isNotBlank(v.getString("selectOptionId"))
|
||||||
|
&& v.getString("selectOptionId").equals(option.getId())
|
||||||
|
&& StrUtil.isNotBlank(v.getString("selectUserId")) // 确保 userId 有效
|
||||||
|
)
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
v -> v.getString("selectUserId"),
|
||||||
|
v -> v,
|
||||||
|
(existing, replacement) -> existing // 保留第一个
|
||||||
|
// 不传第四个参数,默认用 HashMap
|
||||||
|
))
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.mapToInt(v -> v.getInt("selectNum"))
|
||||||
|
.sum();
|
||||||
|
union.put(option.getId(), total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +378,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
|||||||
exportEntities.add(new ExcelExportEntity("电话号码", "mobile", 20));
|
exportEntities.add(new ExcelExportEntity("电话号码", "mobile", 20));
|
||||||
exportEntities.add(new ExcelExportEntity("所在分工会", "welfareUnionName", 20));
|
exportEntities.add(new ExcelExportEntity("所在分工会", "welfareUnionName", 20));
|
||||||
exportEntities.add(new ExcelExportEntity("所在单位", "welfareUnitName", 20));
|
exportEntities.add(new ExcelExportEntity("所在单位", "welfareUnitName", 20));
|
||||||
exportEntities.add(new ExcelExportEntity("所在福利", "optionName", 50));
|
exportEntities.add(new ExcelExportEntity("所在福利", "selectOptionName", 50));
|
||||||
|
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
@@ -419,14 +437,22 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
|||||||
|
|
||||||
List<ExcelExportEntity> entities = new ArrayList<>();
|
List<ExcelExportEntity> entities = new ArrayList<>();
|
||||||
entities.add(new ExcelExportEntity("分工会", "name", 20));
|
entities.add(new ExcelExportEntity("分工会", "name", 20));
|
||||||
entities.add(new ExcelExportEntity("本次福利会员人数", "teacherSum", 20));
|
ExcelExportEntity teacherSumEntity = new ExcelExportEntity("本次福利会员人数", "teacherSum", 20);
|
||||||
entities.add(new ExcelExportEntity("已选人数", "selectedNum", 20));
|
teacherSumEntity.setType(10);
|
||||||
entities.add(new ExcelExportEntity("未选人数", "unSelectedNum", 20));
|
entities.add(teacherSumEntity);
|
||||||
|
ExcelExportEntity selectedNumEntity = new ExcelExportEntity("已选人数", "selectedNum", 20);
|
||||||
|
selectedNumEntity.setType(10);
|
||||||
|
entities.add(selectedNumEntity);
|
||||||
|
ExcelExportEntity unSelectedNumEntity = new ExcelExportEntity("未选人数", "unSelectedNum", 20);
|
||||||
|
unSelectedNumEntity.setType(10);
|
||||||
|
entities.add(unSelectedNumEntity);
|
||||||
|
|
||||||
// 选项数据
|
// 选项数据
|
||||||
List<WelfareProjectSubjectOption> welfareOptions = dao().query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", projectId));
|
List<WelfareProjectSubjectOption> welfareOptions = dao().query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", projectId));
|
||||||
for (WelfareProjectSubjectOption welfareOption : welfareOptions) {
|
for (WelfareProjectSubjectOption welfareOption : welfareOptions) {
|
||||||
entities.add(new ExcelExportEntity(welfareOption.getOptionName(), welfareOption.getId(), 20));
|
ExcelExportEntity entity = new ExcelExportEntity(welfareOption.getOptionName(), welfareOption.getId(), 20);
|
||||||
|
entity.setType(10);
|
||||||
|
entities.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询福利名单以及查询出选项数据
|
// 查询福利名单以及查询出选项数据
|
||||||
@@ -474,8 +500,25 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
|||||||
|
|
||||||
// 各选项的选择人数
|
// 各选项的选择人数
|
||||||
for (WelfareProjectSubjectOption option : welfareOptions) {
|
for (WelfareProjectSubjectOption option : welfareOptions) {
|
||||||
long count = userSelections.stream().filter(v -> v.getString("welfareUnionId").equals(union.getString("id")) && v.getString("selectOptionId").equals(option.getId())).map(v -> v.getString("selectUserId")).distinct().count();
|
int total = userSelections.stream()
|
||||||
union.put(option.getId(), count);
|
.filter(v ->
|
||||||
|
StrUtil.isNotBlank(v.getString("welfareUnionId"))
|
||||||
|
&& v.getString("welfareUnionId").equals(union.getString("id"))
|
||||||
|
&& StrUtil.isNotBlank(v.getString("selectOptionId"))
|
||||||
|
&& v.getString("selectOptionId").equals(option.getId())
|
||||||
|
&& StrUtil.isNotBlank(v.getString("selectUserId")) // 确保 userId 有效
|
||||||
|
)
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
v -> v.getString("selectUserId"),
|
||||||
|
v -> v,
|
||||||
|
(existing, replacement) -> existing // 保留第一个
|
||||||
|
// 不传第四个参数,默认用 HashMap
|
||||||
|
))
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.mapToInt(v -> v.getInt("selectNum"))
|
||||||
|
.sum();
|
||||||
|
union.put(option.getId(), total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ const selectView = {
|
|||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<div class="info-label">联系电话</div>
|
<div class="info-label">联系电话</div>
|
||||||
<div class="info-value">{{ mergedSelections[0]?.mobile || '暂无' }}</div>
|
<div class="info-value">{{ mergedSelections[0]?.mobile || '暂无' }}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-label">收货地址</div>
|
||||||
|
<div class="info-value">{{ mergedSelections[0]?.receiveAddress || '暂无' }}</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!--#include("../addressManage/addressDialog.js"){}#-->
|
||||||
const optionSelect = {
|
const optionSelect = {
|
||||||
template: /*language=HTML*/ `
|
template: /*language=HTML*/ `
|
||||||
<div class="welfare-select-container" v-if="projectInfo.id">
|
<div class="welfare-select-container" v-if="projectInfo.id">
|
||||||
@@ -23,9 +24,9 @@ const optionSelect = {
|
|||||||
<i class="el-icon-info"></i>
|
<i class="el-icon-info"></i>
|
||||||
<span>项目信息</span>
|
<span>项目信息</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-cover" v-if="projectInfo.cover">
|
<!-- <div class="project-cover" v-if="projectInfo.cover">
|
||||||
<el-image :src="projectInfo.cover" fit="cover"></el-image>
|
<el-image :src="projectInfo.cover" fit="cover"></el-image>
|
||||||
</div>
|
</div>-->
|
||||||
<div class="welfare-info-content">
|
<div class="welfare-info-content">
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<div class="info-label">项目名称</div>
|
<div class="info-label">项目名称</div>
|
||||||
@@ -133,7 +134,7 @@ const optionSelect = {
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
title="确认选择"
|
title="确认选择"
|
||||||
:visible.sync="showConfirmDialog"
|
:visible.sync="showConfirmDialog"
|
||||||
width="500px"
|
width="60%"
|
||||||
append-to-body
|
append-to-body
|
||||||
custom-class="welfare-confirm-dialog">
|
custom-class="welfare-confirm-dialog">
|
||||||
<div class="confirm-content">
|
<div class="confirm-content">
|
||||||
@@ -141,25 +142,37 @@ const optionSelect = {
|
|||||||
<div class="confirm-mobile-section">
|
<div class="confirm-mobile-section">
|
||||||
<div class="confirm-section-title">联系信息</div>
|
<div class="confirm-section-title">联系信息</div>
|
||||||
<el-form :model="contactForm" ref="contactForm" :rules="contactRules" label-width="80px">
|
<el-form :model="contactForm" ref="contactForm" :rules="contactRules" label-width="80px">
|
||||||
<el-form-item prop="mobile" label="联系电话">
|
<el-row :gutter="10">
|
||||||
<el-input
|
<el-col :span="24">
|
||||||
v-model="contactForm.mobile"
|
<el-form-item prop="mobile" label="联系电话">
|
||||||
placeholder="请输入手机号码"
|
<el-input
|
||||||
maxlength="11"
|
v-model="contactForm.mobile"
|
||||||
clearable>
|
placeholder="请输入手机号码"
|
||||||
</el-input>
|
maxlength="11"
|
||||||
</el-form-item>
|
clearable>
|
||||||
<el-form-item v-if="projectInfo.provideMode == 3" prop="receiveAddress" label="收货地址"
|
</el-input>
|
||||||
:rules="[{ required: true, message: '请选择收货地址', trigger: 'change' }]">
|
</el-form-item>
|
||||||
<el-select v-model="contactForm.receiveAddress" placeholder="请选择收货地址"
|
</el-col>
|
||||||
style="width: 100%">
|
<el-col :span="20">
|
||||||
<el-option v-for="item in addressOptions"
|
<el-form-item v-if="projectInfo.provideMode == 3" prop="receiveAddress"
|
||||||
:key="item.id"
|
label="收货地址"
|
||||||
:label="item.userName + ' ' + item.tel + ' ' + item.province + ' ' + item.city + ' ' + item.county + ' ' + item.addressDetail"
|
:rules="[{ required: true, message: '请选择收货地址', trigger: 'change' }]">
|
||||||
:value="item.userName + ' ' + item.tel + ' ' + item.province + ' ' + item.city + ' ' + item.county + ' ' + item.addressDetail">
|
<el-select v-model="contactForm.receiveAddress" placeholder="请选择收货地址"
|
||||||
</el-option>
|
style="width: 100%">
|
||||||
</el-select>
|
<el-option v-for="item in addressOptions"
|
||||||
</el-form-item>
|
:key="item.id"
|
||||||
|
:label="'收货人:'+item.userName + ',联系电话:' + item.tel + ',收货地址:' + item.province+ item.city+ item.county+ item.addressDetail"
|
||||||
|
:value="'收货人:'+item.userName + ',联系电话:' + item.tel + ',收货地址:' + item.province+ item.city+ item.county+ item.addressDetail">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-button @click="openAddress" type="primary">添加地址</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -217,6 +230,8 @@ const optionSelect = {
|
|||||||
<el-button type="primary" :loading="isSubmitting" @click="doSubmit">{{ hasSubmittedBefore ? '确认修改' : '确认提交' }}</el-button>
|
<el-button type="primary" :loading="isSubmitting" @click="doSubmit">{{ hasSubmittedBefore ? '确认修改' : '确认提交' }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<address-dialog ref="addressDialog" @select_user_address="getAddress"></address-dialog>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
store,
|
store,
|
||||||
@@ -250,6 +265,9 @@ const optionSelect = {
|
|||||||
addressOptions: []
|
addressOptions: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
"address-dialog": ADDRESS_DIALOG
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// 是否有选择
|
// 是否有选择
|
||||||
hasSelection() {
|
hasSelection() {
|
||||||
@@ -323,6 +341,10 @@ const optionSelect = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
openAddress() {
|
||||||
|
this.$refs.addressDialog.dialogVisible = true
|
||||||
|
this.$refs.addressDialog.formData = {userId: this.userId}
|
||||||
|
},
|
||||||
// 打开选择项目弹窗 userId为null默认则是本人
|
// 打开选择项目弹窗 userId为null默认则是本人
|
||||||
onOpen(projectId, userId = null) {
|
onOpen(projectId, userId = null) {
|
||||||
this.projectId = projectId
|
this.projectId = projectId
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ layout("/layouts/platform.html"){
|
|||||||
<el-button type="primary" size="small" icon="el-icon-download" style="margin-left: 10px" @click="exportXlsx">
|
<el-button type="primary" size="small" icon="el-icon-download" style="margin-left: 10px" @click="exportXlsx">
|
||||||
导出选择情况表
|
导出选择情况表
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
<el-button type="primary" size="small" icon="el-icon-download" style="margin-left: 10px" @click="receiveXlsx">
|
||||||
|
导出领取表
|
||||||
|
</el-button>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
@@ -195,6 +199,11 @@ layout("/layouts/platform.html"){
|
|||||||
this.$downLoad("/platform/welfare/selection/situation/exportXlsx", { pageForm: JSON.stringify(this.pageForm) })
|
this.$downLoad("/platform/welfare/selection/situation/exportXlsx", { pageForm: JSON.stringify(this.pageForm) })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 导出选择情况表
|
||||||
|
receiveXlsx() {
|
||||||
|
this.$downLoad("/platform/welfare/selection/situation/receiveXlsx", { pageForm: JSON.stringify(this.pageForm) })
|
||||||
|
},
|
||||||
|
|
||||||
// 管理员待选
|
// 管理员待选
|
||||||
proxySelect(row) {
|
proxySelect(row) {
|
||||||
this.optionSelectVisible = true
|
this.optionSelectVisible = true
|
||||||
|
|||||||
@@ -85,11 +85,11 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<div class="wf-card-heading">{{row.name}}</div>
|
<div class="wf-card-heading">{{row.name}}</div>
|
||||||
<div class="wf-time-row">
|
<div class="wf-time-row">
|
||||||
<span class="wf-time-label">开始时间:</span>
|
<span class="wf-time-label">开始时间:</span>
|
||||||
{{row.choiceTimeStart}}
|
{{$moment(row.choiceTimeStart).format('YYYY-MM-DD HH:mm')}}
|
||||||
</div>
|
</div>
|
||||||
<div class="wf-time-row">
|
<div class="wf-time-row">
|
||||||
<span class="wf-time-label">结束时间:</span>
|
<span class="wf-time-label">结束时间:</span>
|
||||||
{{row.choiceTimeEnd}}
|
{{$moment(row.choiceTimeEnd).format('YYYY-MM-DD HH:mm')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
const selectView = {
|
const selectView = {
|
||||||
template: /*language=HTML*/ `
|
template: /*language=HTML*/ `
|
||||||
<van-action-sheet
|
<van-action-sheet
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:title="'我的福利选择'"
|
:title="'我的福利选择'"
|
||||||
close-icon="close"
|
close-icon="close"
|
||||||
safe-area-inset-bottom
|
safe-area-inset-bottom
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
:overlay-class="detailVisible ? 'no-overlay' : ''"
|
:overlay-class="detailVisible ? 'no-overlay' : ''"
|
||||||
>
|
>
|
||||||
<div class="welfare-view">
|
<div class="welfare-view">
|
||||||
<!-- 内容区域 -->
|
<!-- 内容区域 -->
|
||||||
@@ -14,37 +14,58 @@ const selectView = {
|
|||||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||||
<van-skeleton title :row="6" :loading="loading" animated>
|
<van-skeleton title :row="6" :loading="loading" animated>
|
||||||
<!-- 项目基本信息 -->
|
<!-- 项目基本信息 -->
|
||||||
|
|
||||||
<div class="welfare-card">
|
<div class="welfare-card">
|
||||||
<div class="welfare-card__header">
|
<van-collapse v-model="activeNames">
|
||||||
<i class="el-icon-s-flag"></i>
|
<van-collapse-item name="1">
|
||||||
<span>项目基本信息</span>
|
<template #title>
|
||||||
</div>
|
<div class="welfare-card__header">
|
||||||
<div class="welfare-card__content">
|
<i class="el-icon-s-flag"></i>
|
||||||
<div class="info-row">
|
<span>项目基本信息</span>
|
||||||
<div class="info-row__label">项目名称</div>
|
</div>
|
||||||
<div class="info-row__value">{{ projectInfo.name }}</div>
|
</template>
|
||||||
</div>
|
<div class="welfare-card__content">
|
||||||
<div class="info-row info-row--time">
|
<div class="info-row">
|
||||||
<div class="info-row__label">选择时间</div>
|
<div class="info-row__label">项目名称</div>
|
||||||
<div class="info-row__value">
|
<div class="info-row__value">{{ projectInfo.name }}</div>
|
||||||
<div class="time-item time-item--start">{{ projectInfo.choiceTimeStart }}</div>
|
</div>
|
||||||
<div class="time-item time-item--end">{{ projectInfo.choiceTimeEnd }}</div>
|
<div class="info-row info-row--time">
|
||||||
|
<div class="info-row__label">选择时间</div>
|
||||||
|
<div class="info-row__value">
|
||||||
|
<div class="time-item time-item--start">{{
|
||||||
|
$moment(projectInfo.choiceTimeStart).format('YYYY-MM-DD HH:mm')
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<div class="time-item time-item--end">{{
|
||||||
|
$moment(projectInfo.choiceTimeEnd).format('YYYY-MM-DD HH:mm') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-row info-row--time">
|
||||||
|
<div class="info-row__label">发放时间</div>
|
||||||
|
<div class="info-row__value">
|
||||||
|
<div class="time-item time-item--start">{{
|
||||||
|
$moment(projectInfo.provideTimeStart).format('YYYY-MM-DD HH:mm')
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<div class="time-item time-item--end">{{
|
||||||
|
$moment(projectInfo.provideTimeEnd).format('YYYY-MM-DD HH:mm')
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<div class="info-row__label">发放地点</div>
|
||||||
|
<div class="info-row__value">{{ projectInfo.provideAddress || '暂无'
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</van-collapse-item>
|
||||||
<div class="info-row info-row--time">
|
</van-collapse>
|
||||||
<div class="info-row__label">发放时间</div>
|
|
||||||
<div class="info-row__value">
|
|
||||||
<div class="time-item time-item--start">{{ projectInfo.provideTimeStart }}</div>
|
|
||||||
<div class="time-item time-item--end">{{ projectInfo.provideTimeEnd }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<div class="info-row__label">发放地点</div>
|
|
||||||
<div class="info-row__value">{{ projectInfo.provideAddress || '暂无' }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- 联系信息 -->
|
<!-- 联系信息 -->
|
||||||
<div class="welfare-card">
|
<div class="welfare-card">
|
||||||
<div class="welfare-card__header">
|
<div class="welfare-card__header">
|
||||||
@@ -58,7 +79,9 @@ const selectView = {
|
|||||||
</div>
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<div class="info-row__label">收货地址</div>
|
<div class="info-row__label">收货地址</div>
|
||||||
<div class="info-row__value">{{ mergedSelections[0]?.receiveAddress || '暂无' }}</div>
|
<div class="info-row__value">{{ mergedSelections[0]?.receiveAddress || '暂无'
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,11 +96,11 @@ const selectView = {
|
|||||||
|
|
||||||
<div v-if="mergedSelections.length > 0" class="selection-list">
|
<div v-if="mergedSelections.length > 0" class="selection-list">
|
||||||
<div class="selection-item"
|
<div class="selection-item"
|
||||||
v-for="item in mergedSelections"
|
v-for="item in mergedSelections"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@click="showOptionDetail(item)">
|
@click="showOptionDetail(item)">
|
||||||
<div class="selection-item__image">
|
<div class="selection-item__image">
|
||||||
<img :src="item.imgUrl"
|
<img :src="item.imgUrl"
|
||||||
alt="福利图片"
|
alt="福利图片"
|
||||||
@error="handleImageError">
|
@error="handleImageError">
|
||||||
</div>
|
</div>
|
||||||
@@ -110,16 +133,17 @@ const selectView = {
|
|||||||
|
|
||||||
<!-- 选项详情弹窗 -->
|
<!-- 选项详情弹窗 -->
|
||||||
<van-action-sheet
|
<van-action-sheet
|
||||||
v-model="detailVisible"
|
v-model="detailVisible"
|
||||||
:title="currentOption?.optionName || '福利详情'"
|
:title="currentOption?.optionName || '福利详情'"
|
||||||
close-icon="close"
|
close-icon="close"
|
||||||
safe-area-inset-bottom
|
safe-area-inset-bottom
|
||||||
@close="closeDetail"
|
@close="closeDetail"
|
||||||
:z-index="2001"
|
:z-index="2001"
|
||||||
>
|
>
|
||||||
<div class="welfare-detail" v-if="currentOption">
|
<div class="welfare-detail" v-if="currentOption">
|
||||||
<van-skeleton title :row="10" :loading="descLoading" animated>
|
<van-skeleton title :row="10" :loading="descLoading" animated>
|
||||||
<div class="welfare-detail__content rich-text" v-html="currentOption.description || '暂无详细说明'"></div>
|
<div class="welfare-detail__content rich-text"
|
||||||
|
v-html="currentOption.description || '暂无详细说明'"></div>
|
||||||
</van-skeleton>
|
</van-skeleton>
|
||||||
</div>
|
</div>
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
@@ -144,7 +168,8 @@ const selectView = {
|
|||||||
},
|
},
|
||||||
selectedOptions: [],
|
selectedOptions: [],
|
||||||
detailVisible: false,
|
detailVisible: false,
|
||||||
currentOption: null
|
currentOption: null,
|
||||||
|
activeNames:[]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -535,15 +535,16 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
<div id="app" v-cloak>
|
<div id="app" v-cloak>
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<van-nav-bar title="福利选择" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
<van-nav-bar title="福利选择" left-text="返回" left-arrow @click-left="historyBack" fixed
|
||||||
|
placeholder></van-nav-bar>
|
||||||
|
|
||||||
<!-- 项目头部信息 -->
|
<!-- 项目头部信息 -->
|
||||||
<div class="welfare-header" v-if="projectInfo.id">
|
<div class="welfare-header" v-if="projectInfo.id">
|
||||||
<img :src="projectInfo.cover" class="welfare-header-img" />
|
<img :src="projectInfo.cover" class="welfare-header-img"/>
|
||||||
<div class="welfare-header-overlay">
|
<div class="welfare-header-overlay">
|
||||||
<div class="welfare-title">{{ projectInfo.name }}</div>
|
<div class="welfare-title">{{ projectInfo.name }}</div>
|
||||||
<div class="welfare-subtitle">
|
<div class="welfare-subtitle">
|
||||||
<van-icon name="calendar-o" />
|
<van-icon name="calendar-o"/>
|
||||||
<span>{{ projectInfo.festival }} · {{ projectInfo.year }}年</span>
|
<span>{{ projectInfo.festival }} · {{ projectInfo.year }}年</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -552,14 +553,14 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<!-- 加载中 -->
|
<!-- 加载中 -->
|
||||||
<van-empty v-if="!projectInfo.id" description="加载中...">
|
<van-empty v-if="!projectInfo.id" description="加载中...">
|
||||||
<template #image>
|
<template #image>
|
||||||
<van-loading type="spinner" color="#1989fa" />
|
<van-loading type="spinner" color="#1989fa"/>
|
||||||
</template>
|
</template>
|
||||||
</van-empty>
|
</van-empty>
|
||||||
|
|
||||||
<div class="main-content" v-if="projectInfo.id">
|
<div class="main-content" v-if="projectInfo.id">
|
||||||
<!-- 截止时间提醒 -->
|
<!-- 截止时间提醒 -->
|
||||||
<div class="welfare-deadline" v-if="isDeadlineSoon">
|
<div class="welfare-deadline" v-if="isDeadlineSoon">
|
||||||
<van-icon name="warning-o" />
|
<van-icon name="warning-o"/>
|
||||||
<span>选择截止时间即将到期,请尽快选择!</span>
|
<span>选择截止时间即将到期,请尽快选择!</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -567,26 +568,37 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<div class="welfare-notice">
|
<div class="welfare-notice">
|
||||||
<van-notice-bar wrapable :scrollable="false" background="#ecf6ff" color="var(--primary-color)">
|
<van-notice-bar wrapable :scrollable="false" background="#ecf6ff" color="var(--primary-color)">
|
||||||
<van-icon name="info-o" style="margin-right: 5px"></van-icon>
|
<van-icon name="info-o" style="margin-right: 5px"></van-icon>
|
||||||
{{ projectInfo.isCheckBox === "radio" ? "请选择一项福利" : "您可以选择多项福利,最多可选 " + (projectInfo.multiSelectNum ||
|
{{ projectInfo.isCheckBox === "radio" ? "请选择一项福利" : "您可以选择多项福利,最多可选 " +
|
||||||
|
(projectInfo.multiSelectNum ||
|
||||||
projectInfo.options.length) + " 项" }}
|
projectInfo.options.length) + " 项" }}
|
||||||
</van-notice-bar>
|
</van-notice-bar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 项目信息卡片 -->
|
<!-- 项目信息卡片 -->
|
||||||
<div class="welfare-info-card">
|
<div class="welfare-info-card">
|
||||||
<div class="welfare-info-header">
|
|
||||||
<div class="header-text">
|
|
||||||
<van-icon name="info-o" />
|
<van-collapse v-model="activeNames">
|
||||||
<span>项目信息</span>
|
<van-collapse-item name="1">
|
||||||
</div>
|
<template #title>
|
||||||
</div>
|
<div class="welfare-info-header">
|
||||||
<div class="welfare-cell-group">
|
<div class="header-text">
|
||||||
<van-cell title="选择时间" :value="formatTimeRange(projectInfo.choiceTimeStart, projectInfo.choiceTimeEnd)"></van-cell>
|
<van-icon name="info-o"></van-icon>
|
||||||
<van-cell title="发放时间" :value="formatTimeRange(projectInfo.provideTimeStart, projectInfo.provideTimeEnd)"></van-cell>
|
<span>项目信息</span>
|
||||||
<van-cell title="发放地点" :value="projectInfo.provideAddress"></van-cell>
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="welfare-cell-group">
|
||||||
|
<van-cell title="选择时间"
|
||||||
|
:value="formatTimeRange(projectInfo.choiceTimeStart, projectInfo.choiceTimeEnd)"></van-cell>
|
||||||
|
<van-cell title="发放时间"
|
||||||
|
:value="formatTimeRange(projectInfo.provideTimeStart, projectInfo.provideTimeEnd)"></van-cell>
|
||||||
|
<van-cell title="发放地点" :value="projectInfo.provideAddress"></van-cell>
|
||||||
|
</div>
|
||||||
|
</van-collapse-item>
|
||||||
<!-- <van-cell title="发放方式" :value="getProvideModeName(projectInfo.provideMode)"></van-cell>-->
|
<!-- <van-cell title="发放方式" :value="getProvideModeName(projectInfo.provideMode)"></van-cell>-->
|
||||||
<!-- <van-cell title="签字方式" :value="getSignModeName(projectInfo.signMode)"></van-cell>-->
|
<!-- <van-cell title="签字方式" :value="getSignModeName(projectInfo.signMode)"></van-cell>-->
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-divider"></div>
|
<div class="section-divider"></div>
|
||||||
@@ -594,7 +606,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<!-- 福利选项标题 -->
|
<!-- 福利选项标题 -->
|
||||||
<div class="welfare-section-title">
|
<div class="welfare-section-title">
|
||||||
<div class="title-text">
|
<div class="title-text">
|
||||||
<van-icon name="gift-o" />
|
<van-icon name="gift-o"/>
|
||||||
<span>福利选项</span>
|
<span>福利选项</span>
|
||||||
<span class="title-count">共 {{ projectInfo.options.length }} 项</span>
|
<span class="title-count">共 {{ projectInfo.options.length }} 项</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -603,15 +615,16 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<!-- 福利选项列表 -->
|
<!-- 福利选项列表 -->
|
||||||
<div class="welfare-options-container">
|
<div class="welfare-options-container">
|
||||||
<div
|
<div
|
||||||
v-for="(option,index) in projectInfo.options"
|
v-for="(option,index) in projectInfo.options"
|
||||||
:key="option.id"
|
:key="option.id"
|
||||||
class="welfare-option"
|
class="welfare-option"
|
||||||
:class="{ selected: projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0 }"
|
:class="{ selected: projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0 }"
|
||||||
@click="projectInfo.isCheckBox === 'radio' && !isDeadlinePassed ? selectRadioOption(option.id) : null"
|
@click="projectInfo.isCheckBox === 'radio' && !isDeadlinePassed ? selectRadioOption(option.id) : null"
|
||||||
>
|
>
|
||||||
<div class="welfare-option-image">
|
<div class="welfare-option-image">
|
||||||
<van-image :src="option.imgUrl" fit="cover" width="100%" height="100%" radius="4px"></van-image>
|
<van-image :src="option.imgUrl" fit="cover" width="100%" height="100%" radius="4px"></van-image>
|
||||||
<div class="welfare-tag" v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0">
|
<div class="welfare-tag"
|
||||||
|
v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0">
|
||||||
<van-tag type="primary" round>已选择</van-tag>
|
<van-tag type="primary" round>已选择</van-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -621,34 +634,34 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
<!-- 查看详情按钮 -->
|
<!-- 查看详情按钮 -->
|
||||||
<div class="welfare-detail-btn" @click.stop="showOptionDetail(option)">
|
<div class="welfare-detail-btn" @click.stop="showOptionDetail(option)">
|
||||||
<van-icon name="info-o" />
|
<van-icon name="info-o"/>
|
||||||
<span>查看详情</span>
|
<span>查看详情</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 单选模式使用单选按钮 -->
|
<!-- 单选模式使用单选按钮 -->
|
||||||
<div class="welfare-option-radio" v-if="projectInfo.isCheckBox === 'radio'">
|
<div class="welfare-option-radio" v-if="projectInfo.isCheckBox === 'radio'">
|
||||||
<van-radio
|
<van-radio
|
||||||
:name="option.id"
|
:name="option.id"
|
||||||
v-model="selectedRadioId"
|
v-model="selectedRadioId"
|
||||||
@click.stop="isDeadlinePassed ? $toast.fail('已过选择截止时间,无法修改') : selectRadioOption(option.id)"
|
@click.stop="isDeadlinePassed ? $toast.fail('已过选择截止时间,无法修改') : selectRadioOption(option.id)"
|
||||||
:disabled="isDeadlinePassed"
|
:disabled="isDeadlinePassed"
|
||||||
></van-radio>
|
></van-radio>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 多选模式使用步进器 -->
|
<!-- 多选模式使用步进器 -->
|
||||||
<div class="welfare-option-checkbox" v-else>
|
<div class="welfare-option-checkbox" v-else>
|
||||||
<van-stepper
|
<van-stepper
|
||||||
:key="'input-number-'+index+'-'+option.selectNumKey|| 0"
|
:key="'input-number-'+index+'-'+option.selectNumKey|| 0"
|
||||||
v-model="option.selectNum"
|
v-model="option.selectNum"
|
||||||
integer
|
integer
|
||||||
disable-input
|
disable-input
|
||||||
:default-value="0"
|
:default-value="0"
|
||||||
:min="0"
|
:min="0"
|
||||||
:disabled="isDeadlinePassed"
|
:disabled="isDeadlinePassed"
|
||||||
input-width="40px"
|
input-width="40px"
|
||||||
button-size="22px"
|
button-size="22px"
|
||||||
@change="selectNumChange(index,option.selectNum)"
|
@change="selectNumChange(index,option.selectNum)"
|
||||||
theme="round"
|
theme="round"
|
||||||
></van-stepper>
|
></van-stepper>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -658,13 +671,15 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
<!-- 底部提交按钮 -->
|
<!-- 底部提交按钮 -->
|
||||||
<div class="welfare-footer" v-if="projectInfo.id">
|
<div class="welfare-footer" v-if="projectInfo.id">
|
||||||
<van-button type="primary" class="welfare-submit-btn" :disabled="submitButtonDisabled" @click="submitSelection" round>
|
<van-button type="primary" class="welfare-submit-btn" :disabled="submitButtonDisabled"
|
||||||
|
@click="submitSelection" round>
|
||||||
{{ isDeadlinePassed ? '已截止' : '确认选择' }}
|
{{ isDeadlinePassed ? '已截止' : '确认选择' }}
|
||||||
</van-button>
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 确认弹窗 -->
|
<!-- 确认弹窗 -->
|
||||||
<van-action-sheet v-model="showConfirmDialog" :close-on-click-overlay="false" :round="true" :style="{ maxHeight: '90%' }">
|
<van-action-sheet v-model="showConfirmDialog" :close-on-click-overlay="false" :round="true"
|
||||||
|
:style="{ maxHeight: '90%' }">
|
||||||
<div class="confirm-action-sheet">
|
<div class="confirm-action-sheet">
|
||||||
<div class="confirm-sheet-title">确认选择</div>
|
<div class="confirm-sheet-title">确认选择</div>
|
||||||
|
|
||||||
@@ -672,24 +687,26 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<!-- 手机号输入 -->
|
<!-- 手机号输入 -->
|
||||||
<div class="mobile-input-section">
|
<div class="mobile-input-section">
|
||||||
<van-field
|
<van-field
|
||||||
v-model="formData.mobile"
|
v-model="formData.mobile"
|
||||||
label="联系电话"
|
label="联系电话"
|
||||||
placeholder="请输入手机号码"
|
placeholder="请输入手机号码"
|
||||||
:error="mobileError"
|
:error="mobileError"
|
||||||
@focus="mobileError = false"
|
@focus="mobileError = false"
|
||||||
maxlength="11"
|
maxlength="11"
|
||||||
required
|
required
|
||||||
></van-field>
|
></van-field>
|
||||||
<!--收货地址-->
|
<!--收货地址-->
|
||||||
<van-field
|
<van-field
|
||||||
v-if="projectInfo.provideMode == 3"
|
v-if="projectInfo.provideMode == 3"
|
||||||
v-model="formData.receiveAddress"
|
v-model="formData.receiveAddress"
|
||||||
label="收货地址"
|
label="收货地址"
|
||||||
placeholder="请选择收货地址"
|
rows="4"
|
||||||
readonly
|
type="textarea"
|
||||||
is-link
|
placeholder="请选择收货地址"
|
||||||
@click="showAddressSheet = true"
|
readonly
|
||||||
required
|
is-link
|
||||||
|
@click="showAddressSheet = true"
|
||||||
|
required
|
||||||
></van-field>
|
></van-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -713,7 +730,9 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<div class="confirm-section" v-if="projectInfo.signMode === 2">
|
<div class="confirm-section" v-if="projectInfo.signMode === 2">
|
||||||
<div class="confirm-section-title">请签字确认</div>
|
<div class="confirm-section-title">请签字确认</div>
|
||||||
<h5-signature v-model="formData.userSign" ref="signatureRef"></h5-signature>
|
<h5-signature v-model="formData.userSign" ref="signatureRef"></h5-signature>
|
||||||
<div class="signature-tips">{{ formData.userSign ? '您已完成签名' : '请在上方空白区域完成签名' }}</div>
|
<div class="signature-tips">{{ formData.userSign ? '您已完成签名' : '请在上方空白区域完成签名'
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<div style="text-align: right; margin-top: 8px">
|
<div style="text-align: right; margin-top: 8px">
|
||||||
<van-button size="small" type="default" @click="resetSignature">重新签名</van-button>
|
<van-button size="small" type="default" @click="resetSignature">重新签名</van-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -721,14 +740,19 @@ layout("/layouts/platform_h5.html"){
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="confirm-fixed-buttons">
|
<div class="confirm-fixed-buttons">
|
||||||
<van-button type="default" block round class="action-sheet-cancel" @click="showConfirmDialog = false">取消</van-button>
|
<van-button type="default" block round class="action-sheet-cancel"
|
||||||
<van-button type="primary" block round @click="doSubmit">{{ hasSubmittedBefore ? '确认修改' : '确认提交' }}</van-button>
|
@click="showConfirmDialog = false">取消
|
||||||
|
</van-button>
|
||||||
|
<van-button type="primary" block round @click="doSubmit">
|
||||||
|
{{ hasSubmittedBefore ? '确认修改' : '确认提交'}}
|
||||||
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
|
|
||||||
<!-- 选项详情弹窗 -->
|
<!-- 选项详情弹窗 -->
|
||||||
<van-popup v-model="showOptionDetailDialog" round closeable close-icon="close" position="bottom" :style="{ maxHeight: '70%' }">
|
<van-popup v-model="showOptionDetailDialog" round closeable close-icon="close" position="bottom"
|
||||||
|
:style="{ maxHeight: '70%' }">
|
||||||
<div class="welfare-detail-popup" v-if="selectedOption">
|
<div class="welfare-detail-popup" v-if="selectedOption">
|
||||||
<div class="welfare-detail-title">{{ selectedOption.optionName }}</div>
|
<div class="welfare-detail-title">{{ selectedOption.optionName }}</div>
|
||||||
<div class="welfare-detail-content" v-html="selectedOption.description"></div>
|
<div class="welfare-detail-content" v-html="selectedOption.description"></div>
|
||||||
@@ -739,25 +763,29 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-action-sheet v-model="showAddressSheet" title="选择收货地址" :round="true">
|
<van-action-sheet v-model="showAddressSheet" title="选择收货地址" :round="true">
|
||||||
<div style="padding: 16px 0 0">
|
<div style="padding: 16px 0 0">
|
||||||
<div
|
<div
|
||||||
v-for="address in addressOptions"
|
v-for="address in addressOptions"
|
||||||
:key="address.id"
|
:key="address.id"
|
||||||
class="address-item"
|
class="address-item"
|
||||||
@click="selectAddress(address)"
|
@click="selectAddress(address)"
|
||||||
style="padding: 12px 16px; border-bottom: 1px solid #f0f0f0; cursor: pointer"
|
style="padding: 12px 16px; border-bottom: 1px solid #f0f0f0; cursor: pointer"
|
||||||
>
|
>
|
||||||
<div style="display: flex; justify-content: space-between; align-items: flex-start">
|
<div style="display: flex; justify-content: space-between; align-items: flex-start">
|
||||||
<div style="flex: 1">
|
<div style="flex: 1">
|
||||||
<div style="font-size: 16px; font-weight: 500; color: #323233; margin-bottom: 4px">
|
<div style="font-size: 16px; font-weight: 500; color: #323233; margin-bottom: 4px">
|
||||||
{{ address.userName }} {{ address.tel }}
|
收货人:{{ address.userName }}{{ address.tel }}
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size: 14px; color: #646566; line-height: 1.4">
|
<div style="font-size: 14px; color: #646566; line-height: 1.4">
|
||||||
{{ address.province }}{{ address.city }}{{ address.county }}{{ address.addressDetail }}
|
收货地址: {{ address.province }}{{ address.city }}{{ address.county }}
|
||||||
|
{{address.addressDetail }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<van-tag v-if="address.isDefault" type="primary" size="mini" style="margin-left: 8px">默认</van-tag>
|
<van-tag v-if="address.isDefault" type="primary" size="mini" style="margin-left: 8px">默认
|
||||||
|
</van-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="addressOptions.length === 0" style="text-align: center; padding: 40px 16px; color: #969799">暂无收货地址</div>
|
<div v-if="addressOptions.length === 0" style="text-align: center; padding: 40px 16px; color: #969799">
|
||||||
|
暂无收货地址
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 16px; border-top: 1px solid #f0f0f0; background: #fafafa">
|
<div style="padding: 16px; border-top: 1px solid #f0f0f0; background: #fafafa">
|
||||||
<van-button type="info" block round @click="goToAddressManage">收货地址管理</van-button>
|
<van-button type="info" block round @click="goToAddressManage">收货地址管理</van-button>
|
||||||
@@ -772,6 +800,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
store,
|
store,
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
activeNames: [],
|
||||||
projectInfo: {},
|
projectInfo: {},
|
||||||
userSelection: [],
|
userSelection: [],
|
||||||
welfareProvideMode: [],
|
welfareProvideMode: [],
|
||||||
@@ -879,7 +908,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
getProjectInfo() {
|
getProjectInfo() {
|
||||||
this.$axios.post("/platform/welfare/common/projectInfo", { id: this.projectId }).then((res) => {
|
this.$axios.post("/platform/welfare/common/projectInfo", {id: this.projectId}).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.projectInfo = res.data
|
this.projectInfo = res.data
|
||||||
|
|
||||||
@@ -904,7 +933,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
// 获取用户选择的数据
|
// 获取用户选择的数据
|
||||||
getUserSelection() {
|
getUserSelection() {
|
||||||
this.$axios.post("/platform/welfare/userSelect/getUserSelection", { projectId: this.projectId }).then((resp) => {
|
this.$axios.post("/platform/welfare/userSelect/getUserSelection", {projectId: this.projectId}).then((resp) => {
|
||||||
if (resp.code === 0) {
|
if (resp.code === 0) {
|
||||||
this.userSelection = resp.data
|
this.userSelection = resp.data
|
||||||
this.hasSubmittedBefore = this.userSelection.length > 0
|
this.hasSubmittedBefore = this.userSelection.length > 0
|
||||||
@@ -1170,7 +1199,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
// 选择收货地址
|
// 选择收货地址
|
||||||
selectAddress(address) {
|
selectAddress(address) {
|
||||||
this.formData.receiveAddress =
|
this.formData.receiveAddress =
|
||||||
address.userName + " " + address.tel + " " + address.province + address.city + address.county + address.addressDetail
|
"收货人:" + address.userName + ",联系电话:" + address.tel + ",收货地址:" + address.province + address.city + address.county + address.addressDetail
|
||||||
this.showAddressSheet = false
|
this.showAddressSheet = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -86,11 +86,11 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<div class="wf-card-heading">{{row.name}}</div>
|
<div class="wf-card-heading">{{row.name}}</div>
|
||||||
<div class="wf-time-row">
|
<div class="wf-time-row">
|
||||||
<span class="wf-time-label">开始时间:</span>
|
<span class="wf-time-label">开始时间:</span>
|
||||||
{{row.choiceTimeStart}}
|
{{$moment(row.choiceTimeStart).format('YYYY-MM-DD HH:mm')}}
|
||||||
</div>
|
</div>
|
||||||
<div class="wf-time-row">
|
<div class="wf-time-row">
|
||||||
<span class="wf-time-label">结束时间:</span>
|
<span class="wf-time-label">结束时间:</span>
|
||||||
{{row.choiceTimeEnd}}
|
{{$moment(row.choiceTimeEnd).format('YYYY-MM-DD HH:mm')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user