mirror of
https://gitee.com/liweiyi/ChestnutCMS.git
synced 2025-12-06 16:38:24 +08:00
调查投票提交接口多选修正
This commit is contained in:
parent
3b838ec2b5
commit
eeb7d951ab
@ -77,6 +77,6 @@ public class CmsArticleDetailDAO extends BackupServiceImpl<CmsArticleDetailMappe
|
||||
if (StringUtils.isEmpty(backupIds)) {
|
||||
return;
|
||||
}
|
||||
this.getBackupMapper().deleteBatchIds(backupIds);
|
||||
this.getBackupMapper().deleteByIds(backupIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,6 +90,6 @@ public class CmsContentDAO extends BackupServiceImpl<CmsContentMapper, CmsConten
|
||||
if (StringUtils.isEmpty(backupIds)) {
|
||||
return;
|
||||
}
|
||||
this.getBackupMapper().deleteBatchIds(backupIds);
|
||||
this.getBackupMapper().deleteByIds(backupIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ public class ImageListener {
|
||||
new LambdaQueryWrapper<BCmsImage>().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());
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -124,7 +124,7 @@ public class BackupServiceImpl<M extends BaseMapper<T>, T extends IBackupable<B>
|
||||
|
||||
@Override
|
||||
public void deleteBackupByIds(Collection<Serializable> backupIds) {
|
||||
this.backupMapper.deleteBatchIds(backupIds);
|
||||
this.backupMapper.deleteByIds(backupIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -155,7 +155,7 @@ public class SysScheduledTaskController extends BaseRestController {
|
||||
@DeleteMapping("/logs")
|
||||
public R<?> removeLogs(@RequestBody @NotEmpty List<Long> logIds) {
|
||||
Assert.isTrue(IdUtils.validate(logIds), () -> CommonErrorCode.INVALID_REQUEST_ARG.exception());
|
||||
this.logMapper.deleteBatchIds(logIds);
|
||||
this.logMapper.deleteByIds(logIds);
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ public class GroovyController extends BaseRestController {
|
||||
@Log(title = "刪除Groovy脚本", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/delete")
|
||||
public R<?> deleteGroovyScript(@RequestBody @NotEmpty List<Long> scriptIds) {
|
||||
this.groovyScriptMapper.deleteBatchIds(scriptIds);
|
||||
this.groovyScriptMapper.deleteByIds(scriptIds);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
@ -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<Map<String, String>> 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<Map<String, String>> 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)
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ package com.chestnut.vote.core;
|
||||
*/
|
||||
public interface IVoteUserType {
|
||||
|
||||
public String BEAN_PREFIX = "VoteUserType_";
|
||||
String BEAN_PREFIX = "VoteUserType_";
|
||||
|
||||
/**
|
||||
* 问卷调查用户类型ID,唯一标识
|
||||
|
||||
@ -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 {
|
||||
|
||||
/**
|
||||
* 投票结果
|
||||
*
|
||||
* 格式:<subjectId, itemId|inputText>
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Map<Long, String> result;
|
||||
private List<VoteSubmitDTO.SubjectResult> result;
|
||||
|
||||
/**
|
||||
* 日志记录时间
|
||||
|
||||
@ -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<String> result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -28,4 +30,7 @@ import com.chestnut.vote.domain.Vote;
|
||||
*/
|
||||
public interface VoteMapper extends BaseMapper<Vote> {
|
||||
|
||||
@Update("UPDATE " + Vote.TABLE_NAME + " SET total = total + ${delta} WHERE vote_id = #{voteId}")
|
||||
void increaseVoteTotal(@Param("voteId") Long voteId, @Param("delta") Integer delta);
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -28,4 +30,6 @@ import com.chestnut.vote.domain.VoteSubjectItem;
|
||||
*/
|
||||
public interface VoteSubjectItemMapper extends BaseMapper<VoteSubjectItem> {
|
||||
|
||||
@Update("UPDATE " + VoteSubjectItem.TABLE_NAME + " SET total = total + ${delta} WHERE item_id = #{itemId}")
|
||||
void increaseVoteSubjectItemTotal(@Param("itemId") Long itemId, @Param("delta") Integer delta);
|
||||
}
|
||||
@ -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<Long, String> 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());
|
||||
|
||||
@ -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<VoteMapper, Vote> implements IV
|
||||
|
||||
private final VoteSubjectItemMapper itemMapper;
|
||||
|
||||
private final VoteMapper voteMapper;
|
||||
|
||||
private final VoteLogMapper voteLogMapper;
|
||||
|
||||
private final RedisCache redisCache;
|
||||
|
||||
private final Map<String, IVoteUserType> voteUserTypes;
|
||||
|
||||
|
||||
private final Map<String, IVoteItemType> voteItemTypes;
|
||||
|
||||
private final RedissonClient redissonClient;
|
||||
@ -235,22 +236,66 @@ public class VoteServiceImpl extends ServiceImpl<VoteMapper, Vote> 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<VoteSubmitDTO.SubjectResult> subjectResults = voteLog.getResult();
|
||||
Optional<VoteSubmitDTO.SubjectResult> 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<VoteLog> voteLogs = voteLogMapper.selectList(new LambdaQueryWrapper<VoteLog>()
|
||||
.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<Long, Integer> itemTotalMap = new HashMap<>();
|
||||
List<Long> itemIds = subject.getItems().stream().map(VoteSubjectItemVO::getItemId).toList();
|
||||
for (VoteLog voteLog : voteLogs) {
|
||||
Optional<VoteSubmitDTO.SubjectResult> 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<Long, Integer> entry : itemTotalMap.entrySet()) {
|
||||
new LambdaUpdateChainWrapper<>(itemMapper).set(VoteSubjectItem::getTotal, entry.getValue())
|
||||
.eq(VoteSubjectItem::getItemId, entry.getKey())
|
||||
.update();
|
||||
}
|
||||
}
|
||||
});
|
||||
// 更新缓存
|
||||
|
||||
@ -143,7 +143,7 @@ public class VoteSubjectServiceImpl extends ServiceImpl<VoteSubjectMapper, VoteS
|
||||
List<Long> removeItemIds = dbItems.stream().map(VoteSubjectItem::getItemId)
|
||||
.filter(itemId -> !updateItemIds.contains(itemId)).toList();
|
||||
if (!removeItemIds.isEmpty()) {
|
||||
this.voteSubjectItemMapper.deleteBatchIds(removeItemIds);
|
||||
this.voteSubjectItemMapper.deleteByIds(removeItemIds);
|
||||
}
|
||||
|
||||
Map<Long, VoteSubjectItem> updateMap = dbItems.stream().filter(item -> updateItemIds.contains(item.getItemId()))
|
||||
|
||||
@ -172,9 +172,9 @@
|
||||
<el-radio-group v-model="form.userType">
|
||||
<el-radio
|
||||
v-for="ut in userTypeOptions"
|
||||
:key="ut.id"
|
||||
:label="ut.id"
|
||||
>{{ ut.name }}</el-radio>
|
||||
:key="ut.value"
|
||||
:label="ut.value"
|
||||
>{{ ut.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('Vote.DayLimit')" prop="totalLimit">
|
||||
|
||||
@ -76,9 +76,9 @@
|
||||
<el-select v-model="scope2.row.type" size="mini" disabled>
|
||||
<el-option
|
||||
v-for="type in subjectItemTypes"
|
||||
:key="type.id"
|
||||
:label="type.name"
|
||||
:value="type.id"
|
||||
:key="type.value"
|
||||
:label="type.label"
|
||||
:value="type.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
@ -221,14 +221,14 @@
|
||||
<el-select v-model="scope.row.type">
|
||||
<el-option
|
||||
v-for="type in subjectItemTypes"
|
||||
:key="type.id"
|
||||
:label="type.name"
|
||||
:value="type.id"
|
||||
:key="type.value"
|
||||
:label="type.label"
|
||||
:value="type.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('Comment.Details')">
|
||||
<el-table-column :label="$t('Common.Details')">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-if="scope.row.type==='Text'" type="text" v-model="scope.row.content"></el-input>
|
||||
</template>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user