Compare commits
6 Commits
ef224aa546
...
1a71904608
Author | SHA1 | Date | |
---|---|---|---|
1a71904608 | |||
68474c0c80 | |||
23ff4c814d | |||
363bcb83c6 | |||
0200382ddf | |||
fa278dec01 |
@@ -1,3 +1,19 @@
|
|||||||
|
drop table if exists `user`
|
||||||
|
|
||||||
|
create table user
|
||||||
|
(
|
||||||
|
id int unsigned auto_increment
|
||||||
|
primary key,
|
||||||
|
create_time datetime null,
|
||||||
|
update_time datetime null,
|
||||||
|
username varchar(100) not null,
|
||||||
|
password varchar(255) not null,
|
||||||
|
nickname varchar(100) null
|
||||||
|
)
|
||||||
|
comment '用户表';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
drop table if exists `goal`;
|
drop table if exists `goal`;
|
||||||
|
|
||||||
CREATE TABLE if not exists `goal`
|
CREATE TABLE if not exists `goal`
|
||||||
@@ -34,8 +50,9 @@ create table habit_record
|
|||||||
id int unsigned auto_increment,
|
id int unsigned auto_increment,
|
||||||
create_time datetime null,
|
create_time datetime null,
|
||||||
update_time datetime null,
|
update_time datetime null,
|
||||||
|
name varchar(100) not null,
|
||||||
date date not null comment '重要的日期',
|
date date not null comment '重要的日期',
|
||||||
type enum ('anniversary', 'commemoration') default 'anniversary' not null
|
type enum ('ANNIVERSARY', 'COMMEMORATION') default 'ANNIVERSARY' not null
|
||||||
)
|
)
|
||||||
comment '周年纪念日';
|
comment '周年纪念日';
|
||||||
|
|
||||||
|
2
pom.xml
2
pom.xml
@@ -27,7 +27,7 @@
|
|||||||
<url/>
|
<url/>
|
||||||
</scm>
|
</scm>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>21</java.version>
|
<java.version>17</java.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -14,6 +14,14 @@ public class AnniversaryController {
|
|||||||
this.anniversaryService = anniversaryService;
|
this.anniversaryService = anniversaryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有周年日和纪念日
|
||||||
|
*/
|
||||||
|
@GetMapping
|
||||||
|
public R get() {
|
||||||
|
return R.ok(anniversaryService.getAll());
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public R add(Anniversary anniversary) {
|
public R add(Anniversary anniversary) {
|
||||||
anniversaryService.save(anniversary);
|
anniversaryService.save(anniversary);
|
||||||
|
28
src/main/java/com/dota/nexus/controller/UserController.java
Normal file
28
src/main/java/com/dota/nexus/controller/UserController.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package com.dota.nexus.controller;
|
||||||
|
|
||||||
|
import com.dota.nexus.entity.LoginDTO;
|
||||||
|
import com.dota.nexus.entity.R;
|
||||||
|
import com.dota.nexus.service.UserService;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("user")
|
||||||
|
public class UserController {
|
||||||
|
UserService userService;
|
||||||
|
|
||||||
|
public UserController(UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public R login(LoginDTO loginDTO) throws Exception {
|
||||||
|
var res = userService.login(loginDTO.username(), loginDTO.password());
|
||||||
|
if (res==null) {
|
||||||
|
return R.error("用户不存在或者密码错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
return R.ok(res);
|
||||||
|
}
|
||||||
|
}
|
@@ -8,7 +8,9 @@ import java.time.LocalDate;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class Anniversary extends Entity{
|
public class Anniversary extends Entity{
|
||||||
|
private String name;
|
||||||
|
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
private type;
|
private AnniversaryEnum type;
|
||||||
}
|
}
|
||||||
|
4
src/main/java/com/dota/nexus/entity/LoginDTO.java
Normal file
4
src/main/java/com/dota/nexus/entity/LoginDTO.java
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package com.dota.nexus.entity;
|
||||||
|
|
||||||
|
public record LoginDTO(String username, String password) {
|
||||||
|
}
|
@@ -27,8 +27,12 @@ public class R {
|
|||||||
return new R(200, "ok", data);
|
return new R(200, "ok", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static R error(String msg){
|
||||||
|
return new R(500, msg);
|
||||||
|
}
|
||||||
|
|
||||||
public static R error(){
|
public static R error(){
|
||||||
return new R(500, "服务端发生未知错误");
|
return error("服务端发生未知错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static R unauthorized() {
|
public static R unauthorized() {
|
||||||
|
14
src/main/java/com/dota/nexus/entity/User.java
Normal file
14
src/main/java/com/dota/nexus/entity/User.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package com.dota.nexus.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class User extends Entity{
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String nickname;
|
||||||
|
}
|
@@ -0,0 +1,4 @@
|
|||||||
|
package com.dota.nexus.entity.vo;
|
||||||
|
|
||||||
|
public record AnniversaryRecord(String name, String date, int distance) {
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
package com.dota.nexus.entity.vo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record AnniversaryVO (List<AnniversaryRecord> anniversaryList, List<AnniversaryRecord> commemorationList){
|
||||||
|
}
|
9
src/main/java/com/dota/nexus/mapper/UserMapper.java
Normal file
9
src/main/java/com/dota/nexus/mapper/UserMapper.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package com.dota.nexus.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.dota.nexus.entity.User;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserMapper extends BaseMapper<User> {
|
||||||
|
}
|
@@ -2,6 +2,8 @@ package com.dota.nexus.service;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.dota.nexus.entity.Anniversary;
|
import com.dota.nexus.entity.Anniversary;
|
||||||
|
import com.dota.nexus.entity.vo.AnniversaryVO;
|
||||||
|
|
||||||
public interface AnniversaryService extends IService<Anniversary> {
|
public interface AnniversaryService extends IService<Anniversary> {
|
||||||
|
AnniversaryVO getAll();
|
||||||
}
|
}
|
||||||
|
9
src/main/java/com/dota/nexus/service/UserService.java
Normal file
9
src/main/java/com/dota/nexus/service/UserService.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package com.dota.nexus.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.dota.nexus.entity.User;
|
||||||
|
|
||||||
|
public interface UserService extends IService<User> {
|
||||||
|
|
||||||
|
String login(String username, String password) throws Exception;
|
||||||
|
}
|
@@ -2,10 +2,45 @@ package com.dota.nexus.service.impl;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.dota.nexus.entity.Anniversary;
|
import com.dota.nexus.entity.Anniversary;
|
||||||
|
import com.dota.nexus.entity.AnniversaryEnum;
|
||||||
|
import com.dota.nexus.entity.vo.AnniversaryRecord;
|
||||||
|
import com.dota.nexus.entity.vo.AnniversaryVO;
|
||||||
import com.dota.nexus.mapper.AnniversaryMapper;
|
import com.dota.nexus.mapper.AnniversaryMapper;
|
||||||
import com.dota.nexus.service.AnniversaryService;
|
import com.dota.nexus.service.AnniversaryService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AnniversaryServiceImpl extends ServiceImpl<AnniversaryMapper, Anniversary> implements AnniversaryService {
|
public class AnniversaryServiceImpl extends ServiceImpl<AnniversaryMapper, Anniversary> implements AnniversaryService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnniversaryVO getAll() {
|
||||||
|
var aList = new ArrayList<AnniversaryRecord>();
|
||||||
|
var bList = new ArrayList<AnniversaryRecord>();
|
||||||
|
var res = new AnniversaryVO(aList, bList);
|
||||||
|
var anniversaries = this.baseMapper.selectList(null);
|
||||||
|
var now = LocalDate.now();
|
||||||
|
for (Anniversary anniversary : anniversaries) {
|
||||||
|
// 周年,变成今年或者明年
|
||||||
|
if (anniversary.getType() == AnniversaryEnum.ANNIVERSARY) {
|
||||||
|
LocalDate date = anniversary.getDate();
|
||||||
|
date = date.withYear(now.getYear());
|
||||||
|
if (date.isBefore(now)) {
|
||||||
|
date = date.withYear(now.getYear() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
aList.add(new AnniversaryRecord(anniversary.getName(), date.toString(), (int) ChronoUnit.DAYS.between(now, date)));
|
||||||
|
} else if (anniversary.getType() == AnniversaryEnum.COMMEMORATION) {
|
||||||
|
bList.add(new AnniversaryRecord(anniversary.getName(), anniversary.getDate().toString(), (int) ChronoUnit.DAYS.between(anniversary.getDate(), now)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
package com.dota.nexus.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.dota.nexus.entity.User;
|
||||||
|
import com.dota.nexus.mapper.UserMapper;
|
||||||
|
import com.dota.nexus.service.UserService;
|
||||||
|
import com.dota.nexus.util.GlobalMap;
|
||||||
|
import com.dota.nexus.util.PasswordUtil;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||||
|
public String login(String username, String password) throws Exception {
|
||||||
|
var q = new LambdaQueryWrapper<User>();
|
||||||
|
q.eq(User::getName, username);
|
||||||
|
var u = this.baseMapper.selectOne(q);
|
||||||
|
if (u!=null && PasswordUtil.verify(password, u.getPassword())) {
|
||||||
|
var uuid = UUID.randomUUID().toString();
|
||||||
|
GlobalMap.put(uuid, u.getId());
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
16
src/main/java/com/dota/nexus/util/GlobalMap.java
Normal file
16
src/main/java/com/dota/nexus/util/GlobalMap.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package com.dota.nexus.util;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class GlobalMap {
|
||||||
|
private static final Map<String, Object> MAP = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static void put(String k, Object v) {
|
||||||
|
MAP.put(k,v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object get(String k) {
|
||||||
|
return MAP.get(k);
|
||||||
|
}
|
||||||
|
}
|
47
src/main/java/com/dota/nexus/util/PasswordUtil.java
Normal file
47
src/main/java/com/dota/nexus/util/PasswordUtil.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package com.dota.nexus.util;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class PasswordUtil {
|
||||||
|
public static String encrypt(String password) throws Exception{
|
||||||
|
var random = new SecureRandom();
|
||||||
|
var salt = new byte[16];
|
||||||
|
random.nextBytes(salt);
|
||||||
|
|
||||||
|
var spec = new PBEKeySpec(
|
||||||
|
password.toCharArray(),
|
||||||
|
salt,
|
||||||
|
100000,
|
||||||
|
256
|
||||||
|
);
|
||||||
|
var factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||||
|
var hash = factory.generateSecret(spec).getEncoded();
|
||||||
|
return Base64.getEncoder().encodeToString(salt) + ":" + Base64.getEncoder().encodeToString(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean verify(String password, String storedHash) throws Exception {
|
||||||
|
var parts = storedHash.split(":");
|
||||||
|
var salt = Base64.getDecoder().decode(parts[0]);
|
||||||
|
PBEKeySpec spec = new PBEKeySpec(
|
||||||
|
password.toCharArray(),
|
||||||
|
salt,
|
||||||
|
100000,
|
||||||
|
256
|
||||||
|
);
|
||||||
|
byte[] testHash = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
|
||||||
|
.generateSecret(spec).getEncoded();
|
||||||
|
|
||||||
|
return parts[1].equals(Base64.getEncoder().encodeToString(testHash));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception{
|
||||||
|
var s = "nexus2017";
|
||||||
|
var pass =encrypt(s);
|
||||||
|
System.out.println(pass);
|
||||||
|
System.out.println(pass.length());
|
||||||
|
System.out.println(verify(s, pass));
|
||||||
|
}
|
||||||
|
}
|
13
src/main/java/com/dota/nexus/util/TokenUtil.java
Normal file
13
src/main/java/com/dota/nexus/util/TokenUtil.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package com.dota.nexus.util;
|
||||||
|
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
public class TokenUtil {
|
||||||
|
public static Integer CurrentUserId() {
|
||||||
|
var req = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||||
|
String authorization = req.getHeader("Authorization");
|
||||||
|
var token = authorization.replace("Bearer ", "");
|
||||||
|
return (Integer) GlobalMap.get(token);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user