学习18

对老年人能力评估系统的后端代码进行了修改。
RegisterController.java

package com.example.elserevaluate.controller;

import com.example.elserevaluate.entity.Customer;
import com.example.elserevaluate.entity.User;
import com.example.elserevaluate.service.CustomerService;
import com.example.elserevaluate.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://127.0.0.1:5501", allowCredentials = "true")
public class RegisterController {

    @Autowired
    private UserService userService;

    @Autowired
    private CustomerService customerService;

    @PostMapping("/register")
    public ResponseEntity<Map<String, Object>> register(@RequestBody RegisterRequest request) {
        Map<String, Object> response = new HashMap<>();

        try {
            // 1. 创建用户
            User user = new User();
            user.setUsername(request.getUsername());
            user.setPassword(request.getPassword());

            // 2. 创建空的客户信息记录
            Customer customer = new Customer();
            // 设置必填字段的默认值
            customer.setName("未填写");
            customer.setGender("未填写");
            customer.setBirthDate(new Date());
            customer.setIdCard("未填写");
            customer.setSocialSecurityCard("未填写");
            customer.setEthnicity("未填写");
            customer.setEducation("未填写");
            customer.setMaritalStatus("未填写");
            customer.setLivingCondition("未填写");
            boolean success = userService.register(
                    request.getUsername(),
                    request.getPassword(),
                    request.getImageCaptchaCode()
            );

            if (success) {
                response.put("code", "1");
                response.put("msg", "注册成功");
                return ResponseEntity.ok(response);
            } else {
                response.put("code", "0");
                response.put("msg", "注册失败");
                return ResponseEntity.badRequest().body(response);
            }
        } catch (RuntimeException e) {
            response.put("code", "0");
            response.put("msg", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }
}

// 添加请求体对象
class RegisterRequest {
    private String username;
    private String password;
    private String imageCaptchaCode;

    // Getters and Setters
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getImageCaptchaCode() {
        return imageCaptchaCode;
    }

    public void setImageCaptchaCode(String imageCaptchaCode) {
        this.imageCaptchaCode = imageCaptchaCode;
    }
}

userMapper

package com.example.elserevaluate.mapper;

import com.example.elserevaluate.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Update;

@Mapper
public interface userMapper {
    @Select("SELECT * FROM user WHERE username = #{username}")
    User findByUsername(String username);

    @Insert("INSERT INTO user(username, password) VALUES(#{username}, #{password})")
    int insert(User user);

    @Select("SELECT * FROM user WHERE username = #{username} AND password = #{password}")
    User findByUsernameAndPassword(String username, String password);
    @Select("SELECT * FROM user WHERE id = #{id}")
    User findById(Long id);
    // 添加更新用户信息的方法
    @Update("UPDATE user SET username = #{username}, password = #{password}, customer_id = #{customer.id}, create_time = #{createTime}, update_time = #{updateTime} WHERE id = #{id}")
    int updateById(User user);
}

userService

package com.example.elserevaluate.service;

import com.example.elserevaluate.entity.Customer;
import com.example.elserevaluate.entity.User;
import com.example.elserevaluate.mapper.userMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

@Service
public class UserService {
    @Autowired
    private userMapper userMapper;
    @Autowired
    private CustomerService customerService;

    public User login(String username, String password, String imageCaptchaCode) {
        // 参数验证
        if (username == null || username.trim().isEmpty()) {
            throw new RuntimeException("用户名不能为空");
        }
        if (password == null || password.trim().isEmpty()) {
            throw new RuntimeException("密码不能为空");
        }
        if (imageCaptchaCode == null || imageCaptchaCode.trim().isEmpty()) {
            throw new RuntimeException("验证码不能为空");
        }

        // 验证验证码
        if (!validateCaptcha(imageCaptchaCode)) {
            throw new RuntimeException("验证码错误");
        }

        try {
            // MD5加密密码
            String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());

            // 查询用户
            User user = userMapper.findByUsernameAndPassword(username, md5Password);

            if (user == null) {
                throw new RuntimeException("用户名或密码错误");
            }

            return user;
        } catch (Exception e) {
            throw new RuntimeException("登录失败:" + e.getMessage());
        }
    }

    public boolean register(String username, String password, String imageCaptchaCode) {
        // 参数验证
        if (username == null || username.trim().isEmpty()) {
            throw new RuntimeException("用户名不能为空");
        }
        if (password == null || password.trim().isEmpty()) {
            throw new RuntimeException("密码不能为空");
        }
        if (imageCaptchaCode == null || imageCaptchaCode.trim().isEmpty()) {
            throw new RuntimeException("验证码不能为空");
        }

        // 验证验证码
        if (!validateCaptcha(imageCaptchaCode)) {
            throw new RuntimeException("验证码错误");
        }

        // 检查用户名是否已存在
        if (userMapper.findByUsername(username) != null) {
            throw new RuntimeException("用户名已存在");
        }

        try {
            // 创建新用户
            User user = new User();
            user.setUsername(username);
            // MD5加密密码
            String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
            user.setPassword(md5Password);

            // 1. 保存用户信息
            userMapper.insert(user);

            // 2. 设置关联关系
            // 创建新客户
            Customer customer = new Customer();
            customer.setUserId(user.getId());

            // 3. 保存客户信息
            customerService.saveCustomer(customer);


            // 假设您已经有了 customer 对象
            user.setCustomer(customer);
            userMapper.updateById(user);


            return true;
        } catch (Exception e) {
            throw new RuntimeException("注册失败:" + e.getMessage());
        }

    }

    private boolean validateCaptcha(String imageCaptchaCode) {
        // TODO: 实现验证码验证逻辑
        return true;
    }
    public User getUserById(Long id) {
        if (id == null) {
            return null;
        }
        return userMapper.findById(id);
    }
    public boolean updateUser(User user) {
        // 调用 mapper 的 updateById 方法更新用户信息
        int result = userMapper.updateById(user);
        return result > 0;
    }

}

user

package com.example.elserevaluate.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import jakarta.persistence.*;
import java.util.Date;

@Data
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String username;

