addd
This commit is contained in:
66
backend/pom.xml
Normal file
66
backend/pom.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<groupId>com.community</groupId>
|
||||
<artifactId>community-activities</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>community-activities</name>
|
||||
<description>Community solar-term activity system</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<maven.compiler.release>17</maven.compiler.release>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>3.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||
<version>1.38.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
48
backend/schema.sql
Normal file
48
backend/schema.sql
Normal file
@@ -0,0 +1,48 @@
|
||||
create database if not exists community_activity default character set utf8mb4 collate utf8mb4_general_ci;
|
||||
use community_activity;
|
||||
|
||||
create table if not exists sys_user (
|
||||
id bigint primary key auto_increment,
|
||||
username varchar(64) not null unique,
|
||||
password_hash varchar(255) not null,
|
||||
nickname varchar(64) not null,
|
||||
phone varchar(32),
|
||||
role varchar(32) not null default 'user',
|
||||
created_at datetime not null,
|
||||
updated_at datetime not null
|
||||
);
|
||||
|
||||
create table if not exists activity (
|
||||
id bigint primary key auto_increment,
|
||||
title varchar(255) not null,
|
||||
term varchar(64) not null,
|
||||
summary varchar(255),
|
||||
content text,
|
||||
location varchar(255) not null,
|
||||
start_time datetime not null,
|
||||
end_time datetime not null,
|
||||
signup_start datetime not null,
|
||||
signup_end datetime not null,
|
||||
quota int not null,
|
||||
status varchar(32) not null,
|
||||
cover_url varchar(255),
|
||||
created_by bigint,
|
||||
created_at datetime not null,
|
||||
updated_at datetime not null,
|
||||
index idx_activity_status (status),
|
||||
index idx_activity_time (start_time)
|
||||
);
|
||||
|
||||
create table if not exists activity_signup (
|
||||
id bigint primary key auto_increment,
|
||||
activity_id bigint not null,
|
||||
user_id bigint not null,
|
||||
status varchar(32) not null,
|
||||
checkin_status varchar(32) not null,
|
||||
signed_at datetime not null,
|
||||
canceled_at datetime,
|
||||
checkin_at datetime,
|
||||
unique key uk_activity_user (activity_id, user_id),
|
||||
index idx_activity (activity_id),
|
||||
index idx_user (user_id)
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.community.app;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.community.app.mapper")
|
||||
public class CommunityApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CommunityApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.community.app.config;
|
||||
|
||||
import com.community.app.dto.ApiResponse;
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
@ExceptionHandler(IllegalStateException.class)
|
||||
public ApiResponse<Void> handleIllegalState(IllegalStateException ex) {
|
||||
return ApiResponse.fail(ex.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ApiResponse<Void> handleValidation(MethodArgumentNotValidException ex) {
|
||||
String message = ex.getBindingResult().getFieldErrors().isEmpty()
|
||||
? "参数错误"
|
||||
: ex.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
|
||||
return ApiResponse.fail(message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NotLoginException.class)
|
||||
public ApiResponse<Void> handleNotLogin(NotLoginException ex) {
|
||||
return ApiResponse.fail("未登录或登录已失效");
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ApiResponse<Void> handleOther(Exception ex) {
|
||||
return ApiResponse.fail("服务器异常");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.community.app.config;
|
||||
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import com.community.app.entity.User;
|
||||
import com.community.app.service.UserService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class SaTokenConfig {
|
||||
@Bean
|
||||
public StpInterface stpInterface(UserService userService) {
|
||||
return new StpInterface() {
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
User user = userService.findById(Long.valueOf(loginId.toString()));
|
||||
if (user == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.singletonList(user.getRole());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.community.app.config;
|
||||
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOrigins("*")
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.allowedHeaders("*")
|
||||
.allowCredentials(false)
|
||||
.maxAge(3600);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new SaInterceptor(handle -> {
|
||||
String method = SaHolder.getRequest().getMethod();
|
||||
if ("OPTIONS".equalsIgnoreCase(method)) {
|
||||
return;
|
||||
}
|
||||
StpUtil.checkLogin();
|
||||
}))
|
||||
.addPathPatterns("/api/**")
|
||||
.excludePathPatterns("/api/auth/**", "/api/public/**");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.community.app.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.community.app.dto.ActivityRequest;
|
||||
import com.community.app.dto.ActivityView;
|
||||
import com.community.app.dto.ApiResponse;
|
||||
import com.community.app.entity.User;
|
||||
import com.community.app.service.ActivityService;
|
||||
import com.community.app.service.SignupService;
|
||||
import com.community.app.service.UserService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/activities")
|
||||
public class ActivityController {
|
||||
private final ActivityService activityService;
|
||||
private final SignupService signupService;
|
||||
private final UserService userService;
|
||||
|
||||
public ActivityController(ActivityService activityService, SignupService signupService, UserService userService) {
|
||||
this.activityService = activityService;
|
||||
this.signupService = signupService;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ApiResponse<List<ActivityView>> list(@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) String keyword) {
|
||||
User user = currentUser();
|
||||
if (user == null || !"admin".equals(user.getRole())) {
|
||||
status = "published";
|
||||
}
|
||||
return ApiResponse.ok(activityService.list(status, keyword));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ApiResponse<ActivityView> detail(@PathVariable Long id) {
|
||||
ActivityView view = activityService.getView(id);
|
||||
if (view == null) {
|
||||
return ApiResponse.fail("活动不存在");
|
||||
}
|
||||
User user = currentUser();
|
||||
if (user == null || !"admin".equals(user.getRole())) {
|
||||
if (!"published".equals(view.getStatus())) {
|
||||
return ApiResponse.fail("活动未发布");
|
||||
}
|
||||
}
|
||||
return ApiResponse.ok(view);
|
||||
}
|
||||
|
||||
@SaCheckRole("admin")
|
||||
@PostMapping
|
||||
public ApiResponse<Void> create(@Valid @RequestBody ActivityRequest request) {
|
||||
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
|
||||
activityService.create(request, userId);
|
||||
return ApiResponse.ok("创建成功", null);
|
||||
}
|
||||
|
||||
@SaCheckRole("admin")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<Void> update(@PathVariable Long id, @Valid @RequestBody ActivityRequest request) {
|
||||
activityService.update(id, request);
|
||||
return ApiResponse.ok("更新成功", null);
|
||||
}
|
||||
|
||||
@SaCheckRole("admin")
|
||||
@PostMapping("/{id}/publish")
|
||||
public ApiResponse<Void> publish(@PathVariable Long id) {
|
||||
activityService.publish(id);
|
||||
return ApiResponse.ok("已发布", null);
|
||||
}
|
||||
|
||||
@SaCheckRole("admin")
|
||||
@PostMapping("/{id}/close")
|
||||
public ApiResponse<Void> close(@PathVariable Long id) {
|
||||
activityService.close(id);
|
||||
return ApiResponse.ok("已结束", null);
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/signup")
|
||||
public ApiResponse<Void> signup(@PathVariable Long id) {
|
||||
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
|
||||
signupService.signup(id, userId);
|
||||
return ApiResponse.ok("报名成功", null);
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/cancel")
|
||||
public ApiResponse<Void> cancel(@PathVariable Long id) {
|
||||
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
|
||||
signupService.cancel(id, userId);
|
||||
return ApiResponse.ok("已取消报名", null);
|
||||
}
|
||||
|
||||
private User currentUser() {
|
||||
if (!StpUtil.isLogin()) {
|
||||
return null;
|
||||
}
|
||||
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
|
||||
return userService.findById(userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.community.app.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import com.community.app.dto.AdminSignupView;
|
||||
import com.community.app.dto.ApiResponse;
|
||||
import com.community.app.entity.User;
|
||||
import com.community.app.service.SignupService;
|
||||
import com.community.app.service.UserService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin")
|
||||
@SaCheckRole("admin")
|
||||
public class AdminController {
|
||||
private final SignupService signupService;
|
||||
private final UserService userService;
|
||||
|
||||
public AdminController(SignupService signupService, UserService userService) {
|
||||
this.signupService = signupService;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@GetMapping("/activities/{id}/signups")
|
||||
public ApiResponse<List<AdminSignupView>> listSignups(@PathVariable Long id) {
|
||||
return ApiResponse.ok(signupService.listByActivity(id));
|
||||
}
|
||||
|
||||
@PostMapping("/signups/{id}/checkin")
|
||||
public ApiResponse<Void> checkin(@PathVariable Long id) {
|
||||
signupService.checkin(id);
|
||||
return ApiResponse.ok("签到成功", null);
|
||||
}
|
||||
|
||||
@GetMapping("/users")
|
||||
public ApiResponse<List<User>> listUsers() {
|
||||
return ApiResponse.ok(userService.listAll());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.community.app.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.community.app.dto.ApiResponse;
|
||||
import com.community.app.dto.AuthRequest;
|
||||
import com.community.app.dto.AuthResponse;
|
||||
import com.community.app.dto.RegisterRequest;
|
||||
import com.community.app.entity.User;
|
||||
import com.community.app.service.UserService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/auth")
|
||||
public class AuthController {
|
||||
private final UserService userService;
|
||||
|
||||
public AuthController(UserService userService) {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public ApiResponse<AuthResponse> login(@Valid @RequestBody AuthRequest request) {
|
||||
User user = userService.findByUsername(request.getUsername());
|
||||
if (user == null || !userService.verifyPassword(user, request.getPassword())) {
|
||||
return ApiResponse.fail("用户名或密码错误");
|
||||
}
|
||||
StpUtil.login(user.getId());
|
||||
AuthResponse response = new AuthResponse();
|
||||
response.setToken(StpUtil.getTokenValue());
|
||||
response.setUserId(user.getId());
|
||||
response.setUsername(user.getUsername());
|
||||
response.setNickname(user.getNickname());
|
||||
response.setRole(user.getRole());
|
||||
return ApiResponse.ok("登录成功", response);
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
public ApiResponse<AuthResponse> register(@Valid @RequestBody RegisterRequest request) {
|
||||
User user = userService.register(request.getUsername(), request.getPassword(), request.getNickname(), request.getPhone());
|
||||
StpUtil.login(user.getId());
|
||||
AuthResponse response = new AuthResponse();
|
||||
response.setToken(StpUtil.getTokenValue());
|
||||
response.setUserId(user.getId());
|
||||
response.setUsername(user.getUsername());
|
||||
response.setNickname(user.getNickname());
|
||||
response.setRole(user.getRole());
|
||||
return ApiResponse.ok("注册成功", response);
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
public ApiResponse<Void> logout() {
|
||||
StpUtil.logout();
|
||||
return ApiResponse.ok("已退出", null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.community.app.controller;
|
||||
|
||||
import com.community.app.dto.ActivityView;
|
||||
import com.community.app.dto.ApiResponse;
|
||||
import com.community.app.service.ActivityService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/public")
|
||||
public class PublicController {
|
||||
private final ActivityService activityService;
|
||||
|
||||
public PublicController(ActivityService activityService) {
|
||||
this.activityService = activityService;
|
||||
}
|
||||
|
||||
@GetMapping("/activities")
|
||||
public ApiResponse<List<ActivityView>> list(@RequestParam(required = false) String keyword) {
|
||||
return ApiResponse.ok(activityService.list("published", keyword));
|
||||
}
|
||||
|
||||
@GetMapping("/activities/{id}")
|
||||
public ApiResponse<ActivityView> detail(@PathVariable Long id) {
|
||||
ActivityView view = activityService.getView(id);
|
||||
if (view == null || !"published".equals(view.getStatus())) {
|
||||
return ApiResponse.fail("活动不存在或未发布");
|
||||
}
|
||||
return ApiResponse.ok(view);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.community.app.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.community.app.dto.ApiResponse;
|
||||
import com.community.app.dto.SignupView;
|
||||
import com.community.app.entity.User;
|
||||
import com.community.app.service.SignupService;
|
||||
import com.community.app.service.UserService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/me")
|
||||
public class UserController {
|
||||
private final UserService userService;
|
||||
private final SignupService signupService;
|
||||
|
||||
public UserController(UserService userService, SignupService signupService) {
|
||||
this.userService = userService;
|
||||
this.signupService = signupService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ApiResponse<User> me() {
|
||||
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
|
||||
return ApiResponse.ok(userService.findById(userId));
|
||||
}
|
||||
|
||||
@GetMapping("/signups")
|
||||
public ApiResponse<List<SignupView>> mySignups() {
|
||||
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
|
||||
return ApiResponse.ok(signupService.listByUser(userId));
|
||||
}
|
||||
}
|
||||
124
backend/src/main/java/com/community/app/dto/ActivityRequest.java
Normal file
124
backend/src/main/java/com/community/app/dto/ActivityRequest.java
Normal file
@@ -0,0 +1,124 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class ActivityRequest {
|
||||
@NotBlank
|
||||
private String title;
|
||||
@NotBlank
|
||||
private String term;
|
||||
private String summary;
|
||||
private String content;
|
||||
@NotBlank
|
||||
private String location;
|
||||
@NotNull
|
||||
private LocalDateTime startTime;
|
||||
@NotNull
|
||||
private LocalDateTime endTime;
|
||||
@NotNull
|
||||
private LocalDateTime signupStart;
|
||||
@NotNull
|
||||
private LocalDateTime signupEnd;
|
||||
@NotNull
|
||||
private Integer quota;
|
||||
private String status;
|
||||
private String coverUrl;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTerm() {
|
||||
return term;
|
||||
}
|
||||
|
||||
public void setTerm(String term) {
|
||||
this.term = term;
|
||||
}
|
||||
|
||||
public String getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
public void setSummary(String summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public LocalDateTime getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(LocalDateTime startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(LocalDateTime endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignupStart() {
|
||||
return signupStart;
|
||||
}
|
||||
|
||||
public void setSignupStart(LocalDateTime signupStart) {
|
||||
this.signupStart = signupStart;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignupEnd() {
|
||||
return signupEnd;
|
||||
}
|
||||
|
||||
public void setSignupEnd(LocalDateTime signupEnd) {
|
||||
this.signupEnd = signupEnd;
|
||||
}
|
||||
|
||||
public Integer getQuota() {
|
||||
return quota;
|
||||
}
|
||||
|
||||
public void setQuota(Integer quota) {
|
||||
this.quota = quota;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getCoverUrl() {
|
||||
return coverUrl;
|
||||
}
|
||||
|
||||
public void setCoverUrl(String coverUrl) {
|
||||
this.coverUrl = coverUrl;
|
||||
}
|
||||
}
|
||||
132
backend/src/main/java/com/community/app/dto/ActivityView.java
Normal file
132
backend/src/main/java/com/community/app/dto/ActivityView.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class ActivityView {
|
||||
private Long id;
|
||||
private String title;
|
||||
private String term;
|
||||
private String summary;
|
||||
private String content;
|
||||
private String location;
|
||||
private LocalDateTime startTime;
|
||||
private LocalDateTime endTime;
|
||||
private LocalDateTime signupStart;
|
||||
private LocalDateTime signupEnd;
|
||||
private Integer quota;
|
||||
private String status;
|
||||
private String coverUrl;
|
||||
private Long signupCount;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTerm() {
|
||||
return term;
|
||||
}
|
||||
|
||||
public void setTerm(String term) {
|
||||
this.term = term;
|
||||
}
|
||||
|
||||
public String getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
public void setSummary(String summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public LocalDateTime getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(LocalDateTime startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(LocalDateTime endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignupStart() {
|
||||
return signupStart;
|
||||
}
|
||||
|
||||
public void setSignupStart(LocalDateTime signupStart) {
|
||||
this.signupStart = signupStart;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignupEnd() {
|
||||
return signupEnd;
|
||||
}
|
||||
|
||||
public void setSignupEnd(LocalDateTime signupEnd) {
|
||||
this.signupEnd = signupEnd;
|
||||
}
|
||||
|
||||
public Integer getQuota() {
|
||||
return quota;
|
||||
}
|
||||
|
||||
public void setQuota(Integer quota) {
|
||||
this.quota = quota;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getCoverUrl() {
|
||||
return coverUrl;
|
||||
}
|
||||
|
||||
public void setCoverUrl(String coverUrl) {
|
||||
this.coverUrl = coverUrl;
|
||||
}
|
||||
|
||||
public Long getSignupCount() {
|
||||
return signupCount;
|
||||
}
|
||||
|
||||
public void setSignupCount(Long signupCount) {
|
||||
this.signupCount = signupCount;
|
||||
}
|
||||
}
|
||||
105
backend/src/main/java/com/community/app/dto/AdminSignupView.java
Normal file
105
backend/src/main/java/com/community/app/dto/AdminSignupView.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class AdminSignupView {
|
||||
private Long id;
|
||||
private Long activityId;
|
||||
private Long userId;
|
||||
private String username;
|
||||
private String nickname;
|
||||
private String phone;
|
||||
private String status;
|
||||
private String checkinStatus;
|
||||
private LocalDateTime signedAt;
|
||||
private LocalDateTime canceledAt;
|
||||
private LocalDateTime checkinAt;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getActivityId() {
|
||||
return activityId;
|
||||
}
|
||||
|
||||
public void setActivityId(Long activityId) {
|
||||
this.activityId = activityId;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getCheckinStatus() {
|
||||
return checkinStatus;
|
||||
}
|
||||
|
||||
public void setCheckinStatus(String checkinStatus) {
|
||||
this.checkinStatus = checkinStatus;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignedAt() {
|
||||
return signedAt;
|
||||
}
|
||||
|
||||
public void setSignedAt(LocalDateTime signedAt) {
|
||||
this.signedAt = signedAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCanceledAt() {
|
||||
return canceledAt;
|
||||
}
|
||||
|
||||
public void setCanceledAt(LocalDateTime canceledAt) {
|
||||
this.canceledAt = canceledAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCheckinAt() {
|
||||
return checkinAt;
|
||||
}
|
||||
|
||||
public void setCheckinAt(LocalDateTime checkinAt) {
|
||||
this.checkinAt = checkinAt;
|
||||
}
|
||||
}
|
||||
52
backend/src/main/java/com/community/app/dto/ApiResponse.java
Normal file
52
backend/src/main/java/com/community/app/dto/ApiResponse.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
public class ApiResponse<T> {
|
||||
private boolean success;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
public ApiResponse() {
|
||||
}
|
||||
|
||||
public ApiResponse(boolean success, String message, T data) {
|
||||
this.success = success;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> ok(T data) {
|
||||
return new ApiResponse<>(true, "success", data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> ok(String message, T data) {
|
||||
return new ApiResponse<>(true, message, data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> fail(String message) {
|
||||
return new ApiResponse<>(false, message, null);
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
26
backend/src/main/java/com/community/app/dto/AuthRequest.java
Normal file
26
backend/src/main/java/com/community/app/dto/AuthRequest.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class AuthRequest {
|
||||
@NotBlank
|
||||
private String username;
|
||||
@NotBlank
|
||||
private String password;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
public class AuthResponse {
|
||||
private String token;
|
||||
private Long userId;
|
||||
private String username;
|
||||
private String nickname;
|
||||
private String role;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PageResponse<T> {
|
||||
private long total;
|
||||
private List<T> list;
|
||||
|
||||
public PageResponse() {
|
||||
}
|
||||
|
||||
public PageResponse(long total, List<T> list) {
|
||||
this.total = total;
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public List<T> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class RegisterRequest {
|
||||
@NotBlank
|
||||
private String username;
|
||||
@NotBlank
|
||||
private String password;
|
||||
@NotBlank
|
||||
private String nickname;
|
||||
private String phone;
|
||||
|
||||
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 getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
||||
114
backend/src/main/java/com/community/app/dto/SignupView.java
Normal file
114
backend/src/main/java/com/community/app/dto/SignupView.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package com.community.app.dto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class SignupView {
|
||||
private Long id;
|
||||
private Long activityId;
|
||||
private String activityTitle;
|
||||
private String term;
|
||||
private String location;
|
||||
private LocalDateTime startTime;
|
||||
private LocalDateTime endTime;
|
||||
private String status;
|
||||
private String checkinStatus;
|
||||
private LocalDateTime signedAt;
|
||||
private LocalDateTime canceledAt;
|
||||
private LocalDateTime checkinAt;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getActivityId() {
|
||||
return activityId;
|
||||
}
|
||||
|
||||
public void setActivityId(Long activityId) {
|
||||
this.activityId = activityId;
|
||||
}
|
||||
|
||||
public String getActivityTitle() {
|
||||
return activityTitle;
|
||||
}
|
||||
|
||||
public void setActivityTitle(String activityTitle) {
|
||||
this.activityTitle = activityTitle;
|
||||
}
|
||||
|
||||
public String getTerm() {
|
||||
return term;
|
||||
}
|
||||
|
||||
public void setTerm(String term) {
|
||||
this.term = term;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public LocalDateTime getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(LocalDateTime startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(LocalDateTime endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getCheckinStatus() {
|
||||
return checkinStatus;
|
||||
}
|
||||
|
||||
public void setCheckinStatus(String checkinStatus) {
|
||||
this.checkinStatus = checkinStatus;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignedAt() {
|
||||
return signedAt;
|
||||
}
|
||||
|
||||
public void setSignedAt(LocalDateTime signedAt) {
|
||||
this.signedAt = signedAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCanceledAt() {
|
||||
return canceledAt;
|
||||
}
|
||||
|
||||
public void setCanceledAt(LocalDateTime canceledAt) {
|
||||
this.canceledAt = canceledAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCheckinAt() {
|
||||
return checkinAt;
|
||||
}
|
||||
|
||||
public void setCheckinAt(LocalDateTime checkinAt) {
|
||||
this.checkinAt = checkinAt;
|
||||
}
|
||||
}
|
||||
150
backend/src/main/java/com/community/app/entity/Activity.java
Normal file
150
backend/src/main/java/com/community/app/entity/Activity.java
Normal file
@@ -0,0 +1,150 @@
|
||||
package com.community.app.entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class Activity {
|
||||
private Long id;
|
||||
private String title;
|
||||
private String term;
|
||||
private String summary;
|
||||
private String content;
|
||||
private String location;
|
||||
private LocalDateTime startTime;
|
||||
private LocalDateTime endTime;
|
||||
private LocalDateTime signupStart;
|
||||
private LocalDateTime signupEnd;
|
||||
private Integer quota;
|
||||
private String status;
|
||||
private String coverUrl;
|
||||
private Long createdBy;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTerm() {
|
||||
return term;
|
||||
}
|
||||
|
||||
public void setTerm(String term) {
|
||||
this.term = term;
|
||||
}
|
||||
|
||||
public String getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
public void setSummary(String summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public LocalDateTime getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(LocalDateTime startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(LocalDateTime endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignupStart() {
|
||||
return signupStart;
|
||||
}
|
||||
|
||||
public void setSignupStart(LocalDateTime signupStart) {
|
||||
this.signupStart = signupStart;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignupEnd() {
|
||||
return signupEnd;
|
||||
}
|
||||
|
||||
public void setSignupEnd(LocalDateTime signupEnd) {
|
||||
this.signupEnd = signupEnd;
|
||||
}
|
||||
|
||||
public Integer getQuota() {
|
||||
return quota;
|
||||
}
|
||||
|
||||
public void setQuota(Integer quota) {
|
||||
this.quota = quota;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getCoverUrl() {
|
||||
return coverUrl;
|
||||
}
|
||||
|
||||
public void setCoverUrl(String coverUrl) {
|
||||
this.coverUrl = coverUrl;
|
||||
}
|
||||
|
||||
public Long getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
public void setCreatedBy(Long createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.community.app.entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class ActivitySignup {
|
||||
private Long id;
|
||||
private Long activityId;
|
||||
private Long userId;
|
||||
private String status;
|
||||
private String checkinStatus;
|
||||
private LocalDateTime signedAt;
|
||||
private LocalDateTime canceledAt;
|
||||
private LocalDateTime checkinAt;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getActivityId() {
|
||||
return activityId;
|
||||
}
|
||||
|
||||
public void setActivityId(Long activityId) {
|
||||
this.activityId = activityId;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getCheckinStatus() {
|
||||
return checkinStatus;
|
||||
}
|
||||
|
||||
public void setCheckinStatus(String checkinStatus) {
|
||||
this.checkinStatus = checkinStatus;
|
||||
}
|
||||
|
||||
public LocalDateTime getSignedAt() {
|
||||
return signedAt;
|
||||
}
|
||||
|
||||
public void setSignedAt(LocalDateTime signedAt) {
|
||||
this.signedAt = signedAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCanceledAt() {
|
||||
return canceledAt;
|
||||
}
|
||||
|
||||
public void setCanceledAt(LocalDateTime canceledAt) {
|
||||
this.canceledAt = canceledAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCheckinAt() {
|
||||
return checkinAt;
|
||||
}
|
||||
|
||||
public void setCheckinAt(LocalDateTime checkinAt) {
|
||||
this.checkinAt = checkinAt;
|
||||
}
|
||||
}
|
||||
80
backend/src/main/java/com/community/app/entity/User.java
Normal file
80
backend/src/main/java/com/community/app/entity/User.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package com.community.app.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class User {
|
||||
private Long id;
|
||||
private String username;
|
||||
@JsonIgnore
|
||||
private String passwordHash;
|
||||
private String nickname;
|
||||
private String phone;
|
||||
private String role;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
public void setPasswordHash(String passwordHash) {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.community.app.mapper;
|
||||
|
||||
import com.community.app.dto.ActivityView;
|
||||
import com.community.app.entity.Activity;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ActivityMapper {
|
||||
int insert(Activity activity);
|
||||
|
||||
int update(Activity activity);
|
||||
|
||||
Activity findById(@Param("id") Long id);
|
||||
|
||||
ActivityView findViewById(@Param("id") Long id);
|
||||
|
||||
List<ActivityView> list(@Param("status") String status, @Param("keyword") String keyword);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.community.app.mapper;
|
||||
|
||||
import com.community.app.dto.AdminSignupView;
|
||||
import com.community.app.dto.SignupView;
|
||||
import com.community.app.entity.ActivitySignup;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SignupMapper {
|
||||
ActivitySignup findByActivityAndUser(@Param("activityId") Long activityId, @Param("userId") Long userId);
|
||||
|
||||
ActivitySignup findById(@Param("id") Long id);
|
||||
|
||||
int insert(ActivitySignup signup);
|
||||
|
||||
int updateStatus(@Param("id") Long id, @Param("status") String status, @Param("canceledAt") java.time.LocalDateTime canceledAt);
|
||||
|
||||
int resign(@Param("id") Long id, @Param("status") String status, @Param("signedAt") java.time.LocalDateTime signedAt);
|
||||
|
||||
int checkin(@Param("id") Long id, @Param("checkinStatus") String checkinStatus, @Param("checkinAt") java.time.LocalDateTime checkinAt);
|
||||
|
||||
long countSignedByActivity(@Param("activityId") Long activityId);
|
||||
|
||||
List<SignupView> listByUser(@Param("userId") Long userId);
|
||||
|
||||
List<AdminSignupView> listByActivity(@Param("activityId") Long activityId);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.community.app.mapper;
|
||||
|
||||
import com.community.app.entity.User;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserMapper {
|
||||
User findById(@Param("id") Long id);
|
||||
|
||||
User findByUsername(@Param("username") String username);
|
||||
|
||||
int insert(User user);
|
||||
|
||||
List<User> listAll();
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.community.app.service;
|
||||
|
||||
import com.community.app.dto.ActivityRequest;
|
||||
import com.community.app.dto.ActivityView;
|
||||
import com.community.app.entity.Activity;
|
||||
import com.community.app.mapper.ActivityMapper;
|
||||
import com.community.app.mapper.SignupMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ActivityService {
|
||||
private final ActivityMapper activityMapper;
|
||||
private final SignupMapper signupMapper;
|
||||
|
||||
public ActivityService(ActivityMapper activityMapper, SignupMapper signupMapper) {
|
||||
this.activityMapper = activityMapper;
|
||||
this.signupMapper = signupMapper;
|
||||
}
|
||||
|
||||
public ActivityView getView(Long id) {
|
||||
return activityMapper.findViewById(id);
|
||||
}
|
||||
|
||||
public Activity getEntity(Long id) {
|
||||
return activityMapper.findById(id);
|
||||
}
|
||||
|
||||
public List<ActivityView> list(String status, String keyword) {
|
||||
return activityMapper.list(status, keyword);
|
||||
}
|
||||
|
||||
public Activity create(ActivityRequest request, Long creatorId) {
|
||||
validateTimes(request);
|
||||
Activity activity = new Activity();
|
||||
applyRequest(activity, request);
|
||||
activity.setCreatedBy(creatorId);
|
||||
if (activity.getStatus() == null || activity.getStatus().isEmpty()) {
|
||||
activity.setStatus("draft");
|
||||
}
|
||||
activityMapper.insert(activity);
|
||||
return activity;
|
||||
}
|
||||
|
||||
public void update(Long id, ActivityRequest request) {
|
||||
validateTimes(request);
|
||||
Activity activity = activityMapper.findById(id);
|
||||
if (activity == null) {
|
||||
throw new IllegalStateException("活动不存在");
|
||||
}
|
||||
activity.setId(id);
|
||||
applyRequest(activity, request);
|
||||
if (activity.getStatus() == null || activity.getStatus().isEmpty()) {
|
||||
activity.setStatus("draft");
|
||||
}
|
||||
activityMapper.update(activity);
|
||||
}
|
||||
|
||||
public void publish(Long id) {
|
||||
Activity activity = activityMapper.findById(id);
|
||||
if (activity == null) {
|
||||
throw new IllegalStateException("活动不存在");
|
||||
}
|
||||
activity.setStatus("published");
|
||||
activityMapper.update(activity);
|
||||
}
|
||||
|
||||
public void close(Long id) {
|
||||
Activity activity = activityMapper.findById(id);
|
||||
if (activity == null) {
|
||||
throw new IllegalStateException("活动不存在");
|
||||
}
|
||||
activity.setStatus("closed");
|
||||
activityMapper.update(activity);
|
||||
}
|
||||
|
||||
public long countSigned(Long activityId) {
|
||||
return signupMapper.countSignedByActivity(activityId);
|
||||
}
|
||||
|
||||
private void validateTimes(ActivityRequest request) {
|
||||
LocalDateTime start = request.getStartTime();
|
||||
LocalDateTime end = request.getEndTime();
|
||||
LocalDateTime signupStart = request.getSignupStart();
|
||||
LocalDateTime signupEnd = request.getSignupEnd();
|
||||
if (start != null && end != null && end.isBefore(start)) {
|
||||
throw new IllegalStateException("活动结束时间不能早于开始时间");
|
||||
}
|
||||
if (signupStart != null && signupEnd != null && signupEnd.isBefore(signupStart)) {
|
||||
throw new IllegalStateException("报名结束时间不能早于开始时间");
|
||||
}
|
||||
}
|
||||
|
||||
private void applyRequest(Activity activity, ActivityRequest request) {
|
||||
activity.setTitle(request.getTitle());
|
||||
activity.setTerm(request.getTerm());
|
||||
activity.setSummary(request.getSummary());
|
||||
activity.setContent(request.getContent());
|
||||
activity.setLocation(request.getLocation());
|
||||
activity.setStartTime(request.getStartTime());
|
||||
activity.setEndTime(request.getEndTime());
|
||||
activity.setSignupStart(request.getSignupStart());
|
||||
activity.setSignupEnd(request.getSignupEnd());
|
||||
activity.setQuota(request.getQuota());
|
||||
activity.setStatus(request.getStatus());
|
||||
activity.setCoverUrl(request.getCoverUrl());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.community.app.service;
|
||||
|
||||
import com.community.app.dto.AdminSignupView;
|
||||
import com.community.app.dto.SignupView;
|
||||
import com.community.app.entity.Activity;
|
||||
import com.community.app.entity.ActivitySignup;
|
||||
import com.community.app.mapper.ActivityMapper;
|
||||
import com.community.app.mapper.SignupMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class SignupService {
|
||||
private final SignupMapper signupMapper;
|
||||
private final ActivityMapper activityMapper;
|
||||
|
||||
public SignupService(SignupMapper signupMapper, ActivityMapper activityMapper) {
|
||||
this.signupMapper = signupMapper;
|
||||
this.activityMapper = activityMapper;
|
||||
}
|
||||
|
||||
public void signup(Long activityId, Long userId) {
|
||||
Activity activity = activityMapper.findById(activityId);
|
||||
if (activity == null) {
|
||||
throw new IllegalStateException("活动不存在");
|
||||
}
|
||||
if (!"published".equals(activity.getStatus())) {
|
||||
throw new IllegalStateException("活动未发布或已结束");
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (activity.getSignupStart() != null && now.isBefore(activity.getSignupStart())) {
|
||||
throw new IllegalStateException("报名尚未开始");
|
||||
}
|
||||
if (activity.getSignupEnd() != null && now.isAfter(activity.getSignupEnd())) {
|
||||
throw new IllegalStateException("报名已结束");
|
||||
}
|
||||
long count = signupMapper.countSignedByActivity(activityId);
|
||||
if (activity.getQuota() != null && count >= activity.getQuota()) {
|
||||
throw new IllegalStateException("报名名额已满");
|
||||
}
|
||||
|
||||
ActivitySignup existing = signupMapper.findByActivityAndUser(activityId, userId);
|
||||
if (existing == null) {
|
||||
ActivitySignup signup = new ActivitySignup();
|
||||
signup.setActivityId(activityId);
|
||||
signup.setUserId(userId);
|
||||
signup.setStatus("SIGNED");
|
||||
signup.setCheckinStatus("NOT");
|
||||
signup.setSignedAt(now);
|
||||
signupMapper.insert(signup);
|
||||
return;
|
||||
}
|
||||
if ("SIGNED".equals(existing.getStatus())) {
|
||||
throw new IllegalStateException("已报名该活动");
|
||||
}
|
||||
signupMapper.resign(existing.getId(), "SIGNED", now);
|
||||
}
|
||||
|
||||
public void cancel(Long activityId, Long userId) {
|
||||
ActivitySignup existing = signupMapper.findByActivityAndUser(activityId, userId);
|
||||
if (existing == null || !"SIGNED".equals(existing.getStatus())) {
|
||||
throw new IllegalStateException("未找到可取消的报名");
|
||||
}
|
||||
if ("CHECKED".equals(existing.getCheckinStatus())) {
|
||||
throw new IllegalStateException("已签到的报名不可取消");
|
||||
}
|
||||
signupMapper.updateStatus(existing.getId(), "CANCELED", LocalDateTime.now());
|
||||
}
|
||||
|
||||
public void checkin(Long signupId) {
|
||||
ActivitySignup existing = signupMapper.findById(signupId);
|
||||
if (existing == null) {
|
||||
throw new IllegalStateException("报名记录不存在");
|
||||
}
|
||||
if (!"SIGNED".equals(existing.getStatus())) {
|
||||
throw new IllegalStateException("该报名已取消,无法签到");
|
||||
}
|
||||
if ("CHECKED".equals(existing.getCheckinStatus())) {
|
||||
throw new IllegalStateException("已完成签到");
|
||||
}
|
||||
signupMapper.checkin(signupId, "CHECKED", LocalDateTime.now());
|
||||
}
|
||||
|
||||
public List<SignupView> listByUser(Long userId) {
|
||||
return signupMapper.listByUser(userId);
|
||||
}
|
||||
|
||||
public List<AdminSignupView> listByActivity(Long activityId) {
|
||||
return signupMapper.listByActivity(activityId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.community.app.service;
|
||||
|
||||
import com.community.app.entity.User;
|
||||
import com.community.app.mapper.UserMapper;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserService {
|
||||
private final UserMapper userMapper;
|
||||
private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
||||
|
||||
public UserService(UserMapper userMapper) {
|
||||
this.userMapper = userMapper;
|
||||
}
|
||||
|
||||
public User findById(Long id) {
|
||||
return userMapper.findById(id);
|
||||
}
|
||||
|
||||
public User findByUsername(String username) {
|
||||
return userMapper.findByUsername(username);
|
||||
}
|
||||
|
||||
public User register(String username, String rawPassword, String nickname, String phone) {
|
||||
if (userMapper.findByUsername(username) != null) {
|
||||
throw new IllegalStateException("用户名已存在");
|
||||
}
|
||||
User user = new User();
|
||||
user.setUsername(username);
|
||||
user.setPasswordHash(encoder.encode(rawPassword));
|
||||
user.setNickname(nickname);
|
||||
user.setPhone(phone);
|
||||
user.setRole("user");
|
||||
userMapper.insert(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
public boolean verifyPassword(User user, String rawPassword) {
|
||||
return encoder.matches(rawPassword, user.getPasswordHash());
|
||||
}
|
||||
|
||||
public List<User> listAll() {
|
||||
return userMapper.listAll();
|
||||
}
|
||||
}
|
||||
25
backend/src/main/resources/application.yml
Normal file
25
backend/src/main/resources/application.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3307/community_activity?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: qq5211314
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
jackson:
|
||||
time-zone: Asia/Shanghai
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
|
||||
mybatis:
|
||||
mapper-locations: classpath:mapper/*.xml
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
|
||||
sa-token:
|
||||
token-name: satoken
|
||||
timeout: 2592000
|
||||
is-concurrent: true
|
||||
is-share: true
|
||||
token-style: uuid
|
||||
active-timeout: 1800
|
||||
92
backend/src/main/resources/mapper/ActivityMapper.xml
Normal file
92
backend/src/main/resources/mapper/ActivityMapper.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.community.app.mapper.ActivityMapper">
|
||||
<resultMap id="ActivityMap" type="com.community.app.entity.Activity">
|
||||
<id column="id" property="id"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="term" property="term"/>
|
||||
<result column="summary" property="summary"/>
|
||||
<result column="content" property="content"/>
|
||||
<result column="content" property="content"/>
|
||||
<result column="location" property="location"/>
|
||||
<result column="start_time" property="startTime"/>
|
||||
<result column="end_time" property="endTime"/>
|
||||
<result column="signup_start" property="signupStart"/>
|
||||
<result column="signup_end" property="signupEnd"/>
|
||||
<result column="quota" property="quota"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="cover_url" property="coverUrl"/>
|
||||
<result column="created_by" property="createdBy"/>
|
||||
<result column="created_at" property="createdAt"/>
|
||||
<result column="updated_at" property="updatedAt"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="ActivityViewMap" type="com.community.app.dto.ActivityView">
|
||||
<id column="id" property="id"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="term" property="term"/>
|
||||
<result column="summary" property="summary"/>
|
||||
<result column="location" property="location"/>
|
||||
<result column="start_time" property="startTime"/>
|
||||
<result column="end_time" property="endTime"/>
|
||||
<result column="signup_start" property="signupStart"/>
|
||||
<result column="signup_end" property="signupEnd"/>
|
||||
<result column="quota" property="quota"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="cover_url" property="coverUrl"/>
|
||||
<result column="signup_count" property="signupCount"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into activity (title, term, summary, content, location, start_time, end_time,
|
||||
signup_start, signup_end, quota, status, cover_url, created_by, created_at, updated_at)
|
||||
values (#{title}, #{term}, #{summary}, #{content}, #{location}, #{startTime}, #{endTime},
|
||||
#{signupStart}, #{signupEnd}, #{quota}, #{status}, #{coverUrl}, #{createdBy}, now(), now())
|
||||
</insert>
|
||||
|
||||
<update id="update">
|
||||
update activity
|
||||
set title = #{title},
|
||||
term = #{term},
|
||||
summary = #{summary},
|
||||
content = #{content},
|
||||
location = #{location},
|
||||
start_time = #{startTime},
|
||||
end_time = #{endTime},
|
||||
signup_start = #{signupStart},
|
||||
signup_end = #{signupEnd},
|
||||
quota = #{quota},
|
||||
status = #{status},
|
||||
cover_url = #{coverUrl},
|
||||
updated_at = now()
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="findById" resultMap="ActivityMap">
|
||||
select * from activity where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="findViewById" resultMap="ActivityViewMap">
|
||||
select a.*, coalesce(sum(case when s.status = 'SIGNED' then 1 else 0 end), 0) as signup_count
|
||||
from activity a
|
||||
left join activity_signup s on a.id = s.activity_id
|
||||
where a.id = #{id}
|
||||
group by a.id
|
||||
</select>
|
||||
|
||||
<select id="list" resultMap="ActivityViewMap">
|
||||
select a.*, coalesce(sum(case when s.status = 'SIGNED' then 1 else 0 end), 0) as signup_count
|
||||
from activity a
|
||||
left join activity_signup s on a.id = s.activity_id
|
||||
<where>
|
||||
<if test="status != null and status != ''">
|
||||
a.status = #{status}
|
||||
</if>
|
||||
<if test="keyword != null and keyword != ''">
|
||||
and (a.title like concat('%', #{keyword}, '%') or a.term like concat('%', #{keyword}, '%'))
|
||||
</if>
|
||||
</where>
|
||||
group by a.id
|
||||
order by a.start_time desc
|
||||
</select>
|
||||
</mapper>
|
||||
92
backend/src/main/resources/mapper/SignupMapper.xml
Normal file
92
backend/src/main/resources/mapper/SignupMapper.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.community.app.mapper.SignupMapper">
|
||||
<resultMap id="SignupMap" type="com.community.app.entity.ActivitySignup">
|
||||
<id column="id" property="id"/>
|
||||
<result column="activity_id" property="activityId"/>
|
||||
<result column="user_id" property="userId"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="checkin_status" property="checkinStatus"/>
|
||||
<result column="signed_at" property="signedAt"/>
|
||||
<result column="canceled_at" property="canceledAt"/>
|
||||
<result column="checkin_at" property="checkinAt"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="SignupViewMap" type="com.community.app.dto.SignupView">
|
||||
<id column="id" property="id"/>
|
||||
<result column="activity_id" property="activityId"/>
|
||||
<result column="activity_title" property="activityTitle"/>
|
||||
<result column="term" property="term"/>
|
||||
<result column="location" property="location"/>
|
||||
<result column="start_time" property="startTime"/>
|
||||
<result column="end_time" property="endTime"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="checkin_status" property="checkinStatus"/>
|
||||
<result column="signed_at" property="signedAt"/>
|
||||
<result column="canceled_at" property="canceledAt"/>
|
||||
<result column="checkin_at" property="checkinAt"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="AdminSignupViewMap" type="com.community.app.dto.AdminSignupView">
|
||||
<id column="id" property="id"/>
|
||||
<result column="activity_id" property="activityId"/>
|
||||
<result column="user_id" property="userId"/>
|
||||
<result column="username" property="username"/>
|
||||
<result column="nickname" property="nickname"/>
|
||||
<result column="phone" property="phone"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="checkin_status" property="checkinStatus"/>
|
||||
<result column="signed_at" property="signedAt"/>
|
||||
<result column="canceled_at" property="canceledAt"/>
|
||||
<result column="checkin_at" property="checkinAt"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="findByActivityAndUser" resultMap="SignupMap">
|
||||
select * from activity_signup where activity_id = #{activityId} and user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<select id="findById" resultMap="SignupMap">
|
||||
select * from activity_signup where id = #{id}
|
||||
</select>
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into activity_signup (activity_id, user_id, status, checkin_status, signed_at)
|
||||
values (#{activityId}, #{userId}, #{status}, #{checkinStatus}, #{signedAt})
|
||||
</insert>
|
||||
|
||||
<update id="updateStatus">
|
||||
update activity_signup set status = #{status}, canceled_at = #{canceledAt} where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="resign">
|
||||
update activity_signup set status = #{status}, signed_at = #{signedAt}, canceled_at = null
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="checkin">
|
||||
update activity_signup set checkin_status = #{checkinStatus}, checkin_at = #{checkinAt}
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="countSignedByActivity" resultType="long">
|
||||
select count(1) from activity_signup where activity_id = #{activityId} and status = 'SIGNED'
|
||||
</select>
|
||||
|
||||
<select id="listByUser" resultMap="SignupViewMap">
|
||||
select s.id, s.activity_id, a.title as activity_title, a.term, a.location, a.start_time, a.end_time,
|
||||
s.status, s.checkin_status, s.signed_at, s.canceled_at, s.checkin_at
|
||||
from activity_signup s
|
||||
join activity a on s.activity_id = a.id
|
||||
where s.user_id = #{userId}
|
||||
order by s.signed_at desc
|
||||
</select>
|
||||
|
||||
<select id="listByActivity" resultMap="AdminSignupViewMap">
|
||||
select s.id, s.activity_id, s.user_id, u.username, u.nickname, u.phone,
|
||||
s.status, s.checkin_status, s.signed_at, s.canceled_at, s.checkin_at
|
||||
from activity_signup s
|
||||
join sys_user u on s.user_id = u.id
|
||||
where s.activity_id = #{activityId}
|
||||
order by s.signed_at desc
|
||||
</select>
|
||||
</mapper>
|
||||
31
backend/src/main/resources/mapper/UserMapper.xml
Normal file
31
backend/src/main/resources/mapper/UserMapper.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.community.app.mapper.UserMapper">
|
||||
<resultMap id="UserMap" type="com.community.app.entity.User">
|
||||
<id column="id" property="id"/>
|
||||
<result column="username" property="username"/>
|
||||
<result column="password_hash" property="passwordHash"/>
|
||||
<result column="nickname" property="nickname"/>
|
||||
<result column="phone" property="phone"/>
|
||||
<result column="role" property="role"/>
|
||||
<result column="created_at" property="createdAt"/>
|
||||
<result column="updated_at" property="updatedAt"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="findById" resultMap="UserMap">
|
||||
select * from sys_user where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="findByUsername" resultMap="UserMap">
|
||||
select * from sys_user where username = #{username}
|
||||
</select>
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into sys_user (username, password_hash, nickname, phone, role, created_at, updated_at)
|
||||
values (#{username}, #{passwordHash}, #{nickname}, #{phone}, #{role}, now(), now())
|
||||
</insert>
|
||||
|
||||
<select id="listAll" resultMap="UserMap">
|
||||
select * from sys_user order by id desc
|
||||
</select>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user