/*
|
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions are met:
|
*
|
* Redistributions of source code must retain the above copyright notice,
|
* this list of conditions and the following disclaimer.
|
* Redistributions in binary form must reproduce the above copyright
|
* notice, this list of conditions and the following disclaimer in the
|
* documentation and/or other materials provided with the distribution.
|
* Neither the name of the dreamlu.net developer nor the names of its
|
* contributors may be used to endorse or promote products derived from
|
* this software without specific prior written permission.
|
* Author: Chill 庄骞 (smallchill@163.com)
|
*/
|
package org.springblade.modules.discuss.service.impl;
|
|
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.ExcelWriter;
|
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
|
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.StringUtils;
|
import org.jetbrains.annotations.Nullable;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springblade.common.constant.CommonConstant;
|
import org.springblade.common.utils.SpringUtils;
|
import org.springblade.core.redis.cache.BladeRedis;
|
import org.springblade.core.secure.utils.AuthUtil;
|
import org.springblade.core.tool.utils.DateUtil;
|
import org.springblade.core.tool.utils.Func;
|
import org.springblade.core.tool.utils.SpringUtil;
|
import org.springblade.modules.discuss.entity.PublicDiscussEntity;
|
import org.springblade.modules.discuss.entity.TopicsEntity;
|
import org.springblade.modules.discuss.entity.UserTopicsEntity;
|
import org.springblade.modules.discuss.excel.UserTopicsExcel;
|
import org.springblade.modules.discuss.excel.holdExcel;
|
import org.springblade.modules.discuss.mapper.UserTopicsMapper;
|
import org.springblade.modules.discuss.service.IPublicDiscussService;
|
import org.springblade.modules.discuss.service.ITopicsService;
|
import org.springblade.modules.discuss.service.IUserTopicsService;
|
import org.springblade.modules.discuss.vo.TopicsVO;
|
import org.springblade.modules.discuss.vo.UserTopicsVO;
|
import org.springblade.modules.district.entity.DistrictEntity;
|
import org.springblade.modules.district.service.IDistrictService;
|
import org.springblade.modules.house.entity.HouseholdEntity;
|
import org.springblade.modules.house.service.IHouseholdService;
|
import org.springblade.modules.house.service.impl.HouseServiceImpl;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import java.io.OutputStream;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
|
/**
|
* 用户议题报表 服务实现类
|
*
|
* @author BladeX
|
* @since 2023-11-22
|
*/
|
@Service
|
public class UserTopicsServiceImpl extends ServiceImpl<UserTopicsMapper, UserTopicsEntity> implements IUserTopicsService {
|
@Resource
|
private ITopicsService topicsService;
|
public static final String SMS_VALIDATE_PHONE = "sms:validate:code:";
|
|
private static final Logger logger = LoggerFactory.getLogger(UserTopicsServiceImpl.class);
|
|
|
@Autowired
|
private BladeRedis redisTemplate;
|
|
@Override
|
public IPage<UserTopicsVO> selectUserTopicsPage(IPage<UserTopicsVO> page, UserTopicsVO userTopics) {
|
if (StringUtils.isNotBlank(userTopics.getDistrictId())) {
|
List<String> longs = Arrays.asList(userTopics.getDistrictId().split(","));
|
IDistrictService bean = SpringUtils.getBean(IDistrictService.class);
|
List<DistrictEntity> list = bean.list(Wrappers.<DistrictEntity>lambdaQuery().in(DistrictEntity::getId, longs));
|
List<String> collect = list.stream().map(item ->
|
item.getAoiCode()
|
).collect(Collectors.toList());
|
if (collect != null) {
|
userTopics.setAoiCodeList(collect);
|
}
|
}
|
IHouseholdService householdService = SpringUtils.getBean(IHouseholdService.class);
|
HouseholdEntity householdEntity = householdService.getOne(Wrappers.<HouseholdEntity>lambdaQuery()
|
.eq(HouseholdEntity::getHouseCode, userTopics.getHouseCode())
|
.eq(HouseholdEntity::getAssociatedUserId, AuthUtil.getUserId())
|
.eq(HouseholdEntity::getIsDeleted, 0)
|
.last("limit 1"));
|
if (householdEntity != null) {
|
userTopics.setHouseholdId(householdEntity.getId());
|
}
|
List<UserTopicsVO> userTopicsVOS = baseMapper.selectUserTopicsPage(page, userTopics);
|
return page.setRecords(userTopicsVOS);
|
}
|
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public String batchSave(TopicsVO topics) throws Exception {
|
List<TopicsVO> topicsList = topics.getChildren();
|
if (topicsList == null || topicsList.isEmpty()) {
|
return "你未选选项内容";
|
}
|
IPublicDiscussService bean = SpringUtil.getBean(IPublicDiscussService.class);
|
PublicDiscussEntity discussEntity = bean.getOne(Wrappers.<PublicDiscussEntity>lambdaQuery().eq(PublicDiscussEntity::getArticleId, topicsList.get(0).getArticleId()));
|
// 判断是否在开始和结束时间内
|
if (discussEntity.getStartTime().getTime() > System.currentTimeMillis() || discussEntity.getEndTime().getTime() < System.currentTimeMillis()) {
|
return "目前不在投票时间内,投票时间:" + DateUtil.formatDateTime(discussEntity.getStartTime()) + " 至 " + DateUtil.formatDateTime(discussEntity.getEndTime());
|
}
|
if (StringUtils.isNotBlank(topics.getPhone())) {
|
if (StringUtils.isBlank(topics.getCode())) {
|
return "验证码不能为空!";
|
}
|
Object validateCode = redisTemplate.get(SMS_VALIDATE_PHONE + topics.getPhone());
|
if (validateCode == null) {
|
return "验证码已过期";
|
}
|
if (!validateCode.toString().equals(topics.getCode())) {
|
return "验证码错误";
|
}
|
//删除验证码
|
redisTemplate.del(SMS_VALIDATE_PHONE + topics.getPhone());
|
}
|
// 判断是否一户一票 还是一人一票
|
IHouseholdService householdService = SpringUtils.getBean(IHouseholdService.class);
|
HouseholdEntity householdEntity = householdService.getOne(Wrappers.<HouseholdEntity>lambdaQuery()
|
.eq(HouseholdEntity::getHouseCode, topicsList.get(0).getHouseCode())
|
.eq(HouseholdEntity::getAssociatedUserId, AuthUtil.getUserId())
|
.eq(HouseholdEntity::getIsDeleted, 0)
|
.last("limit 1"));
|
if (ObjectUtils.isEmpty(householdEntity)) {
|
logger.error("未查询到住户信息!", JSON.toJSONString(topics));
|
return "未查询到住户信息!";
|
}
|
// 一户一票
|
if (discussEntity.getVoteRestrictions().equals(CommonConstant.NUMBER_ONE)) {
|
long count = count(Wrappers.<UserTopicsEntity>lambdaQuery()
|
.eq(UserTopicsEntity::getHouseCode, topicsList.get(0).getHouseCode())
|
.eq(UserTopicsEntity::getArticleId, topicsList.get(0).getArticleId()));
|
if (count > 0) {
|
return "您的房屋已投票,不能重复投票!";
|
}
|
} else {
|
//
|
long count = count(Wrappers.<UserTopicsEntity>lambdaQuery()
|
.eq(UserTopicsEntity::getHouseholdId, householdEntity.getId())
|
.eq(UserTopicsEntity::getArticleId, topicsList.get(0).getArticleId()));
|
if (count > 0) {
|
return "您已投票,不能重复投票!";
|
}
|
}
|
for (TopicsVO topic : topicsList) {
|
if (topic.getMandatoryFlag().equals(2)) {
|
if (topic.getOptionNumberMin() > 1) {
|
JSONArray objects1 = JSON.parseArray(topic.getSelected());
|
if (objects1.size() < topic.getOptionNumberMin()) {
|
return topic.getDiscussContent() + ":议题最少需要选择" + topic.getOptionNumberMin() + "项";
|
}
|
}
|
if (topic.getOptionNumber() > 1) {
|
JSONArray objects1 = JSON.parseArray(topic.getSelected());
|
if (objects1.size() > topic.getOptionNumber()) {
|
return topic.getDiscussContent() + ":议题最多需要选择" + topic.getOptionNumber() + "项";
|
}
|
}
|
}
|
}
|
Boolean userTopics = getaBoolean(topicsList, householdEntity);
|
if (userTopics) return "200";
|
return "操作失败!";
|
}
|
|
@Nullable
|
private Boolean getaBoolean(List<TopicsVO> topics, HouseholdEntity householdEntity) {
|
List<UserTopicsEntity> objects = new ArrayList<>();
|
Boolean result = false;
|
for (TopicsVO topic : topics) {
|
UserTopicsEntity userTopicsEntity = new UserTopicsEntity();
|
userTopicsEntity.setHouseholdId(householdEntity.getId());
|
userTopicsEntity.setSelected(topic.getSelected());
|
userTopicsEntity.setTopicsId(topic.getId());
|
userTopicsEntity.setPublicDiscussId(topic.getPublicDiscussId());
|
objects.add(userTopicsEntity);
|
// 单选
|
if (topic.getOptionRange().equals(0)) {
|
if (StringUtils.isBlank(topic.getSelected())) {
|
break;
|
}
|
UserTopicsEntity userTopics = new UserTopicsEntity();
|
userTopics.setSelected(topic.getSelected());
|
userTopics.setHouseholdId(householdEntity.getId());
|
userTopics.setPublicDiscussId(topic.getPublicDiscussId());
|
userTopics.setTopicsId(Integer.valueOf(topic.getSelected()));
|
userTopics.setArticleId(topic.getArticleId());
|
userTopics.setHouseCode(topic.getHouseCode());
|
userTopics.setSignaturePath(topic.getSignaturePath());
|
UpdateWrapper<TopicsEntity> objectUpdateWrapper = new UpdateWrapper<>();
|
objectUpdateWrapper.setSql("number = number + 1");
|
objectUpdateWrapper.eq("id", topic.getSelected());
|
topicsService.update(null, objectUpdateWrapper);
|
result = save(userTopics);
|
} else {
|
// 多选
|
if (StringUtils.isBlank(topic.getSelected())) {
|
break;
|
}
|
JSONArray objects1 = JSON.parseArray(topic.getSelected());
|
List<UserTopicsEntity> objectsTwo = new ArrayList<>();
|
for (Object o : objects1) {
|
UserTopicsEntity userTopics = new UserTopicsEntity();
|
userTopics.setSelected(topic.getSelected());
|
userTopics.setHouseholdId(householdEntity.getId());
|
userTopics.setPublicDiscussId(topic.getPublicDiscussId());
|
userTopics.setArticleId(topic.getArticleId());
|
userTopics.setHouseCode(topic.getHouseCode());
|
userTopics.setTopicsId((Integer) o);
|
userTopics.setSignaturePath(topic.getSignaturePath());
|
objectsTwo.add(userTopics);
|
UpdateWrapper<TopicsEntity> objectUpdateWrapper = new UpdateWrapper<>();
|
objectUpdateWrapper.setSql("number = number + 1");
|
objectUpdateWrapper.eq("id", o);
|
topicsService.update(null, objectUpdateWrapper);
|
}
|
result = saveBatch(objectsTwo);
|
}
|
}
|
return result;
|
}
|
|
|
@Override
|
public Integer getCount(Integer id) {
|
List<UserTopicsEntity> list = list(Wrappers.<UserTopicsEntity>lambdaQuery()
|
.eq(UserTopicsEntity::getPublicDiscussId, id)
|
.groupBy(UserTopicsEntity::getHouseholdId));
|
return list.size();
|
}
|
|
@Override
|
public List<UserTopicsExcel> exportUser(UserTopicsVO userTopics) {
|
if (StringUtils.isNotBlank(userTopics.getDistrictId())) {
|
List<String> longs = Arrays.asList(userTopics.getDistrictId().split(","));
|
IDistrictService bean = SpringUtils.getBean(IDistrictService.class);
|
List<DistrictEntity> list = bean.list(Wrappers.<DistrictEntity>lambdaQuery().in(DistrictEntity::getId, longs));
|
List<String> collect = list.stream().map(item ->
|
item.getAoiCode()
|
).collect(Collectors.toList());
|
if (collect != null) {
|
userTopics.setAoiCodeList(collect);
|
}
|
}
|
List<UserTopicsExcel> userTopicsExcels = baseMapper.exportUser(userTopics);
|
return userTopicsExcels;
|
}
|
|
@Override
|
public Boolean saveUserTopicsEntity(UserTopicsEntity userTopics) {
|
IHouseholdService householdService = SpringUtils.getBean(IHouseholdService.class);
|
HouseholdEntity householdEntity = householdService.getOne(Wrappers.<HouseholdEntity>lambdaQuery()
|
.eq(HouseholdEntity::getHouseCode, userTopics.getHouseCode())
|
.eq(HouseholdEntity::getAssociatedUserId, AuthUtil.getUserId())
|
.eq(HouseholdEntity::getIsDeleted, 0)
|
.last("limit 1"));
|
if (householdEntity != null) {
|
userTopics.setHouseholdId(householdEntity.getId());
|
}
|
return save(userTopics);
|
}
|
|
/**
|
* 处理Excel文件的生成,将用户主题数据写入Excel并输出到流中。
|
*
|
* @param out 输出流,用于保存生成的Excel文件。
|
* @param userTopics 用户主题数据,包含提案和投票记录信息。
|
*/
|
@Override
|
public void handleExcel(OutputStream out, UserTopicsVO userTopics) {
|
|
// 初始化Excel写入器
|
ExcelWriter excelWriter = EasyExcel.write(out)
|
.build();
|
|
// 设置内容自动换行的样式
|
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
|
contentWriteCellStyle.setWrapped(true);
|
|
// 处理并写入提案数据
|
List<holdExcel> proposal = getProposal(userTopics);
|
ExcelWriterSheetBuilder userExcelSheet = new ExcelWriterSheetBuilder();
|
userExcelSheet.registerWriteHandler(new HorizontalCellStyleStrategy(null, contentWriteCellStyle));
|
userExcelSheet.sheetName("小区投票人员");
|
userExcelSheet.sheetNo(0);
|
userExcelSheet.head(holdExcel.class);
|
excelWriter.write(proposal, userExcelSheet.build());
|
|
// 处理并写入投票记录数据
|
List<UserTopicsExcel> publicopinion = getPublicopinion(userTopics);
|
ExcelWriterSheetBuilder classExcelSheet = new ExcelWriterSheetBuilder();
|
classExcelSheet.registerWriteHandler(new HorizontalCellStyleStrategy(null, contentWriteCellStyle));
|
classExcelSheet.sheetName("投票记录");
|
classExcelSheet.sheetNo(1);
|
classExcelSheet.head(UserTopicsExcel.class);
|
excelWriter.write(publicopinion, classExcelSheet.build());
|
// 完成Excel写入并释放资源
|
excelWriter.finish();
|
}
|
|
/**
|
* 获取首页的房屋记录
|
*
|
* @param userTopics 包含用户话题信息的对象,其中可能含有区域ID等关键信息
|
* @return 返回一个包含房屋记录信息的列表
|
*/
|
private List<holdExcel> getProposal(UserTopicsVO userTopics) {
|
List<holdExcel> resultList = new ArrayList<>();
|
try {
|
// 检查区域ID字符串是否有效
|
List<String> strings = validateAndParseDistrictId(userTopics.getDistrictId());
|
// 获取区域服务和话题服务的实例
|
IDistrictService districtService = SpringUtils.getBean(IDistrictService.class);
|
ITopicsService topicsService = SpringUtils.getBean(ITopicsService.class);
|
// 处理区域ID并查询对应的区域实体列表
|
List<String> aoiCodeList = processDistrictIds(districtService, strings);
|
// 设置AOI代码列表到用户话题对象中
|
userTopics.setAoiCodeList(aoiCodeList);
|
// 查询并处理房屋列表信息
|
List<holdExcel> householdList = processHouseholdList(topicsService, userTopics);
|
resultList.addAll(householdList);
|
} catch (Exception e) {
|
// 适当的异常处理逻辑
|
// 例如:记录日志、返回错误信息等
|
e.printStackTrace();
|
}
|
return resultList;
|
}
|
|
/**
|
* 验证并解析区域ID字符串。
|
*
|
* @param districtIdStr 区域ID的字符串表示。不能为空或空白字符串。
|
* @return 返回一个JSONArray对象,包含解析后的区域ID。
|
* @throws IllegalArgumentException 如果区域ID字符串为空或空白字符串,抛出此异常。
|
*/
|
private List<String> validateAndParseDistrictId(String districtIdStr) throws IllegalArgumentException {
|
// 验证区域ID字符串是否为空
|
if (StringUtils.isBlank(districtIdStr)) {
|
throw new IllegalArgumentException("区域ID不能为空");
|
}
|
// 解析区域ID字符串为JSONArray对象
|
return Arrays.asList(districtIdStr.split(","));
|
}
|
|
private List<String> processDistrictIds(IDistrictService districtService, List<String> districtIds) {
|
List<String> collect1 = districtIds.stream().map(item -> (String) item).collect(Collectors.toList());
|
List<DistrictEntity> list3 = districtService.list(Wrappers.<DistrictEntity>lambdaQuery().in(DistrictEntity::getId, collect1));
|
return list3.stream().map(item -> item.getAoiCode()).collect(Collectors.toList());
|
}
|
|
private List<holdExcel> processHouseholdList(ITopicsService topicsService, UserTopicsVO userTopics) {
|
List<holdExcel> householdList = baseMapper.getHouseholdList(userTopics);
|
householdList.forEach(item -> processItem(topicsService, item));
|
return householdList;
|
}
|
|
private void processItem(ITopicsService topicsService, holdExcel item) {
|
if (StringUtils.isBlank(item.getOptionContent())) {
|
item.setVoteFlag("否");
|
} else {
|
List<Long> longs = Func.toLongList(item.getOptionContent());
|
for (Long aLong : longs) {
|
TopicsEntity topics = topicsService.getById(aLong);
|
setManagementRegulationsOrRulesOfProcedure(item, topics);
|
}
|
item.setVoteFlag("是");
|
}
|
}
|
|
private void setManagementRegulationsOrRulesOfProcedure(holdExcel item, TopicsEntity topics) {
|
if (StringUtils.isNotBlank(topics.getDiscussContent())) {
|
if (topics.getDiscussContent().equals("管理规约")) {
|
item.setManagementRegulations(topics.getOptionContent());
|
} else if (topics.getDiscussContent().equals("议事规则")) {
|
item.setRulesOfProcedure(topics.getOptionContent());
|
}
|
}
|
}
|
|
|
/**
|
* 获取公开意见信息
|
*
|
* @param userTopics 用户话题VO对象,封装了用户话题的查询条件
|
* @return 返回用户话题的Excel格式列表,包含所有符合条件的意见信息
|
*/
|
private List<UserTopicsExcel> getPublicopinion(UserTopicsVO userTopics) {
|
// 初始化返回列表
|
List<UserTopicsExcel> list = new ArrayList<>();
|
// 通过基础mapper查询结果,并将结果添加到列表中
|
List<UserTopicsExcel> userTopicsExcels = baseMapper.getresultTwo(userTopics);
|
list.addAll(userTopicsExcels);
|
return list;
|
}
|
|
@Override
|
public Map<String, Object> getUserTopicsTotal(Integer articleId) {
|
return baseMapper.getUserTopicsTotal(articleId);
|
}
|
}
|