liujie
2025-11-12 fb97f83e39a0995fb70326c492a0bcd37af5e300
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/mobile_community

# Conflicts:
# ruoyi-system/src/main/resources/mapper/system/TAssistedDiningMapper.xml
9个文件已添加
39个文件已修改
1753 ■■■■■ 已修改文件
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/DataStatisticsController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TAssistedDiningController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCommunityActivityController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THelpNeedsController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeKeyGridUserController.java 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeOrganizationController.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeResourceController.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeSocialWorkerController.java 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeVolunteerController.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TMerchantController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TOldsterController.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TOldsterWarningController.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TOtherConfigController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TQuestionnaireController.java 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TServiceGuideFileController.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/TQuestionnaireDTO.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeKeyGridUserImport.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeOrganizationImport.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeResourceImport.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeSocialWorkerImport.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeVolunteerImport.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/export/OldsterImport.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TOldsterWarningMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TQuestionnaireMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/TLargeKeyGridUser.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/TQuestionnaireStem.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/TQuestionnaireStemBriefAnswer.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/TQuestionnaireStemOption.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/query/TQuestionnaireQuery.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/query/TServiceGuideFileQuery.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/TOldsterWarningService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/TQuestionnaireService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TLargeKeyGridUserServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOldsterServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOldsterWarningServiceImpl.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TQuestionnaireServiceImpl.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/task/base/AbstractJob.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/task/base/TimeJobType.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/task/jobs/QuestionnairePush.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/TQuestionnaireVO.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TAssistedDiningMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/THelpNeedsMapper.xml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TOldsterWarningMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TQuestionnaireMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TQuestionnaireStemBriefAnswerMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TServiceGuideFileMapper.xml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/DataStatisticsController.java
@@ -58,7 +58,7 @@
    /**
     * 获取组织人员管理列表
     */
    @ApiOperation(value = "获取组织人员分页列表")
    @ApiOperation(value = "获取组织人员列表")
    @GetMapping(value = "/largeUserList")
    public R<List<TLargeUser>> largeUserList(@RequestParam String deptId) {
        List<TLargeUser> list = largeUserService.list(Wrappers.lambdaQuery(TLargeUser.class)
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TAssistedDiningController.java
@@ -75,7 +75,7 @@
    }
    @ApiOperation(value = "查看详情")
    @GetMapping(value = "/detail")
    public R<TAssistedDining> detail(Integer id) {
    public R<TAssistedDining> detail(String id) {
        return R.ok(assistedDiningService.getById( id));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCommunityActivityController.java
@@ -225,7 +225,7 @@
            QuartzManager.addJob(
                    ActivityPush.class,
                    (ActivityPush.name+communityActivity.getId()).toUpperCase(),
                    TimeJobType.DELIBERATION_VOTE_PUSH,
                    TimeJobType.ACTIVITY_PUSH,
                    DateUtils.localDateTimeToDate(communityActivity.getEndTime()),
                    maps
            );
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THelpNeedsController.java
@@ -88,7 +88,7 @@
    }
    @ApiOperation(value = "查看详情")
    @GetMapping(value = "/detail")
    public R<THelpNeeds> detail(Integer id) {
    public R<THelpNeeds> detail(String id) {
        return R.ok(helpNeedsService.getById( id));
    }
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeKeyGridUserController.java
@@ -1,22 +1,47 @@
package com.ruoyi.web.controller.api;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.WebUtils;
import com.ruoyi.system.export.LargeKeyGridUserImport;
import com.ruoyi.system.model.TLargeKeyGridUser;
import com.ruoyi.system.model.TLargeKeyPersonnelType;
import com.ruoyi.system.query.TLargeKeyGridUserQuery;
import com.ruoyi.system.service.TLargeKeyGridUserService;
import com.ruoyi.system.service.TLargeKeyPersonnelTypeService;
import com.ruoyi.system.vo.TLargeKeyGridUserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * <p>
@@ -26,15 +51,18 @@
 * @author xiaochen
 * @since 2025-11-11
 */
@Slf4j
@Api(tags = "大屏-重点人员-网格人员")
@RestController
@RequestMapping("/t-large-key-grid-user")
public class TLargeKeyGridUserController {
    private final TLargeKeyGridUserService largeKeyGridUserService;
    private final TLargeKeyPersonnelTypeService largeKeyPersonnelTypeService;
    @Autowired
    public TLargeKeyGridUserController(TLargeKeyGridUserService largeKeyGridUserService) {
    public TLargeKeyGridUserController(TLargeKeyGridUserService largeKeyGridUserService, TLargeKeyPersonnelTypeService largeKeyPersonnelTypeService) {
        this.largeKeyGridUserService = largeKeyGridUserService;
        this.largeKeyPersonnelTypeService = largeKeyPersonnelTypeService;
    }
    /**
@@ -111,6 +139,148 @@
    public R<Boolean> deleteByIds(@RequestBody List<String> ids) {
        return R.ok(largeKeyGridUserService.removeByIds(ids));
    }
    @ApiOperation(value = "重点人员-网格人员导入模板下载")
    @GetMapping("/import-template")
    public void importTemplate() {
        List<LargeKeyGridUserImport> largeLargeKeyGridUserImports = new ArrayList<>();
        LargeKeyGridUserImport largeLargeKeyGridUserImport = new LargeKeyGridUserImport();
        largeLargeKeyGridUserImports.add(largeLargeKeyGridUserImport);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), LargeKeyGridUserImport.class, largeLargeKeyGridUserImports);
        HttpServletResponse response = WebUtils.response();
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("重点人员-网格人员信息导入模板.xls", "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("重点人员-网格人员导入模板下载失败!");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Log(title = "重点人员-网格人员信息-重点人员信息导入", businessType = BusinessType.INSERT)
    @ApiOperation(value = "重点人员信息导入")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/import")
    public R<String> importInfo(@RequestPart("file") MultipartFile file) {
        List<TLargeKeyGridUser> largeKeyGridUsers = new ArrayList<>();
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
        InputStream inputStream = null;
        List<LargeKeyGridUserImport> largeKeyGridUserImports;
        try {
            inputStream = file.getInputStream();
            largeKeyGridUserImports = ExcelImportUtil.importExcel(inputStream,
                    LargeKeyGridUserImport.class, params);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("重点人员信息导入失败:{}", e.getMessage());
            throw new ServiceException("重点人员信息导入失败!");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new ServiceException(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(largeKeyGridUserImports)) {
            throw new ServiceException("重点人员信息数据为空!");
        }
        JSONObject result = new JSONObject();
        int i = 1;
        for (LargeKeyGridUserImport largeKeyGridUserImport : largeKeyGridUserImports) {
            if (!StringUtils.hasLength(largeKeyGridUserImport.getGridInfo())){
                result.append("第"+i+"行:[", "网格"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getCommunityName())){
                result.append("第"+i+"行:[", "小区名称"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getBuildingInfo())){
                result.append("第"+i+"行:[", "楼栋信息"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getUnitNumber())){
                result.append("第"+i+"行:[", "单元号"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getHouseNumber())){
                result.append("第"+i+"行:[", "门牌号"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getUserName())){
                result.append("第"+i+"行:[", "姓名"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getUserSexStr())){
                result.append("第"+i+"行:[", "性别"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getIdCard())){
                result.append("第"+i+"行:[", "身份证号"+"]不能为空");
                continue;
            }
            if (largeKeyGridUserImport.getIdCard().matches("^$|(^[1-9]\\\\d{7}((0\\\\d)|(1[0-2]))(([0-2]\\\\d)|3[0-1])\\\\d{3}$)|(^[1-9]\\\\d{5}[1-9]\\\\d{3}((0\\\\d)|(1[0-2]))(([0-2]\\\\d)|3[0-1])((\\\\d{4})|\\\\d{3}[Xx])$)")){
                result.append("第"+i+"行:[", "身份证号"+"]格式不正确");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getContactNumber())){
                result.append("第"+i+"行:[", "联系电话"+"]不能为空");
                continue;
            }
            if (largeKeyGridUserImport.getContactNumber().matches("^1[3-9]\\\\d{9}$")){
                result.append("第"+i+"行:[", "联系电话"+"]格式不正确");
                continue;
            }
            if (!StringUtils.hasLength(largeKeyGridUserImport.getTypeName())){
                result.append("第"+i+"行:[", "类型名称"+"]不能为空");
                continue;
            }
            TLargeKeyGridUser largeKeyGridUser = new TLargeKeyGridUser();
            BeanUtils.copyProperties(largeKeyGridUserImport, largeKeyGridUser);
            switch (largeKeyGridUserImport.getUserSexStr()){
                case "男":
                    largeKeyGridUser.setUserSex(1);
                    break;
                case "女":
                    largeKeyGridUser.setUserSex(2);
                    break;
                default:
                    result.append("第"+i+"行:[", "性别"+"]格式错误");
                    continue;
            }
            TLargeKeyPersonnelType largeKeyPersonnelType = largeKeyPersonnelTypeService.getOne(Wrappers.lambdaQuery(TLargeKeyPersonnelType.class)
                    .eq(TLargeKeyPersonnelType::getTypeName, largeKeyGridUserImport.getTypeName())
                    .last("LIMIT 1"));
            if(Objects.isNull(largeKeyPersonnelType)){
                result.append("第"+i+"行:[", "类型名称"+"]不存在");
                continue;
            }
            largeKeyGridUser.setTypeId(largeKeyPersonnelType.getId());
            largeKeyGridUser.setUserType(1);
            largeKeyGridUsers.add(largeKeyGridUser);
            i++;
        }
        largeKeyGridUserService.saveBatch(largeKeyGridUsers);
        if(!result.isEmpty()){
            return R.fail(result.toString());
        }
        return R.ok();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeOrganizationController.java
@@ -1,21 +1,47 @@
package com.ruoyi.web.controller.api;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.WebUtils;
import com.ruoyi.system.export.LargeOrganizationImport;
import com.ruoyi.system.export.MerchantImport;
import com.ruoyi.system.model.TLargeOrganization;
import com.ruoyi.system.model.TMerchant;
import com.ruoyi.system.model.TMerchantType;
import com.ruoyi.system.query.TLargeOrganizationQuery;
import com.ruoyi.system.service.TLargeOrganizationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * <p>
@@ -25,6 +51,7 @@
 * @author xiaochen
 * @since 2025-11-11
 */
@Slf4j
@Api(tags = "大屏-社会组织")
@RestController
@RequestMapping("/t-large-organization")
@@ -116,6 +143,101 @@
    public R<Boolean> deleteByIds(@RequestBody List<String> ids) {
        return R.ok(largeOrganizationService.removeByIds(ids));
    }
    @ApiOperation(value = "社会组织导入模板下载")
    @GetMapping("/import-template")
    public void importTemplate() {
        List<LargeOrganizationImport> largeOrganizationImports = new ArrayList<>();
        LargeOrganizationImport largeOrganizationImport = new LargeOrganizationImport();
        largeOrganizationImports.add(largeOrganizationImport);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), LargeOrganizationImport.class, largeOrganizationImports);
        HttpServletResponse response = WebUtils.response();
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("社会组织导入模板.xls", "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("社会组织导入模板下载失败!");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Log(title = "社会组织-社会组织导入", businessType = BusinessType.INSERT)
    @ApiOperation(value = "社会组织导入")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/import")
    public R<String> importInfo(@RequestPart("file") MultipartFile file) {
        List<TLargeOrganization> largeOrganizations = new ArrayList<>();
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
        InputStream inputStream = null;
        List<LargeOrganizationImport> largeOrganizationImports;
        try {
            inputStream = file.getInputStream();
            largeOrganizationImports = ExcelImportUtil.importExcel(inputStream,
                    LargeOrganizationImport.class, params);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("社会组织导入失败:{}", e.getMessage());
            throw new ServiceException("社会组织导入失败!");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new ServiceException(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(largeOrganizationImports)) {
            throw new ServiceException("社会组织数据为空!");
        }
        JSONObject result = new JSONObject();
        int i = 1;
        for (LargeOrganizationImport largeOrganizationImport : largeOrganizationImports) {
            if (!StringUtils.hasLength(largeOrganizationImport.getOrganizationName())){
                result.append("第"+i+"行:[", "组织名称"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeOrganizationImport.getOrganizationPerson())){
                result.append("第"+i+"行:[", "组织负责人"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeOrganizationImport.getAddress())){
                result.append("第"+i+"行:[", "地址"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeOrganizationImport.getContactNumber())){
                result.append("第"+i+"行:[", "联系电话"+"]不能为空");
                continue;
            }
            if (largeOrganizationImport.getContactNumber().matches("^1[3-9]\\\\d{9}$")){
                result.append("第"+i+"行:[", "联系电话"+"]格式不正确");
                continue;
            }
            if (!StringUtils.hasLength(largeOrganizationImport.getBusinessScope())){
                result.append("第"+i+"行:[", "业务范围"+"]不能为空");
                continue;
            }
            TLargeOrganization largeOrganization = new TLargeOrganization();
            BeanUtils.copyProperties(largeOrganizationImport, largeOrganization);
            largeOrganizations.add(largeOrganization);
            i++;
        }
        largeOrganizationService.saveBatch(largeOrganizations);
        if(!result.isEmpty()){
            return R.fail(result.toString());
        }
        return R.ok();
    }
    
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeResourceController.java
@@ -1,22 +1,47 @@
package com.ruoyi.web.controller.api;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.WebUtils;
import com.ruoyi.system.export.LargeResourceImport;
import com.ruoyi.system.model.TLargeResource;
import com.ruoyi.system.model.TLargeResourceType;
import com.ruoyi.system.query.TLargeResourceQuery;
import com.ruoyi.system.service.TLargeResourceService;
import com.ruoyi.system.service.TLargeResourceTypeService;
import com.ruoyi.system.vo.TLargeResourceVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * <p>
@@ -26,15 +51,18 @@
 * @author xiaochen
 * @since 2025-11-11
 */
@Slf4j
@Api(tags = "大屏-社区资源")
@RestController
@RequestMapping("/t-large-resource")
public class TLargeResourceController {
    private final TLargeResourceService largeResourceService;
    private final TLargeResourceTypeService largeResourceTypeService;
    @Autowired
    public TLargeResourceController(TLargeResourceService largeResourceService) {
    public TLargeResourceController(TLargeResourceService largeResourceService, TLargeResourceTypeService largeResourceTypeService) {
        this.largeResourceService = largeResourceService;
        this.largeResourceTypeService = largeResourceTypeService;
    }
    /**
@@ -112,6 +140,130 @@
        return R.ok(largeResourceService.removeByIds(ids));
    }
    @ApiOperation(value = "社区资源信息导入模板下载")
    @GetMapping("/import-template")
    public void importTemplate() {
        List<LargeResourceImport> largeLargeResourceImports = new ArrayList<>();
        LargeResourceImport largeLargeResourceImport = new LargeResourceImport();
        largeLargeResourceImports.add(largeLargeResourceImport);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), LargeResourceImport.class, largeLargeResourceImports);
        HttpServletResponse response = WebUtils.response();
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("社区资源信息导入模板.xls", "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("社区资源信息导入模板下载失败!");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Log(title = "社区资源信息-社区资源信息导入", businessType = BusinessType.INSERT)
    @ApiOperation(value = "社区资源信息导入")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/import")
    public R<String> importInfo(@RequestPart("file") MultipartFile file) {
        List<TLargeResource> largeResources = new ArrayList<>();
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
        InputStream inputStream = null;
        List<LargeResourceImport> largeResourceImports;
        try {
            inputStream = file.getInputStream();
            largeResourceImports = ExcelImportUtil.importExcel(inputStream,
                    LargeResourceImport.class, params);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("社区资源信息导入失败:{}", e.getMessage());
            throw new ServiceException("社区资源信息导入失败!");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new ServiceException(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(largeResourceImports)) {
            throw new ServiceException("社区资源信息数据为空!");
        }
        JSONObject result = new JSONObject();
        int i = 1;
        for (LargeResourceImport largeResourceImport : largeResourceImports) {
            if (!StringUtils.hasLength(largeResourceImport.getTypeParentName())){
                result.append("第"+i+"行:[", "一级类型名称"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeResourceImport.getTypeChildrenName())){
                result.append("第"+i+"行:[", "二级类型名称"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeResourceImport.getResourceUnit())){
                result.append("第"+i+"行:[", "资源单位"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeResourceImport.getResourceNameDesc())){
                result.append("第"+i+"行:[", "资源名称描述"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeResourceImport.getResourceSource())){
                result.append("第"+i+"行:[", "资源来源"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeResourceImport.getQuantityScale())){
                result.append("第"+i+"行:[", "数量规模"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeResourceImport.getContactPerson())){
                result.append("第"+i+"行:[", "联系人"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeResourceImport.getContactNumber())){
                result.append("第"+i+"行:[", "联系电话"+"]不能为空");
                continue;
            }
            if (largeResourceImport.getContactNumber().matches("^1[3-9]\\\\d{9}$")){
                result.append("第"+i+"行:[", "联系电话"+"]格式不正确");
                continue;
            }
            TLargeResource largeResource = new TLargeResource();
            BeanUtils.copyProperties(largeResourceImport, largeResource);
            TLargeResourceType parent = largeResourceTypeService.getOne(Wrappers.lambdaQuery(TLargeResourceType.class)
                    .eq(TLargeResourceType::getTypeName, largeResourceImport.getTypeParentName())
                    .last("LIMIT 1"));
            if(Objects.isNull(parent)){
                result.append("第"+i+"行:[", "一级类型名称"+"]不存在");
                continue;
            }
            largeResource.setTypeParentId(parent.getId());
            TLargeResourceType children = largeResourceTypeService.getOne(Wrappers.lambdaQuery(TLargeResourceType.class)
                    .eq(TLargeResourceType::getTypeName, largeResourceImport.getTypeChildrenName())
                    .eq(TLargeResourceType::getParentId, parent.getId())
                    .last("LIMIT 1"));
            if(Objects.isNull(children)){
                result.append("第"+i+"行:[", "二级类型名称"+"]不存在");
                continue;
            }
            largeResource.setTypeChildrenId(children.getId());
            largeResources.add(largeResource);
            i++;
        }
        largeResourceService.saveBatch(largeResources);
        if(!result.isEmpty()){
            return R.fail(result.toString());
        }
        return R.ok();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeSocialWorkerController.java
@@ -1,20 +1,43 @@
package com.ruoyi.web.controller.api;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.WebUtils;
import com.ruoyi.system.export.LargeSocialWorkerImport;
import com.ruoyi.system.model.TLargeSocialWorker;
import com.ruoyi.system.query.TLargeSocialWorkerQuery;
import com.ruoyi.system.service.TLargeSocialWorkerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
/**
@@ -25,6 +48,7 @@
 * @author xiaochen
 * @since 2025-11-11
 */
@Slf4j
@Api(tags = "大屏-社会工作者")
@RestController
@RequestMapping("/t-large-social-worker")
@@ -110,6 +134,146 @@
    public R<Boolean> deleteByIds(@RequestBody List<String> ids) {
        return R.ok(largeSocialWorkerService.removeByIds(ids));
    }
    @ApiOperation(value = "社会工作者信息导入模板下载")
    @GetMapping("/import-template")
    public void importTemplate() {
        List<LargeSocialWorkerImport> largeLargeSocialWorkerImports = new ArrayList<>();
        LargeSocialWorkerImport largeLargeSocialWorkerImport = new LargeSocialWorkerImport();
        largeLargeSocialWorkerImports.add(largeLargeSocialWorkerImport);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), LargeSocialWorkerImport.class, largeLargeSocialWorkerImports);
        HttpServletResponse response = WebUtils.response();
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("社会工作者信息导入模板.xls", "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("社会工作者信息导入模板下载失败!");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Log(title = "社会工作者信息-社会工作者信息导入", businessType = BusinessType.INSERT)
    @ApiOperation(value = "社会工作者信息导入")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/import")
    public R<String> importInfo(@RequestPart("file") MultipartFile file) {
        List<TLargeSocialWorker> largeSocialWorkers = new ArrayList<>();
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
        InputStream inputStream = null;
        List<LargeSocialWorkerImport> largeSocialWorkerImports;
        try {
            inputStream = file.getInputStream();
            largeSocialWorkerImports = ExcelImportUtil.importExcel(inputStream,
                    LargeSocialWorkerImport.class, params);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("社会工作者信息导入失败:{}", e.getMessage());
            throw new ServiceException("社会工作者信息导入失败!");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new ServiceException(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(largeSocialWorkerImports)) {
            throw new ServiceException("社会工作者信息数据为空!");
        }
        JSONObject result = new JSONObject();
        int i = 1;
        for (LargeSocialWorkerImport largeSocialWorkerImport : largeSocialWorkerImports) {
            if (!StringUtils.hasLength(largeSocialWorkerImport.getUserName())){
                result.append("第"+i+"行:[", "姓名"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeSocialWorkerImport.getUserSexStr())){
                result.append("第"+i+"行:[", "性别"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeSocialWorkerImport.getBirthDateStr())){
                result.append("第"+i+"行:[", "出生日期"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeSocialWorkerImport.getEducationalLevel())){
                result.append("第"+i+"行:[", "文化程度"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeSocialWorkerImport.getPoliticalStatus())){
                result.append("第"+i+"行:[", "政治面貌"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeSocialWorkerImport.getContactNumber())){
                result.append("第"+i+"行:[", "联系电话"+"]不能为空");
                continue;
            }
            if (largeSocialWorkerImport.getContactNumber().matches("^1[3-9]\\\\d{9}$")){
                result.append("第"+i+"行:[", "联系电话"+"]格式不正确");
                continue;
            }
            if (!StringUtils.hasLength(largeSocialWorkerImport.getEmployerPosition())){
                result.append("第"+i+"行:[", "工作单位及职务"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeSocialWorkerImport.getQualificationLevelStr())){
                result.append("第"+i+"行:[", "职业资格等级"+"]不能为空");
                continue;
            }
            TLargeSocialWorker largeSocialWorker = new TLargeSocialWorker();
            BeanUtils.copyProperties(largeSocialWorkerImport, largeSocialWorker);
            switch (largeSocialWorkerImport.getUserSexStr()){
                case "男":
                    largeSocialWorker.setUserSex(1);
                    break;
                case "女":
                    largeSocialWorker.setUserSex(2);
                    break;
                default:
                    result.append("第"+i+"行:[", "性别"+"]格式错误");
                    continue;
            }
            switch (largeSocialWorkerImport.getQualificationLevelStr()){
                case "助理社会工作师(初级)":
                    largeSocialWorker.setQualificationLevel(1);
                    break;
                case "社会工作师(中级)":
                    largeSocialWorker.setQualificationLevel(2);
                    break;
                case "高级社会工作师(高级)":
                    largeSocialWorker.setQualificationLevel(3);
                    break;
                default:
                    result.append("第"+i+"行:[", "职业资格等级"+"]格式错误");
                    continue;
            }
            try{
                largeSocialWorker.setBirthDate(DateUtils.stringToLocalDate(largeSocialWorkerImport.getBirthDateStr()));
            }catch (Exception e){
                result.append("第"+i+"行:[", "出生日期"+"]格式错误");
                continue;
            }
            largeSocialWorkers.add(largeSocialWorker);
            i++;
        }
        largeSocialWorkerService.saveBatch(largeSocialWorkers);
        if(!result.isEmpty()){
            return R.fail(result.toString());
        }
        return R.ok();
    }
    
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLargeVolunteerController.java
@@ -1,21 +1,47 @@
package com.ruoyi.web.controller.api;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.WebUtils;
import com.ruoyi.system.export.LargeSocialWorkerImport;
import com.ruoyi.system.export.LargeVolunteerImport;
import com.ruoyi.system.model.TLargeSocialWorker;
import com.ruoyi.system.model.TLargeVolunteer;
import com.ruoyi.system.query.TLargeVolunteerQuery;
import com.ruoyi.system.service.TLargeVolunteerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * <p>
@@ -25,6 +51,7 @@
 * @author xiaochen
 * @since 2025-11-11
 */
@Slf4j
@Api(tags = "大屏-社区志愿者")
@RestController
@RequestMapping("/t-large-volunteer")
@@ -110,6 +137,136 @@
    public R<Boolean> deleteByIds(@RequestBody List<String> ids) {
        return R.ok(largeVolunteerService.removeByIds(ids));
    }
    @ApiOperation(value = "社区志愿者信息导入模板下载")
    @GetMapping("/import-template")
    public void importTemplate() {
        List<LargeVolunteerImport> largeLargeVolunteerImports = new ArrayList<>();
        LargeVolunteerImport largeLargeVolunteerImport = new LargeVolunteerImport();
        largeLargeVolunteerImports.add(largeLargeVolunteerImport);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), LargeVolunteerImport.class, largeLargeVolunteerImports);
        HttpServletResponse response = WebUtils.response();
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("社区志愿者信息导入模板.xls", "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("社区志愿者信息导入模板下载失败!");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Log(title = "社区志愿者信息-社区志愿者信息导入", businessType = BusinessType.INSERT)
    @ApiOperation(value = "社区志愿者信息导入")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/import")
    public R<String> importInfo(@RequestPart("file") MultipartFile file) {
        List<TLargeVolunteer> largeVolunteers = new ArrayList<>();
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
        InputStream inputStream = null;
        List<LargeVolunteerImport> largeVolunteerImports;
        try {
            inputStream = file.getInputStream();
            largeVolunteerImports = ExcelImportUtil.importExcel(inputStream,
                    LargeVolunteerImport.class, params);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("社区志愿者信息导入失败:{}", e.getMessage());
            throw new ServiceException("社区志愿者信息导入失败!");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new ServiceException(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(largeVolunteerImports)) {
            throw new ServiceException("社区志愿者信息数据为空!");
        }
        JSONObject result = new JSONObject();
        int i = 1;
        for (LargeVolunteerImport largeVolunteerImport : largeVolunteerImports) {
            if (!StringUtils.hasLength(largeVolunteerImport.getUserName())){
                result.append("第"+i+"行:[", "姓名"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeVolunteerImport.getUserSexStr())){
                result.append("第"+i+"行:[", "性别"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeVolunteerImport.getBirthDateStr())){
                result.append("第"+i+"行:[", "出生日期"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeVolunteerImport.getServiceArea())){
                result.append("第"+i+"行:[", "服务区域"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeVolunteerImport.getRegisterDateStr())){
                result.append("第"+i+"行:[", "注册日期"+"]不能为空");
                continue;
            }
            if (Objects.isNull(largeVolunteerImport.getTotalServiceDuration())){
                result.append("第"+i+"行:[", "总服务时长"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(largeVolunteerImport.getJoinTeamDateStr())){
                result.append("第"+i+"行:[", "加入队伍时间"+"]不能为空");
                continue;
            }
            TLargeVolunteer largeVolunteer = new TLargeVolunteer();
            BeanUtils.copyProperties(largeVolunteerImport, largeVolunteer);
            switch (largeVolunteerImport.getUserSexStr()){
                case "男":
                    largeVolunteer.setUserSex(1);
                    break;
                case "女":
                    largeVolunteer.setUserSex(2);
                    break;
                default:
                    result.append("第"+i+"行:[", "性别"+"]格式错误");
                    continue;
            }
            try{
                largeVolunteer.setBirthDate(DateUtils.stringToLocalDate(largeVolunteerImport.getBirthDateStr()));
            }catch (Exception e){
                result.append("第"+i+"行:[", "出生日期"+"]格式错误");
                continue;
            }
            try{
                largeVolunteer.setRegisterDate(DateUtils.stringToLocalDateTime(largeVolunteerImport.getBirthDateStr()));
            }catch (Exception e){
                result.append("第"+i+"行:[", "注册日期"+"]格式错误");
                continue;
            }
            try{
                largeVolunteer.setJoinTeamDate(DateUtils.stringToLocalDateTime(largeVolunteerImport.getBirthDateStr()));
            }catch (Exception e){
                result.append("第"+i+"行:[", "加入队伍时间"+"]格式错误");
                continue;
            }
            largeVolunteers.add(largeVolunteer);
            i++;
        }
        largeVolunteerService.saveBatch(largeVolunteers);
        if(!result.isEmpty()){
            return R.fail(result.toString());
        }
        return R.ok();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TMerchantController.java
@@ -172,11 +172,11 @@
            }
        }
    }
    @Log(title = "商户信息导入", businessType = BusinessType.INSERT)
    @Log(title = "商户信息-商户信息导入", businessType = BusinessType.INSERT)
    @ApiOperation(value = "商户信息导入")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/import")
    public R<String> importLocation(@RequestPart("file") MultipartFile file) {
    public R<String> importInfo(@RequestPart("file") MultipartFile file) {
        List<TMerchant> merchants = new ArrayList<>();
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
@@ -205,21 +205,26 @@
        for (MerchantImport merchantImport : merchantImports) {
            if (!StringUtils.hasLength(merchantImport.getMerchantName())){
                result.append("第"+i+"行:[", "商户名称"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(merchantImport.getMerchantPhone())){
                result.append("第"+i+"行:[", "商户电话"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(merchantImport.getTypeName())){
                result.append("第"+i+"行:[", "商户分类"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(merchantImport.getAddress())){
                result.append("第"+i+"行:[", "商户地址"+"]不能为空");
                continue;
            }
            TMerchantType merchantType = merchantTypeService.getOne(Wrappers.lambdaQuery(TMerchantType.class)
                    .eq(TMerchantType::getTypeName, merchantImport.getTypeName())
                    .last("LIMIT 1"));
            if(Objects.isNull(merchantType)){
                result.append("第"+i+"行:[", "商户分类"+"]不存在");
                continue;
            }
            TMerchant merchant = new TMerchant();
            BeanUtils.copyProperties(merchantImport, merchant);
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TOldsterController.java
@@ -13,6 +13,7 @@
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.WebUtils;
import com.ruoyi.system.export.OldsterImport;
import com.ruoyi.system.model.TNotice;
@@ -140,11 +141,11 @@
            }
        }
    }
    @Log(title = "老人户籍信息导入", businessType = BusinessType.INSERT)
    @Log(title = "老人户籍信息-老人户籍信息导入", businessType = BusinessType.INSERT)
    @ApiOperation(value = "老人户籍信息导入")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/import")
    public R<String> importLocation(@RequestPart("file") MultipartFile file) {
    public R<String> importInfo(@RequestPart("file") MultipartFile file) {
        List<TOldster> oldsters = new ArrayList<>();
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
@@ -173,24 +174,57 @@
        for (OldsterImport oldsterImport : assetHouseInspectionImports) {
            if (!StringUtils.hasLength(oldsterImport.getOldsterName())){
                result.append("第"+i+"行:[", "老人姓名"+"]不能为空");
                continue;
            }
            if (oldsterImport.getOldsterAge()!=null){
                result.append("第"+i+"行:[", "老人年龄"+"]不能为空");
            }
            if (oldsterImport.getOldsterSex()!=null){
            if (!StringUtils.hasLength(oldsterImport.getOldsterSexStr())){
                result.append("第"+i+"行:[", "老人性别"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(oldsterImport.getContactPhone())){
                result.append("第"+i+"行:[", "联系方式"+"]不能为空");
                continue;
            }
            if (oldsterImport.getOldsterType()!=null){
            if (!StringUtils.hasLength(oldsterImport.getOldsterTypeStr())){
                result.append("第"+i+"行:[", "人员类型"+"]不能为空");
                continue;
            }
            if (!StringUtils.hasLength(oldsterImport.getAddress())){
                result.append("第"+i+"行:[", "居住地址"+"]不能为空");
                continue;
            }
            TOldster tOldster = new TOldster();
            BeanUtils.copyProperties(oldsterImport, tOldster);
            if(StringUtils.hasLength(oldsterImport.getBirthDateStr())){
                try{
                    LocalDate localDate = DateUtils.stringToLocalDate(oldsterImport.getBirthDateStr());
                    tOldster.setBirthDate(localDate);
                }catch (Exception e){
                    result.append("第"+i+"行:[", "出生日期"+"]格式错误");
                    continue;
                }
            }
            switch (oldsterImport.getOldsterSexStr()){
                case "男":
                    tOldster.setOldsterSex(1);
                    break;
                case "女":
                    tOldster.setOldsterSex(2);
                    break;
            }
            switch (oldsterImport.getOldsterTypeStr()){
                case "独居老人":
                    tOldster.setOldsterType(1);
                    break;
                case "高龄老人":
                    tOldster.setOldsterType(2);
                    break;
                case "散居特困供养老人":
                    tOldster.setOldsterType(3);
                    break;
                case "失能老人":
                    tOldster.setOldsterType(4);
                    break;
            }
            oldsters.add(tOldster);
            i++;
        }
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TOldsterWarningController.java
@@ -34,6 +34,8 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.Period;
import java.util.List;
import java.util.Objects;
@@ -80,7 +82,6 @@
        TOldster oldster = oldsterService.getById(oldsterWarning.getOldsterId());
        if(Objects.nonNull(oldster)){
            oldsterWarningVO.setOldsterName(oldster.getOldsterName());
            oldsterWarningVO.setOldsterAge(oldster.getOldsterAge());
            oldsterWarningVO.setOldsterSex(oldster.getOldsterSex());
            oldsterWarningVO.setContactPhone(oldster.getContactPhone());
            oldsterWarningVO.setGuardianName(oldster.getGuardianName());
@@ -90,14 +91,32 @@
            oldsterWarningVO.setIdCard(oldster.getIdCard());
            oldsterWarningVO.setBirthDate(oldster.getBirthDate());
            oldsterWarningVO.setOldsterType(oldster.getOldsterType());
            LocalDate birthDate = oldster.getBirthDate();
            LocalDate currentDate = LocalDate.now();
            // 使用Period类计算两个日期之间的年数差异
            Period period = Period.between(birthDate, currentDate);
            int years = period.getYears();
            // 如果当前日期小于出生日期的下一个生日,则需要减去一年(因为我们还没有过生日)
            if (currentDate.isBefore(birthDate.plusYears(years).plusMonths(1).minusDays(1))) {
                years--;
            }
            oldsterWarningVO.setOldsterAge(years);
        }
        return R.ok(oldsterWarningVO);
    }
    /**
     * 删除老人预警信息
     */
    @Log(title = "老人预警信息-删除", businessType = BusinessType.DELETE)
    @ApiOperation(value = "老人预警信息-删除")
    @DeleteMapping(value = "/deleteById")
    public R<Boolean> deleteById(@RequestParam String id) {
        return R.ok(oldsterWarningService.removeById(id));
    }
    @Log(title = "老人预警管理-老人预警记录导出", businessType = BusinessType.EXPORT)
    @ApiOperation(value = "老人预警记录导出")
    @PostMapping("/exportOldsterWarning")
    public void exportOldsterWarning(@RequestBody TCourseOrderQuery query){
    public void exportOldsterWarning(@RequestBody OldsterListQuery query){
        List<TOldsterWarningExport> oldsterWarningExports = oldsterWarningService.exportOldsterWarning(query);
        for (TOldsterWarningExport oldsterWarningExport : oldsterWarningExports) {
            if(Objects.nonNull(oldsterWarningExport.getWarningTime())){
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TOtherConfigController.java
@@ -39,6 +39,9 @@
    @ApiOperation(value = "修改系统其他设置-通知阈值管理")
    @PostMapping(value = "/update")
    public R<Boolean> update(@Validated @RequestBody TOtherConfig dto) {
        if(dto.getDays()>=365){
            return R.fail("天数不能超过365天");
        }
        return R.ok(otherConfigService.updateById(dto));
    }
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TQuestionnaireController.java
@@ -1,9 +1,35 @@
package com.ruoyi.web.controller.api;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.ImmutableMap;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.dto.TQuestionnaireDTO;
import com.ruoyi.system.model.*;
import com.ruoyi.system.query.TQuestionnaireQuery;
import com.ruoyi.system.service.*;
import com.ruoyi.system.task.base.QuartzManager;
import com.ruoyi.system.task.base.TimeJobType;
import com.ruoyi.system.task.jobs.QuestionnairePush;
import com.ruoyi.system.vo.TQuestionnaireVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
@@ -13,9 +39,253 @@
 * @author xiaochen
 * @since 2025-11-06
 */
@Api(tags = "问卷调查")
@RestController
@RequestMapping("/t-questionnaire")
public class TQuestionnaireController {
    private final TQuestionnaireService questionnaireService;
    private final TQuestionnaireStemService questionnaireStemService;
    private final TQuestionnaireStemOptionService questionnaireStemOptionService;
    private final TQuestionnaireStemBriefAnswerService questionnaireStemBriefAnswerService;
    private final TAppUserService appUserService;
    @Autowired
    public TQuestionnaireController(TQuestionnaireService questionnaireService, TQuestionnaireStemService questionnaireStemService, TQuestionnaireStemOptionService questionnaireStemOptionService, TQuestionnaireStemBriefAnswerService questionnaireStemBriefAnswerService, TAppUserService appUserService) {
        this.questionnaireService = questionnaireService;
        this.questionnaireStemService = questionnaireStemService;
        this.questionnaireStemOptionService = questionnaireStemOptionService;
        this.questionnaireStemBriefAnswerService = questionnaireStemBriefAnswerService;
        this.appUserService = appUserService;
    }
    /**
     * 获取问卷调查管理列表
     */
    @ApiOperation(value = "获取问卷调查分页列表")
    @PostMapping(value = "/pageList")
    public R<PageInfo<TQuestionnaireVO>> pageList(@RequestBody TQuestionnaireQuery query) {
        return R.ok(questionnaireService.pageList(query));
    }
    /**
     * 添加问卷调查管理
     */
    @Log(title = "问卷调查信息-新增问卷调查", businessType = BusinessType.INSERT)
    @ApiOperation(value = "添加问卷调查")
    @PostMapping(value = "/add")
    public R<Boolean> add(@Validated @RequestBody TQuestionnaireDTO dto) {
        LocalDateTime startTime = dto.getStartTime();
        LocalDateTime endTime = dto.getEndTime();
        LocalDateTime now = LocalDateTime.now();
        if(now.isBefore(startTime)){
            dto.setStatus(1);
        }
        if(now.isAfter(startTime) && now.isBefore(endTime)){
            dto.setStatus(2);
        }
        if(now.isAfter(endTime)){
            dto.setStatus(3);
        }
        questionnaireService.save(dto);
        // 添加题干
        List<TQuestionnaireStemOption> options = new ArrayList<>();
        List<TQuestionnaireStem> questionnaireStems = dto.getQuestionnaireStems();
        for (TQuestionnaireStem questionnaireStem : questionnaireStems) {
            questionnaireStem.setQuestionnaireId(dto.getId());
            questionnaireStemService.save(questionnaireStem);
            options = questionnaireStem.getOptions();
            for (TQuestionnaireStemOption option : options) {
                option.setStemId(questionnaireStem.getId());
            }
        }
        if(!CollectionUtils.isEmpty(options)){
            questionnaireStemOptionService.saveBatch(options);
        }
        if(now.isBefore(startTime)){
            // 添加定时任务
            Map<String, ? extends Object> maps =
                    new ImmutableMap.Builder<String, String>().
                            put("id", dto.getId()).put("type","1")
                            .build();
            QuartzManager.addJob(
                    QuestionnairePush.class,
                    (QuestionnairePush.name+dto.getId()).toUpperCase(),
                    TimeJobType.QUESTIONNAIRE_PUSH,
                    DateUtils.localDateTimeToDate(dto.getStartTime()),
                    maps
            );
        }
        if(now.isAfter(startTime) && now.isBefore(endTime)){
            // 添加定时任务
            Map<String, ? extends Object> maps =
                    new ImmutableMap.Builder<String, String>().
                            put("id", dto.getId()).put("type","2")
                            .build();
            QuartzManager.addJob(
                    QuestionnairePush.class,
                    (QuestionnairePush.name+dto.getId()).toUpperCase(),
                    TimeJobType.QUESTIONNAIRE_PUSH,
                    DateUtils.localDateTimeToDate(dto.getEndTime()),
                    maps
            );
        }
        return R.ok();
    }
    /**
     * 修改问卷调查
     */
    @Log(title = "问卷调查信息-修改问卷调查", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "修改问卷调查")
    @PostMapping(value = "/update")
    public R<Boolean> update(@Validated @RequestBody TQuestionnaireDTO dto) {
        TQuestionnaire communityActivity = questionnaireService.getById(dto.getId());
        if(communityActivity.getStatus() == 2 || communityActivity.getStatus() == 3){
            return R.fail("问卷调查正在进行中或已结束,无法修改");
        }
        LocalDateTime startTime = dto.getStartTime();
        LocalDateTime endTime = dto.getEndTime();
        LocalDateTime now = LocalDateTime.now();
        if(now.isBefore(startTime)){
            dto.setStatus(1);
            // 添加定时任务
            Map<String, ? extends Object> maps =
                    new ImmutableMap.Builder<String, String>().
                            put("id", communityActivity.getId()).put("type","1")
                            .build();
            QuartzManager.addJob(
                    QuestionnairePush.class,
                    (QuestionnairePush.name+communityActivity.getId()).toUpperCase(),
                    TimeJobType.QUESTIONNAIRE_PUSH,
                    DateUtils.localDateTimeToDate(communityActivity.getStartTime()),
                    maps
            );
        }
        if(now.isAfter(startTime) && now.isBefore(endTime)){
            dto.setStatus(2);
            // 添加定时任务
            Map<String, ? extends Object> maps =
                    new ImmutableMap.Builder<String, String>().
                            put("id", communityActivity.getId()).put("type","2")
                            .build();
            QuartzManager.addJob(
                    QuestionnairePush.class,
                    (QuestionnairePush.name+communityActivity.getId()).toUpperCase(),
                    TimeJobType.QUESTIONNAIRE_PUSH,
                    DateUtils.localDateTimeToDate(communityActivity.getEndTime()),
                    maps
            );
        }
        if(now.isAfter(endTime)){
            dto.setStatus(3);
        }
        questionnaireService.updateById(dto);
        return R.ok();
    }
    /**
     * 查看问卷调查详情
     */
    @ApiOperation(value = "查看问卷调查详情")
    @GetMapping(value = "/getDetailById")
    public R<TQuestionnaireVO> getDetailById(@RequestParam String id) {
        TQuestionnaire questionnaire = questionnaireService.getById(id);
        TQuestionnaireVO questionnaireVO = new TQuestionnaireVO();
        BeanUtils.copyProperties(questionnaire, questionnaireVO);
        // 查询用户
        List<TAppUser> appUsers = appUserService.list();
        // 查询题干
        List<TQuestionnaireStem> questionnaireStems = questionnaireStemService.list(Wrappers.lambdaQuery(TQuestionnaireStem.class)
                .eq(TQuestionnaireStem::getQuestionnaireId, id));
        if(!CollectionUtils.isEmpty(questionnaireStems)){
            List<String> stemIds = questionnaireStems.stream().map(TQuestionnaireStem::getId).collect(Collectors.toList());
            // 查询选项
            List<TQuestionnaireStemOption> questionnaireStemOptions = questionnaireStemOptionService.list(Wrappers.lambdaQuery(TQuestionnaireStemOption.class)
                    .in(TQuestionnaireStemOption::getStemId, stemIds));
            // 查询解答题答案
            List<TQuestionnaireStemBriefAnswer> questionnaireStemBriefAnswers = questionnaireStemBriefAnswerService.list(Wrappers.lambdaQuery(TQuestionnaireStemBriefAnswer.class)
                    .in(TQuestionnaireStemBriefAnswer::getStemId, stemIds));
            for (TQuestionnaireStem questionnaireStem : questionnaireStems) {
                List<TQuestionnaireStemOption> options = questionnaireStemOptions.stream().filter(questionnaireStemOption -> questionnaireStemOption.getStemId().equals(questionnaireStem.getId())).collect(Collectors.toList());
                // 匹配作答人数
                for (TQuestionnaireStemOption option : options) {
                    String answerValue = option.getAnswerValue();
                    option.setAnswerNum(StringUtils.hasLength(answerValue)?answerValue.split(",").length:0);
                }
                questionnaireStem.setOptions(options);
                // 匹配解答题答案
                List<TQuestionnaireStemBriefAnswer> answers = questionnaireStemBriefAnswers.stream().filter(questionnaireStemBriefAnswer -> questionnaireStemBriefAnswer.getStemId().equals(questionnaireStem.getId())).collect(Collectors.toList());
                for (TQuestionnaireStemBriefAnswer answer : answers) {
                    List<TAppUser> appUserList = appUsers.stream().filter(appUser -> appUser.getId().equals(answer.getAppUserId())).collect(Collectors.toList());
                    if(!CollectionUtils.isEmpty(appUserList)){
                        answer.setNickName(appUserList.get(0).getNickName());
                    }
                }
                questionnaireStem.setAnswers(answers);
            }
            questionnaireVO.setQuestionnaireStems(questionnaireStems);
        }
        return R.ok(questionnaireVO);
    }
    /**
     * 删除问卷调查
     */
    @Log(title = "问卷调查信息-删除问卷调查", businessType = BusinessType.DELETE)
    @ApiOperation(value = "删除问卷调查")
    @DeleteMapping(value = "/deleteById")
    public R<Boolean> deleteById(@RequestParam String id) {
        // 查询题干
        List<TQuestionnaireStem> questionnaireStems = questionnaireStemService.list(Wrappers.lambdaQuery(TQuestionnaireStem.class)
                .eq(TQuestionnaireStem::getQuestionnaireId, id));
        if(!CollectionUtils.isEmpty(questionnaireStems)){
            List<String> stemIds = questionnaireStems.stream().map(TQuestionnaireStem::getId).collect(Collectors.toList());
            // 删除题干选项
            questionnaireStemOptionService.remove(Wrappers.lambdaQuery(TQuestionnaireStemOption.class)
                    .in(TQuestionnaireStemOption::getStemId, stemIds));
            // 删除解答题信息
            questionnaireStemBriefAnswerService.remove(Wrappers.lambdaQuery(TQuestionnaireStemBriefAnswer.class)
                    .in(TQuestionnaireStemBriefAnswer::getStemId, stemIds));
        }
        // 删除题干
        questionnaireStemService.remove(Wrappers.lambdaQuery(TQuestionnaireStem.class)
                .eq(TQuestionnaireStem::getQuestionnaireId, id));
        return R.ok(questionnaireService.removeById(id));
    }
    /**
     * 社区活动发布和完成
     */
    @Log(title = "问卷调查信息-问卷调查发布和完成", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "问卷调查发布和完成")
    @PostMapping(value = "/updateReleaseFinish")
    public R<Boolean> updateReleaseFinish(@RequestParam(value = "id") String id,
                                          @RequestParam(value = "status") Integer status) {
        TQuestionnaire questionnaire = questionnaireService.getById(id);
        if(status == 2){
            // 添加定时任务
            Map<String, ? extends Object> maps =
                    new ImmutableMap.Builder<String, String>().
                            put("id", questionnaire.getId()).put("type","2")
                            .build();
            QuartzManager.addJob(
                    QuestionnairePush.class,
                    (QuestionnairePush.name+questionnaire.getId()).toUpperCase(),
                    TimeJobType.QUESTIONNAIRE_PUSH,
                    DateUtils.localDateTimeToDate(questionnaire.getEndTime()),
                    maps
            );
        }
        questionnaireService.update(Wrappers.lambdaUpdate(TQuestionnaire.class)
                .set(TQuestionnaire::getStatus, status)
                .eq(TQuestionnaire::getId, id));
        return R.ok();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TServiceGuideFileController.java
@@ -60,8 +60,8 @@
    @Log(title = "办事指南文件管理信息-新增办事指南文件管理", businessType = BusinessType.INSERT)
    @ApiOperation(value = "添加办事指南文件管理")
    @PostMapping(value = "/add")
    public R<Boolean> add(@Validated @RequestBody TServiceGuideFile dto) {
        return R.ok(serviceGuideFileService.save(dto));
    public R<Boolean> add(@Validated @RequestBody List<TServiceGuideFile> dto) {
        return R.ok(serviceGuideFileService.saveBatch(dto));
    }
    /**
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java
@@ -1,7 +1,21 @@
package com.ruoyi.web.controller.task;
import com.ruoyi.system.model.TOldster;
import com.ruoyi.system.model.TOldsterWarning;
import com.ruoyi.system.model.TOtherConfig;
import com.ruoyi.system.service.TOldsterService;
import com.ruoyi.system.service.TOldsterWarningService;
import com.ruoyi.system.service.TOtherConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
 * @author xiaochen
@@ -10,6 +24,40 @@
@Component
public class TaskUtil {
    @Autowired
    private TOldsterService oldsterService;
    @Autowired
    private TOldsterWarningService oldsterWarningService;
    @Autowired
    private TOtherConfigService otherConfigService;
    /**
     * 每日0点定时任务
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void generateOldsterWarning(){
        // 查询所有老人信息
        List<TOldster> oldsterList = oldsterService.list();
        // 查询预警阈值
        TOtherConfig otherConfig = otherConfigService.getById(1);
        Integer elderlyAge = otherConfig.getElderlyAge();
        Integer days = otherConfig.getDays();
        List<TOldsterWarning> oldsterWarningList = new ArrayList<>();
        for (TOldster oldster : oldsterList) {
            LocalDate birthDate = oldster.getBirthDate();
            // 判断年龄是否与elderlyAge是否为同一年
            if(birthDate.plusYears(elderlyAge).getYear() == LocalDate.now().getYear() && birthDate.plusYears(elderlyAge).minusDays(days).isEqual(LocalDate.now())){
                // 添加预警信息
                TOldsterWarning oldsterWarning = new TOldsterWarning();
                oldsterWarning.setOldsterId(oldster.getId());
                oldsterWarning.setWarningTime(LocalDateTime.now());
                oldsterWarningList.add(oldsterWarning);
            }
        }
        if(!CollectionUtils.isEmpty(oldsterWarningList)){
            oldsterWarningService.saveBatch(oldsterWarningList);
        }
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
@@ -390,6 +390,16 @@
    }
    /**
     * 字符串转为localdatetime
     *
     * @param time localdatetime
     * @return 字符串
     */
    public static LocalDateTime stringToLocalDateTime(String time) {
        return LocalDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    /**
     *  LocalDateTime转为Date
     * @param time
     * @return
ruoyi-system/src/main/java/com/ruoyi/system/dto/TQuestionnaireDTO.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.system.dto;
import com.ruoyi.system.model.TQuestionnaire;
import com.ruoyi.system.model.TQuestionnaireStem;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value="TQuestionnaire对象", description="问卷调查")
public class TQuestionnaireDTO extends TQuestionnaire {
    @ApiModelProperty(value = "题干")
    private List<TQuestionnaireStem> questionnaireStems;
}
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeKeyGridUserImport.java
New file
@@ -0,0 +1,49 @@
package com.ruoyi.system.export;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "重点人员-网格人员导入对象LargeKeyGridUserImport")
public class LargeKeyGridUserImport implements Serializable {
    @Excel(name = "网格", width = 20)
    private String gridInfo;
    @Excel(name = "小区名称", width = 20)
    private String communityName;
    @Excel(name = "楼栋信息", width = 20)
    private String buildingInfo;
    @Excel(name = "单元号", width = 20)
    private String unitNumber;
    @Excel(name = "门牌号", width = 20)
    private String houseNumber;
    @Excel(name = "姓名", width = 20)
    private String userName;
    @Excel(name = "性别[男|女]", width = 20)
    private String userSexStr;
    private Integer userSex;
    @Excel(name = "身份证号", width = 20)
    private String idCard;
    @Excel(name = "联系电话", width = 20)
    private String contactNumber;
    @Excel(name = "类型名称", width = 20)
    private String typeName;
    private String typeId;
    @ApiModelProperty(name = "人员类型 1=重点人员,2=网格人员]")
    private Integer userType;
}
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeOrganizationImport.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.system.export;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "社会组织导入LargeOrganizationImport")
public class LargeOrganizationImport implements Serializable {
    @Excel(name = "组织名称", width = 20)
    private String organizationName;
    @Excel(name = "组织负责人", width = 20)
    private String organizationPerson;
    @Excel(name = "地址", width = 20)
    private String address;
    @Excel(name = "联系电话", width = 20)
    private String contactNumber;
    @Excel(name = "业务范围", width = 20)
    private String businessScope;
}
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeResourceImport.java
New file
@@ -0,0 +1,39 @@
package com.ruoyi.system.export;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "社区资源导入LargeResourceImport")
public class LargeResourceImport implements Serializable {
    @Excel(name = "一级类型名称",width = 20)
    private String typeParentName;
    private String typeParentId;
    @Excel(name = "二级类型名称",width = 20)
    private String typeChildrenName;
    private String typeChildrenId;
    @Excel(name = "资源单位",width = 20)
    private String resourceUnit;
    @Excel(name = "资源名称描述",width = 20)
    private String resourceNameDesc;
    @Excel(name = "资源来源",width = 20)
    private String resourceSource;
    @Excel(name = "数量规模",width = 20)
    private String quantityScale;
    @Excel(name = "联系人",width = 20)
    private String contactPerson;
    @Excel(name = "联系电话",width = 20)
    private String contactNumber;
}
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeSocialWorkerImport.java
New file
@@ -0,0 +1,41 @@
package com.ruoyi.system.export;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
@Data
@ApiModel(value = "大屏-社会工作者导入LargeSocialWorkerImport")
public class LargeSocialWorkerImport implements Serializable {
    @Excel(name = "姓名", width = 20)
    private String userName;
    @Excel(name = "性别[男|女]", width = 20)
    private String userSexStr;
    private Integer userSex;
    @Excel(name = "出生日期[yyyy-mm-dd]", width = 20)
    private String birthDateStr;
    private LocalDate birthDate;
    @Excel(name = "文化程度", width = 20)
    private String educationalLevel;
    @Excel(name = "政治面貌", width = 20)
    private String politicalStatus;
    @Excel(name = "联系电话", width = 20)
    private String contactNumber;
    @Excel(name = "工作单位及职务", width = 20)
    private String employerPosition;
    @Excel(name = "职业资格等级[助理社会工作师(初级)|社会工作师(中级)|高级社会工作师(高级)]", width = 20)
    private String qualificationLevelStr;
    private Integer qualificationLevel;
}
ruoyi-system/src/main/java/com/ruoyi/system/export/LargeVolunteerImport.java
New file
@@ -0,0 +1,44 @@
package com.ruoyi.system.export;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@ApiModel(value = "社区志愿者导入对象LargeVolunteerImport")
public class LargeVolunteerImport implements Serializable {
    @Excel(name = "姓名", width = 20)
    private String userName;
    @Excel(name = "性别[男|女]", width = 20)
    private String userSexStr;
    private Integer userSex;
    @Excel(name = "出生日期[yyyy-mm-dd]", width = 20)
    private String birthDateStr;
    private LocalDate birthDate;
    @Excel(name = "服务区域", width = 20)
    private String serviceArea;
    @Excel(name = "注册日期[yyyy-mm-dd hh:mm:ss]", width = 20)
    private String registerDateStr;
    private LocalDateTime registerDate;
    @Excel(name = "总服务时长", width = 20)
    private BigDecimal totalServiceDuration;
    @Excel(name = "加入队伍时间[yyyy-mm-dd hh:mm:ss]", width = 20)
    private String joinTeamDateStr;
    private LocalDateTime joinTeamDate;
}
ruoyi-system/src/main/java/com/ruoyi/system/export/OldsterImport.java
@@ -10,6 +10,7 @@
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@ApiModel(value = "老人户籍信息导入excel")
@@ -23,8 +24,9 @@
    @Excel(name = "老人年龄",width = 20)
    private Integer oldsterAge;
    @ApiModelProperty(value = "性别 1=男 2=女")
    @ApiModelProperty(value = "性别 男 女")
    @Excel(name = "性别",width = 20)
    private String oldsterSexStr;
    private Integer oldsterSex;
    @ApiModelProperty(value = "联系方式")
@@ -39,18 +41,20 @@
    @Excel(name = "监护人电话",width = 20)
    private String guardianPhone;
    @ApiModelProperty(value = "身份证")
    @Excel(name = "身份证",width = 40)
    private String idCard;
    @ApiModelProperty(value = "出生日期")
    @Excel(name = "出生日期",width = 20)
    private String birthDate;
    @Excel(name = "出生日期[yyyy-mm-dd]",width = 20)
    private String birthDateStr;
    private LocalDate birthDate;
    @ApiModelProperty(value = "人员类型 1=独居老人 2=高龄老人 3=散居特困供养老人 4=失能老人")
    @Excel(name = "人员类型",width = 20)
    private String oldsterType;
    @ApiModelProperty(value = "人员类型 独居老人 高龄老人 散居特困供养老人 失能老人")
    @Excel(name = "人员类型 [独居老人|高龄老人|散居特困供养老人|失能老人]",width = 20)
    private String oldsterTypeStr;
    private Integer oldsterType;
    @ApiModelProperty(value = "居住地址")
    @Excel(name = "居住地址",width = 50)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TOldsterWarningMapper.java
@@ -34,5 +34,5 @@
     * @param query
     * @return
     */
    List<TOldsterWarningExport> exportOldsterWarning(@Param("query")TCourseOrderQuery query);
    List<TOldsterWarningExport> exportOldsterWarning(@Param("query")OldsterListQuery query);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TQuestionnaireMapper.java
@@ -1,7 +1,13 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.model.TQuestionnaire;
import com.ruoyi.system.query.TQuestionnaireQuery;
import com.ruoyi.system.vo.TQuestionnaireVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -13,4 +19,12 @@
 */
public interface TQuestionnaireMapper extends BaseMapper<TQuestionnaire> {
    /**
     * 分页查询
     *
     * @param query
     * @param pageInfo
     * @return
     */
    List<TQuestionnaireVO> pageList(@Param("query") TQuestionnaireQuery query,@Param("pageInfo") PageInfo<TQuestionnaireVO> pageInfo);
}
ruoyi-system/src/main/java/com/ruoyi/system/model/TLargeKeyGridUser.java
@@ -65,7 +65,7 @@
    @TableField("user_sex")
    private Integer userSex;
    @Pattern(regexp = "^$|(^[1-9]\\\\d{7}((0\\\\d)|(1[0-2]))(([0-2]\\\\d)|3[0-1])\\\\d{3}$)|(^[1-9]\\\\d{5}[1-9]\\\\d{3}((0\\\\d)|(1[0-2]))(([0-2]\\\\d)|3[0-1])((\\\\d{4})|\\\\d{3}[Xx])$)\n",message = "身份证号格式不正确")
    @Pattern(regexp = "^$|(^[1-9]\\\\d{7}((0\\\\d)|(1[0-2]))(([0-2]\\\\d)|3[0-1])\\\\d{3}$)|(^[1-9]\\\\d{5}[1-9]\\\\d{3}((0\\\\d)|(1[0-2]))(([0-2]\\\\d)|3[0-1])((\\\\d{4})|\\\\d{3}[Xx])$)",message = "身份证号格式不正确")
    @ApiModelProperty(value = "身份证号")
    @TableField("id_card")
    private String idCard;
ruoyi-system/src/main/java/com/ruoyi/system/model/TQuestionnaireStem.java
@@ -51,5 +51,9 @@
    @TableField(exist = false)
    private List<TQuestionnaireStemOption> options;
    @ApiModelProperty(value = "解答题答案")
    @TableField(exist = false)
    private List<TQuestionnaireStemBriefAnswer> answers;
}
ruoyi-system/src/main/java/com/ruoyi/system/model/TQuestionnaireStemBriefAnswer.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -23,7 +24,7 @@
@EqualsAndHashCode(callSuper = false)
@TableName("t_questionnaire_stem_brief_answer")
@ApiModel(value="TQuestionnaireStemBriefAnswer对象", description="简答题答案")
public class TQuestionnaireStemBriefAnswer implements Serializable {
public class TQuestionnaireStemBriefAnswer extends BaseModel {
    private static final long serialVersionUID = 1L;
@@ -42,5 +43,8 @@
    @TableField("answer_content")
    private String answerContent;
    @ApiModelProperty(value = "用户昵称")
    @TableField(exist = false)
    private String nickName;
}
ruoyi-system/src/main/java/com/ruoyi/system/model/TQuestionnaireStemOption.java
@@ -46,5 +46,8 @@
    @TableField("answer_value")
    private String answerValue;
    @ApiModelProperty(value = "答题人数")
    @TableField(exist = false)
    private Integer answerNum;
}
ruoyi-system/src/main/java/com/ruoyi/system/query/TQuestionnaireQuery.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.system.query;
import com.ruoyi.common.core.domain.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "问卷查询参数TQuestionnaireQuery")
public class TQuestionnaireQuery extends BasePage {
    @ApiModelProperty(value = "问卷题目")
    private String questionnaireTitle;
    @ApiModelProperty(value = "状态 1=待发布 2=发布中 3=已结束")
    private Integer status;
}
ruoyi-system/src/main/java/com/ruoyi/system/query/TServiceGuideFileQuery.java
@@ -2,9 +2,14 @@
import com.ruoyi.common.core.domain.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "办事指南文件管理查询参数TServiceGuideFileQuery")
public class TServiceGuideFileQuery extends BasePage {
    @ApiModelProperty(value = "文件名称")
    private String fileName;
}
ruoyi-system/src/main/java/com/ruoyi/system/service/TOldsterWarningService.java
@@ -32,6 +32,6 @@
     * @param query
     * @return
     */
    List<TOldsterWarningExport> exportOldsterWarning(TCourseOrderQuery query);
    List<TOldsterWarningExport> exportOldsterWarning(OldsterListQuery query);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/TQuestionnaireService.java
@@ -1,7 +1,10 @@
package com.ruoyi.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.model.TQuestionnaire;
import com.ruoyi.system.query.TQuestionnaireQuery;
import com.ruoyi.system.vo.TQuestionnaireVO;
/**
 * <p>
@@ -13,4 +16,11 @@
 */
public interface TQuestionnaireService extends IService<TQuestionnaire> {
    /**
     * 分页查询
     *
     * @param query 查询参数
     * @return PageInfo<TQuestionnaireVO>
     */
    PageInfo<TQuestionnaireVO> pageList(TQuestionnaireQuery query);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TLargeKeyGridUserServiceImpl.java
@@ -11,6 +11,7 @@
import com.ruoyi.system.vo.TLargeKeyGridUserVO;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
@@ -34,8 +35,10 @@
        }
        for (TLargeKeyGridUserVO tLargeKeyGridUserVO : list) {
            int age = IDCardAgeCalculator.calculateAge(tLargeKeyGridUserVO.getIdCard());
            tLargeKeyGridUserVO.setAge(age);
            if(StringUtils.hasLength(tLargeKeyGridUserVO.getIdCard())){
                int age = IDCardAgeCalculator.calculateAge(tLargeKeyGridUserVO.getIdCard());
                tLargeKeyGridUserVO.setAge(age);
            }
        }
        pageInfo.setRecords(list);
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOldsterServiceImpl.java
@@ -12,6 +12,8 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalDate;
import java.time.Period;
import java.util.List;
/**
@@ -34,8 +36,17 @@
        }
        for (TOldster oldster : list) {
            int age = IDCardAgeCalculator.calculateAge(oldster.getIdCard());
            oldster.setAge(age);
            LocalDate birthDate = oldster.getBirthDate();
            LocalDate currentDate = LocalDate.now();
            // 使用Period类计算两个日期之间的年数差异
            Period period = Period.between(birthDate, currentDate);
            int years = period.getYears();
            // 如果当前日期小于出生日期的下一个生日,则需要减去一年(因为我们还没有过生日)
            if (currentDate.isBefore(birthDate.plusYears(years).plusMonths(1).minusDays(1))) {
                years--;
            }
            oldster.setOldsterAge(years);
            oldster.setAge(years);
        }
        pageInfo.setRecords( list);
        return pageInfo;
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOldsterWarningServiceImpl.java
@@ -15,6 +15,8 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.List;
@@ -36,23 +38,37 @@
        if(CollectionUtils.isEmpty(list)){
            return pageInfo;
        }
        for (TOldsterWarningVO oldsterWarningVO : list) {
            int age = IDCardAgeCalculator.calculateAge(oldsterWarningVO.getIdCard());
            oldsterWarningVO.setOldsterAge(age);
            LocalDate birthDate = oldsterWarningVO.getBirthDate();
            LocalDate currentDate = LocalDate.now();
            // 使用Period类计算两个日期之间的年数差异
            Period period = Period.between(birthDate, currentDate);
            int years = period.getYears();
            // 如果当前日期小于出生日期的下一个生日,则需要减去一年(因为我们还没有过生日)
            if (currentDate.isBefore(birthDate.plusYears(years).plusMonths(1).minusDays(1))) {
                years--;
            }
            oldsterWarningVO.setOldsterAge(years);
        }
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public List<TOldsterWarningExport> exportOldsterWarning(TCourseOrderQuery query) {
    public List<TOldsterWarningExport> exportOldsterWarning(OldsterListQuery query) {
        List<TOldsterWarningExport> list = this.baseMapper.exportOldsterWarning(query);
        if(CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        for (TOldsterWarningExport oldsterWarningExport : list) {
            int age = IDCardAgeCalculator.calculateAge(oldsterWarningExport.getIdCard());
            oldsterWarningExport.setOldsterAge(age);
            LocalDate birthDate = oldsterWarningExport.getBirthDate();
            LocalDate currentDate = LocalDate.now();
            // 使用Period类计算两个日期之间的年数差异
            Period period = Period.between(birthDate, currentDate);
            int years = period.getYears();
            // 如果当前日期小于出生日期的下一个生日,则需要减去一年(因为我们还没有过生日)
            if (currentDate.isBefore(birthDate.plusYears(years).plusMonths(1).minusDays(1))) {
                years--;
            }
            oldsterWarningExport.setOldsterAge(years);
        }
        return list;
    }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TQuestionnaireServiceImpl.java
@@ -1,10 +1,24 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.mapper.TQuestionnaireMapper;
import com.ruoyi.system.mapper.TQuestionnaireRecordMapper;
import com.ruoyi.system.mapper.TQuestionnaireStemMapper;
import com.ruoyi.system.model.TAssistedDining;
import com.ruoyi.system.model.TQuestionnaire;
import com.ruoyi.system.model.TQuestionnaireRecord;
import com.ruoyi.system.model.TQuestionnaireStem;
import com.ruoyi.system.query.TQuestionnaireQuery;
import com.ruoyi.system.service.TQuestionnaireService;
import com.ruoyi.system.vo.TQuestionnaireVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -17,4 +31,31 @@
@Service
public class TQuestionnaireServiceImpl extends ServiceImpl<TQuestionnaireMapper, TQuestionnaire> implements TQuestionnaireService {
    @Autowired
    private TQuestionnaireStemMapper questionnaireStemMapper;
    @Autowired
    private TQuestionnaireRecordMapper questionnaireRecordMapper;
    @Override
    public PageInfo<TQuestionnaireVO> pageList(TQuestionnaireQuery query) {
        PageInfo<TQuestionnaireVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        List<TQuestionnaireVO> list = this.baseMapper.pageList(query,pageInfo);
        if(CollectionUtils.isEmpty(list)){
            return pageInfo;
        }
        List<String> ids = list.stream().map(TQuestionnaireVO::getId).collect(Collectors.toList());
        List<TQuestionnaireStem> questionnaireStemList = questionnaireStemMapper.selectList(Wrappers.lambdaQuery(TQuestionnaireStem.class)
                .in(TQuestionnaireStem::getQuestionnaireId, ids));
        List<TQuestionnaireRecord> questionnaireRecordList = questionnaireRecordMapper.selectList(Wrappers.lambdaQuery(TQuestionnaireRecord.class)
                .in(TQuestionnaireRecord::getQuestionnaireId, ids));
        for (TQuestionnaireVO questionnaireVO : list) {
            List<TQuestionnaireStem> questionnaireStems = questionnaireStemList.stream().filter(questionnaireStem -> questionnaireVO.getId().equals(questionnaireStem.getQuestionnaireId())).collect(Collectors.toList());
            questionnaireVO.setOptionNum(questionnaireStems.size());
            List<TQuestionnaireRecord> questionnaireRecords = questionnaireRecordList.stream().filter(questionnaireRecord -> questionnaireVO.getId().equals(questionnaireRecord.getQuestionnaireId())).collect(Collectors.toList());
            questionnaireVO.setTotalNum(questionnaireRecords.size());
        }
        pageInfo.setRecords(list);
        return pageInfo;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/task/base/AbstractJob.java
@@ -3,9 +3,12 @@
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.model.TCommunityActivity;
import com.ruoyi.system.model.TDeliberationVote;
import com.ruoyi.system.model.TQuestionnaire;
import com.ruoyi.system.model.TQuestionnaireStem;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.TCommunityActivityService;
import com.ruoyi.system.service.TDeliberationVoteService;
import com.ruoyi.system.service.TQuestionnaireService;
import com.ruoyi.system.task.utils.SpringContextsUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
@@ -23,12 +26,13 @@
    protected RedisCache redisCache;
    protected TDeliberationVoteService deliberationVoteService;
    protected TCommunityActivityService communityActivityService;
    protected TQuestionnaireService questionnaireService;
    public AbstractJob(){
        this.sysUserService = SpringContextsUtil.getBean(ISysUserService.class);
        this.redisCache = SpringContextsUtil.getBean(RedisCache.class);
        this.deliberationVoteService = SpringContextsUtil.getBean(TDeliberationVoteService.class);
        this.communityActivityService = SpringContextsUtil.getBean(TCommunityActivityService.class);
        this.questionnaireService = SpringContextsUtil.getBean(TQuestionnaireService.class);
    }
     
ruoyi-system/src/main/java/com/ruoyi/system/task/base/TimeJobType.java
@@ -6,7 +6,8 @@
 */
public enum TimeJobType {
    DELIBERATION_VOTE_PUSH("deliberation_vote_push","议事投票"),
    ACTIVITY_PUSH("activity_push","社区活动");
    ACTIVITY_PUSH("activity_push","社区活动"),
    QUESTIONNAIRE_PUSH("questionnaire_push","问卷调查");
    private String type;
    private String desc;
    private TimeJobType(String type, String desc) {
ruoyi-system/src/main/java/com/ruoyi/system/task/jobs/QuestionnairePush.java
New file
@@ -0,0 +1,67 @@
package com.ruoyi.system.task.jobs;
import com.google.common.collect.ImmutableMap;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.model.TCommunityActivity;
import com.ruoyi.system.model.TQuestionnaire;
import com.ruoyi.system.task.base.AbstractJob;
import com.ruoyi.system.task.base.QuartzManager;
import com.ruoyi.system.task.base.TimeJobType;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
/**
 * 问卷调查
 * @author Administrator
 *
 */
public class QuestionnairePush extends AbstractJob {
    public static final String name = "questionnairePush_";
    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        JobDataMap maps = context.getMergedJobDataMap();
        String questionnaireId = maps.getString("id");
        String type = maps.getString("type");
        try {
            TQuestionnaire questionnaire = questionnaireService.getById(questionnaireId);
            if(Objects.isNull(questionnaire)){
                return;
            }
            LocalDateTime startTime = questionnaire.getStartTime();
            LocalDateTime endTime = questionnaire.getEndTime();
            LocalDateTime now = LocalDateTime.now();
            if("1".equals(type) && now.compareTo(startTime) > -1 && now.compareTo(endTime) < 1){
                questionnaire.setStatus(2);
                // 添加定时任务
                Map<String, ? extends Object> map =
                        new ImmutableMap.Builder<String, String>().
                                put("id", questionnaire.getId()).put("type","2")
                                .build();
                QuartzManager.addJob(
                        QuestionnairePush.class,
                        (DeliberationVotePush.name+questionnaire.getId()).toUpperCase(),
                        TimeJobType.QUESTIONNAIRE_PUSH,
                        DateUtils.localDateTimeToDate(questionnaire.getEndTime()),
                        map
                );
            }
            if("2".equals(type) && now.isAfter(endTime)){
                questionnaire.setStatus(3);
            }
            questionnaireService.updateById(questionnaire);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/TQuestionnaireVO.java
New file
@@ -0,0 +1,19 @@
package com.ruoyi.system.vo;
import com.ruoyi.system.model.TQuestionnaire;
import com.ruoyi.system.model.TQuestionnaireStem;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "TQuestionnaireVO对象", description = "问卷调查VO")
public class TQuestionnaireVO extends TQuestionnaire {
    @ApiModelProperty(value = "题干")
    private List<TQuestionnaireStem> questionnaireStems;
    @ApiModelProperty(value = "题目数量")
    private Integer optionNum;
}
ruoyi-system/src/main/resources/mapper/system/TAssistedDiningMapper.xml
@@ -22,14 +22,16 @@
        id, point_name, point_phone, point_cover, address, point_detail, create_time, update_time, create_by, update_by, disabled
    </sql>
    <select id="pageList" resultType="com.ruoyi.system.model.TAssistedDining">
        select t1.* from t_assisted_dining t1 where 1=1
        <if test="query.pointName != null and query.pointName != ''">
            and t1.point_name like concat('%',#{query.pointName},'%')
        </if>
        <if test="query.pointPhone != null and query.pointPhone != ''">
            and t1.point_phone like concat('%',#{query.pointPhone},'%')
        </if>
        select t1.* from t_assisted_dining t1
        <where>
            <if test="query.pointName != null and query.pointName != ''">
                and t1.point_name like concat('%',#{query.pointName},'%')
            </if>
            <if test="query.pointPhone != null and query.pointPhone != ''">
                and t1.point_phone like concat('%',#{query.pointPhone},'%')
            </if>
            AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
        </where>
        order by t1.create_time desc
    </select>
ruoyi-system/src/main/resources/mapper/system/THelpNeedsMapper.xml
@@ -22,7 +22,7 @@
        id, app_user_id, nick_name, contact_number, requirement_description, pictures, create_time, update_time, create_by, update_by, disabled
    </sql>
    <select id="pageList" resultType="com.ruoyi.system.model.THelpNeeds">
        select t1.* from t_help_needs
        select t1.* from t_help_needs t1
        where 1=1
        <if test="query.nickName != null and query.nickName != ''">
            and t1.nick_name like concat('%',#{query.nickName},'%')
@@ -35,7 +35,7 @@
        </if>
    </select>
    <select id="exportHelpNeeds" resultType="com.ruoyi.system.export.THelpNeedsExport">
        select t1.* from t_help_needs
        select t1.* from t_help_needs t1
        where 1=1
        <if test="query.nickName != null and query.nickName != ''">
            and t1.nick_name like concat('%',#{query.nickName},'%')
ruoyi-system/src/main/resources/mapper/system/TOldsterWarningMapper.xml
@@ -19,9 +19,9 @@
        id, oldster_id, warning_time, create_time, update_time, create_by, update_by, disabled
    </sql>
    <select id="pageList" resultType="com.ruoyi.system.vo.TOldsterWarningVO">
        select t.id, t.oldster_id, t.warning_time, t.create_time, t.update_time, t.create_by, t.update_by, t.disabled,
        tow.oldster_name, tow.oldster_age, tow.oldster_sex, tow.contact_phone, tow.guardian_name, tow.guardian_phone,
        tow.passport_photo, tow.id_card, tow.birth_date, tow.oldster_type, tow.address
        select tow.id, tow.oldster_id, tow.warning_time, tow.create_time, tow.update_time, tow.create_by, tow.update_by, tow.disabled,
        t.oldster_name, t.oldster_age, t.oldster_sex, t.contact_phone, t.guardian_name, t.guardian_phone,
        t.passport_photo, t.id_card, t.birth_date, t.oldster_type, t.address
        from t_oldster_warning tow
        left join t_oldster t on tow.oldster_id = t.id
        <where>
@@ -39,9 +39,9 @@
        order by tow.warning_time desc
    </select>
    <select id="exportOldsterWarning" resultType="com.ruoyi.system.export.TOldsterWarningExport">
        select t.id, t.oldster_id, t.warning_time, t.create_time, t.update_time, t.create_by, t.update_by, t.disabled,
        tow.oldster_name, tow.oldster_age, tow.oldster_sex, tow.contact_phone, tow.guardian_name, tow.guardian_phone,
        tow.passport_photo, tow.id_card, tow.birth_date, tow.oldster_type, tow.address
        select tow.id, tow.oldster_id, tow.warning_time, tow.create_time, tow.update_time, tow.create_by, tow.update_by, tow.disabled,
        t.oldster_name, t.oldster_age, t.oldster_sex, t.contact_phone, t.guardian_name, t.guardian_phone,
        t.passport_photo, t.id_card, t.birth_date, t.oldster_type, t.address
        from t_oldster_warning tow
        left join t_oldster t on tow.oldster_id = t.id
        <where>
ruoyi-system/src/main/resources/mapper/system/TQuestionnaireMapper.xml
@@ -20,5 +20,20 @@
    <sql id="Base_Column_List">
        id, questionnaire_title, start_time, end_time, status, create_time, update_time, create_by, update_by, disabled
    </sql>
    <select id="pageList" resultType="com.ruoyi.system.vo.TQuestionnaireVO">
        select id, questionnaire_title, start_time, end_time, status,
               create_time, update_time, create_by, update_by, disabled
        from t_questionnaire
        <where>
            <if test="query.questionnaireTitle != null and query.questionnaireTitle != ''">
                and questionnaire_title like concat('%',#{query.questionnaireTitle},'%')
            </if>
            <if test="query.status != null">
                and status = #{query.status}
            </if>
            AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
        </where>
        ORDER BY create_time DESC
    </select>
</mapper>
ruoyi-system/src/main/resources/mapper/system/TQuestionnaireStemBriefAnswerMapper.xml
@@ -8,11 +8,16 @@
        <result column="stem_id" property="stemId" />
        <result column="app_user_id" property="appUserId" />
        <result column="answer_content" property="answerContent" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="create_by" property="createBy" />
        <result column="update_by" property="updateBy" />
        <result column="disabled" property="disabled" />
    </resultMap>
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, stem_id, app_user_id, answer_content
        id, stem_id, app_user_id, answer_content,create_time, update_time, create_by, update_by, disabled
    </sql>
</mapper>
ruoyi-system/src/main/resources/mapper/system/TServiceGuideFileMapper.xml
@@ -24,8 +24,8 @@
        <include refid="Base_Column_List"/>
            FROM t_service_guide_file
        <where>
            <if test="fileName != null and fileName != ''">
                AND file_name LIKE concat('%',#{fileName},'%')
            <if test="query.fileName != null and query.fileName != ''">
                AND file_name LIKE concat('%',#{query.fileName},'%')
            </if>
            AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
        </where>