    @Column(nullable = false)
    private String password;

    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer customer;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Column(name = "create_time")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Column(name = "update_time")
    private Date updateTime;

}

LoginController

package com.example.elserevaluate.controller;

import com.example.elserevaluate.config.JwtConfig;
import com.example.elserevaluate.entity.User;
import com.example.elserevaluate.service.CustomerService;
import com.example.elserevaluate.service.UserService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = {"http://127.0.0.1:5500", "http://127.0.0.1:5501"}, allowCredentials = "true")
public class LoginController {

    @Autowired
    private UserService userService;

    @Autowired
    private JwtConfig jwtConfig;  // 注入配置类

    // 在需要使用 secretKey 的地方
    private SecretKey getSecretKey() {
        return jwtConfig.secretKey();
    }

    // 生成安全的密钥
//    private final SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    private long expirationTime = 86400000; // 24小时

    @PostMapping("/login")
    public ResponseEntity<Map<String, Object>> login(@RequestBody LoginRequest request) {
        Map<String, Object> response = new HashMap<>();

        try {
            // 参数验证
            if (request.getUsername() == null || request.getPassword() == null) {
                response.put("code", "0");
                response.put("msg", "用户名和密码不能为空");
                return ResponseEntity.ok(response);
            }

            // 验证码验证
            if (request.getImageCaptchaCode() == null) {
                response.put("code", "0");
                response.put("msg", "验证码不能为空");
                return ResponseEntity.ok(response);
            }

            User user = userService.login(
                    request.getUsername(),
                    request.getPassword(),
                    request.getImageCaptchaCode()
            );

            if (user != null) {
                try {
                    // 创建JWT claims
                    Map<String, Object> claims = new HashMap<>();
                    claims.put("userId", user.getId());
                    claims.put("username", user.getUsername());

                    // 生成token
                    String token = Jwts.builder()
                            .setClaims(claims)
                            .setSubject(user.getUsername())
                            .setIssuedAt(new Date())
                            .setExpiration(new Date(System.currentTimeMillis() + expirationTime))
                            .signWith(getSecretKey())  // 使用 getSecretKey() 方法
                            .compact();

                    // 构建返回数据
                    Map<String, Object> userData = new HashMap<>();
                    userData.put("id", user.getId());
                    userData.put("username", user.getUsername());
                    userData.put("token", token);

                    response.put("code", "1");
                    response.put("msg", "登录成功");
                    response.put("data", userData);
                } catch (Exception e) {
                    e.printStackTrace(); // 添加日志输出
                    response.put("code", "0");
                    response.put("msg", "Token生成失败: " + e.getMessage());
                }
            } else {
                response.put("code", "0");
                response.put("msg", "用户名或密码错误");
            }
        } catch (Exception e) {
            e.printStackTrace(); // 添加日志输出
            response.put("code", "0");
            response.put("msg", "登录失败:" + e.getMessage());
        }

        return ResponseEntity.ok(response);
    }
}

class LoginRequest {
    private String username;
    private String password;
    private String imageCaptchaCode;

    // Getters and Setters
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getImageCaptchaCode() {
        return imageCaptchaCode;
    }

    public void setImageCaptchaCode(String imageCaptchaCode) {
        this.imageCaptchaCode = imageCaptchaCode;
    }
}

JwtConfig

package com.example.elserevaluate.config;

import io.jsonwebtoken.security.Keys;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import io.jsonwebtoken.SignatureAlgorithm;

@Configuration
@Component
public class JwtConfig {

    @Bean
    public SecretKey secretKey() {
        return Keys.secretKeyFor(SignatureAlgorithm.HS256);
    }
}

AddController

package com.example.elserevaluate.controller;

import com.example.elserevaluate.config.JwtConfig;
import com.example.elserevaluate.entity.Customer;
import com.example.elserevaluate.entity.User;
import com.example.elserevaluate.service.CustomerService;
import com.example.elserevaluate.service.UserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.crypto.SecretKey;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/user")
@CrossOrigin(origins = {"http://127.0.0.1:5500", "http://127.0.0.1:5501"}, allowCredentials = "true")
public class AddController {

    @Autowired
    private CustomerService customerService;

    @Autowired
    private UserService userService;

    @Autowired
    private JwtConfig jwtConfig;  // 注入配置类

    // 在需要使用 secretKey 的地方
    private SecretKey getSecretKey() {
        return jwtConfig.secretKey();
    }

