基板
This commit is contained in:
17
src/main/java/com/quinn/common/ExceptionCode.java
Normal file
17
src/main/java/com/quinn/common/ExceptionCode.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.quinn.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class ExceptionCode implements Serializable {
|
||||
public Integer code;
|
||||
public String msg;
|
||||
|
||||
public ExceptionCode(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.msg = message;
|
||||
}
|
||||
|
||||
public static ExceptionCode init(Integer code, String message) {
|
||||
return new ExceptionCode(code, message);
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,18 @@ import org.springframework.security.config.annotation.method.configuration.Enabl
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@@ -29,9 +39,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
http.authorizeRequests()
|
||||
.antMatchers("/","/index").permitAll()
|
||||
.antMatchers("/register","/login","/toLogin").permitAll()
|
||||
.antMatchers("/source","/source/view/*").permitAll()
|
||||
.antMatchers("/blog","/blog/read/*").permitAll()
|
||||
.antMatchers("/hotspot").permitAll()
|
||||
.antMatchers("/blog/**").authenticated()
|
||||
.antMatchers("/source/**").authenticated()
|
||||
.antMatchers("/user/**").authenticated()
|
||||
.antMatchers("/wx/**").authenticated()
|
||||
.antMatchers("/*").authenticated();
|
||||
|
||||
// 登录配置
|
||||
@@ -40,6 +54,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
.passwordParameter("password")
|
||||
.loginPage("/toLogin")
|
||||
.loginProcessingUrl("/login") // 登陆表单提交请求
|
||||
.failureForwardUrl("/loginError")
|
||||
.defaultSuccessUrl("/index"); // 设置默认登录成功后跳转的页面
|
||||
|
||||
// 注销配置
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.quinn.controller;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.quinn.common.RoleType;
|
||||
import com.quinn.intergration.AttrIcon;
|
||||
import com.quinn.intergration.SendBMail;
|
||||
import com.quinn.pojo.Invite;
|
||||
import com.quinn.pojo.User;
|
||||
import com.quinn.pojo.UserInfo;
|
||||
@@ -18,6 +19,10 @@ import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@Controller
|
||||
public class LoginController {
|
||||
|
||||
@@ -35,9 +40,10 @@ public class LoginController {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/error/check")
|
||||
public String error(){
|
||||
return "error/check";
|
||||
@PostMapping("/loginError")
|
||||
public String error(Model model){
|
||||
model.addAttribute("loginMsg","错误的用户名或者密码!");
|
||||
return "forget";
|
||||
}
|
||||
|
||||
@GetMapping("/toLogin")
|
||||
@@ -52,55 +58,57 @@ public class LoginController {
|
||||
|
||||
// 注册业务
|
||||
@PostMapping("/register")
|
||||
public String register(RegisterForm registerForm,Model model){
|
||||
public String register(HttpServletResponse response,RegisterForm registerForm, Model model) throws IOException {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter writer = response.getWriter();
|
||||
// 表单密码重复判断
|
||||
if (!registerForm.getPassword().equals(registerForm.getRepassword())){
|
||||
model.addAttribute("registerMsg","密码输入有误");
|
||||
return "register";
|
||||
return toResult(writer,"两次输入密码不一致!");
|
||||
}
|
||||
// 用户名已存在
|
||||
User hasUser = userService.getOne(new QueryWrapper<User>().eq("username", registerForm.getUsername()));
|
||||
if (hasUser!=null){
|
||||
model.addAttribute("registerMsg","用户名已存在");
|
||||
return "register";
|
||||
return toResult(writer,"用户名太热门了,请更换用户名");
|
||||
}
|
||||
|
||||
// 验证邀请码
|
||||
Invite invite = inviteService.getOne(new QueryWrapper<Invite>().eq("code", registerForm.getCode()));
|
||||
if (invite==null){
|
||||
model.addAttribute("registerMsg","邀请码不存在");
|
||||
return "register";
|
||||
}else {
|
||||
// 邀请码存在,判断邀请码是否有效
|
||||
if (invite.getStatus()==1){
|
||||
model.addAttribute("registerMsg","邀请码已被使用");
|
||||
return "register";
|
||||
}else {
|
||||
// 构建用户对象
|
||||
User user = new User();
|
||||
user.setUid(QuinnUtils.getUuid()); // 用户唯一id
|
||||
user.setRole(RoleType.NORMAL.name());
|
||||
user.setUsername(registerForm.getUsername());
|
||||
// 密码加密
|
||||
String bCryptPassword = new BCryptPasswordEncoder().encode(registerForm.getPassword());
|
||||
user.setAvatar(AttrIcon.INSTANCE.generateImgUrl(registerForm.getUsername()));
|
||||
user.setPassword(bCryptPassword);
|
||||
user.setGmtCreate(QuinnUtils.getTime());
|
||||
user.setLoginDate(QuinnUtils.getTime());
|
||||
// 保存对象!
|
||||
userService.save(user);
|
||||
// 激活邀请码
|
||||
invite.setActiveTime(QuinnUtils.getTime());
|
||||
invite.setStatus(1);
|
||||
invite.setUid(user.getUid());
|
||||
inviteService.updateById(invite);
|
||||
|
||||
userInfoService.save(new UserInfo().setUid(user.getUid()));
|
||||
|
||||
// 注册成功,重定向到登录页面
|
||||
return "redirect:/toLogin";
|
||||
}
|
||||
return toResult(writer,"注册码不存在!");
|
||||
}
|
||||
if (invite.getApplyEmail().equals(registerForm.getEmail())){
|
||||
return toResult(writer,"请使用申请注册码邮箱注册用户!");
|
||||
}
|
||||
// 构建用户对象
|
||||
User user = new User();
|
||||
user.setUid(QuinnUtils.getUuid()); // 用户唯一id
|
||||
user.setRole(RoleType.NORMAL.name());
|
||||
user.setUsername(registerForm.getUsername());
|
||||
// 密码加密
|
||||
String bCryptPassword = new BCryptPasswordEncoder().encode(registerForm.getPassword());
|
||||
user.setAvatar(AttrIcon.INSTANCE.generateImgUrl(registerForm.getUsername()));
|
||||
user.setPassword(bCryptPassword);
|
||||
user.setGmtCreate(QuinnUtils.getTime());
|
||||
user.setLoginDate(QuinnUtils.getTime());
|
||||
// 保存对象!
|
||||
userService.save(user);
|
||||
// 激活邀请码
|
||||
invite.setActiveTime(QuinnUtils.getTime());
|
||||
invite.setStatus(1);
|
||||
invite.setUid(user.getUid());
|
||||
inviteService.updateById(invite);
|
||||
userInfoService.save(new UserInfo().setUid(user.getUid()).setEmail(registerForm.getEmail()));
|
||||
// 发送注册成功通知邮件
|
||||
SendBMail.INSTANCE.sendWelcome(registerForm.getUsername(),registerForm.getEmail());
|
||||
// 注册成功,重定向到登录页面
|
||||
return "redirect:/toLogin";
|
||||
}
|
||||
|
||||
private String toResult(PrintWriter writer, String msg) {
|
||||
writer.write(msg);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
return "register";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.quinn.service.CommentService;
|
||||
import com.quinn.service.SourceCategoryService;
|
||||
import com.quinn.service.SourceService;
|
||||
import com.quinn.service.StarService;
|
||||
import com.quinn.utils.QuinnUtils;
|
||||
import com.quinn.vo.*;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
@@ -151,4 +152,16 @@ public class SourceController extends BaseModelController {
|
||||
}
|
||||
}
|
||||
|
||||
// 评论
|
||||
@PostMapping("/source/comment/{sid}")
|
||||
public String comment(@PathVariable("sid") String sid, Comment comment){
|
||||
// 存储评论
|
||||
comment.setCommentId(QuinnUtils.getUuid());
|
||||
comment.setTopicCategory(Category.SOURCE.name());
|
||||
comment.setGmtCreate(QuinnUtils.getTime());
|
||||
commentService.save(comment);
|
||||
// 重定向到列表页面
|
||||
return "redirect:/source/view/"+sid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
94
src/main/java/com/quinn/controller/WxController.java
Normal file
94
src/main/java/com/quinn/controller/WxController.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.quinn.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.quinn.dto.req.SearchPage;
|
||||
import com.quinn.dto.req.SendCode;
|
||||
import com.quinn.dto.res.AboutDTO;
|
||||
import com.quinn.dto.res.ResponseDTO;
|
||||
import com.quinn.intergration.SendBMail;
|
||||
import com.quinn.pojo.About;
|
||||
import com.quinn.pojo.Invite;
|
||||
import com.quinn.pojo.UserInfo;
|
||||
import com.quinn.service.AboutService;
|
||||
import com.quinn.service.InviteService;
|
||||
import com.quinn.service.UserInfoService;
|
||||
import com.quinn.service.UserService;
|
||||
import com.quinn.utils.QuinnUtils;
|
||||
import com.quinn.vo.MyPageParam;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author limqsh
|
||||
* @since 2022-05-01
|
||||
*/
|
||||
@RestController("/wx")
|
||||
public class WxController extends BaseModelController {
|
||||
|
||||
@Resource
|
||||
AboutService aboutService;
|
||||
@Resource
|
||||
UserInfoService userInfoService;
|
||||
@Resource
|
||||
InviteService inviteService;
|
||||
|
||||
@PostMapping("about/us")
|
||||
public ResponseDTO userIndexBlog(SearchPage searchPage){
|
||||
Page<About> pageParam = new Page<>(searchPage.getPage(), searchPage.getPageSize());
|
||||
aboutService.page(pageParam,new QueryWrapper<About>().orderByDesc("gmt_create"));
|
||||
// 结果
|
||||
List<About> sayList = pageParam.getRecords();
|
||||
List<AboutDTO> aboutDTOS = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(sayList)){
|
||||
sayList.forEach(x->{
|
||||
AboutDTO aboutDTO = new AboutDTO();
|
||||
aboutDTO.setId(x.getId());
|
||||
aboutDTO.setTitle(x.getTitle());
|
||||
aboutDTO.setContent(x.getContent());
|
||||
aboutDTO.setGmtCreate(QuinnUtils.getViewStrFromDate(x.getGmtCreate()));
|
||||
aboutDTOS.add(aboutDTO);
|
||||
});
|
||||
}
|
||||
MyPageParam myPageParam = new MyPageParam(searchPage.getPage(),searchPage.getPageSize());
|
||||
myPageParam.setTotal((int) pageParam.getTotal());
|
||||
return ResponseDTO.ok().setPage(myPageParam).setData(aboutDTOS);
|
||||
}
|
||||
|
||||
@PostMapping("send/register/code")
|
||||
public ResponseDTO sendCode(SendCode sendCode){
|
||||
Invite email = inviteService.getOne(new QueryWrapper<Invite>().eq("apply_email", sendCode.getEmail()));
|
||||
if (email != null){
|
||||
return ResponseDTO.ok().setData("该邮箱已经获取过注册码");
|
||||
}
|
||||
String code = inviteService.getCode();
|
||||
Invite invite = new Invite();
|
||||
invite.setUid(QuinnUtils.getUuid());
|
||||
invite.setApplyEmail(sendCode.getEmail());
|
||||
invite.setCode(code);
|
||||
invite.setGmtCreate(QuinnUtils.getTime());
|
||||
inviteService.save(invite);
|
||||
boolean sendFlag = SendBMail.INSTANCE.sendRegisterMail(code, sendCode.getEmail());
|
||||
if (!sendFlag){
|
||||
return ResponseDTO.ok().setData("发送识别,请确认邮箱是否正确!");
|
||||
}
|
||||
return ResponseDTO.ok().setData("success");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
13
src/main/java/com/quinn/dto/req/SearchPage.java
Normal file
13
src/main/java/com/quinn/dto/req/SearchPage.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.quinn.dto.req;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class SearchPage implements Serializable {
|
||||
|
||||
int page;
|
||||
int pageSize;
|
||||
|
||||
}
|
||||
12
src/main/java/com/quinn/dto/req/SendCode.java
Normal file
12
src/main/java/com/quinn/dto/req/SendCode.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.quinn.dto.req;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class SendCode implements Serializable {
|
||||
|
||||
String email;
|
||||
|
||||
}
|
||||
35
src/main/java/com/quinn/dto/res/AboutDTO.java
Normal file
35
src/main/java/com/quinn/dto/res/AboutDTO.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.quinn.dto.res;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author limqsh
|
||||
* @since 2022-05-01
|
||||
*/
|
||||
@Data
|
||||
public class AboutDTO implements Serializable {
|
||||
|
||||
private String id;
|
||||
|
||||
private String title;
|
||||
|
||||
private String content;
|
||||
|
||||
private String gmtCreate;
|
||||
|
||||
|
||||
}
|
||||
74
src/main/java/com/quinn/dto/res/ResponseDTO.java
Normal file
74
src/main/java/com/quinn/dto/res/ResponseDTO.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package com.quinn.dto.res;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import com.quinn.common.ExceptionCode;
|
||||
import com.quinn.vo.MyPageParam;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class ResponseDTO extends LinkedHashMap<String, Object> {
|
||||
public static final String ERR_CODE = "err_code";
|
||||
public static final String ERR_MSG = "err_msg";
|
||||
|
||||
public ResponseDTO() {
|
||||
this(0, "OK");
|
||||
}
|
||||
|
||||
public ResponseDTO(Integer errCode, String errMsg) {
|
||||
this(errCode, errMsg, System.currentTimeMillis() / 1000L);
|
||||
}
|
||||
|
||||
public ResponseDTO(Integer errCode, String errMsg, Long timestamp) {
|
||||
this.addAttribute(ERR_CODE, errCode);
|
||||
this.addAttribute(ERR_MSG, errMsg);
|
||||
this.addAttribute("timestamp", timestamp);
|
||||
}
|
||||
|
||||
public ResponseDTO(ExceptionCode exceptionCode) {
|
||||
this(exceptionCode.code, exceptionCode.msg);
|
||||
}
|
||||
|
||||
public ResponseDTO(Integer errCode, String errMsg, String attrName, Object attrValue) {
|
||||
this(errCode, errMsg);
|
||||
this.addAttribute(attrName, attrValue);
|
||||
}
|
||||
|
||||
public static ResponseDTO ok() {
|
||||
return new ResponseDTO();
|
||||
}
|
||||
|
||||
public static ResponseDTO ok(String msg) {
|
||||
ResponseDTO ret = ok();
|
||||
ret.setErrorMsg(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ResponseDTO addAttribute(String attrName, Object attrValue) {
|
||||
Assert.notNull(attrName, "属性名称不能为空");
|
||||
this.put(attrName, attrValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResponseDTO setPage(MyPageParam pagination) {
|
||||
this.addAttribute("page", pagination);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResponseDTO setData(Object obj){
|
||||
this.addAttribute("data",obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setExceptionCode(ExceptionCode exceptionCode) {
|
||||
this.addAttribute("err_code", exceptionCode.code);
|
||||
this.addAttribute("err_msg", exceptionCode.msg);
|
||||
}
|
||||
|
||||
public void setErrorCode(Integer errCode) {
|
||||
this.addAttribute("err_code", errCode);
|
||||
}
|
||||
|
||||
public void setErrorMsg(String errMsg) {
|
||||
this.addAttribute("err_msg", errMsg);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,17 @@ public enum SendBMail {
|
||||
boolean isAuth = true;
|
||||
String from = "quinn.admin@88.com";
|
||||
|
||||
public boolean sendMail(String registerCode,String toEmail){
|
||||
public boolean sendRegisterMail(String registerCode,String email){
|
||||
return sendMail("QUINN注册码",
|
||||
"您好,您的注册码是【" + registerCode + "】",email);
|
||||
}
|
||||
|
||||
public boolean sendWelcome(String username,String email){
|
||||
return sendMail("QUINN-注册成功",
|
||||
username + "您好,欢迎使用!",email);
|
||||
}
|
||||
|
||||
private boolean sendMail(String subject,String content,String toEmail){
|
||||
Properties props = new Properties();
|
||||
props.put("mail.smtp.ssl.enable", isSSL);
|
||||
props.put("mail.smtp.host", host);
|
||||
@@ -42,8 +52,8 @@ public enum SendBMail {
|
||||
try {
|
||||
Message message = new MimeMessage(session);
|
||||
message.setFrom(new InternetAddress(from));
|
||||
message.setSubject("");
|
||||
message.setContent("","text/html;charset=UTF-8");
|
||||
message.setSubject(subject);
|
||||
message.setContent(content,"text/html;charset=UTF-8");
|
||||
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
|
||||
Transport.send(message);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -34,6 +34,9 @@ public class Invite implements Serializable {
|
||||
@ApiModelProperty(value = "用户id")
|
||||
private String uid;
|
||||
|
||||
@ApiModelProperty(value = "申请邮箱")
|
||||
private String applyEmail;
|
||||
|
||||
@ApiModelProperty(value = "状态 0 未使用 1 使用")
|
||||
private Integer status;
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
*/
|
||||
public interface InviteService extends IService<Invite> {
|
||||
|
||||
String getCode();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.quinn.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.quinn.pojo.Invite;
|
||||
import com.quinn.mapper.InviteMapper;
|
||||
import com.quinn.service.InviteService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.quinn.utils.QuinnUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
@@ -17,4 +19,17 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class InviteServiceImpl extends ServiceImpl<InviteMapper, Invite> implements InviteService {
|
||||
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
String code = "";
|
||||
while (true){
|
||||
code = QuinnUtils.getCode();
|
||||
int count = count(new QueryWrapper<Invite>().eq("apply_email", code).eq("status",'0'));
|
||||
if (count <= 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,14 @@ package com.quinn.utils;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
public class QuinnUtils {
|
||||
|
||||
private static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
private final static SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMdd");
|
||||
private final static SimpleDateFormat sdfv = new SimpleDateFormat( "yyyy-MM-dd");
|
||||
|
||||
public static String getUuid(){
|
||||
return UUID.randomUUID().toString().replaceAll("-","");
|
||||
@@ -21,4 +24,19 @@ public class QuinnUtils {
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static String getViewStrFromDate(Date date){
|
||||
return sdfv.format(date);
|
||||
}
|
||||
|
||||
public static String getCode(){
|
||||
int length = 6;
|
||||
//随机数
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ public class RegisterForm {
|
||||
@ApiModelProperty(value = "确认密码")
|
||||
private String repassword;
|
||||
|
||||
@ApiModelProperty(value = "申请邮箱")
|
||||
private String email;
|
||||
|
||||
@ApiModelProperty(value = "邀请码")
|
||||
private String code;
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* BootstrapValidator (http://bootstrapvalidator.com)
|
||||
* The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3
|
||||
*
|
||||
* @author http://twitter.com/nghuuphuoc
|
||||
* @copyright (c) 2013 - 2014 Nguyen Huu Phuoc
|
||||
* @license Commercial: http://bootstrapvalidator.com/license/
|
||||
* Non-commercial: http://creativecommons.org/licenses/by-nc-nd/3.0/
|
||||
*/
|
||||
|
||||
.bv-form .help-block {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.bv-form .tooltip-inner {
|
||||
text-align: left;
|
||||
}
|
||||
.nav-tabs li.bv-tab-success > a {
|
||||
color: #3c763d;
|
||||
}
|
||||
.nav-tabs li.bv-tab-error > a {
|
||||
color: #a94442;
|
||||
}
|
||||
|
||||
.bv-form .bv-icon-no-label {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.bv-form .bv-icon-input-group {
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
BIN
src/main/resources/static/images/menu/wxbg.png
Normal file
BIN
src/main/resources/static/images/menu/wxbg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 603 KiB |
@@ -1,6 +1,6 @@
|
||||
/* 如果使用该初始化方法,请一定要在html放三个标签,或者直接看代码修改内容
|
||||
* <div id="editor-toolbar"></div>
|
||||
* <div id="editor-text-area" style="height: 400px;border: 1px solid lightgrey"></div>
|
||||
* <div id="editor-text-area" style="height: 600px;border: 1px solid lightgrey"></div>
|
||||
* <textarea id="content-textarea" name="content" style="display: none;"></textarea>
|
||||
* 另外此方法依赖layer.js & axios.js 做遮罩弹框,
|
||||
* 也可以重写 uploadImage:onFailed | onError 自定义提示
|
||||
@@ -28,21 +28,7 @@ const editorConfig = {
|
||||
},
|
||||
// 上传错误,或者触发 timeout 超时
|
||||
onError(file, err, res) {
|
||||
layer.open({
|
||||
type: 1, //1:自定义内容 2:iframe
|
||||
title: '图片超过1MB',
|
||||
// area: ['500px', '170px'],
|
||||
content: '资源有限,大佬请使用网络图片╮(╯▽╰)╭',
|
||||
btn: ['好吧穷鬼'],
|
||||
skin: 'layui-layer-hui',
|
||||
yes: function(){
|
||||
layer.closeAll(); //关闭所有弹出框
|
||||
},
|
||||
cancel: function(){
|
||||
//右上角关闭回调
|
||||
//return false 开启该代码可禁止点击该按钮关闭
|
||||
}
|
||||
});
|
||||
layer.open({ content: '穷╮(╯▽╰)╭,图片不能超过1M', skin: 'msg', time: 2 });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 如果使用该初始化方法,请一定要在html放三个标签,或者直接看代码修改内容
|
||||
* <div id="editor-toolbar"></div>
|
||||
* <div id="editor-text-area" style="height: 400px;border: 1px solid lightgrey"></div>
|
||||
* <div id="editor-text-area" style="height: 600px;border: 1px solid lightgrey"></div>
|
||||
* <textarea id="content-textarea" name="content" style="display: none;"></textarea>
|
||||
* 另外此方法依赖layer.js & axios.js 做遮罩弹框,
|
||||
* 也可以重写 uploadImage:onFailed | onError 自定义提示
|
||||
|
||||
@@ -32,13 +32,13 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 mb-3">
|
||||
<label for="firstName">论坛标题</label>
|
||||
<input required th:value="${blog.getTitle()}" name="title" type="text" class="form-control" id="firstName">
|
||||
<label for="title">论坛标题</label>
|
||||
<input required th:value="${blog.getTitle()}" name="title" type="text" class="form-control" id="title">
|
||||
</div>
|
||||
|
||||
<div class="col-md-2 mb-3">
|
||||
<label for="country">标签</label>
|
||||
<select name="categoryId" class="custom-select d-block w-100" id="country">
|
||||
<label for="categoryId">标签</label>
|
||||
<select name="categoryId" class="custom-select d-block w-100" id="categoryId" required>
|
||||
<option th:each="category:${categoryList}"
|
||||
th:selected="${blog.getCategoryId() == category.getId()}"
|
||||
th:value="${category.getId()}" th:text="${category.getCategory()}">
|
||||
@@ -50,7 +50,7 @@
|
||||
<p>论坛详情</p>
|
||||
<div id="blog-content">
|
||||
<div id="editor-toolbar"></div>
|
||||
<div id="editor-text-area" style="height: 400px;border: 1px solid lightgrey"></div>
|
||||
<div id="editor-text-area" style="height: 600px;border: 1px solid lightgrey"></div>
|
||||
<textarea id="content-textarea" name="content" th:text="${blog.getContent()}" style="display: none;"></textarea>
|
||||
<textarea id="contentText-textarea" name="contentJson" style="display: none;"></textarea>
|
||||
</div>
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-lg btn-block" onclick="this.disabled=true; this.form.submit();" type="submit">提交修改</button>
|
||||
<button class="btn btn-primary btn-lg btn-block" onclick="talkWith()" type="submit">提交修改</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,7 +76,32 @@
|
||||
|
||||
<script th:src="@{/wangedit/js/wang.min.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.init.js}"></script>
|
||||
<script th:src="@{/layer/layer.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script th:src="@{/js/axios.js}"></script>
|
||||
<script type="text/javascript">
|
||||
function talkWith(){
|
||||
var title = $('#title').val();
|
||||
var content = $('#content-textarea').val();
|
||||
var categoryId = $('#categoryId').val();
|
||||
if (!title){
|
||||
layer.open({ content: '请输入标题', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if(title.length>30){
|
||||
layer.open({ content: '标题过长', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (!categoryId){
|
||||
layer.open({ content: '请选择博客分类', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (content.length < 30){
|
||||
layer.open({ content: '内容过短!请多表达一点思想吧?', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
this.disabled = true;
|
||||
this.submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
[[${blog.getViews()}]]
|
||||
</span>
|
||||
<!-- 自己写的文章可以编辑和删除 -->
|
||||
<a th:if="${session.loginUser.getUid()==blog.getAuthorId()}"
|
||||
<a th:if="@{${session.loginUser} ? ${session.loginUser.getUid()==blog.getAuthorId()} : false}"
|
||||
class="float-right text-decoration-none" style="color: red"
|
||||
th:href="@{'/blog/delete/'+${blog.getBid()}}"
|
||||
onclick="if(!confirm('你确认要删除吗?')) return false;">
|
||||
@@ -49,7 +49,7 @@
|
||||
</svg>
|
||||
删除
|
||||
</a>
|
||||
<a th:if="${session.loginUser.getUid()==blog.getAuthorId()}"
|
||||
<a th:if="@{${session.loginUser} ? ${session.loginUser.getUid()==blog.getAuthorId()} : false}"
|
||||
class="float-right mr-3 text-decoration-none"
|
||||
th:href="@{'/blog/editor/'+${blog.getBid()}}">
|
||||
<svg class="bi bi-pencil-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -58,7 +58,7 @@
|
||||
</svg>
|
||||
编辑
|
||||
</a>
|
||||
<span class="float-right" th:if="${session.loginUser.getUid()!=blog.getAuthorId()}">
|
||||
<span class="float-right" th:if="@{${session.loginUser} ? ${session.loginUser.getUid()!=blog.getAuthorId()} : false}">
|
||||
<a class="text-danger text-decoration-none" th:fragment="star_refresh" th:id="id_star_refresh"
|
||||
href="javascript:starFun(this);">
|
||||
<svg th:if="${starValue.isStar() == true}" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16">
|
||||
@@ -76,7 +76,7 @@
|
||||
<hr style="margin-top: 18px">
|
||||
|
||||
<!--文章主体内容-->
|
||||
<div id="editor-text-area" style="height: 400px"></div>
|
||||
<div id="editor-text-area" style="height: 600px"></div>
|
||||
<textarea id="content-textarea" th:text="${blog.getContent()}" name="content" style="display: none;"></textarea>
|
||||
|
||||
</div>
|
||||
@@ -87,14 +87,13 @@
|
||||
|
||||
<div class="col-md-12 blog-main" style="margin-top: 20px">
|
||||
<form th:action="@{'/blog/comment/'+${blog.getBid()}}" method="post">
|
||||
<input type="hidden" id="userId" name="userId" th:value="${session.loginUser.getUid()}">
|
||||
<input type="hidden" name="userName" th:value="${session.loginUser.getUsername()}">
|
||||
<input type="hidden" name="userAvatar" th:value="${session.loginUser.getAvatar()}">
|
||||
<input type="hidden" id="userId" name="userId" th:value="@{${session.loginUser} ? ${session.loginUser.getUid()} : ''}">
|
||||
<input type="hidden" name="userName" th:value="@{${session.loginUser} ? ${session.loginUser.getUsername()} : ''}">
|
||||
<input type="hidden" id="topicId" name="topicId" th:value="${blog.getBid()}">
|
||||
<div class="form-group">
|
||||
<input name="content" class="form-control" rows="3" required />
|
||||
<input id="commentTo" name="content" class="form-control" rows="3" required/>
|
||||
</div>
|
||||
<button type="submit" onclick="this.disabled=true; this.form.submit();" class="btn btn-primary float-right">提交评论</button>
|
||||
<button type="submit" onclick="comment()" class="btn btn-primary float-right">提交评论</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -132,6 +131,7 @@
|
||||
<script th:src="@{/live/js/addlive2d.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.min.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.read.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script type="text/javascript">
|
||||
function starFun(btn){
|
||||
btn.disabled = true;
|
||||
@@ -147,6 +147,15 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
function comment(){
|
||||
var content = $('#commentTo').val();
|
||||
console.log(content);
|
||||
if (!content){
|
||||
layer.open({ content: '评论内容不能为空', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
this.submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -31,17 +31,15 @@
|
||||
<!-- 隐藏域 -->
|
||||
<input type="hidden" name="authorId" th:value="${session.loginUser.getUid()}">
|
||||
<input type="hidden" name="authorName" th:value="${session.loginUser.getUsername()}">
|
||||
<input type="hidden" name="authorAvatar" th:value="${session.loginUser.getAvatar()}">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 mb-3">
|
||||
<label for="firstName">文章标题</label>
|
||||
<input type="text" name="title" class="form-control" id="firstName" value="" required>
|
||||
<label for="title">文章标题</label>
|
||||
<input type="text" name="title" maxlength="30" class="form-control" id="title" placeholder="请输入标题" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2 mb-3">
|
||||
<label for="country">文章标签</label>
|
||||
<select name="categoryId" class="custom-select d-block w-100" id="country">
|
||||
<label for="categoryId">文章标签</label>
|
||||
<select name="categoryId" class="custom-select d-block w-100" id="categoryId" required>
|
||||
<option th:each="category:${categoryList}"
|
||||
th:value="${category.getId()}" th:text="${category.getCategory()}">
|
||||
</option>
|
||||
@@ -52,7 +50,7 @@
|
||||
<p>文章内容</p>
|
||||
<div id="blog-content">
|
||||
<div id="editor-toolbar"></div>
|
||||
<div id="editor-text-area" style="height: 400px;border: 1px solid lightgrey"></div>
|
||||
<div id="editor-text-area" style="height: 600px;border: 1px solid lightgrey"></div>
|
||||
<textarea id="content-textarea" name="content" style="display: none;"></textarea>
|
||||
<textarea id="contentText-textarea" name="contentJson" style="display: none;"></textarea>
|
||||
</div>
|
||||
@@ -60,7 +58,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-lg btn-block" type="submit" onclick="this.disabled=true; this.form.submit();" >发布文章</button>
|
||||
<button class="btn btn-primary btn-lg btn-block" type="submit" onclick="talkWith()" >发布文章</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,8 +75,31 @@
|
||||
|
||||
<script th:src="@{/wangedit/js/wang.min.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.init.js}"></script>
|
||||
<script th:src="@{/layer/layer.js}"></script>
|
||||
<script th:src="@{/js/axios.js}"></script>
|
||||
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script type="text/javascript">
|
||||
function talkWith(){
|
||||
var title = $('#title').val();
|
||||
var content = $('#content-textarea').val();
|
||||
var categoryId = $('#categoryId').val();
|
||||
if (!title){
|
||||
layer.open({ content: '请输入标题', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if(title.length>30){
|
||||
layer.open({ content: '标题过长', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (!categoryId){
|
||||
layer.open({ content: '请选择博客分类', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (content.length < 30){
|
||||
layer.open({ content: '内容过短!请多表达一点思想吧?', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
this.disabled = true;
|
||||
this.submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
<!--如果未登录-->
|
||||
<div>
|
||||
<form th:action="@{/search}" method="get">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<ul class="navbar-nav mr-2">
|
||||
<li>
|
||||
<input name="findWhat" type="text" placeholder="大佬想找什么呢?"/>
|
||||
<input class="mr-2" name="findWhat" type="text" placeholder="大佬想找什么呢?"/>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" class="btn btn-sm btn-primary mr-2">
|
||||
|
||||
36
src/main/resources/templates/forget.html
Normal file
36
src/main/resources/templates/forget.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!doctype html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>注册-Quinn</title>
|
||||
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}">
|
||||
<link rel="stylesheet" th:href="@{/css/backgroud.css}">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-4" >
|
||||
</div>
|
||||
<div class="col-md-4 mt-5" id='login_box'>
|
||||
<form id="registerForm" class="form-horizontal was-validated" method="post" noValidate>
|
||||
<div class="justify-content-center">
|
||||
<h1>联系我们<small style="font-size: small">Quinn</small></h1>
|
||||
<p th:text="${loginMsg}"></p>
|
||||
</div>
|
||||
<p class="mt-1 clearfix">
|
||||
<a style="color: white" th:href="@{/toLogin}" class="float-right text-decoration-none">我记得密码!去登录</a>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script th:src="@{/js/jquery-3.5.1.min.js}"></script>
|
||||
<script th:src="@{/bootstrap/js/bootstrap.bundle.min.js}"></script>
|
||||
<script th:src="@{/js/jquery-ui.min.js}"></script>
|
||||
<script th:src="@{/live/js/addlive2d.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,7 +5,6 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>登录-Quinn</title>
|
||||
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}">
|
||||
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrapValidator.css}">
|
||||
<link rel="stylesheet" th:href="@{/css/backgroud.css}">
|
||||
</head>
|
||||
<body class="text-center">
|
||||
@@ -14,25 +13,24 @@
|
||||
<div class="col-md-4" >
|
||||
</div>
|
||||
<div class="col-md-4 mt-5" id='login_box'>
|
||||
<form class="form-horizontal" method="post" th:action="@{/login}">
|
||||
<form class="form-horizontal" method="post" th:action="@{/login}" novalidate>
|
||||
<div class="justify-content-center">
|
||||
<h1 class="d-block">登录<small style="font-size: small">Quinn</small></h1>
|
||||
<p class="d-block" th:text="${registerMsg}" style="color: red"></p>
|
||||
<h1>登录<small style="font-size: small">Quinn</small></h1>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="username">用户名</label>
|
||||
<input id="username" name="username" class="form-control" placeholder="用户名" required="">
|
||||
<input id="username" name="username" class="form-control" placeholder="用户名" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">密码</label>
|
||||
<input id="password" type="password" name="password" class="form-control" placeholder="密码">
|
||||
<input id="password" type="password" name="password" class="form-control" placeholder="密码" required>
|
||||
</div>
|
||||
<div class="checkbox float-left mb-3">
|
||||
<label>
|
||||
<input type="checkbox" name="remember" value="remember-me"> 记住密码
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-dark btn-block" type="submit" onclick="this.disabled=true; this.form.submit();">登 录</button>
|
||||
<button class="btn btn-dark btn-block" type="submit" onclick="loginSubmit()">登 录</button>
|
||||
<p class="mt-1 clearfix">
|
||||
<a style="color: white" th:href="@{/register}" class="float-right text-decoration-none">没有账号?去注册</a>
|
||||
</p>
|
||||
@@ -46,6 +44,21 @@
|
||||
<script th:src="@{/bootstrap/js/bootstrap.bundle.min.js}"></script>
|
||||
<script th:src="@{/js/jquery-ui.min.js}"></script>
|
||||
<script th:src="@{/live/js/addlive2d.js}"></script>
|
||||
<script th:src="@{/bootstrap/js/bootstrapValidator.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script type="text/javascript">
|
||||
function loginSubmit(){
|
||||
let username = $('#username').val();
|
||||
let password = $('#password').val();
|
||||
if (!username){
|
||||
layer.open({ content: '用户名不能为空', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (!password){
|
||||
layer.open({ content: '密码不能为空', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
this.submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<script th:src="@{/js/jquery-ui.min.js}"></script>
|
||||
<script th:src="@{/live/js/addlive2d.js}"></script>
|
||||
<!-- layer 赞赏码 -->
|
||||
<script th:src="@{/layer/layer.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script th:src="@{/js/axios.js}"></script>
|
||||
<script type="text/javascript">
|
||||
// 后台读取
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>注册-Quinn</title>
|
||||
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}">
|
||||
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrapValidator.css}">
|
||||
<link rel="stylesheet" th:href="@{/css/backgroud.css}">
|
||||
</head>
|
||||
<body>
|
||||
@@ -14,32 +13,32 @@
|
||||
<div class="col-md-4" >
|
||||
</div>
|
||||
<div class="col-md-4 mt-5" id='login_box'>
|
||||
<form id="registerForm" class="form-horizontal" method="post" action="#">
|
||||
<form id="registerForm" class="form-horizontal was-validated" method="post" noValidate>
|
||||
<div class="justify-content-center">
|
||||
<h1 class="d-block">注册<small style="font-size: small">Quinn</small></h1>
|
||||
<p class="d-block" th:text="${registerMsg}" style="color: red"></p>
|
||||
<h1>注册<small style="font-size: small">Quinn</small></h1>
|
||||
<p th:text="${registerMsg}" style="color: red"></p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="username">用户名</label>
|
||||
<input id="username" type="text" name="username" class="form-control" placeholder="用户名">
|
||||
<input id="username" type="text" name="username" class="form-control" placeholder="用户名" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">密码</label>
|
||||
<input id="password" type="password" name="password" class="form-control" placeholder="密码">
|
||||
<input id="password" type="password" name="password" class="form-control" placeholder="密码" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="repassword">确认密码</label>
|
||||
<input id="repassword" type="password" name="repassword" class="form-control" placeholder="确认密码">
|
||||
<input id="repassword" type="password" name="repassword" class="form-control" placeholder="确认密码" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email">email</label>
|
||||
<input id="email" type="text" name="email" class="form-control" placeholder="邮箱">
|
||||
<input id="email" type="text" name="email" class="form-control" placeholder="邮箱" pattern="^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="code">邀请码</label>
|
||||
<input id="code" type="text" name="code" class="form-control" placeholder="邀请码">
|
||||
<input id="code" type="text" name="code" class="form-control" placeholder="邀请码" required>
|
||||
</div>
|
||||
<button class="btn btn-dark btn-block" type="submit" onclick="this.disabled=true; this.form.submit();">注 册</button>
|
||||
<button class="btn btn-dark btn-block" type="button" onclick="javascript:registerSubmit();">注 册</button>
|
||||
<p class="mt-1 clearfix">
|
||||
<a style="color: white" th:href="@{/toLogin}" class="float-right text-decoration-none">已有账号?去登录</a>
|
||||
</p>
|
||||
@@ -53,69 +52,52 @@
|
||||
<script th:src="@{/bootstrap/js/bootstrap.bundle.min.js}"></script>
|
||||
<script th:src="@{/js/jquery-ui.min.js}"></script>
|
||||
<script th:src="@{/live/js/addlive2d.js}"></script>
|
||||
<script th:src="@{/bootstrap/js/bootstrapValidator.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$('#registerForm').bootstrapValidator({
|
||||
message: 'This value is not valid',
|
||||
feedbackIcons: {
|
||||
valid: 'glyphicon glyphicon-ok',
|
||||
invalid: 'glyphicon glyphicon-remove',
|
||||
validating: 'glyphicon glyphicon-refresh'
|
||||
function registerSubmit(){
|
||||
let username = $('#username').val();
|
||||
let password = $('#password').val();
|
||||
let repassword = $('#repassword').val();
|
||||
let email = $('#email').val();
|
||||
let code = $('#code').val();
|
||||
if (!username){
|
||||
layer.open({ content: '用户名不能为空', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (!password){
|
||||
layer.open({ content: '密码不能为空', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (!code){
|
||||
layer.open({ content: '注册码不能为空!', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
var reEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/;
|
||||
if (!reEmail.test(email)){
|
||||
layer.open({ content: '邮箱格式不正确!', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (repassword != password){
|
||||
layer.open({ content: '两次输入密码不一致', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
if (!code || code.length != 6){
|
||||
layer.open({ content: '注册码格式不正确', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: "/register",
|
||||
async: false,
|
||||
type: "post",
|
||||
data: {"username":username,"password":password,"repassword":repassword,"email":email,"code":code},
|
||||
success: function (data) {
|
||||
layer.open({ content: data, skin: 'msg', time: 2 });
|
||||
},
|
||||
fields: {
|
||||
username: {
|
||||
message: 'The username is not valid',
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'The username is required and can\'t be empty'
|
||||
},
|
||||
stringLength: {
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: 'The username must be more than 6 and less than 30 characters long'
|
||||
},
|
||||
regexp: {
|
||||
regexp: /^[a-zA-Z0-9_\.]+$/,
|
||||
message: 'The username can only consist of alphabetical, number, dot and underscore'
|
||||
}
|
||||
}
|
||||
},
|
||||
email: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'The email address is required and can\'t be empty'
|
||||
},
|
||||
emailAddress: {
|
||||
message: 'The input is not a valid email address'
|
||||
}
|
||||
}
|
||||
},
|
||||
password: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'The password is required and can\'t be empty'
|
||||
}
|
||||
}
|
||||
}
|
||||
fail: function (error){
|
||||
layer.open({ content: error, skin: 'msg', time: 2 });
|
||||
}
|
||||
}).on('success.form.bv', function(e) {
|
||||
alert(e);
|
||||
// Prevent form submission
|
||||
e.preventDefault();
|
||||
|
||||
// Get the form instance
|
||||
var $form = $(e.target);
|
||||
|
||||
// Get the BootstrapValidator instance
|
||||
var bv = $form.data('bootstrapValidator');
|
||||
|
||||
// Use Ajax to submit form data
|
||||
$.post($form.attr('action'), $form.serialize(), function(result) {
|
||||
console.log(result);
|
||||
}, 'json');
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
<hr/>
|
||||
<div id="blog-content">
|
||||
<div id="editor-toolbar"></div>
|
||||
<div id="editor-text-area" style="height: 400px;border: 1px solid lightgrey"></div>
|
||||
<div id="editor-text-area" style="height: 600px;border: 1px solid lightgrey"></div>
|
||||
<textarea id="content-textarea" name="sourceContent" style="display: none;" th:text="${source.getSourceContent()}"></textarea>
|
||||
<textarea id="contentText-textarea" name="contentJson" style="display: none;"></textarea>
|
||||
</div>
|
||||
@@ -103,8 +103,7 @@
|
||||
|
||||
<script th:src="@{/wangedit/js/wang.min.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.init.js}"></script>
|
||||
<script th:src="@{/layer/layer.js}"></script>
|
||||
<script th:src="@{/js/axios.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {// 初始化内容
|
||||
const jSourceType = $('#sourceType').val();
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<hr/>
|
||||
<div id="blog-content">
|
||||
<div id="editor-toolbar"></div>
|
||||
<div id="editor-text-area" style="height: 400px;border: 1px solid lightgrey"></div>
|
||||
<div id="editor-text-area" style="height: 600px;border: 1px solid lightgrey"></div>
|
||||
<textarea id="content-textarea" name="content" style="display: none;"></textarea>
|
||||
<textarea id="contentText-textarea" name="contentJson" style="display: none;"></textarea>
|
||||
</div>
|
||||
@@ -95,8 +95,7 @@
|
||||
|
||||
<script th:src="@{/wangedit/js/wang.min.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.init.js}"></script>
|
||||
<script th:src="@{/layer/layer.js}"></script>
|
||||
<script th:src="@{/js/axios.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script type="text/javascript">
|
||||
$("#sourceType").change(function(){
|
||||
const jSourceType = $('#sourceType').val();
|
||||
|
||||
@@ -16,27 +16,27 @@
|
||||
<main role="main" class="container mt-3 p-3 bg-white rounded">
|
||||
<div class="row">
|
||||
<div class="col-md-12 source-main">
|
||||
|
||||
<div class="source-post">
|
||||
<h2 class="source-post-title" th:text="${source.getSourceName()}"></h2>
|
||||
<p class="source-post-meta">
|
||||
<span class="badge-pill badge-primary" th:text="${source.getCategoryName()}">
|
||||
</span>
|
||||
<span th:text="${#dates.format(source.getGmtUpdate(),'yyyy-MM-dd HH:mm:ss')}"></span>
|
||||
<span class="ml-1">
|
||||
<a class="text-danger text-decoration-none" th:fragment="star_refresh" th:id="id_star_refresh"
|
||||
href="javascript:starFun(this);">
|
||||
<svg th:if="${starValue.isStar() == true}" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
|
||||
</svg>
|
||||
<svg th:if="${starValue.isStar() != true}" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16">
|
||||
<path d="m8 2.748-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/>
|
||||
</svg>
|
||||
[[${starValue.getTotal()}]]
|
||||
</a>
|
||||
</span>
|
||||
<a href="javascript:downloadFile(this);" class="btn btn-outline-success col-md-2 float-right">下载</a>
|
||||
</p>
|
||||
<div class="source-post row">
|
||||
<h2 class="source-post-title col-md-12" th:text="${source.getSourceName()}"></h2>
|
||||
<p class="source-post-meta col-md-9">
|
||||
<span class="badge-pill badge-primary" th:text="${source.getCategoryName()}">
|
||||
</span>
|
||||
<span th:text="${#dates.format(source.getGmtUpdate(),'yyyy-MM-dd HH:mm:ss')}"></span>
|
||||
<span class="ml-1">
|
||||
<a th:if="${session.loginUser}" class="text-danger text-decoration-none" th:fragment="star_refresh" th:id="id_star_refresh"
|
||||
href="javascript:starFun(this);">
|
||||
<svg th:if="${starValue.isStar() == true}" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
|
||||
</svg>
|
||||
<svg th:if="${starValue.isStar() != true}" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16">
|
||||
<path d="m8 2.748-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/>
|
||||
</svg>
|
||||
[[${starValue.getTotal()}]]
|
||||
</a>
|
||||
</span>
|
||||
</p>
|
||||
<a th:if="${session.loginUser}" href="javascript:downloadFile();"class="btn btn-outline-success col-md-2">下载</a>
|
||||
<button th:if="!${session.loginUser}" disabled class="btn btn-outline-dark col-md-2">请登录后下载</button>
|
||||
</div>
|
||||
<div style="display: none">
|
||||
<form th:action="@{'/source/download/'+${source.getSid()}}" method="post">
|
||||
@@ -47,7 +47,7 @@
|
||||
<hr style="margin-top: 18px">
|
||||
|
||||
<!--文章主体内容-->
|
||||
<div id="editor-text-area" style="height: 400px"></div>
|
||||
<div id="editor-text-area" style="height: 600px"></div>
|
||||
<textarea id="content-textarea" th:text="${source.getSourceContent()}" name="content" style="display: none;"></textarea>
|
||||
|
||||
</div>
|
||||
@@ -58,21 +58,19 @@
|
||||
|
||||
<div class="col-md-12 source-main" style="margin-top: 20px">
|
||||
<form th:action="@{'/source/comment/'+${source.getSid()}}" method="post">
|
||||
<input type="hidden" id="userId" name="userId" th:value="${session.loginUser.getUid()}">
|
||||
<input type="hidden" name="userName" th:value="${session.loginUser.getUsername()}">
|
||||
<input type="hidden" name="userAvatar" th:value="${session.loginUser.getAvatar()}">
|
||||
<input type="hidden" id="userId" name="userId" th:value="@{${session.loginUser} ? ${session.loginUser.getUid()} : ''}">
|
||||
<input type="hidden" name="userName" th:value="@{${session.loginUser} ? ${session.loginUser.getUsername()} : ''}">
|
||||
<input type="hidden" id="topicId" name="topicId" th:value="${source.getSid()}">
|
||||
<div class="form-group">
|
||||
<input name="content" class="form-control" rows="3" required />
|
||||
<input id="content" name="content" class="form-control" rows="3" required/>
|
||||
</div>
|
||||
<button type="submit" onclick="this.disabled=true; this.form.submit();" class="btn btn-primary float-right">提交评论</button>
|
||||
<button type="submit" onclick="comment()" class="btn btn-primary float-right">提交评论</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div th:if="${commentList.size()!=0}" class="col-md-12 source-main" style="margin-top: 20px">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">评论列表</h6>
|
||||
|
||||
<div th:each="comment:${commentList}" class="media text-muted pt-3">
|
||||
<img th:src="${comment.getAvatar()}" style="border-radius: 5px;margin-right: 5px " width="32" height="32">
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
@@ -103,12 +101,18 @@
|
||||
<script th:src="@{/live/js/addlive2d.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.min.js}"></script>
|
||||
<script th:src="@{/wangedit/js/wang.read.js}"></script>
|
||||
<script th:src="@{/layer/mobile/layer.js}"></script>
|
||||
<script type="text/javascript">
|
||||
function downloadFile(btn){
|
||||
btn.disabled=true;
|
||||
function downloadFile(){
|
||||
if ($('#userId').val()==''){
|
||||
layer.open({ content: '请登录之后下载', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
this.disabled=true;
|
||||
var sid = $('#topicId').val();
|
||||
var sourceDType = $('#sourceDType').val();
|
||||
if (sourceDType == 'OSS'){
|
||||
this.disabled=false;
|
||||
$('#downloadTrans').click();
|
||||
}else {
|
||||
$.ajax({
|
||||
@@ -117,7 +121,12 @@
|
||||
type: "post",
|
||||
data: '',
|
||||
success: function (res) {
|
||||
window.open(res);
|
||||
this.disabled=false;
|
||||
if (res.substr(0,4)!= 'http'){
|
||||
$('#downloadTrans').click();
|
||||
}else {
|
||||
window.open(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -133,11 +142,20 @@
|
||||
async: false,
|
||||
data: {"userId": userId, "topicId": topicId},
|
||||
success: function (data) {
|
||||
console.log(data);
|
||||
$('#id_star_refresh').html(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function comment(){
|
||||
let content = $('#content').val();
|
||||
if (!content){
|
||||
layer.open({ content: '评论内容不能为空', skin: 'msg', time: 2 });
|
||||
return;
|
||||
}
|
||||
this.submit();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user