全局搜索,我们把全局搜索提供,需要博客和资源修改新增的时候同步Context的文本

This commit is contained in:
limqhz
2022-05-11 01:40:57 +08:00
parent 759843e83d
commit 03d805641a
49 changed files with 508 additions and 702 deletions

View File

@@ -0,0 +1,8 @@
package com.quinn.common;
import lombok.Data;
@Data
public class EditText {
String text;
}

View File

@@ -18,17 +18,12 @@ public interface QuinnConstant {
* 登录超时时间
*/
int SESSION_TIME_OUT = 30 * 60;
String SESSION_LOCK = "LOCK";
String SOURCE_KEY = "SOURCE_KEY_";
/**
* SESSION_ID
*/
String SESSION_ID = "SESSION_ID_";
/**
* PASSWORD //TODO 可以配置数据库MD5加密
*/
String SOURCE_PASSWORD = "926462";
String APPEND_PASSWORD = "wangna&limengqi";

View File

@@ -1,16 +1,49 @@
package com.quinn.common;
import org.springframework.util.StringUtils;
/**
* 排名不分先后,篮球迷勿喷
*/
public enum RoleType {
/**
* 管理员
*/
ADMIN,
/**
* 普通用户
*/
NORMAL,
ADMIN("KOBE"),
/**
* VIP
*/
VIP
VIP("VIP"),
/**
* 普通用户
*/
NORMAL("NORMAL");
String name;
RoleType(String name) {
this.name = name;
}
public String getName() {
return name;
}
/**
* 数据库存的权限是 KOBE VIP NORMAL
* @param name
* @return
*/
public static RoleType parse(String name){
if (StringUtils.isEmpty(name)){
if (ADMIN.getName().equals(name)){
return RoleType.ADMIN;
}
if (VIP.getName().equals(name)){
return RoleType.VIP;
}
}
return RoleType.NORMAL;
}
}

View File

@@ -0,0 +1,14 @@
package com.quinn.common;
import lombok.Data;
import java.util.List;
@Data
public class WangEdit {
String type;
List<EditText> children;
}

View File

@@ -4,6 +4,7 @@ import com.quinn.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;
@@ -11,6 +12,7 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired

View File

@@ -3,18 +3,15 @@ package com.quinn.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.quinn.common.RoleType;
import com.quinn.pojo.About;
import com.quinn.pojo.User;
import com.quinn.service.AboutService;
import com.quinn.service.UserService;
import com.quinn.utils.QuinnUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.management.relation.Role;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@@ -31,9 +28,6 @@ public class AboutController extends BaseModelController {
@Resource
AboutService aboutService;
@Resource
UserService userService;
@GetMapping("/about")
public String userIndexBlog(HttpServletRequest request,Model model){
@@ -48,13 +42,8 @@ public class AboutController extends BaseModelController {
}
@PostMapping("/about")
public String saveSay(HttpServletRequest request, About about){
String loginUserId = getLoginUserId(request);
User user = userService.getOne(new QueryWrapper<User>().eq("uid", loginUserId));
// 防止请求提交
if (!RoleType.ADMIN.name().equals(user)){
return "redirect:/about";
}
@PreAuthorize("hasAuthority('ADMIN')")
public String saveSay(About about){
about.setId(QuinnUtils.getUuid());
about.setGmtCreate(QuinnUtils.getTime());
// 结果
@@ -62,6 +51,5 @@ public class AboutController extends BaseModelController {
return "redirect:/about";
}
}

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.quinn.common.Category;
import com.quinn.pojo.*;
import com.quinn.service.*;
import com.quinn.utils.ContentUtil;
import com.quinn.utils.QuinnUtils;
import com.quinn.vo.*;
import org.slf4j.Logger;
@@ -98,6 +99,10 @@ public class BlogController extends BaseModelController{
blog.setBid(QuinnUtils.getUuid());
blog.setTitle(questionWriteForm.getTitle());
blog.setContent(questionWriteForm.getContent());
String s = ContentUtil.toTextContentFromWangEdit(questionWriteForm.getContentJson());
blog.setContentJson(s);
blog.setSort(0);
blog.setViews(0);
@@ -165,6 +170,8 @@ public class BlogController extends BaseModelController{
queryBlog.setTitle(blog.getTitle());
queryBlog.setCategoryId(blog.getCategoryId());
queryBlog.setContent(blog.getContent());
String s = ContentUtil.toTextContentFromWangEdit(blog.getContentJson());
queryBlog.setContentJson(s);
queryBlog.setGmtUpdate(QuinnUtils.getTime());
blogService.updateById(queryBlog);

View File

@@ -2,6 +2,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.pojo.Invite;
import com.quinn.pojo.User;
import com.quinn.pojo.UserInfo;
@@ -78,10 +79,11 @@ public class LoginController {
// 构建用户对象
User user = new User();
user.setUid(QuinnUtils.getUuid()); // 用户唯一id
user.setRoleId(RoleType.NORMAL.name());
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());

View File

@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import javax.annotation.Resource;
@@ -36,29 +37,42 @@ public class SearchController {
CommentService commentService;
@Resource
SourceCategoryService sourceCategoryService;
@Resource
FindService findService;
@PostMapping("/search")
@GetMapping("/search")
public String searchAll(String findWhat,Model model){
/**
* 为空返回主页
*/
if (StringUtils.isEmpty(findWhat)){
return "index";
}
/**
* 新增资源
*/
if (QuinnConstant.NEW_SOURCE_PASSWORD.equals(findWhat)){
List<SourceCategory> categoryList = sourceCategoryService.list(null);
model.addAttribute("categoryList",categoryList);
return "source/uploadSource";
}
/**
* 新增公告
*/
if (QuinnConstant.APPEND_PASSWORD.equals(findWhat)){
return "page/append";
}
/**
* 修改资源
*/
if (findWhat.startsWith(QuinnConstant.EDIT_SOURCE_FIRST)){
findWhat = findWhat.substring(findWhat.indexOf(QuinnConstant.EDIT_SOURCE_FIRST) + QuinnConstant.EDIT_SOURCE_FIRST.length());
if (!StringUtils.isEmpty(findWhat) && findWhat.endsWith(QuinnConstant.EDIT_SOURCE_LAST)){
findWhat = findWhat.substring(0,findWhat.lastIndexOf(QuinnConstant.EDIT_SOURCE_LAST));
String modifyWhat = findWhat.substring(findWhat.indexOf(QuinnConstant.EDIT_SOURCE_FIRST) + QuinnConstant.EDIT_SOURCE_FIRST.length());
if (!StringUtils.isEmpty(modifyWhat) && modifyWhat.endsWith(QuinnConstant.EDIT_SOURCE_LAST)){
modifyWhat = modifyWhat.substring(0,modifyWhat.lastIndexOf(QuinnConstant.EDIT_SOURCE_LAST));
}
if (!StringUtils.isEmpty(findWhat)){
Source source = sourceService.getOne(new QueryWrapper<Source>().eq("sid", findWhat));
Source source = sourceService.getOne(new QueryWrapper<Source>().eq("sid", modifyWhat));
if (source!=null){
source.setKeyWord1(concatKeyWord(source.getKeyWord2()) + concatKeyWord(source.getKeyWord2()) + concatKeyWord(source.getKeyWord3()));
model.addAttribute("source",source);
// 分类信息
List<SourceCategory> categoryList = sourceCategoryService.list(null);
@@ -67,28 +81,20 @@ public class SearchController {
}
}
}
//TODO
/**
* 正式开始,全局搜索
*/
MyPageParam myPageParam = new MyPageParam(1, 10);
List<BlogWithUser> blogList = blogService.getBlogWithUserOrderBySort(myPageParam);
List<FindResult> findList = findService.listFinds(findWhat, myPageParam);
model.addAttribute("findWhat",findWhat);
// 结果
model.addAttribute("blogList",blogList);
model.addAttribute("findList",findList);
model.addAttribute("pageParam",myPageParam);
List<Blog> topBlogList = blogService.getTopBlog();
model.addAttribute("topBlogList",topBlogList);
// 分类信息
List<BlogCategory> categoryList = blogCategoryService.list(null);
model.addAttribute("categoryList",categoryList);
return "page/allsearch";
}
private String concatKeyWord(String keyWord) {
if (!StringUtils.isEmpty(keyWord)) {
return keyWord + QuinnConstant.LINK_KEY_WORD;
}
return "";
}
}

View File

@@ -91,9 +91,6 @@ public class SourceController extends BaseModelController {
if (!CollectionUtils.isEmpty(sourceList)){
sourceList.forEach(x ->{
x.setSourceLink(QuinnConstant.GUN);
x.setKeyWord1(QuinnConstant.GUN);
x.setKeyWord2(QuinnConstant.GUN);
x.setKeyWord3(QuinnConstant.GUN);
x.setSourceContent(QuinnConstant.GUN);
});
}
@@ -114,9 +111,6 @@ public class SourceController extends BaseModelController {
Source source = sourceService.view(sid,sessionId);
if(source != null){
source.setSourceLink(QuinnConstant.GUN);
source.setKeyWord1(QuinnConstant.GUN);
source.setKeyWord2(QuinnConstant.GUN);
source.setKeyWord3(QuinnConstant.GUN);
}
model.addAttribute("source",source);

View File

@@ -1,20 +1,17 @@
package com.quinn.controller;
import com.quinn.common.QuinnConstant;
import com.quinn.service.SourceCategoryService;
import com.quinn.service.SourceService;
import com.quinn.vo.SourceDeleteForm;
import com.quinn.vo.SourceUpdateForm;
import com.quinn.vo.SourceWriteForm;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
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.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* <p>
@@ -25,49 +22,32 @@ import java.io.PrintWriter;
* @since 2022-05-03
*/
@Controller
@PreAuthorize("hasAuthority('ADMIN')")
public class SourceUploadController {
@Resource
SourceCategoryService sourceCategoryService;
@Resource
SourceService sourceService;
@PostMapping("/tracy/mcgrady/lmq/love/wn")
@PostMapping("/source/oper")
public synchronized String write(MultipartFile file, SourceWriteForm sourceWriteForm) throws IOException {
if (!QuinnConstant.SOURCE_PASSWORD.equals(sourceWriteForm.getUploadPassWord())){
return "error/check";
}
sourceService.uploadNewSource(file,sourceWriteForm);
// 重定向到列表页面
return "redirect:/source";
}
// 编辑信息
@PostMapping("/tracy/mcgrady/lmq/love/wn/update")
@PostMapping("/source/oper/update")
public String toEdit(MultipartFile file, SourceUpdateForm sourceUpdateForm) throws IOException {
if (!QuinnConstant.SOURCE_PASSWORD.equals(sourceUpdateForm.getUploadPassWord())){
return "error/check";
}
sourceService.updateSource(file,sourceUpdateForm);
// 重定向详情页面
return "redirect:/source/view/" + sourceUpdateForm.getSid();
}
// 编辑信息
@PostMapping("/tracy/mcgrady/lmq/love/wn/del")
public void toEdit(HttpServletResponse response, SourceDeleteForm sourceDeleteForm) throws IOException {
PrintWriter writer = response.getWriter();
if (!QuinnConstant.SOURCE_PASSWORD.equals(sourceDeleteForm.getUploadPassWord())){
writer.write("/error/check");
writer.flush();
writer.close();
return;
}
sourceService.deleteSource(sourceDeleteForm.getSid());
// 重定向详情页面
writer.write("/source");
writer.flush();
writer.close();
// 删除
@GetMapping("/source/oper/del/{sid}")
public String toDelete(@PathVariable("sid") String sid) {
sourceService.deleteSource(sid);
// 重定向到列表页面
return "redirect:/source";
}
}

View File

@@ -125,7 +125,7 @@ public class UserController extends BaseModelController {
public String userPageStar(UserNavReq navReq,Model model){
// 用户信息回填
userInfoCallBack(navReq.getUserId(),model);
// 用户的论坛列表
// 用户收藏列表
if (navReq.getPageNum() < 1){
navReq.setPageNum(1);
}

View File

@@ -37,7 +37,8 @@ public class UserInfoController extends BaseModelController {
@GetMapping("/userinfo/setting")
public String userSetting(HttpServletRequest request, Model model){
String uid = getLoginUserId(request);
// todo: 可扩展
UserInfo userInfo = userInfoService.getById(uid);
model.addAttribute("userInfo",userInfo);
return "user/settings";
}
@PostMapping("/userinfo/update")

View File

@@ -38,4 +38,10 @@ public enum AttrIcon {
}
return QuinnConstant.DEFAULT_ATTR_BASE64;
}
public static void main(String[] args) {
String limengqi = AttrIcon.INSTANCE.generateImg("limengqi");
System.out.println(limengqi);
}
}

View File

@@ -0,0 +1,22 @@
package com.quinn.mapper;
import com.quinn.pojo.FindResult;
import com.quinn.vo.MyPageParam;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author limqsh
* @since 2022-05-08
*/
public interface FindMapper {
int countListFinds(String findWhat);
List<FindResult> listFinds(String findWhat, MyPageParam myPageParam);
}

View File

@@ -1,5 +0,0 @@
<?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.quinn.mapper.BlogStarMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?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.quinn.mapper.DownloadMapper">
</mapper>

View File

@@ -0,0 +1,30 @@
<?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.quinn.mapper.FindMapper">
<select id="countListFinds" resultType="int">
select count(1) from (
select 1 from qn_source a
where a.source_name like CONCAT('%',#{findWhat},'%')
or a.content_json like CONCAT('%',#{findWhat},'%')
union all
select 1 from qn_blog b
where b.title like CONCAT('%',#{findWhat},'%')
or b.content_json like CONCAT('%',#{findWhat},'%')
) t
</select>
<select id="listFinds" resultType="com.quinn.pojo.FindResult">
select * from (
select a.sid as topicId,'SOURCE' as category,a.gmt_create as gmtCreate,a.source_name as topicName,a.content_json as contentText from qn_source a
where a.source_name like CONCAT('%',#{findWhat},'%')
or a.content_json like CONCAT('%',#{findWhat},'%')
union all
select b.bid as topicId,'BLOG' as category,b.gmt_create as gmtCreate,b.title as topicName,b.content_json as contentText from qn_blog b
where b.title like CONCAT('%',#{findWhat},'%')
or b.content_json like CONCAT('%',#{findWhat},'%')
) t order by gmtCreate
limit #{myPageParam.pageNum},#{myPageParam.size}
</select>
</mapper>

View File

@@ -1,5 +0,0 @@
<?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.quinn.mapper.QuestionCategoryMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?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.quinn.mapper.QuestionMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?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.quinn.mapper.SayMapper">
</mapper>

View File

@@ -41,6 +41,9 @@ public class Blog implements Serializable {
@ApiModelProperty(value = "论坛内容")
private String content;
@ApiModelProperty(value = "文本论坛内容")
private String contentJson;
@ApiModelProperty(value = "排序 0 普通 1 置顶")
private Integer sort;

View File

@@ -0,0 +1,32 @@
package com.quinn.pojo;
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-08
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class FindResult implements Serializable {
private String topicId;
private String category;
private Date gmtCreate;
private String topicName;
private String contentText;
}

View File

@@ -43,14 +43,8 @@ public class Source implements Serializable {
@ApiModelProperty(value = "资源内容")
private String sourceContent;
@ApiModelProperty(value = "关键字1")
private String keyWord1;
@ApiModelProperty(value = "关键字2")
private String keyWord2;
@ApiModelProperty(value = "关键字3")
private String keyWord3;
@ApiModelProperty(value = "文本资源内容")
private String contentJson;
@ApiModelProperty(value = "资源类型")
private String sourceType;

View File

@@ -35,8 +35,8 @@ public class User implements Serializable {
@ApiModelProperty(value = "用户编号")
private String uid;
@ApiModelProperty(value = "角色编号")
private String roleId;
@ApiModelProperty(value = "角色")
private String role;
@ApiModelProperty(value = "用户名")
private String username;

View File

@@ -0,0 +1,20 @@
package com.quinn.service;
import com.quinn.pojo.FindResult;
import com.quinn.vo.MyPageParam;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author limqsh
* @since 2022-05-08
*/
public interface FindService {
List<FindResult> listFinds(String findWhat, MyPageParam myPageParam);
}

View File

@@ -26,9 +26,6 @@ import java.util.List;
*/
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {
@Resource
RedisUtils redisUtils;
@Resource
BlogMapper blogMapper;
@@ -66,12 +63,8 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements Bl
@Override
public void addRecord(Blog blog, String sessionId) {
String value = redisUtils.get(sessionId);
if (StringUtils.isEmpty(value)){
redisUtils.set(sessionId, QuinnConstant.SESSION_LOCK,QuinnConstant.SESSION_TIME_OUT);
blog.setViews(blog.getViews()+1);
updateById(blog);
}
blog.setViews(blog.getViews()+1);
updateById(blog);
}
}

View File

@@ -0,0 +1,36 @@
package com.quinn.service.impl;
import com.quinn.mapper.FindMapper;
import com.quinn.pojo.FindResult;
import com.quinn.service.FindService;
import com.quinn.vo.MyPageParam;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author limqsh
* @since 2022-05-08
*/
@Service
public class FindServiceImpl implements FindService {
@Resource
FindMapper findMapper;
@Override
public List<FindResult> listFinds(String findWhat, MyPageParam myPageParam) {
int total = findMapper.countListFinds(findWhat);
myPageParam.setTotal(total);
if (total > 0){
return findMapper.listFinds(findWhat,myPageParam);
}
return new ArrayList<>();
}
}

View File

@@ -10,6 +10,7 @@ import com.quinn.pojo.SourceCategory;
import com.quinn.pojo.SourceWithStar;
import com.quinn.service.SourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quinn.utils.ContentUtil;
import com.quinn.utils.OSSClientUtil;
import com.quinn.utils.QuinnUtils;
import com.quinn.utils.RedisUtils;
@@ -83,11 +84,7 @@ public class SourceServiceImpl extends ServiceImpl<SourceMapper, Source> impleme
@Override
public Source view(String sid,String sessionId) {
Source source = getOne(new QueryWrapper<Source>().eq("sid", sid));
String value = redisUtils.get(sessionId);
if (StringUtils.isEmpty(value)){
redisUtils.set(sessionId,QuinnConstant.SESSION_LOCK,QuinnConstant.SESSION_TIME_OUT);
addDownLoadRecord(source);
}
addDownLoadRecord(source);
return source;
}
@@ -110,19 +107,8 @@ public class SourceServiceImpl extends ServiceImpl<SourceMapper, Source> impleme
source.setSourceName(sourceWriteForm.getTitle());
source.setDetail(sourceWriteForm.getSubContent());
source.setSourceContent(sourceWriteForm.getContent());
String keyWords = sourceWriteForm.getKeyWords();
if (!StringUtils.isEmpty(keyWords)){
//兼容中英文逗号
keyWords = keyWords.replaceAll("",",");
String[] split = keyWords.split(QuinnConstant.LINK_KEY_WORD);
source.setKeyWord1(split[0]);
if (split.length > 1){
source.setKeyWord2(split[1]);
if (split.length > 2){
source.setKeyWord3(split[2]);
}
}
}
String s = ContentUtil.toTextContentFromWangEdit(sourceWriteForm.getContentJson());
sourceWriteForm.setContentJson(s);
source.setSourceType(sourceWriteForm.getSourceType());
source.setSourceLink(fileLink);
@@ -158,19 +144,8 @@ public class SourceServiceImpl extends ServiceImpl<SourceMapper, Source> impleme
before.setSourceName(sourceUpdateForm.getSourceName());
before.setDetail(sourceUpdateForm.getDetail());
before.setSourceContent(sourceUpdateForm.getSourceContent());
String keyWords = sourceUpdateForm.getKeyWords();
if (!StringUtils.isEmpty(keyWords)){
//兼容中英文逗号
keyWords = keyWords.replaceAll("",",");
String[] split = keyWords.split(QuinnConstant.LINK_KEY_WORD);
before.setKeyWord1(split[0]);
if (split.length > 1){
before.setKeyWord2(split[1]);
if (split.length > 2){
before.setKeyWord3(split[2]);
}
}
}
String s = ContentUtil.toTextContentFromWangEdit(sourceUpdateForm.getContentJson());
before.setContentJson(s);
before.setSourceType(sourceUpdateForm.getSourceType());
before.setSourceLink(fileLink);

View File

@@ -17,7 +17,6 @@ import org.springframework.stereotype.Service;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -28,8 +27,6 @@ import java.util.List;
* @author limqsh
* @since 2020-06-28
*/
// UserDetailsService接口用于返回用户相关数据。
// 它有loadUserByUsername()方法根据username查询用户实体可以实现该接口覆盖该方法实现自定义获取用户过程。
// 该接口实现类被DaoAuthenticationProvider 类使用,用于认证过程中载入用户信息。
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService,UserDetailsService {
@@ -58,10 +55,12 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
session.setMaxInactiveInterval(QuinnConstant.SESSION_TIME_OUT);
//创建一个集合来存放权限
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
RoleType[] values = RoleType.values();
Arrays.stream(values).forEach(x->{
authList.add(new SimpleGrantedAuthority("ROLE_" + x.name()));
});
RoleType roleType = RoleType.parse(user.getRole());
if (roleType == null){
roleType = RoleType.NORMAL;
}
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(roleType.getName());
authList.add(authority);
//实例化UserDetails对象
userDetails=new org.springframework.security.core.userdetails.User(s,password,
true,

View File

@@ -0,0 +1,26 @@
package com.quinn.utils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.quinn.common.EditText;
import com.quinn.common.WangEdit;
import org.springframework.util.CollectionUtils;
import java.util.List;
public interface ContentUtil {
static String toTextContentFromWangEdit(String wangEdit){
List<WangEdit> decode = JsonUtils.decode(wangEdit, new TypeReference<List<WangEdit>>(){});
StringBuffer sb = new StringBuffer();
decode.forEach(x->{
List<EditText> children = x.getChildren();
if (!CollectionUtils.isEmpty(children)){
children.forEach(y ->{
sb.append(y.getText());
});
}
});
return sb.toString();
}
}

View File

@@ -0,0 +1,94 @@
package com.quinn.utils;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* USER: douya
* DATE: 2017-11-01
*/
public class JsonUtils {
/**
* Logger for this class
*/
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
private final static ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
private JsonUtils() {
}
public static String encode(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonGenerationException e) {
logger.error("encode(Object)", e); //$NON-NLS-1$
} catch (JsonMappingException e) {
logger.error("encode(Object)", e); //$NON-NLS-1$
} catch (IOException e) {
logger.error("encode(Object)", e); //$NON-NLS-1$
}
return null;
}
/**
* 将json string反序列化成对象
*
* @param json
* @param valueType
* @return
*/
public static <T> T decode(String json, Class<T> valueType) {
try {
return objectMapper.readValue(json, valueType);
} catch (JsonParseException e) {
logger.error("decode(String, Class<T>)", e);
} catch (JsonMappingException e) {
logger.error("decode(String, Class<T>)", e);
} catch (IOException e) {
logger.error("decode(String, Class<T>)", e);
}
return null;
}
/**
* 将json array反序列化为对象
*
* @param json
* @param typeReference
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T decode(String json, TypeReference<T> typeReference) {
try {
return (T) objectMapper.readValue(json, typeReference);
} catch (JsonParseException e) {
logger.error("decode(String, JsonTypeReference<T>)", e);
} catch (JsonMappingException e) {
logger.error("decode(String, JsonTypeReference<T>)", e);
} catch (IOException e) {
logger.error("decode(String, JsonTypeReference<T>)", e);
}
return null;
}
}

View File

@@ -14,6 +14,8 @@ public class QuestionWriteForm {
private String title;
@ApiModelProperty(value = "内容")
private String content;
@ApiModelProperty(value = "文本内容")
private String contentJson;
@ApiModelProperty(value = "分类")
private Integer categoryId;

View File

@@ -1,27 +0,0 @@
package com.quinn.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author limqsh
* @since 2022-05-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class SourceDeleteForm {
@ApiModelProperty(value = "资源ID")
private String sid;
@ApiModelProperty(value = "管理员密码")
private String uploadPassWord;
}

View File

@@ -30,8 +30,8 @@ public class SourceUpdateForm {
@ApiModelProperty(value = "资源内容")
private String sourceContent;
@ApiModelProperty(value = "关键字")
private String keyWords;
@ApiModelProperty(value = "内容文本")
private String contentJson;
@ApiModelProperty(value = "资源类型")
private String sourceType;
@@ -48,7 +48,4 @@ public class SourceUpdateForm {
@ApiModelProperty(value = "英文名")
private String enName;
@ApiModelProperty(value = "管理员密码")
private String uploadPassWord;
}

View File

@@ -16,10 +16,11 @@ public class SourceWriteForm {
private String subContent;
@ApiModelProperty(value = "内容")
private String content;
@ApiModelProperty(value = "内容文本")
private String contentJson;
@ApiModelProperty(value = "英文名")
private String enName;
@ApiModelProperty(value = "摘要")
private String keyWords;
@ApiModelProperty(value = "分类")
private Integer categoryId;
@@ -29,6 +30,4 @@ public class SourceWriteForm {
@ApiModelProperty(value = "文档路径")
private String sourceLink;
@ApiModelProperty(value = "管理员密码")
private String uploadPassWord;
}

View File

@@ -1,384 +0,0 @@
.message2 {
position: absolute;
top: 10%;
color: #fafafa;
font-size: 30px;
animation: textRotate 0.8s linear 0.5s infinite alternate;
}
.message {
position: absolute;
bottom: 20%;
left: 5%;
color: #fafafa;
font-size: 30px;
animation: textRotate 0.8s linear 0.5s infinite alternate;
}
body {
padding: 0px;
margin: 0px;
border: 0px;
width: 100%;
height: 100%;
}
@keyframes textRotate {
from {
transform-origin: top;
transform: rotateX(-30deg);
}
to {
transform-origin: top;
transform: rotateX(12deg);
}
}
.NotPage {
position: relative;
/*z-index: -10;*/
background: #4d4d4d;
height: 100vh;
overflow: hidden;
display: flex;
font-family: "Anton", sans-serif;
justify-content: center;
align-items: center;
-webkit-perspective: 1000px;
perspective: 1000px;
}
div {
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.rail {
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
-webkit-transform: rotateX(-30deg) rotateY(-30deg);
transform: rotateX(-30deg) rotateY(-30deg);
}
.rail .stamp {
position: absolute;
width: 200px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
background: #141414;
color: #fff;
font-size: 7rem;
}
.rail .stamp:nth-child(1) {
-webkit-animation: stampSlide 40000ms -2300ms linear infinite;
animation: stampSlide 40000ms -2300ms linear infinite;
}
.rail .stamp:nth-child(2) {
-webkit-animation: stampSlide 40000ms -4300ms linear infinite;
animation: stampSlide 40000ms -4300ms linear infinite;
}
.rail .stamp:nth-child(3) {
-webkit-animation: stampSlide 40000ms -6300ms linear infinite;
animation: stampSlide 40000ms -6300ms linear infinite;
}
.rail .stamp:nth-child(4) {
-webkit-animation: stampSlide 40000ms -8300ms linear infinite;
animation: stampSlide 40000ms -8300ms linear infinite;
}
.rail .stamp:nth-child(5) {
-webkit-animation: stampSlide 40000ms -10300ms linear infinite;
animation: stampSlide 40000ms -10300ms linear infinite;
}
.rail .stamp:nth-child(6) {
-webkit-animation: stampSlide 40000ms -12300ms linear infinite;
animation: stampSlide 40000ms -12300ms linear infinite;
}
.rail .stamp:nth-child(7) {
-webkit-animation: stampSlide 40000ms -14300ms linear infinite;
animation: stampSlide 40000ms -14300ms linear infinite;
}
.rail .stamp:nth-child(8) {
-webkit-animation: stampSlide 40000ms -16300ms linear infinite;
animation: stampSlide 40000ms -16300ms linear infinite;
}
.rail .stamp:nth-child(9) {
-webkit-animation: stampSlide 40000ms -18300ms linear infinite;
animation: stampSlide 40000ms -18300ms linear infinite;
}
.rail .stamp:nth-child(10) {
-webkit-animation: stampSlide 40000ms -20300ms linear infinite;
animation: stampSlide 40000ms -20300ms linear infinite;
}
.rail .stamp:nth-child(11) {
-webkit-animation: stampSlide 40000ms -22300ms linear infinite;
animation: stampSlide 40000ms -22300ms linear infinite;
}
.rail .stamp:nth-child(12) {
-webkit-animation: stampSlide 40000ms -24300ms linear infinite;
animation: stampSlide 40000ms -24300ms linear infinite;
}
.rail .stamp:nth-child(13) {
-webkit-animation: stampSlide 40000ms -26300ms linear infinite;
animation: stampSlide 40000ms -26300ms linear infinite;
}
.rail .stamp:nth-child(14) {
-webkit-animation: stampSlide 40000ms -28300ms linear infinite;
animation: stampSlide 40000ms -28300ms linear infinite;
}
.rail .stamp:nth-child(15) {
-webkit-animation: stampSlide 40000ms -30300ms linear infinite;
animation: stampSlide 40000ms -30300ms linear infinite;
}
.rail .stamp:nth-child(16) {
-webkit-animation: stampSlide 40000ms -32300ms linear infinite;
animation: stampSlide 40000ms -32300ms linear infinite;
}
.rail .stamp:nth-child(17) {
-webkit-animation: stampSlide 40000ms -34300ms linear infinite;
animation: stampSlide 40000ms -34300ms linear infinite;
}
.rail .stamp:nth-child(18) {
-webkit-animation: stampSlide 40000ms -36300ms linear infinite;
animation: stampSlide 40000ms -36300ms linear infinite;
}
.rail .stamp:nth-child(19) {
-webkit-animation: stampSlide 40000ms -38300ms linear infinite;
animation: stampSlide 40000ms -38300ms linear infinite;
}
.rail .stamp:nth-child(20) {
-webkit-animation: stampSlide 40000ms -40300ms linear infinite;
animation: stampSlide 40000ms -40300ms linear infinite;
}
@-webkit-keyframes stampSlide {
0% {
-webkit-transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(130px);
transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(130px);
}
100% {
-webkit-transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(-3870px);
transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(-3870px);
}
}
@keyframes stampSlide {
0% {
-webkit-transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(130px);
transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(130px);
}
100% {
-webkit-transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(-3870px);
transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(-3870px);
}
}
.world {
-webkit-transform: rotateX(-30deg) rotateY(-30deg);
transform: rotateX(-30deg) rotateY(-30deg);
}
.world .forward {
position: absolute;
-webkit-animation: slide 2000ms linear infinite;
animation: slide 2000ms linear infinite;
}
.world .box {
width: 200px;
height: 200px;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-webkit-animation: roll 2000ms cubic-bezier(1, 0.01, 1, 1) infinite;
animation: roll 2000ms cubic-bezier(1, 0.01, 1, 1) infinite;
}
.world .box .wall {
position: absolute;
width: 200px;
height: 200px;
background: rgba(10, 10, 10, 0.8);
border: 1px solid #fafafa;
box-sizing: border-box;
}
.world .box .wall::before {
content: "";
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 7rem;
}
.world .box .wall:nth-child(1) {
-webkit-transform: translateZ(100px);
transform: translateZ(100px);
}
.world .box .wall:nth-child(2) {
-webkit-transform: rotateX(180deg) translateZ(100px);
transform: rotateX(180deg) translateZ(100px);
}
.world .box .wall:nth-child(3) {
-webkit-transform: rotateX(90deg) translateZ(100px);
transform: rotateX(90deg) translateZ(100px);
}
.world .box .wall:nth-child(3)::before {
-webkit-transform: rotateX(180deg) rotateZ(90deg) translateZ(-1px);
transform: rotateX(180deg) rotateZ(90deg) translateZ(-1px);
-webkit-animation: zeroFour 4000ms -2000ms linear infinite;
animation: zeroFour 4000ms -2000ms linear infinite;
}
.world .box .wall:nth-child(4) {
-webkit-transform: rotateX(-90deg) translateZ(100px);
transform: rotateX(-90deg) translateZ(100px);
}
.world .box .wall:nth-child(4)::before {
-webkit-transform: rotateX(180deg) rotateZ(-90deg) translateZ(-1px);
transform: rotateX(180deg) rotateZ(-90deg) translateZ(-1px);
-webkit-animation: zeroFour 4000ms -2000ms linear infinite;
animation: zeroFour 4000ms -2000ms linear infinite;
}
.world .box .wall:nth-child(5) {
-webkit-transform: rotateY(90deg) translateZ(100px);
transform: rotateY(90deg) translateZ(100px);
}
.world .box .wall:nth-child(5)::before {
-webkit-transform: rotateX(180deg) translateZ(-1px);
transform: rotateX(180deg) translateZ(-1px);
-webkit-animation: zeroFour 4000ms linear infinite;
animation: zeroFour 4000ms linear infinite;
}
.world .box .wall:nth-child(6) {
-webkit-transform: rotateY(-90deg) translateZ(100px);
transform: rotateY(-90deg) translateZ(100px);
}
.world .box .wall:nth-child(6)::before {
-webkit-transform: rotateX(180deg) rotateZ(180deg) translateZ(-1px);
transform: rotateX(180deg) rotateZ(180deg) translateZ(-1px);
-webkit-animation: zeroFour 4000ms linear infinite;
animation: zeroFour 4000ms linear infinite;
}
@-webkit-keyframes zeroFour {
0% {
content: "错";
}
100% {
content: "误";
}
}
@keyframes zeroFour {
0% {
content: "错";
}
100% {
content: "误";
}
}
@-webkit-keyframes roll {
0% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
}
85% {
-webkit-transform: rotateZ(90deg);
transform: rotateZ(90deg);
}
87% {
-webkit-transform: rotateZ(88deg);
transform: rotateZ(88deg);
}
90% {
-webkit-transform: rotateZ(90deg);
transform: rotateZ(90deg);
}
100% {
-webkit-transform: rotateZ(90deg);
transform: rotateZ(90deg);
}
}
@keyframes roll {
0% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
}
85% {
-webkit-transform: rotateZ(90deg);
transform: rotateZ(90deg);
}
87% {
-webkit-transform: rotateZ(88deg);
transform: rotateZ(88deg);
}
90% {
-webkit-transform: rotateZ(90deg);
transform: rotateZ(90deg);
}
100% {
-webkit-transform: rotateZ(90deg);
transform: rotateZ(90deg);
}
}
@-webkit-keyframes slide {
0% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
100% {
-webkit-transform: translateX(-200px);
transform: translateX(-200px);
}
}
@keyframes slide {
0% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
100% {
-webkit-transform: translateX(-200px);
transform: translateX(-200px);
}
}

View File

@@ -18,21 +18,19 @@ const editorConfig = {
uploadImage: {
fieldName: 'your-fileName',
server: '#', // 可以配置上传应用的地址
base64LimitSize: 2 * 1024 * 1024, // 5M 以下插入 base64
// 单个文件的最大体积限制,默认为 2M
maxFileSize: 2 * 1024 * 1024,
base64LimitSize: 500 * 1024, // 500K 以下插入 base64
// 单个文件的最大体积限制,默认为 500K
maxFileSize: 500 * 1024,
// 单个文件上传失败
onFailed(file, res) {
console.log("文件过大")
$('#warn-text').html(res);
$('.toast').toast();
},
// 上传错误,或者触发 timeout 超时
onError(file, err, res) {
console.log("文件过大")
layer.open({
type: 1, //1:自定义内容 2:iframe
title: '图片大于2M',
title: '图片过大(MAX:500KB)',
// area: ['500px', '170px'],
content: '资源有限,大佬请使用网络图片╮(╯▽╰)╭',
btn: ['好吧穷鬼'],
@@ -49,11 +47,10 @@ const editorConfig = {
}
},
onChange(editor) {
// console.log(editor.getHtml())
// $('#content-textarea').value = editor.getHtml()
const content = editor.children
// const contentStr = JSON.stringify(content)
// document.getElementById('content-textarea').value = contentStr
const contentStr = JSON.stringify(content)
$('#contentText-textarea').val(contentStr)
// 当编辑器选区、内容变化时,即触发
const html = editor.getHtml()
$('#content-textarea').val(html)
}
@@ -66,6 +63,10 @@ const editor = E.createEditor({
html: $('#content-textarea').val(),
config: editorConfig
})
// 初始化 隐藏框
const contentInit = editor.children
const contentStrInit = JSON.stringify(contentInit)
$('#contentText-textarea').val(contentStrInit)
// 创建 toolbar
const toolbar = E.createToolbar({

View File

@@ -53,6 +53,7 @@
<div id="editor-toolbar"></div>
<div id="editor-text-area" style="height: 400px;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>
</div>

View File

@@ -54,6 +54,7 @@
<div id="editor-toolbar"></div>
<div id="editor-text-area" style="height: 400px;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>
</div>

View File

@@ -39,7 +39,7 @@
<!--如果未登录-->
<div>
<form th:action="@{/search}" method="post">
<form th:action="@{/search}" method="get">
<ul class="navbar-nav mr-auto">
<li>
<input name="findWhat" type="text" placeholder="大佬想找什么呢?"/>

View File

@@ -3,16 +3,29 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>ERROR-Quinn</title>
<link rel="stylesheet" th:href="@{/css/error.css}">
<title>关于我们-Quinn</title>
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}">
</head>
<body>
<div class="NotPage">
<div class="message"><a th:href="@{/index}" style="color: white">没有此页面,点击回主页</a></div>
<div class="message2" style="text-align: center"><a style="color: white">Quinn-资源丢失</a></div>
<img th:src="@{/images/logo/logo.png}">
</div>
<div th:replace="~{common/header::header(activeUrl='')}"></div>
<main role="main">
<div class="container">
<div class="jumbotron" style="background-color: #ffffff;">
<div class="container">
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading">错误</h4>
<p>权限不足或者资源丢失。请关注我们提供建议反馈,您的反馈将是我们不断进步的动力!</p>
<hr>
<p class="mb-0">Illegal permissions or missing resources. Please pay attention to us and provide suggestions or feedback. Your feedback is the driving force for our continuous progress!</p>
</div>
</div>
</div>
</div>
</main>
<div th:replace="~{common/footer::footer}"></div>
<script th:src="@{/js/jquery-3.5.1.min.js}"></script>
<script th:src="@{/js/jquery-ui.min.js}"></script>
<script th:src="@{/live/js/addlive2d.js}"></script>
</body>
</html>

View File

@@ -3,16 +3,29 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>ERROR-Quinn</title>
<link rel="stylesheet" th:href="@{/css/error.css}">
<title>关于我们-Quinn</title>
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}">
</head>
<body>
<div class="NotPage">
<div class="message"><a th:href="@{/index}" style="color: white">没有此页面,点击回主页</a></div>
<div class="message2" style="text-align: center"><a style="color: white">Quinn-资源丢失</a></div>
<img th:src="@{/images/logo/logo.png}">
</div>
<div th:replace="~{common/header::header(activeUrl='')}"></div>
<main role="main">
<div class="container">
<div class="jumbotron" style="background-color: #ffffff;">
<div class="container">
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading">错误</h4>
<p>未找到资源或者您没有权限,请关注我们提供建议反馈,您的反馈将是我们不断进步的动力!</p>
<hr>
<p class="mb-0">Illegal permissions or missing resources. Please pay attention to us and provide suggestions or feedback. Your feedback is the driving force for our continuous progress!</p>
</div>
</div>
</div>
</div>
</main>
<div th:replace="~{common/footer::footer}"></div>
<script th:src="@{/js/jquery-3.5.1.min.js}"></script>
<script th:src="@{/js/jquery-ui.min.js}"></script>
<script th:src="@{/live/js/addlive2d.js}"></script>
</body>
</html>

View File

@@ -1,18 +0,0 @@
<!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>ERROR-Quinn</title>
<link rel="stylesheet" th:href="@{/css/error.css}">
</head>
<body>
<div class="NotPage">
<div class="message"><a th:href="@{/index}" style="color: white">请使用浏览器后退,或者点此处【主页】</a></div>
<div class="message2" style="text-align: center"><a style="color: white">Quinn-管理员密码错误,请关注公众号寻找密码!</a></div>
<img th:src="@{/images/logo/logo.png}">
</div>
</body>
</html>

View File

@@ -6,6 +6,16 @@
<title>论坛-Quinn</title>
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/wangedit/css/wang.style.css}"/>
<style>
input[type="file"] {
  width: 100%;
  height: 100%;
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
}
</style>
</head>
<body style="background: #f2f2f2;">
@@ -16,17 +26,17 @@
<div class="col-md-12 order-md-1">
<div class="row mb-4">
<h4 class="col-md-11">修改资源</h4>
<a href="javascript:deleteFile(this);" class="btn btn-outline-danger col-md-1">删除资源</a>
<a th:href="@{'/source/oper/del/'+${source.getSid()}}" class="btn btn-outline-danger col-md-1">删除资源</a>
</div>
<form class="needs-validation" th:action="@{/tracy/mcgrady/lmq/love/wn/update}" enctype="multipart/form-data" method="post">
<form class="needs-validation" th:action="@{/source/oper/update}" enctype="multipart/form-data" method="post">
<input type="hidden" id="sid" name="sid" th:value="${source.getSid()}">
<div class="form-row">
<div class="form-group col-md-8">
<div class="form-group col-md-12">
<label for="title">资源标题</label>
<input type="text" name="sourceName" class="form-control" id="title" th:value="${source.getSourceName()}" required>
</div>
<div class="form-group col-md-4">
<div class="form-group col-md-8">
<label for="enName">英文名</label>
<input type="text" name="enName" class="form-control" id="enName" th:value="${source.getEnName()}" required>
</div>
@@ -40,16 +50,6 @@
</select>
</div>
<div class="form-group col-md-4">
<label for="keyWords">摘要</label>
<input type="text" name="keyWords" class="form-control" id="keyWords" th:value="${source.getKeyWord1()}" required>
</div>
<div id="uploadPassWordDiv" class="form-group col-md-4">
<label for="uploadPassWord">管理员密码(*重要*)</label>
<input type="text" name="uploadPassWord" class="form-control" id="uploadPassWord" required />
</div>
<div class="form-group col-md-12">
<label for="subContent">简介</label>
<textarea name="detail" class="form-control" id="subContent" th:text="${source.getDetail()}" required></textarea>
@@ -80,6 +80,7 @@
<div id="editor-toolbar"></div>
<div id="editor-text-area" style="height: 400px;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>
</div>
</div>
@@ -113,24 +114,6 @@
}
});
function deleteFile(btn) {
btn.disabled=true;
if(!confirm('你确认要删除吗?')) {
return false;
}
var sid = $('#sid').val();
var uploadPassWord = $('#uploadPassWord').val();
$.ajax({
url: "/tracy/mcgrady/lmq/love/wn/del",
async: false,
type: "post",
data: {"sid":sid,"uploadPassWord":uploadPassWord},
success: function (res) {
location.href=res;
}
});
}
$("#sourceType").change(function(){
const jSourceType = $('#sourceType').val();
if (jSourceType == 'BAIDU') {

View File

@@ -38,12 +38,6 @@
<!-- 收藏 -->
<span class="badge badge-primary">
[[${source.getCategoryName()}]]
(
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" 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>
[[${source.getStar()}]]
)
</span>
<p class="float-right" th:text="${#dates.format(source.getGmtUpdate(),'yyyy-MM-dd HH:mm:ss')}"></p>
<div class="small">

View File

@@ -6,6 +6,18 @@
<title>资源-Quinn</title>
<link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/wangedit/css/wang.style.css}"/>
<style>
input[type="file"] {
  width: 100%;
  height: 100%;
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
}
</style>
</head>
<body style="background: #f2f2f2;">
<main role="main" class="container mt-3 p-3 bg-white rounded">
@@ -13,20 +25,14 @@
<div class="col-md-12 blog-main">
<div class="col-md-12 order-md-1">
<h4 class="mb-3">发布新资源</h4>
<form class="needs-validation" th:action="@{/tracy/mcgrady/lmq/love/wn}" enctype="multipart/form-data" method="post">
<!-- 隐藏域 -->
<!-- <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()}">-->
<form class="needs-validation" th:action="@{/source/oper}" enctype="multipart/form-data" method="post">
<div class="form-row">
<div class="form-group col-md-8">
<div class="form-group col-md-12">
<label for="title">资源标题</label>
<input type="text" name="title" class="form-control" id="title" value="" required>
</div>
<div class="form-group col-md-4">
<div class="form-group col-md-8">
<label for="enName">英文名</label>
<input type="text" name="enName" class="form-control" id="enName" value="" required>
</div>
@@ -40,16 +46,6 @@
</select>
</div>
<div class="form-group col-md-4">
<label for="keyWords">摘要</label>
<input type="text" name="keyWords" class="form-control" id="keyWords" value="" required>
</div>
<div id="uploadPassWordDiv" class="form-group col-md-4">
<label for="uploadPassWord">管理员密码(*重要*)</label>
<input type="text" class="form-control" id="uploadPassWord" name="uploadPassWord" required />
</div>
<div class="form-group col-md-12">
<label for="subContent">简介</label>
<textarea name="subContent" class="form-control" id="subContent" required></textarea>
@@ -60,7 +56,7 @@
<select name="sourceType" class="custom-select d-block w-100" id="sourceType" required>
<option value="">请选择...</option>
<option value="BAIDU">百度云</option>
<option value="OSS" >服务器</option>
<option value="OSS" >服务器<span class="badge badge-pill badge-danger">(这个程序员还很穷!文件请不要大于20M)</span></option>
</select>
</div>
@@ -70,8 +66,7 @@
</div>
<div id="uploadData" style="display: none" class="form-group col-md-12">
<label for="toUploadFile" style="color: darkgreen">穷~文件请不要大于20M,否则会报错</label>
<input type="file" id="toUploadFile" class="btn" name="file" value="请选择文件" />
<input type="file" id="toUploadFile" class="alert alert-dark" name="file" />
</div>
<div class="col-md-12 mb-3">
@@ -80,6 +75,7 @@
<div id="editor-toolbar"></div>
<div id="editor-text-area" style="height: 400px;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>
</div>
</div>

View File

@@ -74,7 +74,7 @@
<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.getUserAvatar()}" style="border-radius: 5px;margin-right: 5px " width="32" height="32">
<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">
<strong class="d-block text-gray-dark" th:text="${comment.getUsername()} + '&nbsp;&nbsp;&nbsp;&nbsp;' + ${#dates.format(comment.getGmtCreate(),'yyyy-MM-dd HH:mm:ss')}"></strong>
<span th:text="${comment.getContent()}"></span>

View File

@@ -137,9 +137,9 @@
<span th:text="${session.loginUser.getUsername()}"></span>
<br>
<small>
<span th:if="${session.loginUser.getRoleId()=='ADMIN'}" class="badge badge-primary">超级管理员</span>
<span th:if="${session.loginUser.getRoleId()!='ADMIN'}" th:class="${session.loginUser.getRoleId()=='VIP'?'badge badge-warning':'badge badge-success'}"
th:text="${session.loginUser.getRoleId()=='VIP'?'VIP会员':'普通用户'}">
<span th:if="${session.loginUser.getRole()=='ADMIN'}" class="badge badge-primary">超级管理员</span>
<span th:if="${session.loginUser.getRole()!='ADMIN'}" th:class="${session.loginUser.getRole()=='VIP'?'badge badge-warning':'badge badge-success'}"
th:text="${session.loginUser.getRole()=='VIP'?'VIP会员':'普通用户'}">
</span>
</small>
<p>