    // 保存用户信息
    @PostMapping("/info")
    public ResponseEntity<Map<String, Object>> saveUserInfo(
            @RequestHeader("Authorization") String token,
            @RequestBody Customer customer) {
        Map<String, Object> response = new HashMap<>();

        try {
            // 验证token并获取用户信息
            String actualToken = token.replace("Bearer ", "");
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(getSecretKey())  // 使用 getSecretKey() 方法
                    .build()
                    .parseClaimsJws(actualToken)
                    .getBody();

            Long userId = claims.get("userId", Long.class);
            User user = userService.getUserById(userId);

            if (user == null) {
                response.put("code", "0");
                response.put("msg", "用户未登录或登录已过期");
                return ResponseEntity.ok(response);
            }

            // 获取现有的客户信息
            Customer existingCustomer = customerService.getCustomerByUserId(userId);
            if (existingCustomer != null) {
                // 更新现有客户信息,保持ID不变
                customer.setId(existingCustomer.getId());
                customer.setUserId(userId);
            } else {
                // 新建客户信息
                customer.setUserId(userId);
            }

            // 保存客户信息
            boolean result = customerService.saveCustomer(customer);
            if (result) {
                // 更新用户表中的customer_id
                user.setCustomer(customer);
                userService.updateUser(user);

                response.put("code", "1");
                response.put("msg", "保存成功");
            } else {
                response.put("code", "0");
                response.put("msg", "该身份证号已存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.put("code", "0");
            response.put("msg", "保存失败:" + e.getMessage());
        }

        return ResponseEntity.ok(response);
    }

    // 获取当前登录用户的信息
    @GetMapping("/info")
    public ResponseEntity<Map<String, Object>> getCurrentUserInfo(
            @RequestHeader("Authorization") String token) {
        Map<String, Object> response = new HashMap<>();

        try {
            // 验证token并获取用户信息
            String actualToken = token.replace("Bearer ", "");
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(getSecretKey())  // 使用 getSecretKey() 方法
                    .build()
                    .parseClaimsJws(actualToken)
                    .getBody();

            Long userId = claims.get("userId", Long.class);

            // 获取用户关联的客户信息
            Customer customer = customerService.getCustomerByUserId(userId);
            if (customer != null) {
                response.put("code", "1");
                response.put("msg", "查询成功");
                response.put("data", customer);
            } else {
                response.put("code", "0");
                response.put("msg", "未找到用户信息");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.put("code", "0");
            response.put("msg", "查询失败:" + e.getMessage());
        }

        return ResponseEntity.ok(response);
    }

    // 通过身份证号查询用户信息(需要验证权限)
    @GetMapping("/info/{idCard}")
    public ResponseEntity<Map<String, Object>> getUserInfo(
            @RequestHeader("Authorization") String token,
            @PathVariable String idCard) {
        Map<String, Object> response = new HashMap<>();

        try {
            // 验证token
            String actualToken = token.replace("Bearer ", "");
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(getSecretKey())  // 使用 getSecretKey() 方法
                    .build()
                    .parseClaimsJws(actualToken)
                    .getBody();

            Customer customer = customerService.getCustomerByIdCard(idCard);
            if (customer != null) {
                response.put("code", "1");
                response.put("msg", "查询成功");
                response.put("data", customer);
            } else {
                response.put("code", "0");
                response.put("msg", "未找到该身份证号的客户");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.put("code", "0");
            response.put("msg", "查询失败:" + e.getMessage());
        }

        return ResponseEntity.ok(response);
    }
}

CustomerMapper

package com.example.elserevaluate.mapper;

import com.example.elserevaluate.entity.Customer;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface CustomerMapper {
    @Insert("INSERT INTO customer (name, gender, birth_date, id_card, social_security_card, " +
            "ethnicity, education, religion, marital_status, living_condition, create_time, update_time) " +
            "VALUES (#{name}, #{gender}, #{birthDate}, #{idCard}, #{socialSecurityCard}, " +
            "#{ethnicity}, #{education}, #{religion}, #{maritalStatus}, #{livingCondition}, " +
            "NOW(), NOW())")
    int insert(Customer customer);

    @Select("SELECT * FROM customer WHERE id_card = #{idCard}")
    Customer findByIdCard(String idCard);

    @Select("SELECT * FROM customer WHERE user_id = #{userId}")
    Customer findByUserId(Long userId);



}

customerService

package com.example.elserevaluate.service;

import com.example.elserevaluate.entity.Customer;
import com.example.elserevaluate.mapper.CustomerMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Service
public class CustomerService {

    @Autowired
    private CustomerMapper customerMapper;

    public Customer getCustomerByIdCard(String idCard) {
        if (!StringUtils.hasText(idCard)) {
            return null;
        }
        return customerMapper.findByIdCard(idCard);
    }
    public Customer getCustomerByUserId(Long userId) {
        return customerMapper.findByUserId(userId);
    }

    @Transactional
    public boolean saveCustomer(Customer customer) {
        if (customer == null || !StringUtils.hasText(customer.getIdCard())) {
            return false;
        }

        // 检查是否已存在相同身份证号的记录
        Customer existingCustomer = customerMapper.findByIdCard(customer.getIdCard());
        if (existingCustomer != null) {
            return false;
        }

        return customerMapper.insert(customer) > 0;
    }
}

QuestionnaireController

package com.example.elserevaluate.controller;

import com.example.elserevaluate.entity.Questionnaire;
import com.example.elserevaluate.entity.User;
import com.example.elserevaluate.service.QuestionnaireService;
import com.example.elserevaluate.service.UserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import javax.crypto.SecretKey;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/api/questionnaire")
@CrossOrigin(origins = {"http://127.0.0.1:5501", "http://127.0.0.1:5501"}, allowCredentials = "true",
        allowedHeaders = "*")
public class QuestionnaireController {

    @Autowired
    private QuestionnaireService questionnaireService;

    @Autowired
    private UserService userService;

    @Autowired
    private SecretKey secretKey;

    // 提交问卷
    @PostMapping("/submit")
    public ResponseEntity<Map<String, Object>> submitQuestionnaire(
            @RequestHeader("Authorization") String token,
            @Valid @RequestBody Questionnaire questionnaire,
            BindingResult bindingResult) {

        Map<String, Object> response = new HashMap<>();

        try {
            // 验证token并获取用户信息
            String actualToken = token.replace("Bearer ", "");
            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(actualToken)
                    .getBody();

            Long userId = Long.parseLong(claims.get("userId").toString());
            User user = userService.getUserById(userId);

            if (user == null) {
                response.put("code", "0");
                response.put("msg", "用户未登录或登录已过期");
                return ResponseEntity.ok(response);
            }


            // 设置问卷的用户信息
            questionnaire.setUser(user);

            // 设置问卷的用户ID
            questionnaire.setUser(user);
            questionnaire.setCreateTime(new Date());
            questionnaire.setUpdateTime(new Date());

            // 验证数据
            if (bindingResult.hasErrors()) {
                response.put("code", "0");
                response.put("msg", "数据验证失败:" +
                        bindingResult.getAllErrors().get(0).getDefaultMessage());
                return ResponseEntity.ok(response);
            }

            boolean result = questionnaireService.saveQuestionnaire(questionnaire);
            if (result) {
                response.put("code", "1");
                response.put("msg", "问卷提交成功");
                // 添加评估结果到返回数据中
                response.put("data", new HashMap<String, Object>() {{
                    put("totalScore", questionnaire.getTotalScore());
                    put("assessmentResult", questionnaire.getAssessmentResult());
                }});
            } else {
                response.put("code", "0");
                response.put("msg", "问卷提交失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.put("code", "0");
            response.put("msg", "提交失败:" + e.getMessage());
        }

        return ResponseEntity.ok(response);
    }

    // 获取用户的问卷列表
    @GetMapping("/list")
    public ResponseEntity<Map<String, Object>> getQuestionnaireList(
            @RequestHeader("Authorization") String token) {

        Map<String, Object> response = new HashMap<>();

        try {
            // 验证token并获取用户信息
            String actualToken = token.replace("Bearer ", "");
            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(actualToken)
                    .getBody();

            Long userId = Long.parseLong(claims.get("userId").toString());
            List<Questionnaire> questionnaires = questionnaireService.getQuestionnairesByUserId(userId);

            response.put("code", "1");
            response.put("msg", "查询成功");
            response.put("data", questionnaires);
        } catch (Exception e) {
            e.printStackTrace();
            response.put("code", "0");
            response.put("msg", "查询失败:" + e.getMessage());
        }

        return ResponseEntity.ok(response);
    }

    // 获取单个问卷详情
    @GetMapping("/{id}")
    public ResponseEntity<Map<String, Object>> getQuestionnaireDetail(
            @RequestHeader("Authorization") String token,
            @PathVariable Long id) {

        Map<String, Object> response = new HashMap<>();

        try {
            // 验证token并获取用户信息
            String actualToken = token.replace("Bearer ", "");
            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(actualToken)
                    .getBody();

            Long userId = Long.parseLong(claims.get("userId").toString());
            Questionnaire questionnaire = questionnaireService.getQuestionnaireById(id);

            // 验证问卷是否属于当前用户
            if (questionnaire != null && questionnaire.getUser().getId().equals(userId)) {
                response.put("code", "1");
                response.put("msg", "查询成功");
                response.put("data", questionnaire);
            } else {
                response.put("code", "0");
                response.put("msg", "未找到问卷或无权访问");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.put("code", "0");
            response.put("msg", "查询失败:" + e.getMessage());
        }

        return ResponseEntity.ok(response);
    }
//    查询功能,显示在页面上
//    信息的导出
//    根据填入的信息,给出评估结果
@GetMapping("/search")
public ResponseEntity<Map<String, Object>> searchQuestionnaires(
        @RequestHeader("Authorization") String token,
        @RequestParam(required = false) String startDate,
        @RequestParam(required = false) String endDate,
        @RequestParam(required = false) String assessmentResult) {

    Map<String, Object> response = new HashMap<>();

    try {
        // 验证token并获取用户信息
        String actualToken = token.replace("Bearer ", "");
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(actualToken)
                .getBody();

        Long userId = Long.parseLong(claims.get("userId").toString());

        // 解析日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date start = startDate != null ? sdf.parse(startDate) : null;
        Date end = endDate != null ? sdf.parse(endDate) : null;

        List<Questionnaire> questionnaires = questionnaireService
                .searchQuestionnaires(userId, start, end, assessmentResult);

        response.put("code", "1");
        response.put("msg", "查询成功");
        response.put("data", questionnaires);
    } catch (Exception e) {
        e.printStackTrace();
        response.put("code", "0");
        response.put("msg", "查询失败:" + e.getMessage());
    }

    return ResponseEntity.ok(response);
}

    @GetMapping("/export")
    public ResponseEntity<?> exportQuestionnaires(
            @RequestHeader("Authorization") String token,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false) String assessmentResult) {

        try {
            // 验证token并获取用户信息
            String actualToken = token.replace("Bearer ", "");
            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(actualToken)
                    .getBody();

            Long userId = Long.parseLong(claims.get("userId").toString());

            // 解析日期
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//            Date start = startDate != null ? sdf.parse(startDate) : null;
//            Date end = endDate != null ? sdf.parse(endDate) : null;
            Date start = null;
            Date end = null;
            if (startDate != null && !startDate.trim().isEmpty()) {
                start = sdf.parse(startDate);
            }

            if (endDate != null && !endDate.trim().isEmpty()) {
                end = sdf.parse(endDate);
            }

            // 如果没有指定日期范围,设置默认范围(比如最近一年)
            if (start == null && end == null) {
                end = new Date(); // 当前时间
                Calendar cal = Calendar.getInstance();
                cal.add(Calendar.YEAR, -1); // 一年前
                start = cal.getTime();
            }

            // 获取数据
            List<Questionnaire> questionnaires = questionnaireService
                    .searchQuestionnaires(userId, start, end, assessmentResult);

            // 导出为Excel
            byte[] excelBytes = questionnaireService.exportToExcel(questionnaires);

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            String filename = "questionnaire_export_" +
                    new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".xlsx";
            headers.setContentDispositionFormData("attachment", filename);

            return new ResponseEntity<>(excelBytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            Map<String, String> error = new HashMap<>();
            error.put("message", "导出失败:" + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
        }
    }
}

QuestionnaireMapper

package com.example.elserevaluate.mapper;


import com.example.elserevaluate.entity.Questionnaire;
import com.example.elserevaluate.entity.Questionnaire;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.Date;
import java.util.List;
import org.apache.ibatis.annotations.*;

@Mapper
public interface QuestionnaireMapper {
//    @Insert("INSERT INTO questionnaire (user_id, eating, bathing, grooming, dressing, bowel_control, urine_control, toileting, bed_transfer, walking, stairs, cognitive_memory, cognitive_clock, aggression_physical, aggression_verbal, depression_mood, depression_suicide, consciousness, vision, hearing, communication, life_skills, work_skills, time_space_orientation, create_time, update_time) " +
//            "VALUES (#{user.id}, #{eating}, #{bathing}, #{grooming}, #{dressing}, #{bowelControl}, #{urineControl}, #{toileting}, #{bedTransfer}, #{walking}, #{stairs}, #{cognitiveMemory}, #{cognitiveClock}, #{aggressionPhysical}, #{aggressionVerbal}, #{depressionMood}, #{depressionSuicide}, #{consciousness}, #{vision}, #{hearing}, #{communication}, #{lifeSkills}, #{workSkills}, #{timeSpaceOrientation}, NOW(), NOW())")
//    int insert(Questionnaire questionnaire);

    @Select("SELECT * FROM questionnaire WHERE id = #{id}")
    Questionnaire findById(Long id);

    @Select("SELECT * FROM questionnaire WHERE user_id = #{userId}")
    List<Questionnaire> findByUserId(Long userId);

    @Insert("INSERT INTO questionnaire (user_id, eating, bathing, grooming, dressing, " +
            "bowel_control, urine_control, toileting, bed_transfer, walking, stairs, " +
            "cognitive_memory, cognitive_clock, aggression_physical, aggression_verbal, " +
            "depression_mood, depression_suicide, consciousness, vision, hearing, " +
            "communication, life_skills, work_skills, time_space_orientation, " +
            "total_score, assessment_result, create_time, update_time) " +
            "VALUES (#{user.id}, #{eating}, #{bathing}, #{grooming}, #{dressing}, " +
            "#{bowelControl}, #{urineControl}, #{toileting}, #{bedTransfer}, #{walking}, " +
            "#{stairs}, #{cognitiveMemory}, #{cognitiveClock}, #{aggressionPhysical}, " +
            "#{aggressionVerbal}, #{depressionMood}, #{depressionSuicide}, #{consciousness}, " +
            "#{vision}, #{hearing}, #{communication}, #{lifeSkills}, #{workSkills}, " +
            "#{timeSpaceOrientation}, #{totalScore}, #{assessmentResult}, NOW(), NOW())")
    int insert(Questionnaire questionnaire);



    // 带时间范围的查询
    @Select("SELECT * FROM questionnaire WHERE user_id = #{userId} " +
            "AND create_time BETWEEN #{startDate} AND #{endDate} " +
            "ORDER BY create_time DESC")
    List<Questionnaire> findByUserIdAndDateRange(
            @Param("userId") Long userId,
            @Param("startDate") Date startDate,
            @Param("endDate") Date endDate
    );

    // 带评估结果的查询
    @Select("SELECT * FROM questionnaire WHERE user_id = #{userId} " +
            "AND assessment_result = #{result} " +
            "ORDER BY create_time DESC")
    List<Questionnaire> findByUserIdAndResult(
            @Param("userId") Long userId,
            @Param("result") String result
    );
}


QusetionnaireService

package com.example.elserevaluate.service;


import com.example.elserevaluate.entity.Questionnaire;
import com.example.elserevaluate.mapper.QuestionnaireMapper;
import com.example.elserevaluate.mapper.QuestionnaireMapper;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class QuestionnaireService {

    @Autowired
    private QuestionnaireMapper questionnaireMapper;
    @Autowired
    private AssessmentService assessmentService;

    public List<Questionnaire> getQuestionnairesByUserId(Long userId) {
        return questionnaireMapper.findByUserId(userId);
    }

    @Transactional
    public boolean saveQuestionnaire(Questionnaire questionnaire) {
        if (questionnaire == null) {
            return false;
        }
        // 计算总分
        int adlScore = assessmentService.calculateADLScore(questionnaire);
        int mentalScore = assessmentService.calculateMentalScore(questionnaire);
        int perceptionScore = assessmentService.calculatePerceptionScore(questionnaire);

        int totalScore = adlScore + mentalScore + perceptionScore;

        // 设置评估结果
        questionnaire.setTotalScore(totalScore);
        questionnaire.setAssessmentResult(
                assessmentService.determineAssessmentResult(totalScore)
        );
        return questionnaireMapper.insert(questionnaire) > 0;
    }

    public Questionnaire getQuestionnaireById(Long id) {
        return questionnaireMapper.findById(id);
    }
    public List<Questionnaire> searchQuestionnaires(Long userId, Date startDate,
                                                    Date endDate, String assessmentResult) {
        // 基础查询
        if (startDate == null && endDate == null &&
                (assessmentResult == null || assessmentResult.isEmpty())) {
            return questionnaireMapper.findByUserId(userId);
        }

        // 只有时间范围
        if (startDate != null && endDate != null &&
                (assessmentResult == null || assessmentResult.isEmpty())) {
            return questionnaireMapper.findByUserIdAndDateRange(userId, startDate, endDate);
        }

        // 只有评估结果
        if (startDate == null && endDate == null &&
                assessmentResult != null && !assessmentResult.isEmpty()) {
            return questionnaireMapper.findByUserIdAndResult(userId, assessmentResult);
        }

        // 获取所有记录并在内存中过滤
        List<Questionnaire> questionnaires = questionnaireMapper.findByUserId(userId);
        return questionnaires.stream()
                .filter(q -> {
                    boolean dateMatch = true;
                    if (startDate != null && endDate != null) {
                        dateMatch = !q.getCreateTime().before(startDate) &&
                                !q.getCreateTime().after(endDate);
                    }
                    boolean resultMatch = true;
                    if (assessmentResult != null && !assessmentResult.isEmpty()) {
                        resultMatch = assessmentResult.equals(q.getAssessmentResult());
                    }
                    return dateMatch && resultMatch;
                })
                .collect(Collectors.toList());
    }

    public byte[] exportToExcel(List<Questionnaire> questionnaires) throws IOException {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("评估问卷数据");

        // 创建标题样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);

        // 创建标题行
        Row headerRow = sheet.createRow(0);
        String[] headers = {
                "评估时间", "评估结果", "总分"
        };

        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
        }

        // 创建数据样式
        CellStyle dateStyle = workbook.createCellStyle();
        dateStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd hh:mm:ss"));

        // 填充数据
        int rowNum = 1;
        for (Questionnaire q : questionnaires) {
            Row row = sheet.createRow(rowNum++);

            // 评估时间
            Cell dateCell = row.createCell(0);
            dateCell.setCellValue(q.getCreateTime());
            dateCell.setCellStyle(dateStyle);

            // 评估结果
            row.createCell(1).setCellValue(q.getAssessmentResult());

            // 总分
            row.createCell(2).setCellValue(q.getTotalScore());
        }

        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }

        // 转换为字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        workbook.close();

        return outputStream.toByteArray();
    }


}

Questionnaire

package com.example.elserevaluate.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import java.util.Date;

@Data
@Entity
@Table(name = "questionnaire")
public class Questionnaire {
    private Integer totalScore; // 总分
    private String assessmentResult; // 评估结果:正常/需要关注/需要警惕


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    // ADL部分
    @NotBlank(message = "进食能力不能为空")
    private String eating;

    @NotBlank(message = "洗澡能力不能为空")
    private String bathing;

    @NotBlank(message = "修饰能力不能为空")
    private String grooming;

    @NotBlank(message = "穿衣能力不能为空")
    private String dressing;

    @NotBlank(message = "大便控制不能为空")
    @Column(name = "bowel_control")
    private String bowelControl;

    @NotBlank(message = "小便控制不能为空")
    @Column(name = "urine_control")
    private String urineControl;

    @NotBlank(message = "如厕能力不能为空")
    private String toileting;

    @NotBlank(message = "床椅转移不能为空")
    @Column(name = "bed_transfer")
    private String bedTransfer;

    @NotBlank(message = "平地行走不能为空")
    private String walking;

    @NotBlank(message = "上下楼梯不能为空")
    private String stairs;

    // 精神状态部分
    @Column(name = "cognitive_memory")
    private Boolean cognitiveMemory;

    @Column(name = "cognitive_clock")
    private Boolean cognitiveClock;

    @Column(name = "aggression_physical")
    private Boolean aggressionPhysical;

    @Column(name = "aggression_verbal")
    private Boolean aggressionVerbal;

    @Column(name = "depression_mood")
    private Boolean depressionMood;

    @Column(name = "depression_suicide")
    private Boolean depressionSuicide;

    // 感知觉与沟通部分
    @NotBlank(message = "意识状态不能为空")
    private String consciousness;

    @NotBlank(message = "视觉能力不能为空")
    private String vision;

    @NotBlank(message = "听觉能力不能为空")
    private String hearing;

    @NotBlank(message = "沟通能力不能为空")
    private String communication;

    // 社会参与部分
    @NotBlank(message = "生活技能不能为空")
    @Column(name = "life_skills")
    private String lifeSkills;

    @NotBlank(message = "工作技能不能为空")
    @Column(name = "work_skills")
    private String workSkills;

    @NotBlank(message = "时空定向不能为空")
    @Column(name = "time_space_orientation")
    private String timeSpaceOrientation;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Column(name = "create_time")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Column(name = "update_time")
    private Date updateTime;
}

customer

package com.example.elserevaluate.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import jakarta.persistence.*;
import java.util.Date;

@Data
@Entity
@Table(name = "customer")
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "user_id")
    private Long userId;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String gender;

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Column(name = "birth_date", nullable = false)
    private Date birthDate;

    @Column(name = "id_card", nullable = false)
    private String idCard;

    @Column(name = "social_security_card", nullable = false)
    private String socialSecurityCard;

    @Column(nullable = false)
    private String ethnicity;

    @Column(nullable = false)
    private String education;

    private String religion;

    @Column(name = "marital_status", nullable = false)
    private String maritalStatus;

    @Column(name = "living_condition", nullable = false)
    private String livingCondition;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Column(name = "create_time")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Column(name = "update_time")
    private Date updateTime;
}

AssessmentService

package com.example.elserevaluate.service;

import com.example.elserevaluate.entity.Questionnaire;
import org.springframework.stereotype.Service;

@Service
public class AssessmentService {

    public int calculateADLScore(Questionnaire q) {
        int score = 0;

        // 进食能力评分 (0-10分)
        if ("完全独立,可自行使用餐具".equals(q.getEating())) score += 10;
        else if ("需要部分帮助".equals(q.getEating())) score += 5;
        else if ("使用留置营养管".equals(q.getEating())) score += 0;

        // 洗澡能力评分 (0-10分)
        if ("完全独立,可自行完成".equals(q.getBathing())) score += 10;
        else if ("需要他人帮助".equals(q.getBathing())) score += 0;

        // 修饰能力评分 (0-10分)
        if ("完全独立".equals(q.getGrooming())) score += 10;
        else if ("需要帮助".equals(q.getGrooming())) score += 0;

        // 穿衣能力评分 (0-10分)
        if ("完全独立".equals(q.getDressing())) score += 10;
        else if ("需要帮助".equals(q.getDressing())) score += 0;

        // 大便控制评分 (0-10分)
        if ("完全控制".equals(q.getBowelControl())) score += 10;
        else if ("偶尔失控".equals(q.getBowelControl())) score += 5;
        else if ("完全失控".equals(q.getBowelControl())) score += 0;

        // 小便控制评分 (0-10分)
        if ("完全控制".equals(q.getUrineControl())) score += 10;
        else if ("偶尔失控".equals(q.getUrineControl())) score += 5;
        else if ("完全失控".equals(q.getUrineControl())) score += 0;

        // 如厕能力评分 (0-10分)
        if ("完全独立".equals(q.getToileting())) score += 10;
        else if ("需要帮助".equals(q.getToileting())) score += 0;

        // 床椅转移能力评分 (0-10分)
        if ("完全独立".equals(q.getBedTransfer())) score += 10;
        else if ("部分帮助".equals(q.getBedTransfer())) score += 5;
        else if ("极大帮助".equals(q.getBedTransfer())) score += 2;
        else if ("完全依赖他人".equals(q.getBedTransfer())) score += 0;

        // 平地行走能力评分 (0-10分)
        if ("完全独立".equals(q.getWalking())) score += 10;
        else if ("部分帮助".equals(q.getWalking())) score += 5;
        else if ("极大帮助".equals(q.getWalking())) score += 2;
        else if ("完全依赖他人".equals(q.getWalking())) score += 0;

        // 上下楼梯能力评分 (0-10分)
        if ("完全独立".equals(q.getStairs())) score += 10;
        else if ("部分帮助".equals(q.getStairs())) score += 5;
        else if ("极大帮助".equals(q.getStairs())) score += 2;
        else if ("完全依赖他人".equals(q.getStairs())) score += 0;

        return score;
    }

    public int calculateMentalScore(Questionnaire q) {
        int score = 0;

        // 认知功能评分 (0-10分)
        if (q.getCognitiveMemory()) score += 5;
        if (q.getCognitiveClock()) score += 5;

        // 攻击行为评分(扣分项,0至-10分)
        if (q.getAggressionPhysical()) score -= 5;
        if (q.getAggressionVerbal()) score -= 5;

        // 抑郁症状评分(扣分项,0至-10分)
        if (q.getDepressionMood()) score -= 5;
        if (q.getDepressionSuicide()) score -= 5;

        return score;
    }

    public int calculatePerceptionScore(Questionnaire q) {
        int score = 0;

        // 意识水平评分 (0-10分)
        if ("清醒,对周围环境警觉".equals(q.getConsciousness())) score += 10;
        else if ("嗜睡".equals(q.getConsciousness())) score += 5;
        else if ("昏睡".equals(q.getConsciousness())) score += 2;
        else if ("昏迷".equals(q.getConsciousness())) score += 0;

        // 视力评分 (0-10分)
        if ("能看清书报上的标准字体".equals(q.getVision())) score += 10;
        else if ("能看清楚大字体,但看不清书报上的标准字体".equals(q.getVision())) score += 8;
        else if ("视力有限,看不清报纸大标题,但能辨认物体".equals(q.getVision())) score += 5;
        else if ("辨认物体有困难,但眼睛能跟随物体移动,只能看到光、颜色和形状".equals(q.getVision())) score += 2;
        else if ("没有视力,眼睛不能跟随物体移动".equals(q.getVision())) score += 0;

        // 听力评分 (0-10分)
        if ("能正常交谈,听到电视、电话、门铃的声音".equals(q.getHearing())) score += 10;
        else if ("轻声说话或说话距离超过2米时听不清".equals(q.getHearing())) score += 8;
        else if ("正常交流有些困难,需在安静的环境或大声说话才能听到".equals(q.getHearing())) score += 5;
        else if ("讲话者大声说话或说话很慢,才能部分听见".equals(q.getHearing())) score += 2;
        else if ("完全听不见".equals(q.getHearing())) score += 0;

        // 沟通交流能力评分 (0-10分)
        if ("能与他人正常沟通和交流".equals(q.getCommunication())) score += 10;
        else if ("能表达自己的需要及理解别人的话,但需要增加时间或给予帮助".equals(q.getCommunication())) score += 8;
        else if ("表达需要或理解有困难,需频繁重复或简化口头表达".equals(q.getCommunication())) score += 5;
        else if ("不能表达需要或理解他人的话".equals(q.getCommunication())) score += 0;

        return score;
    }

    public int calculateSocialScore(Questionnaire q) {
        int score = 0;

        // 生活能力评分 (0-10分)
        if ("除个人生活自理外,能料理家务或当家管理事务".equals(q.getLifeSkills())) score += 10;
        else if ("除个人生活自理外,能做家务,但欠好,家庭事务安排欠条理".equals(q.getLifeSkills())) score += 8;
        else if ("个人生活能自理;只有在他人帮助下才能做些家务,但质量不好".equals(q.getLifeSkills())) score += 5;
        else if ("个人基本生活事务能自理,在督促下可洗漱".equals(q.getLifeSkills())) score += 2;
        else if ("个人基本生活事务需要部分帮助或完全依赖他人帮助".equals(q.getLifeSkills())) score += 0;

        // 工作能力评分 (0-10分)
        if ("原来熟练的脑力工作或体力技巧性工作可照常进行".equals(q.getWorkSkills())) score += 10;
        else if ("原来熟练的脑力工作或体力技巧性工作能力有所下降".equals(q.getWorkSkills())) score += 8;
        else if ("原来熟练的脑力工作或体力技巧性工作明显不如以往,部分遗忘".equals(q.getWorkSkills())) score += 5;
        else if ("对熟练工作只有一些片段保留,技能全部遗忘".equals(q.getWorkSkills())) score += 2;
        else if ("对以往的知识或技能全部磨灭".equals(q.getWorkSkills())) score += 0;

        // 时间/空间定向评分 (0-10分)
        if ("时间观念清楚,可单独出远门,能很快掌握新环境的方位".equals(q.getTimeSpaceOrientation())) score += 10;
        else if ("时间观念有些下降,年、月、日清楚,但有时相差几天;可单独来往于近街,知道现住地的名称和方位,但不知回家路线".equals(q.getTimeSpaceOrientation())) score += 8;
        else if ("时间观念较差,年、月、日不清楚,可知上半年或下半年;只能单独在家附近行动,对现住地只知名称,不知道方位".equals(q.getTimeSpaceOrientation())) score += 5;

        return score;
    }

    public int calculateTotalScore(Questionnaire q) {
        int adlScore = calculateADLScore(q);
        int mentalScore = calculateMentalScore(q);
        int perceptionScore = calculatePerceptionScore(q);
        int socialScore = calculateSocialScore(q);

        return adlScore + mentalScore + perceptionScore + socialScore;
    }

    public String determineAssessmentResult(int totalScore) {
        if (totalScore >= 150) {
            return "正常";
        } else if (totalScore >= 80) {
            return "需要关注";
        } else {
            return "需要警惕";
        }
    }
}

上述后端代码帮助我基本实现了登录注册功能,个人资料填写功能,填写问卷功能,能够针对填写的问卷内容生成评估结果,用户能够查询相关数据,导出相关数据。当然,依旧存在一些问题需要改进,整体有待优化。

posted @ 2025-02-15 22:12  haoyinuo  阅读(34)  评论(0)    收藏  举报