Merge remote-tracking branch 'origin/main'
This commit is contained in:
+32
-22
@@ -22,10 +22,8 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
|||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Chain;
|
import org.nutz.dao.Chain;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import com.budwk.app.base.dao.CndPlus;
|
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
|
||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
@@ -89,17 +87,17 @@ public class FitnessWalkStepRaffleController {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手动抽奖规则
|
* 保存手动抽奖规则并返回实际抽取结果。
|
||||||
* @param fitnessWalkRaffleRules
|
* @param fitnessWalkRaffleRules 活动 ID 及奖项规则,包含奖项名称、抽奖人数、类型、位次和兼得设置
|
||||||
* @return
|
* @return Result,code 为 0 表示抽奖完成,msg 包含人数不足奖项的实际抽取说明
|
||||||
*/
|
*/
|
||||||
@At
|
@At
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
@SaCheckPermission("fitnessWalk.stepRaffle")
|
@SaCheckPermission("fitnessWalk.stepRaffle")
|
||||||
public Result saveRaffle(FitnessWalkRaffleRules fitnessWalkRaffleRules){
|
public Result saveRaffle(FitnessWalkRaffleRules fitnessWalkRaffleRules){
|
||||||
baseService.dao().insertOrUpdate(fitnessWalkRaffleRules);
|
baseService.dao().insertOrUpdate(fitnessWalkRaffleRules);
|
||||||
fitnessWalkStepRaffleService.manualLottery(fitnessWalkRaffleRules.getActivityId());
|
String message = fitnessWalkStepRaffleService.manualLottery(fitnessWalkRaffleRules.getActivityId());
|
||||||
return Result.success();
|
return Result.success(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -194,26 +192,37 @@ public class FitnessWalkStepRaffleController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台查看当前活动的全部中奖人员。
|
||||||
|
*
|
||||||
|
* @param activityId 当前活动 ID,必填
|
||||||
|
* @param lotteryTime 奖项名称(沿用页面参数名),空值查询全部奖项
|
||||||
|
* @param searchKeyword 姓名或工号关键字,空值查询全部中奖人员
|
||||||
|
* @return Result,data 为中奖人员 Map 列表,isRaffleText 表示是否已在手机端抽奖
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("fitnessWalk.stepRaffle")
|
||||||
|
public Result awardUsers(String activityId, String lotteryTime, String searchKeyword) {
|
||||||
|
if (StrUtil.isBlank(activityId)) {
|
||||||
|
return Result.error("请选择活动");
|
||||||
|
}
|
||||||
|
return Result.success(fitnessWalkStepRaffleService.getAwardUsers(activityId, lotteryTime, searchKeyword));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出当前筛选条件下的全部中奖人员,包含手机端是否已抽奖。
|
||||||
|
*
|
||||||
|
* @param searchKeyword 姓名或工号关键字,空值不限制人员
|
||||||
|
* @param activityId 当前活动 ID,空值导出空名单
|
||||||
|
* @param lotteryTime 奖项名称(沿用页面参数名),空值不限制奖项
|
||||||
|
* @param response HTTP 下载响应,写入包含人员、奖项、是否抽奖及中奖时间的 XSSF 工作簿
|
||||||
|
*/
|
||||||
@At
|
@At
|
||||||
@Ok("void")
|
@Ok("void")
|
||||||
@SaCheckPermission("fitnessWalk.stepRaffle")
|
@SaCheckPermission("fitnessWalk.stepRaffle")
|
||||||
public void exportAwardExcel(String searchKeyword, String activityId,
|
public void exportAwardExcel(String searchKeyword, String activityId,
|
||||||
String lotteryTime, HttpServletResponse response) {
|
String lotteryTime, HttpServletResponse response) {
|
||||||
CndPlus cnd = CndPlus.create();
|
List<NutMap> list = fitnessWalkStepRaffleService.getAwardUsers(activityId, lotteryTime, searchKeyword);
|
||||||
cnd.andEX("activityId", "=", activityId);
|
|
||||||
cnd.andEX("awardName", "=", lotteryTime);
|
|
||||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
|
||||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
|
||||||
seg.orLike("username", searchKeyword);
|
|
||||||
seg.orLike("loginName", searchKeyword);
|
|
||||||
cnd.and(seg);
|
|
||||||
}
|
|
||||||
cnd.and("isRead", "=", true);
|
|
||||||
List<FitnessWalkAwardUser> list = fitnessWalkCommonService.dao().query(FitnessWalkAwardUser.class, cnd);
|
|
||||||
|
|
||||||
for (FitnessWalkAwardUser awardUser : list) {
|
|
||||||
awardUser.setApplyDate(awardUser.getApplyDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ExcelExportEntity> entityList = new ArrayList<>();
|
List<ExcelExportEntity> entityList = new ArrayList<>();
|
||||||
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
|
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
|
||||||
@@ -224,6 +233,7 @@ public class FitnessWalkStepRaffleController {
|
|||||||
entityList.add(new ExcelExportEntity("分工会", "unionName", 20));
|
entityList.add(new ExcelExportEntity("分工会", "unionName", 20));
|
||||||
entityList.add(new ExcelExportEntity("单位", "unitName", 40));
|
entityList.add(new ExcelExportEntity("单位", "unitName", 40));
|
||||||
entityList.add(new ExcelExportEntity("奖项名称", "awardName", 20));
|
entityList.add(new ExcelExportEntity("奖项名称", "awardName", 20));
|
||||||
|
entityList.add(new ExcelExportEntity("是否抽奖", "isRaffleText", 15));
|
||||||
entityList.add(new ExcelExportEntity("中奖时间", "applyDate2", 20));
|
entityList.add(new ExcelExportEntity("中奖时间", "applyDate2", 20));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
+15
-3
@@ -19,6 +19,17 @@ public interface FitnessWalkStepRaffleService extends BaseService<FitnessWalkRaf
|
|||||||
|
|
||||||
Sql getRaffleSql(PageForm pageForm, String activityId, String unionId, String unitId);
|
Sql getRaffleSql(PageForm pageForm, String activityId, String unionId, String unitId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询后台完整中奖名单,列表和导出共用,不受手机端是否已抽奖限制。
|
||||||
|
*
|
||||||
|
* @param activityId 活动 ID,空值返回空名单,避免跨活动查询
|
||||||
|
* @param awardName 奖项名称,空值表示该活动的全部奖项
|
||||||
|
* @param searchKeyword 姓名或工号关键字,空值表示不限制人员
|
||||||
|
* @return 中奖记录 Map 列表;包含人员及奖项信息,isRaffleText 为“是/否”,
|
||||||
|
* applyDate2 为手机端抽奖时间文本,未抽奖时为空字符串
|
||||||
|
*/
|
||||||
|
List<NutMap> getAwardUsers(String activityId, String awardName, String searchKeyword);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取活动的奖项
|
* 获取活动的奖项
|
||||||
* @param activityId
|
* @param activityId
|
||||||
@@ -27,10 +38,11 @@ public interface FitnessWalkStepRaffleService extends BaseService<FitnessWalkRaf
|
|||||||
List<NutMap> getActivityAwardList(String activityId);
|
List<NutMap> getActivityAwardList(String activityId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手动抽奖
|
* 按规则重新抽奖,人数不足时按实际可抽人数抽取。
|
||||||
* @param activityId 活动id
|
* @param activityId 活动 ID,用于查询资格及奖项规则、替换本活动中奖名单
|
||||||
|
* @return 完成提示,包含人数不足奖项的配置人数及实际抽取人数
|
||||||
*/
|
*/
|
||||||
void manualLottery(String activityId);
|
String manualLottery(String activityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+89
-18
@@ -43,6 +43,16 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
@Inject
|
@Inject
|
||||||
private FitnessWalkCommonService fitnessWalkCommonService;
|
private FitnessWalkCommonService fitnessWalkCommonService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按活动的抽奖资格查询候选人员,供达标列表、导出和手动抽奖共用。
|
||||||
|
*
|
||||||
|
* @param pageForm 查询参数,仅使用姓名或工号关键字;抽奖时可传 null
|
||||||
|
* @param activityId 活动 ID,用于读取活动日期及达标天数、步数门槛
|
||||||
|
* @param unionId 分工会 ID,空值表示不限制分工会
|
||||||
|
* @param unitId 单位 ID,空值表示不限制单位
|
||||||
|
* @return 候选人员查询 SQL;id 为用户 ID,total_steps 为规则口径下的步数,
|
||||||
|
* standardsDays 为统计天数,无匹配记录时返回 0
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Sql getRaffleSql(PageForm pageForm, String activityId, String unionId, String unitId) {
|
public Sql getRaffleSql(PageForm pageForm, String activityId, String unionId, String unitId) {
|
||||||
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
|
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
|
||||||
@@ -65,7 +75,7 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
u.unionName AS unionname,
|
u.unionName AS unionname,
|
||||||
u.unitId AS unitid,
|
u.unitId AS unitid,
|
||||||
u.unitName AS unitname,
|
u.unitName AS unitname,
|
||||||
over3k.standardsDays
|
COALESCE(over3k.standardsDays, 0) AS standardsDays
|
||||||
FROM
|
FROM
|
||||||
vw_user u
|
vw_user u
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
@@ -100,6 +110,9 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
) AS over3k ON u.id = over3k.userId
|
) AS over3k ON u.id = over3k.userId
|
||||||
$condition
|
$condition
|
||||||
""");
|
""");
|
||||||
|
// Nutz 的 groupBy 会重建分组对象,必须先分组再设置 having,否则抽奖资格筛选会丢失。
|
||||||
|
// 达标天数参与分组,确保查询列做空值处理后,having 仍能引用原始天数。
|
||||||
|
cnd.groupBy("u.id", "u.username", "u.loginname", "u.unionId", "u.unionName", "u.unitId", "u.unitName", "over3k.standardsDays");
|
||||||
if (lotteryQualificationDays != null) {
|
if (lotteryQualificationDays != null) {
|
||||||
sql.setVar("lotteryQualificationDaySql", new Static(" AND step >= '%s' ".formatted(effectiveLotteryQualificationSteps)));
|
sql.setVar("lotteryQualificationDaySql", new Static(" AND step >= '%s' ".formatted(effectiveLotteryQualificationSteps)));
|
||||||
cnd.having(Cnd.NEW().and(new Static(" over3k.standardsDays >= '%s' ".formatted(lotteryQualificationDays))));
|
cnd.having(Cnd.NEW().and(new Static(" over3k.standardsDays >= '%s' ".formatted(lotteryQualificationDays))));
|
||||||
@@ -130,13 +143,52 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
cnd.and(seg);
|
cnd.and(seg);
|
||||||
}
|
}
|
||||||
// cnd.and("u.id","in",Sqls.create("select userId from activity_user_scope where groupId = @groupId").setParam("groupId",activity.getGroupId()));
|
// cnd.and("u.id","in",Sqls.create("select userId from activity_user_scope where groupId = @groupId").setParam("groupId",activity.getGroupId()));
|
||||||
cnd.groupBy("u.id", "u.username", "u.loginname", "u.unionId", "u.unionName", "u.unitId", "u.unitName");
|
|
||||||
cnd.desc("total_steps");
|
cnd.desc("total_steps");
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询后台完整中奖名单,列表和导出共用,不受手机端是否已抽奖限制。
|
||||||
|
*
|
||||||
|
* @param activityId 活动 ID,空值返回空名单,避免跨活动查询
|
||||||
|
* @param awardName 奖项名称,空值表示该活动的全部奖项
|
||||||
|
* @param searchKeyword 姓名或工号关键字,空值表示不限制人员
|
||||||
|
* @return 中奖记录 Map 列表;包含人员及奖项信息,isRaffleText 为“是/否”,
|
||||||
|
* applyDate2 为手机端抽奖时间文本,未抽奖时为空字符串
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<NutMap> getAwardUsers(String activityId, String awardName, String searchKeyword) {
|
||||||
|
// 未选活动时不查询,防止空筛选条件返回其他活动的中奖人员。
|
||||||
|
if (Strings.isBlank(activityId)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
id, activityId, userId, loginName, username,
|
||||||
|
unionName, unitName, awardName,
|
||||||
|
CASE WHEN isRead = 1 THEN '是' ELSE '否' END AS isRaffleText,
|
||||||
|
CASE WHEN isRead = 1 THEN COALESCE(DATE_FORMAT(applyDate, '%Y-%m-%d %H:%i:%s'), '')
|
||||||
|
ELSE '' END AS applyDate2
|
||||||
|
FROM fitness_walk_award_user
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
Cnd cnd = Cnd.where("activityId", "=", activityId);
|
||||||
|
if (Strings.isNotBlank(awardName)) {
|
||||||
|
cnd.and("awardName", "=", awardName);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(searchKeyword)) {
|
||||||
|
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||||
|
seg.orLike("username", searchKeyword);
|
||||||
|
seg.orLike("loginName", searchKeyword);
|
||||||
|
cnd.and(seg);
|
||||||
|
}
|
||||||
|
// 手机端抽奖成功会将 isRead 置为 true;false 和历史空值均表示尚未抽奖,仅展示状态,不据此过滤人员。
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
return listMap(sql);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取活动的奖项
|
* 获取活动的奖项
|
||||||
* @param activityId
|
* @param activityId
|
||||||
@@ -216,17 +268,14 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手动抽奖
|
* 按规则重新抽奖;人数不足时抽取全部可抽人员,并汇总不足奖项的实际结果。
|
||||||
*
|
*
|
||||||
* @param activityId 活动id
|
* @param activityId 活动 ID,用于读取资格及奖项规则并替换该活动的中奖名单
|
||||||
|
* @return 抽奖完成提示;人数不足时包含奖项名称、配置人数、可抽人数及实际抽取人数
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void manualLottery(String activityId) {
|
public String manualLottery(String activityId) {
|
||||||
// 删除此活动下的获奖记录
|
|
||||||
dao().clear(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId));
|
|
||||||
dao().clear(FitnessWalkRaffleUser.class, Cnd.where("activityId", "=", activityId));
|
|
||||||
|
|
||||||
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
|
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
|
||||||
Date startDate = DateUtil.parse(DateUtil.format(DateUtil.date(activity.getStartTime()), "yyyy-MM-dd"), "yyyy-MM-dd");
|
Date startDate = DateUtil.parse(DateUtil.format(DateUtil.date(activity.getStartTime()), "yyyy-MM-dd"), "yyyy-MM-dd");
|
||||||
Date endDate = DateUtil.parse(DateUtil.format(DateUtil.date(activity.getEndTime()), "yyyy-MM-dd"), "yyyy-MM-dd");
|
Date endDate = DateUtil.parse(DateUtil.format(DateUtil.date(activity.getEndTime()), "yyyy-MM-dd"), "yyyy-MM-dd");
|
||||||
@@ -235,6 +284,7 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
Sql sql = getRaffleSql(null, activityId, null, null);
|
Sql sql = getRaffleSql(null, activityId, null, null);
|
||||||
List<NutMap> list = listMap(sql);
|
List<NutMap> list = listMap(sql);
|
||||||
|
|
||||||
|
// 无达标日期时按 0 天保存,候选人员及中奖记录均避免使用 NutMap 默认的 -1。
|
||||||
List<FitnessWalkRaffleUser> raffleUserList = list.stream().map(v -> {
|
List<FitnessWalkRaffleUser> raffleUserList = list.stream().map(v -> {
|
||||||
FitnessWalkRaffleUser raffleUser = new FitnessWalkRaffleUser();
|
FitnessWalkRaffleUser raffleUser = new FitnessWalkRaffleUser();
|
||||||
raffleUser.setId(R.UU32());
|
raffleUser.setId(R.UU32());
|
||||||
@@ -243,16 +293,17 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
raffleUser.setLoginName(v.getString("loginname"));
|
raffleUser.setLoginName(v.getString("loginname"));
|
||||||
raffleUser.setUsername(v.getString("username"));
|
raffleUser.setUsername(v.getString("username"));
|
||||||
raffleUser.setAwardSteps(v.getString("total_steps"));
|
raffleUser.setAwardSteps(v.getString("total_steps"));
|
||||||
raffleUser.setStandardsDays(v.getInt("standardsDays"));
|
raffleUser.setStandardsDays(v.getInt("standardsDays", 0));
|
||||||
raffleUser.setIsRaffle(false);
|
raffleUser.setIsRaffle(false);
|
||||||
return raffleUser;
|
return raffleUser;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
dao().fastInsert(raffleUserList);
|
|
||||||
|
|
||||||
Set<String> winningRankLoginNames = new HashSet<>();
|
Set<String> winningRankLoginNames = new HashSet<>();
|
||||||
|
|
||||||
// 获奖人员
|
// 获奖人员
|
||||||
List<FitnessWalkAwardUser> winningUsers = new ArrayList<>();
|
List<FitnessWalkAwardUser> winningUsers = new ArrayList<>();
|
||||||
|
// 收集各奖项人数不足的说明,抽奖完成后一次性返回给页面。
|
||||||
|
List<String> shortageMessages = new ArrayList<>();
|
||||||
|
|
||||||
// 获取抽奖规则
|
// 获取抽奖规则
|
||||||
FitnessWalkRaffleRules rules = fetch(Cnd.where("activityId", "=", activityId));
|
FitnessWalkRaffleRules rules = fetch(Cnd.where("activityId", "=", activityId));
|
||||||
@@ -272,8 +323,12 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
.sorted(Comparator.comparingInt((NutMap v) -> v.getInt("total_steps")).reversed())
|
.sorted(Comparator.comparingInt((NutMap v) -> v.getInt("total_steps")).reversed())
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
// 截取当前奖项的中奖人员
|
// 排除前序中奖人员后,最多抽取当前剩余人数;没有剩余人员时取空名单并继续后续奖项。
|
||||||
List<NutMap> rankNutMaps = canLotteryUsers.subList(0, lotteryUserNum);
|
int actualNum = Math.min(lotteryUserNum, canLotteryUsers.size());
|
||||||
|
if (actualNum < lotteryUserNum) {
|
||||||
|
shortageMessages.add(awardName + ":设置 " + lotteryUserNum + " 人,实际可抽 " + canLotteryUsers.size() + " 人,已抽取 " + actualNum + " 人");
|
||||||
|
}
|
||||||
|
List<NutMap> rankNutMaps = canLotteryUsers.subList(0, actualNum);
|
||||||
// 收集成中奖人员存储
|
// 收集成中奖人员存储
|
||||||
List<FitnessWalkAwardUser> collect = rankNutMaps.stream().map(v -> {
|
List<FitnessWalkAwardUser> collect = rankNutMaps.stream().map(v -> {
|
||||||
FitnessWalkAwardUser awardUser = new FitnessWalkAwardUser();
|
FitnessWalkAwardUser awardUser = new FitnessWalkAwardUser();
|
||||||
@@ -289,7 +344,7 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
awardUser.setUnionName(v.getString("unionname"));
|
awardUser.setUnionName(v.getString("unionname"));
|
||||||
awardUser.setUnitId(v.getString("unitid"));
|
awardUser.setUnitId(v.getString("unitid"));
|
||||||
awardUser.setUnitName(v.getString("unitname"));
|
awardUser.setUnitName(v.getString("unitname"));
|
||||||
awardUser.setStandardsDays(v.getInt("standardsDays"));
|
awardUser.setStandardsDays(v.getInt("standardsDays", 0));
|
||||||
awardUser.setAwardSteps(v.getString("total_steps"));
|
awardUser.setAwardSteps(v.getString("total_steps"));
|
||||||
awardUser.setPoints(rank.getPoints());
|
awardUser.setPoints(rank.getPoints());
|
||||||
return awardUser;
|
return awardUser;
|
||||||
@@ -301,8 +356,9 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 达标奖项不要求填写排名位次;空位次保持原有规则顺序,支持多个达标奖项连续抽取。
|
||||||
List<FitnessWalkRaffleRules.ManualLotteryRules> reachList = manualLotteryRules.stream().filter(v -> "达标".equals(v.getRaffleType()))
|
List<FitnessWalkRaffleRules.ManualLotteryRules> reachList = manualLotteryRules.stream().filter(v -> "达标".equals(v.getRaffleType()))
|
||||||
.sorted(Comparator.comparing(FitnessWalkRaffleRules.ManualLotteryRules::getRankingPosition)).toList();
|
.sorted(Comparator.comparing(FitnessWalkRaffleRules.ManualLotteryRules::getRankingPosition, Comparator.nullsLast(Comparator.naturalOrder()))).toList();
|
||||||
|
|
||||||
for (FitnessWalkRaffleRules.ManualLotteryRules reach : reachList) {
|
for (FitnessWalkRaffleRules.ManualLotteryRules reach : reachList) {
|
||||||
List<NutMap> nutMaps;
|
List<NutMap> nutMaps;
|
||||||
@@ -317,9 +373,15 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
Integer lotteryUserNum = reach.getLotteryUserNum();
|
Integer lotteryUserNum = reach.getLotteryUserNum();
|
||||||
String awardName = reach.getAwardName();
|
String awardName = reach.getAwardName();
|
||||||
|
|
||||||
|
// 兼得规则已决定当前候选池,人数不足时全部抽取,人数为零时继续处理其他奖项。
|
||||||
|
int actualNum = Math.min(lotteryUserNum, nutMaps.size());
|
||||||
|
if (actualNum < lotteryUserNum) {
|
||||||
|
shortageMessages.add(awardName + ":设置 " + lotteryUserNum + " 人,实际可抽 " + nutMaps.size() + " 人,已抽取 " + actualNum + " 人");
|
||||||
|
}
|
||||||
|
|
||||||
List<NutMap> reachNutMaps = nutMaps.stream().collect(Collectors.collectingAndThen(Collectors.toList(), collected -> {
|
List<NutMap> reachNutMaps = nutMaps.stream().collect(Collectors.collectingAndThen(Collectors.toList(), collected -> {
|
||||||
Collections.shuffle(collected);
|
Collections.shuffle(collected);
|
||||||
return collected.subList(0, lotteryUserNum - 1);
|
return collected.subList(0, actualNum);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
List<FitnessWalkAwardUser> collect = reachNutMaps.stream().map(v -> {
|
List<FitnessWalkAwardUser> collect = reachNutMaps.stream().map(v -> {
|
||||||
@@ -336,7 +398,7 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
awardUser.setUnionName(v.getString("unionname"));
|
awardUser.setUnionName(v.getString("unionname"));
|
||||||
awardUser.setUnitId(v.getString("unitid"));
|
awardUser.setUnitId(v.getString("unitid"));
|
||||||
awardUser.setUnitName(v.getString("unitname"));
|
awardUser.setUnitName(v.getString("unitname"));
|
||||||
awardUser.setStandardsDays(v.getInt("standardsDays"));
|
awardUser.setStandardsDays(v.getInt("standardsDays", 0));
|
||||||
awardUser.setAwardSteps(v.getString("total_steps"));
|
awardUser.setAwardSteps(v.getString("total_steps"));
|
||||||
awardUser.setPoints(reach.getPoints());
|
awardUser.setPoints(reach.getPoints());
|
||||||
return awardUser;
|
return awardUser;
|
||||||
@@ -347,7 +409,16 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
|
|||||||
winningUsers.addAll(collect);
|
winningUsers.addAll(collect);
|
||||||
}
|
}
|
||||||
|
|
||||||
dao().fastInsert(winningUsers);
|
// 全部奖项计算完成后,在同一事务中替换旧名单;空候选池或空中奖名单无需批量插入。
|
||||||
|
dao().clear(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId));
|
||||||
|
dao().clear(FitnessWalkRaffleUser.class, Cnd.where("activityId", "=", activityId));
|
||||||
|
if (!raffleUserList.isEmpty()) {
|
||||||
|
dao().fastInsert(raffleUserList);
|
||||||
|
}
|
||||||
|
if (!winningUsers.isEmpty()) {
|
||||||
|
dao().fastInsert(winningUsers);
|
||||||
|
}
|
||||||
|
return shortageMessages.isEmpty() ? "抽奖完成" : "抽奖完成;" + String.join(";", shortageMessages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-form>
|
</el-form>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
<el-button @click="$refs.guava.index()" class="ml10">返回</el-button>
|
<el-button @click="$refs.guava.index()" class="ml10">返回</el-button>
|
||||||
<el-button @click="saveRaffle" class="ml10" type="primary">提交</el-button>
|
<el-button @click="saveRaffle" :loading="formLoading" class="ml10" type="primary">提交</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
@@ -211,7 +211,7 @@ layout("/layouts/platform.html"){
|
|||||||
<table-tool :app="this" label="中奖人员列表">
|
<table-tool :app="this" label="中奖人员列表">
|
||||||
<el-button @click="exportAwardExcel" icon="el-icon-download" type="primary" size="small">导出中奖人员</el-button>
|
<el-button @click="exportAwardExcel" icon="el-icon-download" type="primary" size="small">导出中奖人员</el-button>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
<el-table :data="awardTableData">
|
<el-table :data="awardTableData" v-loading="tableLoading">
|
||||||
<el-table-column :index="indexMethod" align="center" header-align="center" label="排名" type="index"
|
<el-table-column :index="indexMethod" align="center" header-align="center" label="排名" type="index"
|
||||||
width="80px"></el-table-column>
|
width="80px"></el-table-column>
|
||||||
<el-table-column align="center" header-align="center" label="工号" prop="loginName"></el-table-column>
|
<el-table-column align="center" header-align="center" label="工号" prop="loginName"></el-table-column>
|
||||||
@@ -219,6 +219,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-table-column align="center" header-align="center" label="分工会" prop="unionName"></el-table-column>
|
<el-table-column align="center" header-align="center" label="分工会" prop="unionName"></el-table-column>
|
||||||
<el-table-column align="center" header-align="center" label="单位" prop="unitName"></el-table-column>
|
<el-table-column align="center" header-align="center" label="单位" prop="unitName"></el-table-column>
|
||||||
<el-table-column align="center" header-align="center" label="奖项名称" prop="awardName"></el-table-column>
|
<el-table-column align="center" header-align="center" label="奖项名称" prop="awardName"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="是否抽奖" prop="isRaffleText"></el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
@@ -300,32 +301,52 @@ layout("/layouts/platform.html"){
|
|||||||
this.awardPageData()
|
this.awardPageData()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 使用当前活动、奖项和姓名工号筛选后台完整中奖名单,手机端抽奖状态仅作为展示字段。
|
||||||
|
*/
|
||||||
awardPageData() {
|
awardPageData() {
|
||||||
this.awardPageForm.activityId = this.pageForm.activityId
|
this.$set(this.awardPageForm, 'activityId', this.pageForm.activityId)
|
||||||
this.$axios.post('/platform/fitnessWalk/stepWining/prizeUsers', this.awardPageForm).then((resp) => {
|
this.$set(this, 'awardTableData', [])
|
||||||
if (resp.code === 0) {
|
this.$set(this, 'tableLoading', true)
|
||||||
this.awardTableData = resp.data
|
this.$axios.post('/platform/fitnessWalk/stepRaffle/awardUsers', this.awardPageForm)
|
||||||
}
|
.then((resp) => {
|
||||||
})
|
if (resp.code === 0) {
|
||||||
|
this.$set(this, 'awardTableData', resp.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.$set(this, 'tableLoading', false)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
exportAwardExcel(){
|
exportAwardExcel(){
|
||||||
const {searchKeyword,activityId,lotteryTime} = this.awardPageForm
|
const {searchKeyword,activityId,lotteryTime} = this.awardPageForm
|
||||||
window.open( loc() + '/exportAwardExcel?searchKeyword=' + searchKeyword +
|
window.open( loc() + '/exportAwardExcel?searchKeyword=' + searchKeyword +
|
||||||
'&activityId=' + activityId +'&lotteryTime=' + lotteryTime)
|
'&activityId=' + activityId +'&lotteryTime=' + lotteryTime)
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 提交当前活动的奖项规则,展示后端返回的实际抽取结果;提交期间避免重复触发重抽。
|
||||||
|
*/
|
||||||
saveRaffle() {
|
saveRaffle() {
|
||||||
console.log(this.formData)
|
if (this.formLoading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const formData = Object.assign({}, this.formData)
|
const formData = Object.assign({}, this.formData)
|
||||||
formData.activityId = this.pageForm.activityId
|
this.$set(formData, 'activityId', this.pageForm.activityId)
|
||||||
formData.manualLotteryRules = JSON.stringify(this.formData.manualLotteryRules)
|
this.$set(formData, 'manualLotteryRules', JSON.stringify(this.formData.manualLotteryRules))
|
||||||
this.$axios.post('/platform/fitnessWalk/stepRaffle/saveRaffle', formData).then((resp) => {
|
this.$set(this, 'formLoading', true)
|
||||||
if (resp.code === 0) {
|
this.$axios.post('/platform/fitnessWalk/stepRaffle/saveRaffle', formData)
|
||||||
this.$message.success('保存成功')
|
.then((resp) => {
|
||||||
this.$refs.guava.index()
|
if (resp.code === 0) {
|
||||||
} else {
|
// 多个奖项不足时展示完整汇总,并延长提示时间方便核对实际抽取人数。
|
||||||
this.$message.warning(resp.msg)
|
this.$message.success({message: resp.msg || '抽奖完成', duration: 10000, showClose: true})
|
||||||
}
|
this.$refs.guava.index()
|
||||||
})
|
} else {
|
||||||
|
this.$message.warning(resp.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.$set(this, 'formLoading', false)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
exportExcel(){
|
exportExcel(){
|
||||||
const {searchKeyword,activityId,unionId,unitId} = this.pageForm
|
const {searchKeyword,activityId,unionId,unitId} = this.pageForm
|
||||||
|
|||||||
Reference in New Issue
Block a user