ChronoField

ChronoField

System.out.println(year);
int month = date.get(ChronoField.MONTH_OF_YEAR);
System.out.println(month);
int day = date.get(ChronoField.DAY_OF_MONTH);
System.out.println(day);
2017
8
17

现在提供package com.example.bc.service.impl; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.bc.constant.enums.DeleteStateEnum; import com.example.bc.constant.enums.LockFlagEnum; import com.example.bc.constant.enums.StatusEnum; import com.example.bc.entity.BcNews; import com.example.bc.entity.BcNewsUser; import com.example.bc.mapper.BcNewsUserMapper; import com.example.bc.service.BcNewsService; import com.example.bc.service.BcNewsUserService; import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.locks.Lock; import java.util.stream.Collectors; /** * 资讯咨询用户关联 * * @author 3214- * @date 2025-09-12 09:52:09 */ @Service @Slf4j public class BcNewsUserServiceImpl extends ServiceImpl<BcNewsUserMapper, BcNewsUser> implements BcNewsUserService { @Override public void publishNews() {//按 “周期 - 周数” 的规则,为用户匹配对应的资讯,并建立全新的用户 - 资讯关联关系(避免重复关联),最后批量存入数据库 try { LocalDateTime now = LocalDateTime.now();//获取当前时间,用于后续设置关联记录的创建时间 List<BcNewsUser> publishedList = this.list();//查询所有已存在的 BcNewsUser 记录(即已有的用户 - 资讯关联数据)。 Set<String> existingRelations = publishedList.stream() .map(bc -> bc.getUserId() + "_" + bc.getNewsId()) .collect(Collectors.toSet());//将已存在的关联记录,按 userId + "_" + newsId 的格式生成唯一键集合,用于后续判断是否重复关联。 BcNewsService bcNewsService = SpringContextHolder.getBean(BcNewsService.class);//通过 BcNewsService 查询资讯 LambdaQueryWrapper<BcNews> newsQuery = new LambdaQueryWrapper<>(); newsQuery.eq(BcNews::getDelFlag, DeleteStateEnum.UN_DELETED.getState())//delFlag 为未删除(DeleteStateEnum.UN_DELETED) .eq(BcNews::getStatus, StatusEnum.ENABLE.getState());//status 为启用(StatusEnum.ENABLE) newsQuery.ne(BcNews::getPushCycle, 1);//pushCycle 不等于 1(即排除按 “周期为 1” 规则推送的资讯) List<BcNews> newsList = bcNewsService.list(newsQuery); // 调整资讯分组键为“第X周 星期X” Map<String, List<BcNews>> newsGroupByCycleWeek = newsList.stream() .filter(news -> news.getPushCycle() != null && news.getPushWeek() != null) .collect(Collectors.groupingBy( //bug news -> "第"+news.getPushCycle()+"周"+news.getPushWeek() //news -> news.getPushCycle() + "_" + news.getPushWeek() )); //对查询到的资讯进行分组:按 pushCycle + "_" + pushWeek(周期 + 周数)的格式分组, //得到 Map<String, List<BcNews>> newsGroupByCycleWeek,方便后续按周期 - 周数匹配用户。 List<SysUser> userList = baseMapper.listUser();//查询系统中的用户列表 Map<String, List<SysUser>> userGroupByWeekKey = userWeekMap(userList);//调用 userWeekMap 方法(推测是按用户对应的 “周期 - 周数” 规则分组), // 得到按周数键分组的用户映射。 List<BcNewsUser> addList = new ArrayList<>();//新闻咨询用户关联集合 for (Map.Entry<String, List<SysUser>> userEntry : userGroupByWeekKey.entrySet()) {//遍历分组后的用户 String weekKey = userEntry.getKey(); List<SysUser> users = userEntry.getValue(); List<BcNews> matchedNews = newsGroupByCycleWeek.get(weekKey);//对于每个周数键(weekKey),找到对应的资讯列表(matchedNews) if (matchedNews == null || matchedNews.isEmpty()) { continue; } for (BcNews news : matchedNews) {//遍历该周数下的用户 Long newsId = news.getId(); if (newsId == null) {///遍历匹配到的资讯,若资讯 ID(newsId)为 null,跳过该资讯 continue; } for (SysUser user : users) { Long userId = user.getUserId(); if (userId == null) {//若用户 ID(userId)为 null,跳过该用户 continue; } String relationKey = userId + "_" + newsId;//生成关联唯一键 relationKey = userId + "_" + newsId if (existingRelations.contains(relationKey)) { continue;////若该键已存在于 existingRelations(即已关联过),跳过该用户与资讯的关联。 } BcNewsUser relation = new BcNewsUser();//若未关联过,创建 BcNewsUser 实例 relation.setUserId(userId);//设置用户 ID、 relation.setNewsId(newsId);//资讯 ID、 relation.setIsRead(0);//未读状态(isRead = 0) relation.setCreateTime(now);//和创建时间, addList.add(relation);//添加到待保存的 addList 中。 } } } if (!addList.isEmpty()) {//if (!addList.isEmpty()) { this.saveBatch(addList); ... }: // 若有待保存的关联记录,批量保存到数据库,并打印日志记录保存数量 this.saveBatch(addList); log.info("成功添加资讯用户关联数据,数量:{}", addList.size()); } } catch (Exception e) { log.error("发布资讯关联数据失败", e); } } @Override public void pushFirstWeekNews(Long userId) { try { // 1. 查询第一周需要推送的资讯(pushCycle=1) BcNewsService bcNewsService = SpringContextHolder.getBean(BcNewsService.class); LambdaQueryWrapper<BcNews> newsQuery = new LambdaQueryWrapper<>(); newsQuery.eq(BcNews::getPushCycle, 1); // 筛选第一周的资讯 List<BcNews> bcNewsList = bcNewsService.list(newsQuery); // 若没有符合条件的资讯,直接返回 if (ObjectUtil.isEmpty(bcNewsList)) { log.info("没有需要推送的第一周资讯,用户ID:{}", userId); return; } // 2. 查询用户已有的资讯关联记录 LambdaQueryWrapper<BcNewsUser> userNewsQuery = new LambdaQueryWrapper<>(); userNewsQuery.eq(BcNewsUser::getUserId, userId); List<BcNewsUser> existingUserNews = this.list(userNewsQuery); // 3. 提取已有的资讯ID到Set(O(1)判断效率,避免嵌套循环) Set<Long> existingNewsIds = new HashSet<>(); if (ObjectUtil.isNotEmpty(existingUserNews)) { for (BcNewsUser userNews : existingUserNews) { Long newsId = userNews.getNewsId(); if (newsId != null) { // 过滤null,避免空指针 existingNewsIds.add(newsId); } } } // 4. 筛选需要新增的关联记录(不存在于已有记录中) List<BcNewsUser> toAddList = new ArrayList<>(); LocalDateTime now = LocalDateTime.now(); // 统一创建时间,避免循环中重复生成 for (BcNews news : bcNewsList) { Long newsId = news.getId(); // 跳过无效资讯(ID为null) if (newsId == null) { log.warn("发现ID为null的无效资讯,已跳过"); continue; } // 仅添加未关联的资讯 if (!existingNewsIds.contains(newsId)) { BcNewsUser newUserNews = createBcNewsUser(userId, newsId, now); toAddList.add(newUserNews); } } // 5. 批量保存(仅当有数据时执行) if (ObjectUtil.isNotEmpty(toAddList)) { this.saveBatch(toAddList); log.info("给用户[{}]推送第一周资讯成功,新增{}条记录", userId, toAddList.size()); } else { log.info("用户[{}]已拥有所有第一周资讯,无需新增", userId); } } catch (Exception e) { log.error("推送第一周资讯失败,用户ID:{}", userId, e); } } /** * 抽取创建BcNewsUser的逻辑,减少重复代码 */ private BcNewsUser createBcNewsUser(Long userId, Long newsId, LocalDateTime createTime) { BcNewsUser bcNewsUser = new BcNewsUser(); bcNewsUser.setUserId(userId); bcNewsUser.setNewsId(newsId); bcNewsUser.setIsRead(0); // 0表示未读 bcNewsUser.setCreateTime(createTime); return bcNewsUser; } /** * 按“第X周 星期X”分组用户,确保与资讯的pushCycle和pushWeek匹配 */ private Map<String, List<SysUser>> userWeekMap(List<SysUser> userList) { if (userList == null || userList.isEmpty()) { return Collections.emptyMap(); } LocalDateTime now = LocalDateTime.now(); // bug处理星期:将 ChronoField.DAY_OF_WEEK(1 - 7 对应周一到周日)转换为中文“星期一”等 String[] weekDays = {"", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"}; int currentDayOfWeek = now.get(ChronoField.DAY_OF_WEEK); //bug处理为周一到周日 String currentWeekDay = weekDays[currentDayOfWeek]; return userList.stream() .collect(Collectors.groupingBy( user -> { LocalDateTime auditTime = user.getAuditTime(); long weeksSinceCreate; if (auditTime == null) { weeksSinceCreate = -1; } else if (auditTime.isAfter(now)) { weeksSinceCreate = 0; } else { weeksSinceCreate = ChronoUnit.WEEKS.between(auditTime, now) + 1; //计算用户从创建时间到现在的周数是 ChronoUnit.WEEKS.between(auditTime, now) + 1, // 但前端展示的是 “第 X 周 星期 X”,可能周数的起始或计算方式不一致。 } //bug生成与资讯分组一致的键:“第X周 星期X” return "第" + weeksSinceCreate + "周 " + currentWeekDay; //return weeksSinceCreate + "_" + currentDayOfWeek; } )); } }
10-17
Exception in thread "main" java.time.DateTimeException: Invalid value for MonthOfYear (valid values 1 - 12): 0 at java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311) at java.time.temporal.ChronoField.checkValidValue(ChronoField.java:703) at java.time.LocalDate.of(LocalDate.java:267) at java.time.LocalDateTime.of(LocalDateTime.java:336) at org.springframework.boot.loader.jar.CentralDirectoryFileHeader.decodeMsDosFormatDateTime(CentralDirectoryFileHeader.java:127) at org.springframework.boot.loader.jar.CentralDirectoryFileHeader.getTime(CentralDirectoryFileHeader.java:116) at org.springframework.boot.loader.jar.JarEntry.<init>(JarEntry.java:58) at org.springframework.boot.loader.jar.JarFileEntries.getEntry(JarFileEntries.java:316) at org.springframework.boot.loader.jar.JarFileEntries.access$400(JarFileEntries.java:48) at org.springframework.boot.loader.jar.JarFileEntries$EntryIterator.next(JarFileEntries.java:366) at org.springframework.boot.loader.jar.JarFileEntries$EntryIterator.next(JarFileEntries.java:350) at org.springframework.boot.loader.jar.JarFile$2.nextElement(JarFile.java:204) at org.springframework.boot.loader.jar.JarFile$2.nextElement(JarFile.java:195) at org.springframework.boot.loader.archive.JarFileArchive$EntryIterator.next(JarFileArchive.java:189) at org.springframework.boot.loader.archive.JarFileArchive$EntryIterator.next(JarFileArchive.java:174) at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:85) at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:69) at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
08-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值