瀏覽代碼

1.实现Web端用户注册功能和逻辑;
2.优化用户角色实体类及数据仓库、服务类和实现类。

Yumin 6 年之前
父節點
當前提交
ea9a066605

+ 16 - 6
src/main/java/cn/minbb/edu/controller/rest/UserController.java → src/main/java/cn/minbb/edu/controller/rest/SignController.java

@@ -2,25 +2,31 @@ package cn.minbb.edu.controller.rest;
 
 import cn.minbb.edu.data.ResponseResult;
 import cn.minbb.edu.model.User;
+import cn.minbb.edu.model.UserRole;
+import cn.minbb.edu.service.UserRoleService;
 import cn.minbb.edu.service.UserService;
 import com.alibaba.fastjson.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.HashSet;
+import java.util.Set;
 
 @RestController
-@RequestMapping(value = "user")
-public class UserController {
+@RequestMapping("")
+public class SignController {
 
     private UserService userService;
+    private UserRoleService userRoleService;
 
     @Autowired
-    public UserController(UserService userService) {
+    public SignController(UserService userService, UserRoleService userRoleService) {
         this.userService = userService;
+        this.userRoleService = userRoleService;
     }
 
-    @PostMapping(value = "login")
+    @PostMapping(value = "sign-in")
     public ResponseResult<User> login(
             @RequestParam(value = "username") String username,
             @RequestParam(value = "password") String password,
@@ -49,7 +55,7 @@ public class UserController {
         return result;
     }
 
-    @PostMapping(value = "register")
+    @PostMapping(value = "sign-up")
     public ResponseResult<User> register(@RequestBody String userJSON, HttpServletRequest request) {
         ResponseResult<User> result = new ResponseResult<>();
         User userClient = JSONObject.parseObject(userJSON, User.class);
@@ -57,7 +63,11 @@ public class UserController {
             String username = userClient.getUsername();
             if (userService.findUserByUsername(username) == null) {
                 // 用户不存在 - 可以注册
-                User user = userService.save(new User(username, userClient.getPassword()));
+                User u = new User(userClient.getName(), username, userClient.getPassword());
+                Set<UserRole> userRoleSet = new HashSet<>();
+                userRoleSet.add(userRoleService.findOneByRole(UserRole.Role.USER));
+                u.setUserRoleSet(userRoleSet);
+                User user = userService.save(u);
                 if (user != null) {
                     // 注册成功
                     result.setCode(1);

+ 1 - 1
src/main/java/cn/minbb/edu/controller/web/MainController.java

@@ -10,7 +10,7 @@ import org.springframework.web.servlet.ModelAndView;
 import javax.servlet.http.HttpServletRequest;
 
 @Controller
-@RequestMapping(value = "")
+@RequestMapping
 public class MainController {
 
     private UserService userService;

+ 3 - 2
src/main/java/cn/minbb/edu/model/User.java

@@ -127,7 +127,8 @@ public class User implements UserDetails {
     @Column(name = "version", columnDefinition = "INTEGER COMMENT '版本号'")
     public Integer version;
 
-    public User(@NotNull String username, @NotNull String password) {
+    public User(@NotNull String name, @NotNull String username, @NotNull String password) {
+        this.name = name;
         this.username = username;
         this.password = password;
     }
@@ -136,7 +137,7 @@ public class User implements UserDetails {
     public Collection<? extends GrantedAuthority> getAuthorities() {
         List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
         for (UserRole userRole : this.getUserRoleSet()) {
-            grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + userRole.getName()));
+            grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + userRole.getRole().name()));
         }
         return grantedAuthorityList;
     }

+ 9 - 8
src/main/java/cn/minbb/edu/model/UserRole.java

@@ -9,8 +9,8 @@ import java.io.Serializable;
 
 @Entity
 @Table(name = "user_role",
-        uniqueConstraints = {@UniqueConstraint(name = "unique_name", columnNames = {"name"})},
-        indexes = {@Index(name = "index_name", columnList = "name")})
+        uniqueConstraints = {@UniqueConstraint(name = "unique_role", columnNames = {"role"})},
+        indexes = {@Index(name = "index_role", columnList = "role")})
 @NoArgsConstructor
 public class UserRole implements Serializable {
 
@@ -23,20 +23,21 @@ public class UserRole implements Serializable {
 
     @Getter
     @Setter
-    @Column(name = "name", nullable = false, columnDefinition = "VARCHAR(32) COMMENT '角色名称'")
-    private String name;
+    @Enumerated(EnumType.STRING)
+    @Column(name = "role", nullable = false, columnDefinition = "VARCHAR(32) COMMENT '角色名称'")
+    private Role role;
 
     @Getter
     @Setter
     @Column(name = "description", columnDefinition = "VARCHAR(255) COMMENT '角色描述'")
     private String description;
 
-    public UserRole(String name) {
-        this.name = name;
+    public UserRole(Role role) {
+        this.role = role;
     }
 
-    public UserRole(String name, String description) {
-        this.name = name;
+    public UserRole(Role role, String description) {
+        this.role = role;
         this.description = description;
     }
 

+ 2 - 2
src/main/java/cn/minbb/edu/model/repository/UserRoleRepository.java

@@ -8,7 +8,7 @@ import java.util.Set;
 
 @Repository
 public interface UserRoleRepository extends JpaRepository<UserRole, Integer> {
-    UserRole findOneByName(String name);
+    UserRole findOneByRole(UserRole.Role role);
 
-    Set<UserRole> findAllByNameIn(Set<String> nameSet);
+    Set<UserRole> findAllByRoleIn(Set<UserRole.Role> roleSet);
 }

+ 3 - 2
src/main/java/cn/minbb/edu/service/UserRoleService.java

@@ -1,5 +1,6 @@
 package cn.minbb.edu.service;
 
+
 import cn.minbb.edu.model.UserRole;
 
 import java.util.Set;
@@ -7,9 +8,9 @@ import java.util.Set;
 public interface UserRoleService {
     UserRole saveOne(UserRole userRole);
 
-    UserRole findOneByName(String name);
+    UserRole findOneByRole(UserRole.Role role);
 
     Set<UserRole> findAll();
 
-    Set<UserRole> findAllByNameSet(Set<String> nameSet);
+    Set<UserRole> findAllByRoleSet(Set<UserRole.Role> roleSet);
 }

+ 5 - 5
src/main/java/cn/minbb/edu/service/impl/UserRoleServiceImpl.java

@@ -25,8 +25,8 @@ public class UserRoleServiceImpl implements UserRoleService {
     }
 
     @Override
-    public UserRole findOneByName(String name) {
-        return null == name ? null : userRoleRepository.findOneByName(name);
+    public UserRole findOneByRole(UserRole.Role role) {
+        return null == role ? null : userRoleRepository.findOneByRole(role);
     }
 
     @Override
@@ -35,8 +35,8 @@ public class UserRoleServiceImpl implements UserRoleService {
     }
 
     @Override
-    public Set<UserRole> findAllByNameSet(Set<String> nameSet) {
-        if (nameSet.isEmpty()) return new HashSet<>();
-        return userRoleRepository.findAllByNameIn(nameSet);
+    public Set<UserRole> findAllByRoleSet(Set<UserRole.Role> roleSet) {
+        if (roleSet.isEmpty()) return new HashSet<>();
+        return userRoleRepository.findAllByRoleIn(roleSet);
     }
 }

+ 5 - 1
src/main/java/cn/minbb/edu/service/impl/UserServiceImpl.java

@@ -31,6 +31,10 @@ public class UserServiceImpl implements UserService {
 
     @Override
     public User save(User user) {
+        user.setIsAccountNonExpired(true);
+        user.setIsAccountNonLocked(true);
+        user.setIsCredentialsNonExpired(true);
+        user.setIsEnabled(true);
         return userRepository.save(user);
     }
 
@@ -57,7 +61,7 @@ public class UserServiceImpl implements UserService {
                 List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
                 Set<UserRole> userRoleSet = user.getUserRoleSet();
                 for (UserRole userRole : userRoleSet) {
-                    grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + userRole.getName()));
+                    grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + userRole.getRole().name()));
                 }
                 new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorityList);
             }

+ 4 - 5
src/main/java/cn/minbb/edu/task/InitDataRunner.java

@@ -24,11 +24,10 @@ public class InitDataRunner implements ApplicationRunner {
     @Override
     public void run(ApplicationArguments args) throws Exception {
         // 检查用户角色 - 初始化用户角色数据
-        for (UserRole.Role roleEnum : UserRole.Role.values()) {
-            String name = roleEnum.name();
-            if (null == userRoleService.findOneByName(name)) {
-                logger.info("初始化用户角色数据 -> {} = {}", name, roleEnum.getDescription());
-                userRoleService.saveOne(new UserRole(roleEnum.name(), roleEnum.getDescription()));
+        for (UserRole.Role role : UserRole.Role.values()) {
+            if (null == userRoleService.findOneByRole(role)) {
+                logger.info("初始化用户角色数据 -> {} = {}", role.name(), role.getDescription());
+                userRoleService.saveOne(new UserRole(role, role.getDescription()));
             }
         }
     }

+ 1 - 0
src/main/resources/application.properties

@@ -2,6 +2,7 @@
 spring.profiles.active=pro
 server.port=80
 server.servlet.context-path=/
+spring.jmx.default-domain=edu
 spring.datasource.url=
 spring.datasource.username=
 spring.datasource.password=

+ 126 - 1
src/main/resources/templates/index.html

@@ -6,10 +6,135 @@
 <head>
     <meta charset="UTF-8"/>
     <title>知学教育</title>
+
+    <style>
+        /* Since positioning the image, we need to help out the caption */
+        .carousel-caption {
+            bottom: 3rem;
+            z-index: 10;
+        }
+
+        /* Declare heights because of positioning of img element */
+        .carousel-item {
+            height: 32rem;
+            background-color: #777;
+        }
+
+        .carousel-item > img {
+            position: absolute;
+            top: 0;
+            left: 0;
+            min-width: 100%;
+            height: 32rem;
+        }
+
+        /* MARKETING CONTENT */
+        /* Center align the text within the three columns below the carousel */
+        .marketing .col-lg-4 {
+            margin-bottom: 1.5rem;
+            text-align: center;
+        }
+
+        .marketing h2 {
+            font-weight: 400;
+        }
+
+        .marketing .col-lg-4 p {
+            margin-right: .75rem;
+            margin-left: .75rem;
+        }
+
+        /* Featurettes */
+
+        .featurette-divider {
+            margin: 5rem 0; /* Space out the Bootstrap <hr> more */
+        }
+
+        /* Thin out the marketing headings */
+        .featurette-heading {
+            font-weight: 300;
+            line-height: 1;
+            letter-spacing: -.05rem;
+        }
+
+        /* RESPONSIVE CSS */
+
+        @media (min-width: 40em) {
+            /* Bump up size of carousel content */
+            .carousel-caption p {
+                margin-bottom: 20px;
+                font-size: 1.25rem;
+                line-height: 1.4;
+            }
+
+            .featurette-heading {
+                font-size: 50px;
+            }
+        }
+
+        @media (min-width: 62em) {
+            .featurette-heading {
+                margin-top: 7rem;
+            }
+        }
+    </style>
 </head>
 <body>
 <th:block layout:fragment="content">
-    知学教育APP
+    <div id="index-arousel" class="carousel slide" data-ride="carousel">
+        <ol class="carousel-indicators">
+            <li data-target="#index-arousel" data-slide-to="0" class=""></li>
+            <li data-target="#index-arousel" data-slide-to="1" class="active"></li>
+            <li data-target="#index-arousel" data-slide-to="2" class=""></li>
+        </ol>
+        <div class="carousel-inner">
+            <div class="carousel-item">
+                <img class="first-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide">
+                <div class="container">
+                    <div class="carousel-caption text-left">
+                        <h1>Example headline.</h1>
+                        <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam
+                            id dolor id nibh ultricies vehicula ut id elit.</p>
+                        <p><a class="btn btn-lg btn-primary" href="#" role="button">现在去学习</a></p>
+                    </div>
+                </div>
+            </div>
+            <div class="carousel-item active">
+                <img class="second-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide">
+                <div class="container">
+                    <div class="carousel-caption">
+                        <h1>Another example headline.</h1>
+                        <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam
+                            id dolor id nibh ultricies vehicula ut id elit.</p>
+                        <p><a class="btn btn-lg btn-primary" href="#" role="button">了解更多</a></p>
+                    </div>
+                </div>
+            </div>
+            <div class="carousel-item">
+                <img class="third-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide">
+                <div class="container">
+                    <div class="carousel-caption text-right">
+                        <h1>One more for good measure.</h1>
+                        <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam
+                            id dolor id nibh ultricies vehicula ut id elit.</p>
+                        <p><a class="btn btn-lg btn-primary" href="#" role="button">了解更多</a></p>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <a class="carousel-control-prev" href="#index-arousel" role="button" data-slide="prev">
+            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
+            <span class="sr-only">Previous</span>
+        </a>
+        <a class="carousel-control-next" href="#index-arousel" role="button" data-slide="next">
+            <span class="carousel-control-next-icon" aria-hidden="true"></span>
+            <span class="sr-only">Next</span>
+        </a>
+    </div>
+
+    <div class="container" style="margin-top: 24px;">
+        知学教育APP
+    </div>
 </th:block>
 </body>
 </html>

+ 1 - 1
src/main/resources/templates/layouts/layout.html

@@ -24,7 +24,7 @@
 <body style="margin-bottom: 60px;">
 <header th:replace="~{fragments/header :: header}"></header>
 
-<div class="container" style="margin-top: 24px;">
+<div style="margin-top: 1px; margin-bottom: 96px;">
     <div layout:fragment="content">
         <p>内容</p>
     </div>

+ 45 - 3
src/main/resources/templates/sign-up.html

@@ -13,7 +13,7 @@
 </head>
 <body class="text-center">
 
-<form class="form-signin">
+<div class="form-signin">
     <a href="/"><img class="mb-4" src="../static/favicon.ico" alt="" width="72" height="72" th:src="@{/static/favicon.ico}"/></a>
     <h1 class="h3 mb-3 font-weight-normal">用户注册</h1>
 
@@ -34,14 +34,56 @@
            style="height: 44px;" required/>
 
     <div class="mb-3"><a href="/sign-in">我有账号? 去登录</a></div>
-    <button class="btn btn-lg btn-success btn-block" type="submit">注册</button>
+    <button class="btn btn-lg btn-success btn-block" type="button" onclick="return submit();">注册</button>
     <p class="mt-5 mb-3 text-muted">&copy; 2019 知学教育</p>
-</form>
+</div>
 
 <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.js"></script>
 <script>
     $(document).ready(function () {
     });
+
+    function submit() {
+        let nameInput = $('#name'), usernameInput = $('#username'), passwordInput = $('#password'), passwordInput2 = $('#repeat-password');
+        let name = nameInput.val(), username = usernameInput.val(), password = passwordInput.val(), password2 = passwordInput2.val();
+        if (name === "") {
+            alert("姓名不能为空");
+            return;
+        } else if (username === "") {
+            alert("用户名不能为空");
+            return;
+        } else if (password === "") {
+            alert("密码不能为空");
+            return;
+        } else if (password.length < 6) {
+            alert("密码至少六位");
+            return;
+        } else if (password !== password2) {
+            alert("两次密码输入不一致");
+            passwordInput.val("");
+            passwordInput2.val("");
+            return;
+        }
+        $.ajax({
+            url: '/sign-up',
+            type: 'post',
+            data: JSON.stringify({"name": name, "username": username, "password": password}),
+            async: true,
+            dataType: 'json',
+            contentType: false,
+            success: function (result) {
+                if (result && result.success) {
+                    let user = result.data;
+                    alert("恭喜你 " + user.name + " ,注册成功,登录用户名为:" + user.username);
+                    window.location.href = "/sign-in";
+                } else {
+                    alert("注册失败:" + result.message);
+                    window.location.reload();
+                }
+            }
+        });
+        return false;
+    }
 </script>
 </body>
 </html>