diff --git a/chestnut-cms/chestnut-cms-article/src/main/java/com/chestnut/article/dao/CmsArticleDetailDAO.java b/chestnut-cms/chestnut-cms-article/src/main/java/com/chestnut/article/dao/CmsArticleDetailDAO.java index 8927cce0..c32ed3ef 100644 --- a/chestnut-cms/chestnut-cms-article/src/main/java/com/chestnut/article/dao/CmsArticleDetailDAO.java +++ b/chestnut-cms/chestnut-cms-article/src/main/java/com/chestnut/article/dao/CmsArticleDetailDAO.java @@ -77,6 +77,6 @@ public class CmsArticleDetailDAO extends BackupServiceImpl().select(List.of(BCmsImage::getImageId)) .eq(BCmsImage::getSiteId, site.getSiteId()) ).getRecords().stream().map(BCmsImage::getBackupId).toList(); - backupMapper.deleteBatchIds(backupIds); + backupMapper.deleteByIds(backupIds); } } catch (Exception e) { AsyncTaskManager.addErrMessage("删除图片内容备份错误:" + e.getMessage()); diff --git a/chestnut-cms/chestnut-cms-media/src/main/java/com/chestnut/media/listener/MediaListener.java b/chestnut-cms/chestnut-cms-media/src/main/java/com/chestnut/media/listener/MediaListener.java index a7dd513a..7983d2da 100644 --- a/chestnut-cms/chestnut-cms-media/src/main/java/com/chestnut/media/listener/MediaListener.java +++ b/chestnut-cms/chestnut-cms-media/src/main/java/com/chestnut/media/listener/MediaListener.java @@ -79,7 +79,7 @@ public class MediaListener { .eq(BCmsAudio::getSiteId, site.getSiteId()) ).getRecords().stream().map(BCmsAudio::getBackupId).toList(); - backupMapper.deleteBatchIds(backupIds); + backupMapper.deleteByIds(backupIds); } } catch (Exception e) { AsyncTaskManager.addErrMessage("删除音频内容备份错误:" + e.getMessage()); @@ -116,7 +116,7 @@ public class MediaListener { .eq(BCmsVideo::getSiteId, site.getSiteId()) ).getRecords().stream().map(BCmsVideo::getBackupId).toList(); - backupMapper.deleteBatchIds(backupIds); + backupMapper.deleteByIds(backupIds); } } catch (Exception e) { AsyncTaskManager.addErrMessage("删除视频内容备份错误:" + e.getMessage()); diff --git a/chestnut-common/chestnut-common-datasource/src/main/java/com/chestnut/common/db/mybatisplus/BackupServiceImpl.java b/chestnut-common/chestnut-common-datasource/src/main/java/com/chestnut/common/db/mybatisplus/BackupServiceImpl.java index bed81b5c..b2f90092 100644 --- a/chestnut-common/chestnut-common-datasource/src/main/java/com/chestnut/common/db/mybatisplus/BackupServiceImpl.java +++ b/chestnut-common/chestnut-common-datasource/src/main/java/com/chestnut/common/db/mybatisplus/BackupServiceImpl.java @@ -124,7 +124,7 @@ public class BackupServiceImpl, T extends IBackupable @Override public void deleteBackupByIds(Collection backupIds) { - this.backupMapper.deleteBatchIds(backupIds); + this.backupMapper.deleteByIds(backupIds); } @Override diff --git a/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/SysScheduledTaskController.java b/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/SysScheduledTaskController.java index c79bb93e..c5d08bee 100644 --- a/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/SysScheduledTaskController.java +++ b/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/SysScheduledTaskController.java @@ -155,7 +155,7 @@ public class SysScheduledTaskController extends BaseRestController { @DeleteMapping("/logs") public R removeLogs(@RequestBody @NotEmpty List logIds) { Assert.isTrue(IdUtils.validate(logIds), () -> CommonErrorCode.INVALID_REQUEST_ARG.exception()); - this.logMapper.deleteBatchIds(logIds); + this.logMapper.deleteByIds(logIds); return R.ok(); } } diff --git a/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/common/GroovyController.java b/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/common/GroovyController.java index 87ed0d5e..7f5e9843 100644 --- a/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/common/GroovyController.java +++ b/chestnut-modules/chestnut-system/src/main/java/com/chestnut/system/controller/common/GroovyController.java @@ -94,7 +94,7 @@ public class GroovyController extends BaseRestController { @Log(title = "刪除Groovy脚本", businessType = BusinessType.DELETE) @DeleteMapping("/delete") public R deleteGroovyScript(@RequestBody @NotEmpty List scriptIds) { - this.groovyScriptMapper.deleteBatchIds(scriptIds); + this.groovyScriptMapper.deleteByIds(scriptIds); return R.ok(); } diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/controller/VoteController.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/controller/VoteController.java index ceb2731b..a0fe2edb 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/controller/VoteController.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/controller/VoteController.java @@ -18,7 +18,6 @@ package com.chestnut.vote.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.chestnut.common.domain.R; import com.chestnut.common.exception.CommonErrorCode; -import com.chestnut.common.i18n.I18nUtils; import com.chestnut.common.log.annotation.Log; import com.chestnut.common.log.enums.BusinessType; import com.chestnut.common.security.anno.Priv; @@ -40,7 +39,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Map; @RequiredArgsConstructor @RestController @@ -74,17 +72,13 @@ public class VoteController extends BaseRestController { @Priv(type = AdminUserType.TYPE, value = VotePriv.View) @GetMapping("/userTypes") public R getVoteUserTypes() { - List> list = this.userTypes.stream() - .map(vut -> Map.of("id", vut.getId(), "name", I18nUtils.get(vut.getName()))).toList(); - return R.ok(list); + return bindSelectOptions(this.userTypes, IVoteUserType::getId, IVoteUserType::getName); } @Priv(type = AdminUserType.TYPE) @GetMapping("/item/types") public R getVoteItemTypes() { - List> list = this.itemTypes.stream() - .map(vut -> Map.of("id", vut.getId(), "name", I18nUtils.get(vut.getName()))).toList(); - return R.ok(list); + return bindSelectOptions(this.itemTypes, IVoteItemType::getId, IVoteItemType::getName); } @Log(title = "新增问卷调查", businessType = BusinessType.INSERT) diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteItemType.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteItemType.java index c44efc89..8ef52b29 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteItemType.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteItemType.java @@ -23,15 +23,15 @@ package com.chestnut.vote.core; */ public interface IVoteItemType { - public String BEAN_PREFIX = "VoteItemType_"; + String BEAN_PREFIX = "VoteItemType_"; /** * 问卷调查选项类型ID,唯一标识 */ - public String getId(); + String getId(); /** * 问卷调查选项类型名称 */ - public String getName(); + String getName(); } diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteUserType.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteUserType.java index 88ed2fe2..6e7374bf 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteUserType.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/core/IVoteUserType.java @@ -23,7 +23,7 @@ package com.chestnut.vote.core; */ public interface IVoteUserType { - public String BEAN_PREFIX = "VoteUserType_"; + String BEAN_PREFIX = "VoteUserType_"; /** * 问卷调查用户类型ID,唯一标识 diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/VoteLog.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/VoteLog.java index d63a4888..ca93d8fa 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/VoteLog.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/VoteLog.java @@ -15,19 +15,19 @@ */ package com.chestnut.vote.domain; -import java.io.Serializable; -import java.time.LocalDateTime; -import java.util.Map; - import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; - +import com.chestnut.vote.domain.dto.VoteSubmitDTO; import lombok.Getter; import lombok.Setter; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.List; + /** * 问卷调查日志表 * @@ -63,11 +63,9 @@ public class VoteLog implements Serializable { /** * 投票结果 - * - * 格式: */ @TableField(typeHandler = JacksonTypeHandler.class) - private Map result; + private List result; /** * 日志记录时间 diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/dto/VoteSubmitDTO.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/dto/VoteSubmitDTO.java index 7551aab5..b828886d 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/dto/VoteSubmitDTO.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/domain/dto/VoteSubmitDTO.java @@ -15,11 +15,12 @@ */ package com.chestnut.vote.domain.dto; -import java.util.List; - import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; +import java.util.List; + @Getter @Setter public class VoteSubmitDTO { @@ -52,10 +53,15 @@ public class VoteSubmitDTO { * 主题ID */ private Long subjectId; - + + /** + * 主题类型 + */ + private String type; + /** * 结果:itemId || inputText */ - private String result; + private ArrayList result; } } diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteMapper.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteMapper.java index 1fe83c98..d7e8ce56 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteMapper.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteMapper.java @@ -17,6 +17,8 @@ package com.chestnut.vote.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.chestnut.vote.domain.Vote; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; /** *

@@ -28,4 +30,7 @@ import com.chestnut.vote.domain.Vote; */ public interface VoteMapper extends BaseMapper { + @Update("UPDATE " + Vote.TABLE_NAME + " SET total = total + ${delta} WHERE vote_id = #{voteId}") + void increaseVoteTotal(@Param("voteId") Long voteId, @Param("delta") Integer delta); + } \ No newline at end of file diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteSubjectItemMapper.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteSubjectItemMapper.java index 23a31928..34558c8b 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteSubjectItemMapper.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/mapper/VoteSubjectItemMapper.java @@ -17,6 +17,8 @@ package com.chestnut.vote.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.chestnut.vote.domain.VoteSubjectItem; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; /** *

@@ -28,4 +30,6 @@ import com.chestnut.vote.domain.VoteSubjectItem; */ public interface VoteSubjectItemMapper extends BaseMapper { + @Update("UPDATE " + VoteSubjectItem.TABLE_NAME + " SET total = total + ${delta} WHERE item_id = #{itemId}") + void increaseVoteSubjectItemTotal(@Param("itemId") Long itemId, @Param("delta") Integer delta); } \ No newline at end of file diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteApiServiceImpl.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteApiServiceImpl.java index 71f75917..44ae6ebc 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteApiServiceImpl.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteApiServiceImpl.java @@ -22,7 +22,6 @@ import com.chestnut.common.utils.DateUtils; import com.chestnut.vote.core.IVoteUserType; import com.chestnut.vote.domain.VoteLog; import com.chestnut.vote.domain.dto.VoteSubmitDTO; -import com.chestnut.vote.domain.dto.VoteSubmitDTO.SubjectResult; import com.chestnut.vote.domain.vo.VoteVO; import com.chestnut.vote.exception.VoteErrorCode; import com.chestnut.vote.service.IVoteApiService; @@ -35,8 +34,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; -import java.util.Map; -import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -82,13 +79,11 @@ public class VoteApiServiceImpl implements IVoteApiService { Assert.isTrue(dayCount < vote.getDayLimit(), VoteErrorCode.VOTE_DAY_LIMIT::exception); // 记录日志 - Map result = dto.getSubjects().stream() - .collect(Collectors.toMap(SubjectResult::getSubjectId, SubjectResult::getResult)); VoteLog voteLog = new VoteLog(); voteLog.setVoteId(dto.getVoteId()); voteLog.setUserType(vote.getUserType()); voteLog.setUserId(userId); - voteLog.setResult(result); + voteLog.setResult(dto.getSubjects()); voteLog.setLogTime(LocalDateTime.now()); voteLog.setIp(dto.getIp()); voteLog.setUserAgent(dto.getUserAgent()); diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteServiceImpl.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteServiceImpl.java index 4afdd2f8..962f8219 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteServiceImpl.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteServiceImpl.java @@ -16,7 +16,6 @@ package com.chestnut.vote.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.chestnut.common.exception.CommonErrorCode; @@ -30,6 +29,7 @@ import com.chestnut.vote.domain.Vote; import com.chestnut.vote.domain.VoteLog; import com.chestnut.vote.domain.VoteSubject; import com.chestnut.vote.domain.VoteSubjectItem; +import com.chestnut.vote.domain.dto.VoteSubmitDTO; import com.chestnut.vote.domain.vo.VoteSubjectItemVO; import com.chestnut.vote.domain.vo.VoteSubjectVO; import com.chestnut.vote.domain.vo.VoteVO; @@ -51,8 +51,7 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @RequiredArgsConstructor @@ -67,12 +66,14 @@ public class VoteServiceImpl extends ServiceImpl implements IV private final VoteSubjectItemMapper itemMapper; + private final VoteMapper voteMapper; + private final VoteLogMapper voteLogMapper; private final RedisCache redisCache; private final Map voteUserTypes; - + private final Map voteItemTypes; private final RedissonClient redissonClient; @@ -235,22 +236,66 @@ public class VoteServiceImpl extends ServiceImpl implements IV try { VoteVO vote = this.getVote(voteLog.getVoteId()); // 问卷调查参与数+1 - Vote voteEntity = this.lambdaQuery().select(Vote::getVoteId, Vote::getTotal) - .eq(Vote::getVoteId, voteLog.getVoteId()).one(); - this.lambdaUpdate().set(Vote::getTotal, voteEntity.getTotal() + 1) - .eq(Vote::getVoteId, voteLog.getVoteId()).update(); + vote.setTotal(Objects.requireNonNullElse(vote.getTotal(), 0) + 1); + voteMapper.increaseVoteTotal(vote.getVoteId(), 1); // 单选/多选主题选项票数+1 vote.getSubjects().forEach(subject -> { if (!VoteSubjectType.isInput(subject.getType())) { - String result = voteLog.getResult().get(subject.getSubjectId()); - VoteSubjectItem item = new LambdaQueryChainWrapper<>(this.itemMapper) - .select(VoteSubjectItem::getItemId, VoteSubjectItem::getTotal) - .eq(VoteSubjectItem::getItemId, result) - .one(); - new LambdaUpdateChainWrapper<>(this.itemMapper) - .set(VoteSubjectItem::getTotal, item.getTotal() + 1) - .eq(VoteSubjectItem::getItemId, item.getItemId()) - .update(); + List subjectResults = voteLog.getResult(); + Optional opt = subjectResults.stream() + .filter(r -> subject.getSubjectId().equals(r.getSubjectId()) && subject.getType().equals(r.getType())) + .findFirst(); + if (opt.isPresent()) { + VoteSubmitDTO.SubjectResult result = opt.get(); + for (String itemIdStr : result.getResult()) { + Long itemId = Long.parseLong(itemIdStr); + this.itemMapper.increaseVoteSubjectItemTotal(itemId, 1); + } + } + } + }); + // 更新缓存 + this.redisCache.setCacheObject(CACHE_PREFIX + vote.getVoteId(), vote); + } finally { + lock.unlock(); + } + } + + public void resetVoteStat(Long voteId) { + RLock lock = redissonClient.getLock("VoteTotalUpdate-" + voteId); + lock.lock(); + try { + VoteVO vote = this.getVote(voteId); + + List voteLogs = voteLogMapper.selectList(new LambdaQueryWrapper() + .eq(VoteLog::getVoteId, vote.getVoteId())); + // 问卷调查参与数 + vote.setTotal(voteLogs.size()); + this.lambdaUpdate().set(Vote::getTotal, voteLogs.size()).eq(Vote::getVoteId, vote.getVoteId()).update(); + // 单选/多选主题选项票数 + vote.getSubjects().forEach(subject -> { + if (!VoteSubjectType.isInput(subject.getType())) { + Map itemTotalMap = new HashMap<>(); + List itemIds = subject.getItems().stream().map(VoteSubjectItemVO::getItemId).toList(); + for (VoteLog voteLog : voteLogs) { + Optional opt = voteLog.getResult().stream().filter(r -> + r.getSubjectId().equals(subject.getSubjectId()) && r.getType().equals(subject.getTitle()) + ).findFirst(); + if (opt.isPresent()) { + VoteSubmitDTO.SubjectResult result = opt.get(); + for (String itemIdStr : result.getResult()) { + long itemId = Long.parseLong(itemIdStr); + if (itemIds.contains(itemId)) { + itemTotalMap.put(itemId, itemTotalMap.getOrDefault(itemId, 0) + 1); + } + } + } + } + for (Map.Entry entry : itemTotalMap.entrySet()) { + new LambdaUpdateChainWrapper<>(itemMapper).set(VoteSubjectItem::getTotal, entry.getValue()) + .eq(VoteSubjectItem::getItemId, entry.getKey()) + .update(); + } } }); // 更新缓存 diff --git a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteSubjectServiceImpl.java b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteSubjectServiceImpl.java index 3963fb31..c31f9460 100644 --- a/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteSubjectServiceImpl.java +++ b/chestnut-modules/chestnut-vote/src/main/java/com/chestnut/vote/service/impl/VoteSubjectServiceImpl.java @@ -143,7 +143,7 @@ public class VoteSubjectServiceImpl extends ServiceImpl removeItemIds = dbItems.stream().map(VoteSubjectItem::getItemId) .filter(itemId -> !updateItemIds.contains(itemId)).toList(); if (!removeItemIds.isEmpty()) { - this.voteSubjectItemMapper.deleteBatchIds(removeItemIds); + this.voteSubjectItemMapper.deleteByIds(removeItemIds); } Map updateMap = dbItems.stream().filter(item -> updateItemIds.contains(item.getItemId())) diff --git a/chestnut-ui/src/views/vote/index.vue b/chestnut-ui/src/views/vote/index.vue index f08fb14e..addd2afc 100644 --- a/chestnut-ui/src/views/vote/index.vue +++ b/chestnut-ui/src/views/vote/index.vue @@ -172,9 +172,9 @@ {{ ut.name }} + :key="ut.value" + :label="ut.value" + >{{ ut.label }} diff --git a/chestnut-ui/src/views/vote/subjectList.vue b/chestnut-ui/src/views/vote/subjectList.vue index 883cac05..f107679b 100644 --- a/chestnut-ui/src/views/vote/subjectList.vue +++ b/chestnut-ui/src/views/vote/subjectList.vue @@ -76,9 +76,9 @@ @@ -221,14 +221,14 @@ - +