上传代码
@ -0,0 +1,36 @@
|
||||
package com.java2nb.novel;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableTransactionManagement
|
||||
@EnableScheduling
|
||||
@EnableCaching
|
||||
@MapperScan(basePackages = {"com.java2nb.novel.mapper"})
|
||||
public class FrontNovelApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FrontNovelApplication.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解决同一时间只能一个定时任务执行的问题
|
||||
* */
|
||||
@Bean
|
||||
public TaskScheduler taskScheduler() {
|
||||
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
|
||||
taskScheduler.setPoolSize(5);
|
||||
return taskScheduler;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.core.utils.JwtTokenUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
public class BaseController {
|
||||
|
||||
protected JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
|
||||
protected String getToken(HttpServletRequest request){
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if(cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie.getName().equals("Authorization")) {
|
||||
return cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return request.getHeader("Authorization");
|
||||
}
|
||||
|
||||
protected UserDetails getUserDetails(HttpServletRequest request) {
|
||||
String token = getToken(request);
|
||||
if(StringUtils.isBlank(token)){
|
||||
return null;
|
||||
}else{
|
||||
return jwtTokenUtil.getUserDetailsFromToken(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setJwtTokenUtil(JwtTokenUtil jwtTokenUtil) {
|
||||
this.jwtTokenUtil = jwtTokenUtil;
|
||||
}
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.entity.BookComment;
|
||||
import com.java2nb.novel.entity.BookIndex;
|
||||
import com.java2nb.novel.search.BookSP;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.vo.BookVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@RequestMapping("book")
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class BookController extends BaseController{
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
|
||||
/**
|
||||
* 查询首页小说设置列表数据
|
||||
* */
|
||||
@PostMapping("listBookSetting")
|
||||
public ResultBean listBookSetting(){
|
||||
return ResultBean.ok(bookService.listBookSettingVO());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询首页点击榜单数据
|
||||
* */
|
||||
@PostMapping("listClickRank")
|
||||
public ResultBean listClickRank(){
|
||||
return ResultBean.ok(bookService.listClickRank());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询首页新书榜单数据
|
||||
* */
|
||||
@PostMapping("listNewRank")
|
||||
public ResultBean listNewRank(){
|
||||
return ResultBean.ok(bookService.listNewRank());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询首页更新榜单数据
|
||||
* */
|
||||
@PostMapping("listUpdateRank")
|
||||
public ResultBean listUpdateRank(){
|
||||
return ResultBean.ok(bookService.listUpdateRank());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小说分类列表
|
||||
* */
|
||||
@PostMapping("listBookCategory")
|
||||
public ResultBean listBookCategory(){
|
||||
return ResultBean.ok(bookService.listBookCategory());
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页搜索
|
||||
* */
|
||||
@PostMapping("searchByPage")
|
||||
public ResultBean searchByPage(BookSP bookSP, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "20") int pageSize){
|
||||
List<BookVO> books = bookService.searchByPage(bookSP,page,pageSize);
|
||||
return ResultBean.ok(new PageInfo<>(books));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小说详情信息
|
||||
* */
|
||||
@PostMapping("queryBookDetail")
|
||||
public ResultBean queryBookDetail(Long id){
|
||||
return ResultBean.ok(bookService.queryBookDetail(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询小说排行信息
|
||||
* */
|
||||
@PostMapping("listRank")
|
||||
public ResultBean listRank(@RequestParam(value = "type",defaultValue = "0") Byte type,@RequestParam(value = "limit",defaultValue = "30") Integer limit){
|
||||
return ResultBean.ok(bookService.listRank(type,limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加点击次数
|
||||
* */
|
||||
@PostMapping("addVisitCount")
|
||||
public ResultBean addVisitCount(Long bookId){
|
||||
bookService.addVisitCount(bookId);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询章节相关信息
|
||||
* */
|
||||
@PostMapping("queryBookIndexAbout")
|
||||
public ResultBean queryBookIndexAbout(Long bookId,Long lastBookIndexId) {
|
||||
Map<String,Object> data = new HashMap<>(2);
|
||||
data.put("bookIndexCount",bookService.queryIndexCount(bookId));
|
||||
data.put("lastBookContent",bookService.queryBookContent(lastBookIndexId).getContent().substring(0,42));
|
||||
return ResultBean.ok(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类id查询同类推荐书籍
|
||||
* */
|
||||
@PostMapping("listRecBookByCatId")
|
||||
public ResultBean listRecBookByCatId(Integer catId) {
|
||||
return ResultBean.ok(bookService.listRecBookByCatId(catId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*分页查询书籍评论列表
|
||||
* */
|
||||
@PostMapping("listCommentByPage")
|
||||
public ResultBean listCommentByPage(@RequestParam("bookId") Long bookId,@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize) {
|
||||
return ResultBean.ok(new PageInfo<>(bookService.listCommentByPage(null,bookId,page,pageSize)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增评价
|
||||
* */
|
||||
@PostMapping("addBookComment")
|
||||
public ResultBean addBookComment(BookComment comment, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
bookService.addBookComment(userDetails.getId(),comment);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据小说ID查询小说前十条最新更新目录集合
|
||||
* */
|
||||
@PostMapping("queryNewIndexList")
|
||||
public ResultBean queryNewIndexList(Long bookId){
|
||||
return ResultBean.ok(bookService.queryIndexList(bookId,"index_num desc",10));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.service.FriendLinkService;
|
||||
import com.java2nb.novel.service.NewsService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@RequestMapping("cache")
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class CacheController {
|
||||
|
||||
@Value("${cache.manager.password}")
|
||||
private String cacheManagerPass;
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
private final NewsService newsService;
|
||||
|
||||
private final FriendLinkService friendLinkService;
|
||||
|
||||
/**
|
||||
* 刷新缓存
|
||||
* @param type 缓存类型,1:首页书籍推荐,2:首页新闻,3:首页友情链接
|
||||
* */
|
||||
@GetMapping("refresh/{pass}/{type}")
|
||||
public ResultBean refreshCache(@PathVariable("type") Byte type, @PathVariable("pass") String pass){
|
||||
if(!cacheManagerPass.equals(pass)){
|
||||
return ResultBean.fail(ResponseStatus.PASSWORD_ERROR);
|
||||
}
|
||||
switch (type){
|
||||
case 1:{
|
||||
//刷新首页推荐书籍缓存
|
||||
cacheService.del(CacheKey.INDEX_BOOK_SETTINGS_KEY);
|
||||
bookService.listBookSettingVO();
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
//刷新首页新闻缓存
|
||||
cacheService.del(CacheKey.INDEX_NEWS_KEY);
|
||||
newsService.listIndexNews();
|
||||
break;
|
||||
}
|
||||
case 3:{
|
||||
//刷新首页友情链接
|
||||
cacheService.del(CacheKey.INDEX_LINK_KEY);
|
||||
friendLinkService.listIndexLink();
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.utils.RandomValidateCodeUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("file")
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class FileController {
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*/
|
||||
@GetMapping(value = "getVerify")
|
||||
public void getVerify(HttpServletRequest request, HttpServletResponse response) {
|
||||
try {
|
||||
//设置相应类型,告诉浏览器输出的内容为图片
|
||||
response.setContentType("image/jpeg");
|
||||
//设置响应头信息,告诉浏览器不要缓存此内容
|
||||
response.setHeader("Pragma", "No-cache");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setDateHeader("Expire", 0);
|
||||
RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();
|
||||
//输出验证码图片方法
|
||||
randomValidateCode.getRandcode(cacheService, response);
|
||||
} catch (Exception e) {
|
||||
log.error("获取验证码失败>>>> ", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import com.java2nb.novel.service.FriendLinkService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@RequestMapping("friendLink")
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class FriendLinkController {
|
||||
|
||||
private final FriendLinkService friendLinkService;
|
||||
|
||||
/**
|
||||
* 查询首页友情链接
|
||||
* */
|
||||
@PostMapping("listIndexLink")
|
||||
public ResultBean listIndexLink(){
|
||||
return ResultBean.ok(friendLinkService.listIndexLink());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import com.java2nb.novel.service.NewsService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@RequestMapping("news")
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class NewsController {
|
||||
|
||||
private final NewsService newsService;
|
||||
|
||||
/**
|
||||
* 查询首页新闻
|
||||
* */
|
||||
@PostMapping("listIndexNews")
|
||||
public ResultBean listIndexNews(){
|
||||
return ResultBean.ok(newsService.listIndexNews());
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询新闻列表
|
||||
* */
|
||||
@PostMapping("listByPage")
|
||||
public ResultBean listByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize){
|
||||
return ResultBean.ok(new PageInfo<>(newsService.listByPage(page,pageSize)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.java2nb.novel.core.utils.TemplateUtil;
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.entity.BookContent;
|
||||
import com.java2nb.novel.entity.BookIndex;
|
||||
import com.java2nb.novel.entity.News;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.service.NewsService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Controller
|
||||
public class PageController{
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
private final NewsService newsService;
|
||||
|
||||
|
||||
@RequestMapping("{url}.html")
|
||||
public String module(@PathVariable("url") String url) {
|
||||
return url;
|
||||
}
|
||||
|
||||
@RequestMapping("{module}/{url}.html")
|
||||
public String module2(@PathVariable("module") String module, @PathVariable("url") String url) {
|
||||
return module + "/" + url;
|
||||
}
|
||||
|
||||
@RequestMapping("{module}/{classify}/{url}.html")
|
||||
public String module3(@PathVariable("module") String module, @PathVariable("classify") String classify, @PathVariable("url") String url) {
|
||||
return module + "/" + classify + "/" + url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页
|
||||
* */
|
||||
@RequestMapping(path = {"/", "/index", "/index.html"})
|
||||
public String index() {
|
||||
return TemplateUtil.getTemplateDir()+"index";
|
||||
}
|
||||
|
||||
/**
|
||||
* 作品页
|
||||
* */
|
||||
@RequestMapping("book/bookclass.html")
|
||||
public String bookClass() {
|
||||
return "book/bookclass";
|
||||
}
|
||||
|
||||
/**
|
||||
* 排行页
|
||||
* */
|
||||
@RequestMapping("book/book_ranking.html")
|
||||
public String bookRank() {
|
||||
|
||||
return TemplateUtil.getTemplateDir()+"book/book_ranking";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 详情页
|
||||
* */
|
||||
@RequestMapping("/book/{bookId}.html")
|
||||
public String bookDetail(@PathVariable("bookId") Long bookId, Model model) {
|
||||
Book book = bookService.queryBookDetail(bookId);
|
||||
model.addAttribute("book",book);
|
||||
//查询首章目录ID
|
||||
Long firstBookIndexId = bookService.queryFirstBookIndexId(bookId);
|
||||
model.addAttribute("firstBookIndexId",firstBookIndexId);
|
||||
return TemplateUtil.getTemplateDir()+"book/book_detail";
|
||||
}
|
||||
|
||||
/**
|
||||
* 目录页
|
||||
* */
|
||||
@RequestMapping("/book/indexList-{bookId}.html")
|
||||
public String indexList(@PathVariable("bookId") Long bookId, Model model) {
|
||||
Book book = bookService.queryBookDetail(bookId);
|
||||
model.addAttribute("book",book);
|
||||
List<BookIndex> bookIndexList = bookService.queryIndexList(bookId,null,null);
|
||||
model.addAttribute("bookIndexList",bookIndexList);
|
||||
model.addAttribute("bookIndexCount",bookIndexList.size());
|
||||
return TemplateUtil.getTemplateDir()+"book/book_index";
|
||||
}
|
||||
|
||||
/**
|
||||
* 内容页
|
||||
* */
|
||||
@RequestMapping("/book/{bookId}/{bookIndexId}.html")
|
||||
public String indexList(@PathVariable("bookId") Long bookId,@PathVariable("bookIndexId") Long bookIndexId, Model model) {
|
||||
//查询书籍
|
||||
Book book = bookService.queryBookDetail(bookId);
|
||||
model.addAttribute("book",book);
|
||||
//查询目录
|
||||
BookIndex bookIndex = bookService.queryBookIndex(bookIndexId);
|
||||
model.addAttribute("bookIndex",bookIndex);
|
||||
//查询上一章节目录ID
|
||||
Long preBookIndexId = bookService.queryPreBookIndexId(bookId,bookIndex.getIndexNum());
|
||||
model.addAttribute("preBookIndexId",preBookIndexId);
|
||||
//查询下一章目录ID
|
||||
Long nextBookIndexId = bookService.queryNextBookIndexId(bookId,bookIndex.getIndexNum());
|
||||
model.addAttribute("nextBookIndexId",nextBookIndexId);
|
||||
//查询内容
|
||||
BookContent bookContent = bookService.queryBookContent(bookIndex.getId());
|
||||
model.addAttribute("bookContent",bookContent);
|
||||
return TemplateUtil.getTemplateDir()+"book/book_content";
|
||||
}
|
||||
|
||||
/**
|
||||
* 评论页面
|
||||
* */
|
||||
@RequestMapping("/book/comment-{bookId}.html")
|
||||
public String commentList(@PathVariable("bookId") Long bookId, Model model) {
|
||||
//查询书籍
|
||||
Book book = bookService.queryBookDetail(bookId);
|
||||
model.addAttribute("book",book);
|
||||
return "book/book_comment";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新闻内容页面
|
||||
* */
|
||||
@RequestMapping("/about/newsInfo-{newsId}.html")
|
||||
public String newsInfo(@PathVariable("newsId") Long newsId, Model model) {
|
||||
//查询新闻
|
||||
News news = newsService.queryNewsInfo(newsId);
|
||||
model.addAttribute("news",news);
|
||||
return "about/news_info";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,269 @@
|
||||
package com.java2nb.novel.controller;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.java2nb.novel.core.bean.ResultBean;
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.core.utils.RandomValidateCodeUtil;
|
||||
import com.java2nb.novel.entity.User;
|
||||
import com.java2nb.novel.form.UserForm;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("user")
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class UserController extends BaseController {
|
||||
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
/**
|
||||
* 登陆
|
||||
*/
|
||||
@PostMapping("login")
|
||||
public ResultBean login(@Valid UserForm user, BindingResult result) {
|
||||
//判断参数是否合法
|
||||
if (result.hasErrors()) {
|
||||
log.info(result.getAllErrors().toString());
|
||||
return ResultBean.fail(ResponseStatus.PARAM_ERROR);
|
||||
}
|
||||
|
||||
//登陆
|
||||
UserDetails userDetails = userService.login(user);
|
||||
|
||||
Map<String, Object> data = new HashMap<>(1);
|
||||
data.put("token", jwtTokenUtil.generateToken(userDetails));
|
||||
|
||||
return ResultBean.ok(data);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
@PostMapping("register")
|
||||
public ResultBean register(@Valid UserForm user, @RequestParam(value = "velCode", defaultValue = "") String velCode, BindingResult result) {
|
||||
|
||||
//判断参数是否合法
|
||||
if (result.hasErrors()) {
|
||||
log.info(result.getAllErrors().toString());
|
||||
return ResultBean.fail(ResponseStatus.PARAM_ERROR);
|
||||
}
|
||||
|
||||
//判断验证码是否正确
|
||||
if (!velCode.equals(cacheService.get(RandomValidateCodeUtil.RANDOM_CODE_KEY))) {
|
||||
return ResultBean.fail(ResponseStatus.VEL_CODE_ERROR);
|
||||
}
|
||||
|
||||
//注册
|
||||
UserDetails userDetails = userService.register(user);
|
||||
Map<String, Object> data = new HashMap<>(1);
|
||||
data.put("token", jwtTokenUtil.generateToken(userDetails));
|
||||
|
||||
return ResultBean.ok(data);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
*/
|
||||
@PostMapping("refreshToken")
|
||||
public ResultBean refreshToken(HttpServletRequest request) {
|
||||
String token = getToken(request);
|
||||
if (jwtTokenUtil.canRefresh(token)) {
|
||||
token = jwtTokenUtil.refreshToken(token);
|
||||
Map<String, Object> data = new HashMap<>(2);
|
||||
data.put("token", token);
|
||||
data.put("username", jwtTokenUtil.getUserDetailsFromToken(token).getUsername());
|
||||
return ResultBean.ok(data);
|
||||
|
||||
} else {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小说是否已加入书架
|
||||
*/
|
||||
@PostMapping("queryIsInShelf")
|
||||
public ResultBean queryIsInShelf(Long bookId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(userService.queryIsInShelf(userDetails.getId(), bookId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入书架
|
||||
* */
|
||||
@PostMapping("addToBookShelf")
|
||||
public ResultBean addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.addToBookShelf(userDetails.getId(),bookId,preContentId);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移出书架
|
||||
* */
|
||||
@PostMapping("removeFromBookShelf")
|
||||
public ResultBean removeFromBookShelf(Long bookId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.removeFromBookShelf(userDetails.getId(),bookId);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询书架
|
||||
* */
|
||||
@PostMapping("listBookShelfByPage")
|
||||
public ResultBean listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(new PageInfo<>(userService.listBookShelfByPage(userDetails.getId(),page,pageSize)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询阅读记录
|
||||
* */
|
||||
@PostMapping("listReadHistoryByPage")
|
||||
public ResultBean listReadHistoryByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(new PageInfo<>(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加阅读记录
|
||||
* */
|
||||
@PostMapping("addReadHistory")
|
||||
public ResultBean addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.addReadHistory(userDetails.getId(),bookId,preContentId);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加反馈
|
||||
* */
|
||||
@PostMapping("addFeedBack")
|
||||
public ResultBean addFeedBack(String content, HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.addFeedBack(userDetails.getId(),content);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询我的反馈列表
|
||||
* */
|
||||
@PostMapping("listUserFeedBackByPage")
|
||||
public ResultBean listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(new PageInfo<>(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询个人信息
|
||||
* */
|
||||
@PostMapping("userInfo")
|
||||
public ResultBean userInfo(HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(userService.userInfo(userDetails.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新个人信息
|
||||
* */
|
||||
@PostMapping("updateUserInfo")
|
||||
public ResultBean updateUserInfo(User user,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
userService.updateUserInfo(userDetails.getId(),user);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新密码
|
||||
* */
|
||||
@PostMapping("updatePassword")
|
||||
public ResultBean updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
if(!(StringUtils.isNotBlank(newPassword1) && newPassword1.equals(newPassword2))){
|
||||
ResultBean.fail(ResponseStatus.TWO_PASSWORD_DIFF);
|
||||
}
|
||||
userService.updatePassword(userDetails.getId(),oldPassword,newPassword1);
|
||||
return ResultBean.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询用户书评
|
||||
* */
|
||||
@PostMapping("listCommentByPage")
|
||||
public ResultBean listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
return ResultBean.fail(ResponseStatus.NO_LOGIN);
|
||||
}
|
||||
return ResultBean.ok(new PageInfo<>(bookService.listCommentByPage(userDetails.getId(),null,page,pageSize)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.java2nb.novel.core.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Data
|
||||
public class UserDetails {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String username;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.java2nb.novel.core.config;
|
||||
|
||||
import com.java2nb.novel.core.filter.NovelFilter;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 过滤器配置类
|
||||
* @author Administrator
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig{
|
||||
|
||||
@Value("${pic.save.path}")
|
||||
private String picSavePath;
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<NovelFilter> filterRegist() {
|
||||
FilterRegistrationBean<NovelFilter> frBean = new FilterRegistrationBean<>();
|
||||
frBean.setFilter(new NovelFilter());
|
||||
frBean.addUrlPatterns("/*");
|
||||
frBean.addInitParameter("picSavePath",picSavePath);
|
||||
return frBean;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.java2nb.novel.core.filter;
|
||||
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.utils.BrowserUtil;
|
||||
import com.java2nb.novel.core.utils.Constants;
|
||||
import com.java2nb.novel.core.utils.SpringUtil;
|
||||
import com.java2nb.novel.core.utils.TemplateUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* 项目核心过滤器
|
||||
* @author Administrator
|
||||
*/
|
||||
public class NovelFilter implements Filter {
|
||||
|
||||
/**
|
||||
* 本地图片保存路径
|
||||
* */
|
||||
private String picSavePath;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig){
|
||||
picSavePath = filterConfig.getInitParameter("picSavePath");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse resp = (HttpServletResponse) servletResponse;
|
||||
String requestUri = req.getRequestURI();
|
||||
|
||||
//本地图片访问处理
|
||||
if (requestUri.contains(Constants.LOCAL_PIC_PREFIX)) {
|
||||
//缓存10天
|
||||
resp.setDateHeader("expires", System.currentTimeMillis()+60*60*24*10*1000);
|
||||
OutputStream out = resp.getOutputStream();
|
||||
InputStream input = new FileInputStream(new File(picSavePath + requestUri));
|
||||
byte[] b = new byte[4096];
|
||||
for (int n; (n = input.read(b)) != -1; ) {
|
||||
out.write(b, 0, n);
|
||||
}
|
||||
input.close();
|
||||
out.close();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//根据浏览器类型选择前端模板
|
||||
String to = req.getParameter("to");
|
||||
CacheService cacheService = SpringUtil.getBean(CacheService.class);
|
||||
if("pc".equals(to)){
|
||||
//直接进PC站
|
||||
cacheService.set(CacheKey.TEMPLATE_DIR_KEY,"",60*60*24);
|
||||
}else if("mobile".equals(to)){
|
||||
//直接进手机站
|
||||
cacheService.set(CacheKey.TEMPLATE_DIR_KEY,"mobile/",60*60*24);
|
||||
}else{
|
||||
//自动识别是PC站还是手机站
|
||||
if(BrowserUtil.isMobile(req)){
|
||||
//手机端访问
|
||||
TemplateUtil.setTemplateDir("mobile/");
|
||||
}else{
|
||||
//PC端访问
|
||||
TemplateUtil.setTemplateDir("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
filterChain.doFilter(servletRequest,servletResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.java2nb.novel.core.schedule;
|
||||
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 网络图片转存本地任务
|
||||
* @author Administrator
|
||||
*/
|
||||
@ConditionalOnProperty(prefix = "pic.save",name = "type",havingValue = "2")
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class Network2LocalPicSchedule {
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
@Value("${pic.save.type}")
|
||||
private Integer picSaveType;
|
||||
|
||||
@Value("${pic.save.path}")
|
||||
private String picSavePath;
|
||||
|
||||
/**
|
||||
* 10分钟转一次
|
||||
*/
|
||||
@Scheduled(fixedRate = 1000 * 60 * 10)
|
||||
public void trans() {
|
||||
|
||||
log.info("Network2LocalPicSchedule。。。。。。。。。。。。");
|
||||
|
||||
|
||||
Integer offset = 0, limit = 100;
|
||||
List<Book> networkPicBooks;
|
||||
do {
|
||||
networkPicBooks = bookService.queryNetworkPicBooks(limit, offset);
|
||||
for (Book book : networkPicBooks) {
|
||||
bookService.updateBookPicToLocal(book.getPicUrl(), book.getId());
|
||||
}
|
||||
offset += limit;
|
||||
} while (networkPicBooks.size() > 0);
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class BrowserUtil {
|
||||
|
||||
// 浏览器类型
|
||||
public static final String[] mobileAgents = { "iphone", "android", "phone", "mobile", "wap", "netfront", "java",
|
||||
"opera mobi", "opera mini", "ucweb", "windows ce", "symbian", "series", "webos", "sony", "blackberry",
|
||||
"dopod", "nokia", "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma",
|
||||
"docomo", "up.browser", "up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos",
|
||||
"techfaith", "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson", "philips", "sagem", "wellcom",
|
||||
"bunjalloo", "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos", "pantech", "gionee",
|
||||
"portalmmm", "jig browser", "hiptop", "benq", "haier", "^lct", "320x320", "240x320", "176x220", "w3c ",
|
||||
"acs-", "alav", "alca", "amoi", "audi", "avan", "benq", "bird", "blac", "blaz", "brew", "cell", "cldc",
|
||||
"cmd-", "dang", "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs", "kddi", "keji", "leno", "lg-c",
|
||||
"lg-d", "lg-g", "lge-", "maui", "maxo", "midp", "mits", "mmef", "mobi", "mot-", "moto", "mwbp", "nec-",
|
||||
"newt", "noki", "oper", "palm", "pana", "pant", "phil", "play", "port", "prox", "qwap", "sage", "sams",
|
||||
"sany", "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem", "smal", "smar", "sony", "sph-",
|
||||
"symb", "t-mo", "teli", "tim-", "tosh", "tsm-", "upg1", "upsi", "vk-v", "voda", "wap-", "wapa", "wapi",
|
||||
"wapp", "wapr", "webc", "winw", "winw", "xda", "xda-", "Googlebot-Mobile" };
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: JudgelsMobile @Description: TODO(判断是否是手机浏览器) @param @param
|
||||
* request @param @return 设定文件 @return boolean 返回类型 @throws
|
||||
*/
|
||||
public static boolean isMobile(HttpServletRequest request) {
|
||||
boolean isMobile = false;
|
||||
if (request.getHeader("User-Agent") != null) {
|
||||
for (String mobileAgent : mobileAgents) {
|
||||
if (request.getHeader("User-Agent").toLowerCase().indexOf(mobileAgent) > 0) {
|
||||
isMobile = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isMobile;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
/**
|
||||
* 常量类
|
||||
* @author Administrator
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
/**
|
||||
* 模板路径前缀保存key
|
||||
* */
|
||||
public static final String TEMPLATE_PATH_PREFIX_KEY = "templatePathPrefixKey";
|
||||
|
||||
/**
|
||||
* 本地图片保存前缀
|
||||
* */
|
||||
public static final String LOCAL_PIC_PREFIX = "/localPic/";
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class JwtTokenUtil {
|
||||
|
||||
private static final String CLAIM_KEY_USERNAME = "sub";
|
||||
private static final String CLAIM_KEY_CREATED = "created";
|
||||
@Value("${jwt.secret}")
|
||||
private String secret;
|
||||
@Value("${jwt.expiration}")
|
||||
private Long expiration;
|
||||
|
||||
/**
|
||||
* 根据负责生成JWT的token
|
||||
*/
|
||||
private String generateToken(Map<String, Object> claims) {
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setExpiration(generateExpirationDate())
|
||||
.signWith(SignatureAlgorithm.HS512, secret)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取JWT中的负载
|
||||
*/
|
||||
private Claims getClaimsFromToken(String token) {
|
||||
Claims claims = null;
|
||||
try {
|
||||
claims = Jwts.parser()
|
||||
.setSigningKey(secret)
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
} catch (Exception e) {
|
||||
log.info("JWT格式验证失败:{}",token);
|
||||
}
|
||||
return claims;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成token的过期时间
|
||||
*/
|
||||
private Date generateExpirationDate() {
|
||||
return new Date(System.currentTimeMillis() + expiration * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取用户信息
|
||||
*/
|
||||
public UserDetails getUserDetailsFromToken(String token) {
|
||||
if(isTokenExpired(token)){
|
||||
return null;
|
||||
}
|
||||
UserDetails userDetail;
|
||||
try {
|
||||
Claims claims = getClaimsFromToken(token);
|
||||
userDetail = new ObjectMapper().readValue(claims.getSubject(),UserDetails.class);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
userDetail = null;
|
||||
}
|
||||
return userDetail;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断token是否已经失效
|
||||
*/
|
||||
private boolean isTokenExpired(String token) {
|
||||
Date expiredDate = getExpiredDateFromToken(token);
|
||||
return expiredDate.before(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取过期时间
|
||||
*/
|
||||
private Date getExpiredDateFromToken(String token) {
|
||||
Claims claims = getClaimsFromToken(token);
|
||||
return claims.getExpiration();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户信息生成token
|
||||
*/
|
||||
@SneakyThrows
|
||||
public String generateToken(UserDetails userDetails) {
|
||||
Map<String, Object> claims = new HashMap<>(2);
|
||||
claims.put(CLAIM_KEY_USERNAME, new ObjectMapper().writeValueAsString(userDetails));
|
||||
claims.put(CLAIM_KEY_CREATED, new Date());
|
||||
return generateToken(claims);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断token是否可以被刷新
|
||||
*/
|
||||
public boolean canRefresh(String token) {
|
||||
return !isTokenExpired(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
*/
|
||||
public String refreshToken(String token) {
|
||||
Claims claims = getClaimsFromToken(token);
|
||||
claims.put(CLAIM_KEY_CREATED, new Date());
|
||||
return generateToken(claims);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.java2nb.novel.core.utils;
|
||||
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
|
||||
/**
|
||||
* 模板操作工具类
|
||||
* @author Administrator
|
||||
*/
|
||||
public class TemplateUtil {
|
||||
|
||||
/**
|
||||
* 存储当前线程访问的模板目录
|
||||
* */
|
||||
private static ThreadLocal<String> templateDir = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 设置当前应该访问的模板目录
|
||||
* */
|
||||
public static void setTemplateDir(String dir){
|
||||
templateDir.set(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前应该访问的模板路径前缀
|
||||
* */
|
||||
public static String getTemplateDir(){
|
||||
CacheService cacheService = SpringUtil.getBean(CacheService.class);
|
||||
String prefix = cacheService.get(CacheKey.TEMPLATE_DIR_KEY);
|
||||
if(prefix != null){
|
||||
return prefix;
|
||||
}
|
||||
return templateDir.get();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.java2nb.novel.form;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
|
||||
@Data
|
||||
public class UserForm {
|
||||
@NotBlank(message="手机号不能为空!")
|
||||
@Pattern(regexp="^1[3|4|5|6|7|8|9][0-9]{9}$",message="手机号格式不正确!")
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String username;
|
||||
|
||||
@NotBlank(message="密码不能为空!")
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String password;
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.java2nb.novel.mapper;
|
||||
|
||||
import com.java2nb.novel.vo.BookCommentVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public interface FrontBookCommentMapper extends BookCommentMapper {
|
||||
|
||||
List<BookCommentVO> listCommentByPage(@Param("userId") Long userId, @Param("bookId") Long bookId);
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.java2nb.novel.mapper;
|
||||
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.search.BookSP;
|
||||
import com.java2nb.novel.vo.BookVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public interface FrontBookMapper extends BookMapper {
|
||||
|
||||
|
||||
List<BookVO> searchByPage(BookSP params);
|
||||
|
||||
void addVisitCount(@Param("bookId") Long bookId);
|
||||
|
||||
List<Book> listRecBookByCatId(@Param("catId") Integer catId);
|
||||
|
||||
void addCommentCount(@Param("bookId") Long bookId);
|
||||
|
||||
List<Book> queryNetworkPicBooks(@Param("limit") Integer limit,@Param("offset") Integer offset);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.java2nb.novel.mapper;
|
||||
|
||||
import com.java2nb.novel.vo.BookSettingVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public interface FrontBookSettingMapper extends BookSettingMapper {
|
||||
|
||||
List<BookSettingVO> listVO();
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.java2nb.novel.mapper;
|
||||
|
||||
import com.java2nb.novel.vo.BookShelfVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public interface FrontUserBookshelfMapper extends UserBookshelfMapper {
|
||||
|
||||
List<BookShelfVO> listBookShelf(@Param("userId") Long userId);
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.java2nb.novel.mapper;
|
||||
|
||||
import com.java2nb.novel.vo.BookReadHistoryVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public interface FrontUserReadHistoryMapper extends UserReadHistoryMapper {
|
||||
|
||||
List<BookReadHistoryVO> listReadHistory(@Param("userId") Long userId);
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.java2nb.novel.search;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 小说搜索参数
|
||||
* @author 11797
|
||||
*/
|
||||
@Data
|
||||
public class BookSP {
|
||||
|
||||
private String keyword;
|
||||
|
||||
private Byte workDirection;
|
||||
|
||||
private Integer catId;
|
||||
|
||||
private Byte isVip;
|
||||
|
||||
private Byte bookStatus;
|
||||
|
||||
private Integer wordCountMin;
|
||||
|
||||
private Integer wordCountMax;
|
||||
|
||||
private Date updateTimeMin;
|
||||
|
||||
private Long updatePeriod;
|
||||
|
||||
private String sort;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
package com.java2nb.novel.service;
|
||||
|
||||
|
||||
import com.java2nb.novel.search.BookSP;
|
||||
import com.java2nb.novel.vo.BookCommentVO;
|
||||
import com.java2nb.novel.vo.BookSettingVO;
|
||||
import com.java2nb.novel.entity.*;
|
||||
import com.java2nb.novel.vo.BookVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
public interface BookService {
|
||||
|
||||
/**
|
||||
* 查询首页小说设置列表数据
|
||||
* @return
|
||||
* */
|
||||
Map<Byte, List<BookSettingVO>> listBookSettingVO();
|
||||
|
||||
/**
|
||||
* 查询首页点击榜单数据
|
||||
* @return
|
||||
* */
|
||||
List<Book> listClickRank();
|
||||
|
||||
/**
|
||||
* 查询首页新书榜单数据
|
||||
* @return
|
||||
* */
|
||||
List<Book> listNewRank();
|
||||
|
||||
/**
|
||||
* 查询首页更新榜单数据
|
||||
* @return
|
||||
* */
|
||||
List<BookVO> listUpdateRank();
|
||||
|
||||
/**
|
||||
* 分页搜索
|
||||
* @param params 搜索参数
|
||||
* @param page 页码
|
||||
* @param pageSize 分页大小
|
||||
* @return 小说集合
|
||||
* */
|
||||
List<BookVO> searchByPage(BookSP params, int page, int pageSize);
|
||||
|
||||
/**
|
||||
* 查询小说分类列表
|
||||
* @return 分类集合
|
||||
* */
|
||||
List<BookCategory> listBookCategory();
|
||||
|
||||
/**
|
||||
* 查询小说详情信息
|
||||
* @return 书籍信息
|
||||
* @param id 书籍ID*/
|
||||
Book queryBookDetail(Long id);
|
||||
|
||||
/**
|
||||
* 查询目录列表
|
||||
* @param bookId 书籍ID
|
||||
* @param orderBy 排序
|
||||
*@param limit 查询条数
|
||||
*@return 目录集合
|
||||
* */
|
||||
List<BookIndex> queryIndexList(Long bookId, String orderBy, Integer limit);
|
||||
|
||||
/**
|
||||
* 查询目录
|
||||
* @param bookIndexId 目录ID
|
||||
* @return 目录信息
|
||||
* */
|
||||
BookIndex queryBookIndex(Long bookIndexId);
|
||||
|
||||
/**
|
||||
* 查询上一章节目录ID
|
||||
* @param bookId 书籍ID
|
||||
* @param indexNum 目录号
|
||||
* @return 上一章节目录ID,没有则返回0
|
||||
* */
|
||||
Long queryPreBookIndexId(Long bookId, Integer indexNum);
|
||||
|
||||
/**
|
||||
* 查询下一章目录ID
|
||||
* @param bookId 书籍ID
|
||||
* @param indexNum 目录号
|
||||
* @return 下一章节目录ID,没有则返回0
|
||||
* */
|
||||
Long queryNextBookIndexId(Long bookId, Integer indexNum);
|
||||
|
||||
/**
|
||||
* 查询章节内容
|
||||
* @param bookIndexId 目录ID
|
||||
* @return 书籍内容
|
||||
* */
|
||||
BookContent queryBookContent(Long bookIndexId);
|
||||
|
||||
/**
|
||||
* 查询小说排行信息
|
||||
* @param type 排行类型,0点击排行,1新书排行,2更新排行
|
||||
* @param limit 查询条数
|
||||
* @return 小说集合
|
||||
* */
|
||||
List<Book> listRank(Byte type, Integer limit);
|
||||
|
||||
/**
|
||||
* 增加点击次数
|
||||
* @param bookId 书籍ID
|
||||
* */
|
||||
void addVisitCount(Long bookId);
|
||||
|
||||
/**
|
||||
* 查询章节数
|
||||
* @param bookId 书籍ID
|
||||
* @return 章节数量
|
||||
* */
|
||||
long queryIndexCount(Long bookId);
|
||||
|
||||
/**
|
||||
* 根据分类id查询同类推荐书籍
|
||||
* @param catId 分类id
|
||||
* @return 书籍集合
|
||||
* */
|
||||
List<Book> listRecBookByCatId(Integer catId);
|
||||
|
||||
/**
|
||||
* 查询首章目录ID
|
||||
* @param bookId 书籍ID
|
||||
* @return 首章目录ID
|
||||
* */
|
||||
Long queryFirstBookIndexId(Long bookId);
|
||||
|
||||
/**
|
||||
*分页查询书籍评论列表
|
||||
* @param userId 用户ID
|
||||
* @param bookId 书籍ID
|
||||
* @param page 页码
|
||||
* @param pageSize 分页大小
|
||||
* @return 评论集合
|
||||
* */
|
||||
List<BookCommentVO> listCommentByPage(Long userId, Long bookId, int page, int pageSize);
|
||||
|
||||
/**
|
||||
* 新增评价
|
||||
* @param userId 用户ID
|
||||
* @param comment 评论内容
|
||||
* */
|
||||
void addBookComment(Long userId, BookComment comment);
|
||||
|
||||
/**
|
||||
* 通过作者名获取或创建作者Id
|
||||
* @param authorName 作者名
|
||||
* @param workDirection 作品方向
|
||||
* @return 作者ID
|
||||
* */
|
||||
Long getOrCreateAuthorIdByName(String authorName, Byte workDirection);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查询小说ID
|
||||
* @param bookName 书名
|
||||
* @param author 作者名
|
||||
* @return 小说ID
|
||||
* */
|
||||
Long queryIdByNameAndAuthor(String bookName, String author);
|
||||
|
||||
/**
|
||||
* 根据小说ID查询目录号集合
|
||||
* @param bookId 小说ID
|
||||
* @return 目录号集合
|
||||
* */
|
||||
List<Integer> queryIndexNumByBookId(Long bookId);
|
||||
|
||||
/**
|
||||
* 查询网络图片的小说
|
||||
* @param limit 查询条数
|
||||
* @param offset 开始行数
|
||||
* @return 返回小说集合
|
||||
* */
|
||||
List<Book> queryNetworkPicBooks(Integer limit, Integer offset);
|
||||
|
||||
|
||||
/**
|
||||
* 更新小说网络图片到本地
|
||||
* @param picUrl 网络图片路径
|
||||
* @param bookId 小说ID
|
||||
*/
|
||||
void updateBookPicToLocal(String picUrl, Long bookId);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.java2nb.novel.service;
|
||||
|
||||
|
||||
import com.java2nb.novel.entity.FriendLink;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
public interface FriendLinkService {
|
||||
|
||||
/**
|
||||
* 查询首页友情链接
|
||||
* @return 集合
|
||||
* */
|
||||
List<FriendLink> listIndexLink();
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.java2nb.novel.service;
|
||||
|
||||
|
||||
import com.java2nb.novel.entity.News;
|
||||
import com.java2nb.novel.vo.NewsVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
public interface NewsService {
|
||||
|
||||
/**
|
||||
* 查询首页新闻
|
||||
* @return
|
||||
* */
|
||||
List<News> listIndexNews();
|
||||
|
||||
/**
|
||||
* 查询新闻
|
||||
* @param newsId 新闻id
|
||||
* @return 新闻
|
||||
* */
|
||||
News queryNewsInfo(Long newsId);
|
||||
|
||||
/**
|
||||
* 分页查询新闻列表
|
||||
* @param page 页码
|
||||
* @param pageSize 分页大小
|
||||
* @return 新闻集合
|
||||
* */
|
||||
List<NewsVO> listByPage(int page, int pageSize);
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.java2nb.novel.service;
|
||||
|
||||
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.form.UserForm;
|
||||
import com.java2nb.novel.vo.BookReadHistoryVO;
|
||||
import com.java2nb.novel.vo.BookShelfVO;
|
||||
import com.java2nb.novel.entity.User;
|
||||
import com.java2nb.novel.vo.UserFeedbackVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
public interface UserService {
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
* @param form 用户注册提交信息类
|
||||
* @return jwt载体信息类
|
||||
* */
|
||||
UserDetails register(UserForm form);
|
||||
|
||||
/**
|
||||
* 用户登陆
|
||||
* @param form 用户登陆提交信息类
|
||||
* @return jwt载体信息类
|
||||
* */
|
||||
UserDetails login(UserForm form);
|
||||
|
||||
/**
|
||||
* 查询小说是否已加入书架
|
||||
* @param userId 用户ID
|
||||
* @param bookId 小说ID
|
||||
* @return true:已加入书架,未加入书架
|
||||
* */
|
||||
Boolean queryIsInShelf(Long userId, Long bookId);
|
||||
|
||||
/**
|
||||
* 加入书架
|
||||
* @param userId 用户ID
|
||||
* @param bookId 小说ID
|
||||
* @param preContentId 阅读的内容ID
|
||||
* */
|
||||
void addToBookShelf(Long userId, Long bookId, Long preContentId);
|
||||
|
||||
/**
|
||||
* 移出书架
|
||||
* @param userId 用户ID
|
||||
* @param bookId 小说ID
|
||||
* */
|
||||
void removeFromBookShelf(Long userId, Long bookId);
|
||||
|
||||
/**
|
||||
* 查询书架
|
||||
* @param userId 用户ID
|
||||
* @param page
|
||||
* @param pageSize
|
||||
* @return 书架集合
|
||||
* */
|
||||
List<BookShelfVO> listBookShelfByPage(Long userId, int page, int pageSize);
|
||||
|
||||
/**
|
||||
* 添加阅读记录
|
||||
* @param userId 用户id
|
||||
* @param bookId 书籍id
|
||||
* @param preContentId 阅读的目录id
|
||||
* */
|
||||
void addReadHistory(Long userId, Long bookId, Long preContentId);
|
||||
|
||||
/**
|
||||
* 添加反馈
|
||||
* @param userId 用户id
|
||||
* @param content 反馈内容
|
||||
* */
|
||||
void addFeedBack(Long userId, String content);
|
||||
|
||||
/**
|
||||
* 分页查询我的反馈列表
|
||||
* @param userId 用户ID
|
||||
* @param page 页码
|
||||
* @param pageSize 分页大小
|
||||
* @return 反馈集合
|
||||
* */
|
||||
List<UserFeedbackVO> listUserFeedBackByPage(Long userId, int page, int pageSize);
|
||||
|
||||
/**
|
||||
* 查询个人信息
|
||||
* @param userId 用户id
|
||||
* @return 用户信息
|
||||
* */
|
||||
User userInfo(Long userId);
|
||||
|
||||
/**
|
||||
* 分页查询阅读记录
|
||||
* @param userId 用户id
|
||||
* @param page 页码
|
||||
* @param pageSize 分页大小
|
||||
* @return
|
||||
* */
|
||||
List<BookReadHistoryVO> listReadHistoryByPage(Long userId, int page, int pageSize);
|
||||
|
||||
/**
|
||||
* 更新个人信息
|
||||
* @param userId 用户id
|
||||
* @param user 需要更新的信息
|
||||
* */
|
||||
void updateUserInfo(Long userId, User user);
|
||||
|
||||
/**
|
||||
* 更新密码
|
||||
* @param userId 用户id
|
||||
* @param oldPassword 旧密码
|
||||
* @param newPassword 新密码
|
||||
* */
|
||||
void updatePassword(Long userId, String oldPassword, String newPassword);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,403 @@
|
||||
package com.java2nb.novel.service.impl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.core.exception.BusinessException;
|
||||
import com.java2nb.novel.core.utils.BeanUtil;
|
||||
import com.java2nb.novel.core.utils.Constants;
|
||||
import com.java2nb.novel.core.utils.FileUtil;
|
||||
import com.java2nb.novel.core.utils.IdWorker;
|
||||
import com.java2nb.novel.entity.*;
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import com.java2nb.novel.mapper.*;
|
||||
import com.java2nb.novel.search.BookSP;
|
||||
import com.java2nb.novel.service.BookService;
|
||||
import com.java2nb.novel.vo.BookCommentVO;
|
||||
import com.java2nb.novel.vo.BookSettingVO;
|
||||
import com.java2nb.novel.vo.BookVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.mybatis.dynamic.sql.SortSpecification;
|
||||
import org.mybatis.dynamic.sql.render.RenderingStrategies;
|
||||
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import tk.mybatis.orderbyhelper.OrderByHelper;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.java2nb.novel.mapper.BookCategoryDynamicSqlSupport.bookCategory;
|
||||
import static com.java2nb.novel.mapper.BookCommentDynamicSqlSupport.bookComment;
|
||||
import static com.java2nb.novel.mapper.BookContentDynamicSqlSupport.bookContent;
|
||||
import static com.java2nb.novel.mapper.BookDynamicSqlSupport.*;
|
||||
import static com.java2nb.novel.mapper.BookIndexDynamicSqlSupport.bookIndex;
|
||||
import static org.mybatis.dynamic.sql.SqlBuilder.*;
|
||||
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class BookServiceImpl implements BookService {
|
||||
|
||||
/**
|
||||
* 本地图片保存路径
|
||||
* */
|
||||
@Value("${pic.save.path}")
|
||||
private String picSavePath;
|
||||
|
||||
private final FrontBookSettingMapper bookSettingMapper;
|
||||
|
||||
private final FrontBookMapper bookMapper;
|
||||
|
||||
private final BookCategoryMapper bookCategoryMapper;
|
||||
|
||||
private final BookIndexMapper bookIndexMapper;
|
||||
|
||||
private final BookContentMapper bookContentMapper;
|
||||
|
||||
private final FrontBookCommentMapper bookCommentMapper;
|
||||
|
||||
private final BookAuthorMapper bookAuthorMapper;
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
|
||||
@Override
|
||||
public Map<Byte, List<BookSettingVO>> listBookSettingVO() {
|
||||
Map<Byte, List<BookSettingVO>> result = (Map<Byte, List<BookSettingVO>>) cacheService.getObject(CacheKey.INDEX_BOOK_SETTINGS_KEY);
|
||||
if (result == null || result.size() == 0) {
|
||||
List<BookSettingVO> list = bookSettingMapper.listVO();
|
||||
result = list.stream().collect(Collectors.groupingBy(BookSettingVO::getType));
|
||||
cacheService.setObject(CacheKey.INDEX_BOOK_SETTINGS_KEY, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> listClickRank() {
|
||||
List<Book> result = (List<Book>) cacheService.getObject(CacheKey.INDEX_CLICK_BANK_BOOK_KEY);
|
||||
if (result == null || result.size() == 0) {
|
||||
result = listRank((byte) 0, 10);
|
||||
cacheService.setObject(CacheKey.INDEX_CLICK_BANK_BOOK_KEY, result, 5000);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> listNewRank() {
|
||||
List<Book> result = (List<Book>) cacheService.getObject(CacheKey.INDEX_NEW_BOOK_KEY);
|
||||
if (result == null || result.size() == 0) {
|
||||
result = listRank((byte) 1, 10);
|
||||
cacheService.setObject(CacheKey.INDEX_NEW_BOOK_KEY, result, 3600);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookVO> listUpdateRank() {
|
||||
List<BookVO> result = (List<BookVO>) cacheService.getObject(CacheKey.INDEX_UPDATE_BOOK_KEY);
|
||||
if (result == null || result.size() == 0) {
|
||||
List<Book> bookPOList = listRank((byte) 2, 23);
|
||||
result = BeanUtil.copyList(bookPOList,BookVO.class);
|
||||
cacheService.setObject(CacheKey.INDEX_UPDATE_BOOK_KEY, result, 60 * 10);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookVO> searchByPage(BookSP params, int page, int pageSize) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
if (params.getUpdatePeriod() != null) {
|
||||
long cur = System.currentTimeMillis();
|
||||
long period = params.getUpdatePeriod() * 24 * 3600 * 1000;
|
||||
long time = cur - period;
|
||||
params.setUpdateTimeMin(new Date(time));
|
||||
}
|
||||
if (StringUtils.isNotBlank(params.getSort())) {
|
||||
OrderByHelper.orderBy(params.getSort() + " desc");
|
||||
}
|
||||
return bookMapper.searchByPage(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookCategory> listBookCategory() {
|
||||
SelectStatementProvider selectStatementProvider = select(BookCategoryDynamicSqlSupport.id, BookCategoryDynamicSqlSupport.name, BookCategoryDynamicSqlSupport.workDirection)
|
||||
.from(bookCategory)
|
||||
.orderBy(BookCategoryDynamicSqlSupport.sort)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return bookCategoryMapper.selectMany(selectStatementProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Book queryBookDetail(Long bookId) {
|
||||
SelectStatementProvider selectStatement = select(id, catName, catId, picUrl, bookName, authorId, authorName, bookDesc, bookStatus, visitCount, wordCount, lastIndexId, lastIndexName, lastIndexUpdateTime,score)
|
||||
.from(book)
|
||||
.where(id, isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return bookMapper.selectMany(selectStatement).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookIndex> queryIndexList(Long bookId,String orderBy, Integer limit) {
|
||||
if(StringUtils.isNotBlank(orderBy)){
|
||||
OrderByHelper.orderBy(orderBy);
|
||||
}
|
||||
if(limit != null){
|
||||
PageHelper.startPage(1,limit);
|
||||
}
|
||||
|
||||
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.id, BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.indexNum, BookIndexDynamicSqlSupport.indexName, BookIndexDynamicSqlSupport.updateTime)
|
||||
.from(bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
|
||||
return bookIndexMapper.selectMany(selectStatement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BookIndex queryBookIndex(Long bookIndexId) {
|
||||
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.id, BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.indexNum, BookIndexDynamicSqlSupport.indexName, BookIndexDynamicSqlSupport.wordCount, BookIndexDynamicSqlSupport.updateTime)
|
||||
.from(bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.id, isEqualTo(bookIndexId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return bookIndexMapper.selectMany(selectStatement).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long queryPreBookIndexId(Long bookId, Integer indexNum) {
|
||||
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.id)
|
||||
.from(bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.and(BookIndexDynamicSqlSupport.indexNum, isLessThan(indexNum))
|
||||
.orderBy(BookIndexDynamicSqlSupport.indexNum.descending())
|
||||
.limit(1)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
List<BookIndex> list = bookIndexMapper.selectMany(selectStatement);
|
||||
if (list.size() == 0) {
|
||||
return 0L;
|
||||
} else {
|
||||
return list.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long queryNextBookIndexId(Long bookId, Integer indexNum) {
|
||||
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.id)
|
||||
.from(bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.and(BookIndexDynamicSqlSupport.indexNum, isGreaterThan(indexNum))
|
||||
.orderBy(BookIndexDynamicSqlSupport.indexNum)
|
||||
.limit(1)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
List<BookIndex> list = bookIndexMapper.selectMany(selectStatement);
|
||||
if (list.size() == 0) {
|
||||
return 0L;
|
||||
} else {
|
||||
return list.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BookContent queryBookContent(Long bookIndexId) {
|
||||
SelectStatementProvider selectStatement = select(BookContentDynamicSqlSupport.id,BookContentDynamicSqlSupport.content)
|
||||
.from(bookContent)
|
||||
.where(BookContentDynamicSqlSupport.indexId, isEqualTo(bookIndexId))
|
||||
.limit(1)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return bookContentMapper.selectMany(selectStatement).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> listRank(Byte type, Integer limit) {
|
||||
SortSpecification sortSpecification = visitCount.descending();
|
||||
switch (type) {
|
||||
case 1: {
|
||||
//最新入库排序
|
||||
sortSpecification = createTime.descending();
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
//最新更新时间排序
|
||||
sortSpecification = lastIndexUpdateTime.descending();
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
//评论数量排序
|
||||
sortSpecification = commentCount.descending();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SelectStatementProvider selectStatement = select(id, catId, catName, bookName, lastIndexId, lastIndexName, authorId, authorName, picUrl, bookDesc, wordCount, lastIndexUpdateTime)
|
||||
.from(book)
|
||||
.orderBy(sortSpecification)
|
||||
.limit(limit)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return bookMapper.selectMany(selectStatement);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVisitCount(Long bookId) {
|
||||
bookMapper.addVisitCount(bookId);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long queryIndexCount(Long bookId) {
|
||||
SelectStatementProvider selectStatement = select(count(BookIndexDynamicSqlSupport.id))
|
||||
.from(bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
|
||||
return bookIndexMapper.count(selectStatement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> listRecBookByCatId(Integer catId) {
|
||||
return bookMapper.listRecBookByCatId(catId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long queryFirstBookIndexId(Long bookId) {
|
||||
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.id)
|
||||
.from(bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.orderBy(BookIndexDynamicSqlSupport.indexNum)
|
||||
.limit(1)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return bookIndexMapper.selectMany(selectStatement).get(0).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookCommentVO> listCommentByPage(Long userId,Long bookId, int page, int pageSize) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
OrderByHelper.orderBy("t1.create_time desc");
|
||||
return bookCommentMapper.listCommentByPage(userId,bookId);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void addBookComment(Long userId, BookComment comment) {
|
||||
//判断该用户是否已评论过该书籍
|
||||
SelectStatementProvider selectStatement = select(count(BookCommentDynamicSqlSupport.id))
|
||||
.from(bookComment)
|
||||
.where(BookCommentDynamicSqlSupport.createUserId,isEqualTo(userId))
|
||||
.and(BookCommentDynamicSqlSupport.bookId,isEqualTo(comment.getBookId()))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
if(bookCommentMapper.count(selectStatement)>0){
|
||||
throw new BusinessException(ResponseStatus.HAS_COMMENTS);
|
||||
}
|
||||
//增加评论
|
||||
comment.setCreateUserId(userId);
|
||||
comment.setCreateTime(new Date());
|
||||
bookCommentMapper.insertSelective(comment);
|
||||
//增加书籍评论数
|
||||
bookMapper.addCommentCount(comment.getBookId());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getOrCreateAuthorIdByName(String authorName, Byte workDirection) {
|
||||
Long authorId;
|
||||
SelectStatementProvider selectStatement = select(BookAuthorDynamicSqlSupport.id)
|
||||
.from(BookAuthorDynamicSqlSupport.bookAuthor)
|
||||
.where(BookAuthorDynamicSqlSupport.penName,isEqualTo(authorName))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
List<BookAuthor> bookAuthors = bookAuthorMapper.selectMany(selectStatement);
|
||||
if(bookAuthors.size()>0){
|
||||
//作者存在
|
||||
authorId = bookAuthors.get(0).getId();
|
||||
}else{
|
||||
//作者不存在,先创建作者
|
||||
Date currentDate = new Date();
|
||||
authorId = new IdWorker().nextId();
|
||||
BookAuthor bookAuthor = new BookAuthor();
|
||||
bookAuthor.setId(authorId);
|
||||
bookAuthor.setPenName(authorName);
|
||||
bookAuthor.setWorkDirection(workDirection);
|
||||
bookAuthor.setStatus((byte) 1);
|
||||
bookAuthor.setCreateTime(currentDate);
|
||||
bookAuthor.setUpdateTime(currentDate);
|
||||
bookAuthorMapper.insertSelective(bookAuthor);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return authorId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Long queryIdByNameAndAuthor(String bookName, String author) {
|
||||
//查询小说ID
|
||||
SelectStatementProvider selectStatement = select(id)
|
||||
.from(book)
|
||||
.where(BookDynamicSqlSupport.bookName,isEqualTo(bookName))
|
||||
.and(BookDynamicSqlSupport.authorName,isEqualTo(authorName))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
List<Book> books = bookMapper.selectMany(selectStatement);
|
||||
if(books.size()>0){
|
||||
return books.get(0).getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> queryIndexNumByBookId(Long bookId) {
|
||||
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.indexNum)
|
||||
.from(BookIndexDynamicSqlSupport.bookIndex)
|
||||
.where(BookIndexDynamicSqlSupport.bookId,isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
|
||||
return bookIndexMapper.selectMany(selectStatement).stream().map(BookIndex::getIndexNum).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> queryNetworkPicBooks(Integer limit, Integer offset) {
|
||||
return bookMapper.queryNetworkPicBooks(limit,offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBookPicToLocal(String picUrl, Long bookId) {
|
||||
|
||||
picUrl = FileUtil.network2Local(picUrl,picSavePath, Constants.LOCAL_PIC_PREFIX);
|
||||
|
||||
bookMapper.update(update(book)
|
||||
.set(BookDynamicSqlSupport.picUrl)
|
||||
.equalTo(picUrl)
|
||||
.set(updateTime)
|
||||
.equalTo(new Date())
|
||||
.where(id,isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.java2nb.novel.service.impl;
|
||||
|
||||
import com.java2nb.novel.core.utils.BeanUtil;
|
||||
import com.java2nb.novel.service.FriendLinkService;
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.entity.FriendLink;
|
||||
import com.java2nb.novel.mapper.FriendLinkMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.mybatis.dynamic.sql.render.RenderingStrategies;
|
||||
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.java2nb.novel.mapper.FriendLinkDynamicSqlSupport.*;
|
||||
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
|
||||
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class FriendLinkServiceImpl implements FriendLinkService {
|
||||
|
||||
private final FriendLinkMapper friendLinkMapper;
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
|
||||
@Override
|
||||
public List<FriendLink> listIndexLink() {
|
||||
List<FriendLink> result = (List<FriendLink>) cacheService.getObject(CacheKey.INDEX_LINK_KEY);
|
||||
if(result == null || result.size() == 0) {
|
||||
SelectStatementProvider selectStatement = select(linkName,linkUrl)
|
||||
.from(friendLink)
|
||||
.where(isOpen,isEqualTo((byte)1))
|
||||
.orderBy(sort)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
result = friendLinkMapper.selectMany(selectStatement);
|
||||
cacheService.setObject(CacheKey.INDEX_LINK_KEY,result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.java2nb.novel.service.impl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.java2nb.novel.core.utils.BeanUtil;
|
||||
import com.java2nb.novel.service.NewsService;
|
||||
import com.java2nb.novel.core.cache.CacheKey;
|
||||
import com.java2nb.novel.core.cache.CacheService;
|
||||
import com.java2nb.novel.entity.News;
|
||||
import com.java2nb.novel.mapper.NewsMapper;
|
||||
import com.java2nb.novel.vo.NewsVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.mybatis.dynamic.sql.render.RenderingStrategies;
|
||||
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.java2nb.novel.mapper.NewsDynamicSqlSupport.*;
|
||||
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
|
||||
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class NewsServiceImpl implements NewsService {
|
||||
|
||||
private final NewsMapper newsMapper;
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
|
||||
@Override
|
||||
public List<News> listIndexNews() {
|
||||
List<News> result = (List<News>) cacheService.getObject(CacheKey.INDEX_NEWS_KEY);
|
||||
if(result == null || result.size() == 0) {
|
||||
SelectStatementProvider selectStatement = select(id, catName, catId, title)
|
||||
.from(news)
|
||||
.orderBy(createTime.descending())
|
||||
.limit(2)
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
result = newsMapper.selectMany(selectStatement);
|
||||
cacheService.setObject(CacheKey.INDEX_NEWS_KEY,result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public News queryNewsInfo(Long newsId) {
|
||||
SelectStatementProvider selectStatement = select(news.allColumns())
|
||||
.from(news)
|
||||
.where(id,isEqualTo(newsId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return newsMapper.selectMany(selectStatement).get(0);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NewsVO> listByPage(int page, int pageSize) {
|
||||
PageHelper.startPage(page,pageSize);
|
||||
SelectStatementProvider selectStatement = select(id, catName, catId, title,createTime)
|
||||
.from(news)
|
||||
.orderBy(createTime.descending())
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
|
||||
return BeanUtil.copyList(newsMapper.selectMany(selectStatement),NewsVO.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,261 @@
|
||||
package com.java2nb.novel.service.impl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.core.utils.BeanUtil;
|
||||
import com.java2nb.novel.form.UserForm;
|
||||
import com.java2nb.novel.service.UserService;
|
||||
import com.java2nb.novel.core.enums.ResponseStatus;
|
||||
import com.java2nb.novel.core.exception.BusinessException;
|
||||
import com.java2nb.novel.entity.User;
|
||||
import com.java2nb.novel.entity.UserBookshelf;
|
||||
import com.java2nb.novel.entity.UserFeedback;
|
||||
import com.java2nb.novel.entity.UserReadHistory;
|
||||
import com.java2nb.novel.mapper.*;
|
||||
import com.java2nb.novel.vo.BookReadHistoryVO;
|
||||
import com.java2nb.novel.vo.BookShelfVO;
|
||||
import com.java2nb.novel.core.utils.IdWorker;
|
||||
import com.java2nb.novel.core.utils.MD5Util;
|
||||
import com.java2nb.novel.vo.UserFeedbackVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
|
||||
import org.mybatis.dynamic.sql.render.RenderingStrategies;
|
||||
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
|
||||
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static com.java2nb.novel.mapper.UserBookshelfDynamicSqlSupport.userBookshelf;
|
||||
import static com.java2nb.novel.mapper.UserDynamicSqlSupport.*;
|
||||
import static com.java2nb.novel.mapper.UserFeedbackDynamicSqlSupport.userFeedback;
|
||||
import static com.java2nb.novel.mapper.UserReadHistoryDynamicSqlSupport.userReadHistory;
|
||||
import static org.mybatis.dynamic.sql.SqlBuilder.*;
|
||||
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
private final UserMapper userMapper;
|
||||
|
||||
private final FrontUserBookshelfMapper userBookshelfMapper;
|
||||
|
||||
private final FrontUserReadHistoryMapper userReadHistoryMapper;
|
||||
|
||||
private final UserFeedbackMapper userFeedbackMapper;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public UserDetails register(UserForm form) {
|
||||
//查询用户名是否已注册
|
||||
SelectStatementProvider selectStatement = select(count(id))
|
||||
.from(user)
|
||||
.where(username, isEqualTo(form.getUsername()))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
long count = userMapper.count(selectStatement);
|
||||
if (count > 0) {
|
||||
//用户名已注册
|
||||
throw new BusinessException(ResponseStatus.USERNAME_EXIST);
|
||||
}
|
||||
User entity = new User();
|
||||
BeanUtils.copyProperties(form,entity);
|
||||
//数据库生成注册记录
|
||||
Long id = new IdWorker().nextId();
|
||||
entity.setId(id);
|
||||
entity.setNickName(entity.getUsername());
|
||||
Date currentDate = new Date();
|
||||
entity.setCreateTime(currentDate);
|
||||
entity.setUpdateTime(currentDate);
|
||||
entity.setPassword(MD5Util.MD5Encode(entity.getPassword(), Charsets.UTF_8.name()));
|
||||
userMapper.insertSelective(entity);
|
||||
//生成UserDetail对象并返回
|
||||
UserDetails userDetails = new UserDetails();
|
||||
userDetails.setId(id);
|
||||
userDetails.setUsername(entity.getUsername());
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails login(UserForm form) {
|
||||
//根据用户名密码查询记录
|
||||
SelectStatementProvider selectStatement = select(id, username)
|
||||
.from(user)
|
||||
.where(username, isEqualTo(form.getUsername()))
|
||||
.and(password, isEqualTo(MD5Util.MD5Encode(form.getPassword(), Charsets.UTF_8.name())))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
List<User> users = userMapper.selectMany(selectStatement);
|
||||
if (users.size() == 0) {
|
||||
throw new BusinessException(ResponseStatus.USERNAME_PASS_ERROR);
|
||||
}
|
||||
//生成UserDetail对象并返回
|
||||
UserDetails userDetails = new UserDetails();
|
||||
userDetails.setId(users.get(0).getId());
|
||||
userDetails.setUsername(form.getUsername());
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean queryIsInShelf(Long userId, Long bookId) {
|
||||
SelectStatementProvider selectStatement = select(count(UserBookshelfDynamicSqlSupport.id))
|
||||
.from(userBookshelf)
|
||||
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
|
||||
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
|
||||
return userBookshelfMapper.count(selectStatement) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToBookShelf(Long userId, Long bookId, Long preContentId) {
|
||||
if (!queryIsInShelf(userId, bookId)) {
|
||||
UserBookshelf shelf = new UserBookshelf();
|
||||
shelf.setUserId(userId);
|
||||
shelf.setBookId(bookId);
|
||||
shelf.setPreContentId(preContentId);
|
||||
shelf.setCreateTime(new Date());
|
||||
userBookshelfMapper.insert(shelf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFromBookShelf(Long userId, Long bookId) {
|
||||
DeleteStatementProvider deleteStatement = deleteFrom(userBookshelf)
|
||||
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
|
||||
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
userBookshelfMapper.delete(deleteStatement);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookShelfVO> listBookShelfByPage(Long userId, int page, int pageSize) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
return userBookshelfMapper.listBookShelf(userId);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void addReadHistory(Long userId, Long bookId, Long preContentId) {
|
||||
|
||||
Date currentDate = new Date();
|
||||
//删除该书以前的历史记录
|
||||
DeleteStatementProvider deleteStatement = deleteFrom(userReadHistory)
|
||||
.where(UserReadHistoryDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.and(UserReadHistoryDynamicSqlSupport.userId, isEqualTo(userId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
userReadHistoryMapper.delete(deleteStatement);
|
||||
|
||||
//插入该书新的历史记录
|
||||
UserReadHistory userReadHistory = new UserReadHistory();
|
||||
userReadHistory.setBookId(bookId);
|
||||
userReadHistory.setUserId(userId);
|
||||
userReadHistory.setPreContentId(preContentId);
|
||||
userReadHistory.setCreateTime(currentDate);
|
||||
userReadHistory.setUpdateTime(currentDate);
|
||||
userReadHistoryMapper.insertSelective(userReadHistory);
|
||||
|
||||
|
||||
//更新书架的阅读历史
|
||||
UpdateStatementProvider updateStatement = update(userBookshelf)
|
||||
.set(UserBookshelfDynamicSqlSupport.preContentId)
|
||||
.equalTo(preContentId)
|
||||
.set(UserBookshelfDynamicSqlSupport.updateTime)
|
||||
.equalTo(currentDate)
|
||||
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
|
||||
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
|
||||
userBookshelfMapper.update(updateStatement);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeedBack(Long userId, String content) {
|
||||
UserFeedback feedback = new UserFeedback();
|
||||
feedback.setUserId(userId);
|
||||
feedback.setContent(content);
|
||||
feedback.setCreateTime(new Date());
|
||||
userFeedbackMapper.insertSelective(feedback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserFeedbackVO> listUserFeedBackByPage(Long userId, int page, int pageSize) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
SelectStatementProvider selectStatement = select(UserFeedbackDynamicSqlSupport.content, UserFeedbackDynamicSqlSupport.createTime)
|
||||
.from(userFeedback)
|
||||
.where(UserFeedbackDynamicSqlSupport.userId, isEqualTo(userId))
|
||||
.orderBy(UserFeedbackDynamicSqlSupport.id.descending())
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return BeanUtil.copyList(userFeedbackMapper.selectMany(selectStatement),UserFeedbackVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User userInfo(Long userId) {
|
||||
SelectStatementProvider selectStatement = select(username, nickName, userPhoto,userSex)
|
||||
.from(user)
|
||||
.where(id, isEqualTo(userId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
return userMapper.selectMany(selectStatement).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookReadHistoryVO> listReadHistoryByPage(Long userId, int page, int pageSize) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
return userReadHistoryMapper.listReadHistory(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserInfo(Long userId, User user) {
|
||||
User updateUser = new User();
|
||||
updateUser.setId(userId);
|
||||
updateUser.setNickName(user.getNickName());
|
||||
updateUser.setUserSex(user.getUserSex());
|
||||
updateUser.setUpdateTime(new Date());
|
||||
userMapper.updateByPrimaryKeySelective(updateUser);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePassword(Long userId, String oldPassword, String newPassword) {
|
||||
SelectStatementProvider selectStatement = select(password)
|
||||
.from(user)
|
||||
.where(id,isEqualTo(userId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
if(!userMapper.selectMany(selectStatement).get(0).getPassword().equals(MD5Util.MD5Encode(oldPassword, Charsets.UTF_8.name()))){
|
||||
throw new BusinessException(ResponseStatus.OLD_PASSWORD_ERROR);
|
||||
}
|
||||
UpdateStatementProvider updateStatement = update(user)
|
||||
.set(password)
|
||||
.equalTo(MD5Util.MD5Encode(newPassword, Charsets.UTF_8.name()))
|
||||
.where(id,isEqualTo(userId))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
userMapper.update(updateStatement);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.java2nb.novel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.BookComment;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Data
|
||||
public class BookCommentVO extends BookComment {
|
||||
|
||||
private String createUserName;
|
||||
|
||||
private String createUserPhoto;
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.java2nb.novel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.UserReadHistory;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Data
|
||||
public class BookReadHistoryVO extends UserReadHistory {
|
||||
|
||||
private Integer catId;
|
||||
private String catName;
|
||||
private Long lastIndexId;
|
||||
|
||||
private String lastIndexName;
|
||||
private String bookName;
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "MM/dd HH:mm:ss")
|
||||
private Date lastIndexUpdateTime;
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.java2nb.novel.vo;
|
||||
|
||||
import com.java2nb.novel.entity.BookSetting;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Data
|
||||
public class BookSettingVO extends BookSetting implements Serializable {
|
||||
|
||||
private String bookName;
|
||||
|
||||
private String picUrl;
|
||||
|
||||
private String authorName;
|
||||
|
||||
private String bookDesc;
|
||||
|
||||
private Float score;
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.java2nb.novel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.UserBookshelf;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@Data
|
||||
public class BookShelfVO extends UserBookshelf {
|
||||
|
||||
private Integer catId;
|
||||
private String catName;
|
||||
private Long lastIndexId;
|
||||
|
||||
private String lastIndexName;
|
||||
private String bookName;
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "MM/dd HH:mm:ss")
|
||||
private Date lastIndexUpdateTime;
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
20
novel-front/src/main/java/com/java2nb/novel/vo/BookVO.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.java2nb.novel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.Book;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Data
|
||||
public class BookVO extends Book implements Serializable {
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "MM/dd HH:mm")
|
||||
private Date lastIndexUpdateTime;
|
||||
|
||||
|
||||
}
|
17
novel-front/src/main/java/com/java2nb/novel/vo/NewsVO.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.java2nb.novel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.News;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Data
|
||||
public class NewsVO extends News {
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
private Date createTime;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.java2nb.novel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.java2nb.novel.entity.UserFeedback;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Data
|
||||
public class UserFeedbackVO extends UserFeedback {
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
3
novel-front/src/main/resources/application-dev.yml
Normal file
@ -0,0 +1,3 @@
|
||||
spring:
|
||||
profiles:
|
||||
include: [common-dev]
|
3
novel-front/src/main/resources/application-test.yml
Normal file
@ -0,0 +1,3 @@
|
||||
spring:
|
||||
profiles:
|
||||
include: [common-test]
|
18
novel-front/src/main/resources/application.yml
Normal file
@ -0,0 +1,18 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
|
||||
jwt:
|
||||
secret: novel!#20191230
|
||||
expiration: 604800
|
||||
|
||||
#缓存管理密码
|
||||
cache:
|
||||
manager:
|
||||
password: novel@2020117
|
||||
|
||||
|
||||
|
30
novel-front/src/main/resources/ehcache.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="ehcache.xsd">
|
||||
<!--timeToIdleSeconds 当缓存闲置n秒后销毁 -->
|
||||
<!--timeToLiveSeconds 当缓存存活n秒后销毁 -->
|
||||
<!-- 缓存配置 name:缓存名称。 maxElementsInMemory:缓存最大个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。
|
||||
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
|
||||
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
|
||||
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
|
||||
maxElementsOnDisk:硬盘最大缓存个数。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk
|
||||
store persists between restarts of the Virtual Machine. The default value
|
||||
is false. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是
|
||||
LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 maxEntriesLocalHeap="1000"
|
||||
: 堆内存中最大缓存对象数,0没有限制(必须设置) maxEntriesLocalDisk="1000" : 硬盘最大缓存个数。 -->
|
||||
<!-- 磁盘缓存位置 -->
|
||||
<diskStore path="user.dir/cachedata" />
|
||||
|
||||
<!-- 默认缓存 -->
|
||||
<defaultCache maxElementsInMemory="10000" eternal="false"
|
||||
timeToIdleSeconds="120" timeToLiveSeconds="120"
|
||||
maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120"
|
||||
memoryStoreEvictionPolicy="LRU">
|
||||
|
||||
<persistence strategy="localTempSwap" />
|
||||
</defaultCache>
|
||||
|
||||
|
||||
<cache name="util_cache" maxEntriesLocalHeap="0" eternal="true"
|
||||
overflowToDisk="true" diskPersistent="true" />
|
||||
|
||||
</ehcache>
|
64
novel-front/src/main/resources/logback-boot.xml
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 彩色日志依赖的渲染类 -->
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
||||
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
|
||||
<!-- 彩色日志格式 -->
|
||||
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
|
||||
|
||||
<!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,%i索引【从数字0开始递增】,,, -->
|
||||
<!-- appender是configuration的子节点,是负责写日志的组件。 -->
|
||||
<!-- ConsoleAppender:把日志输出到控制台 -->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<!--
|
||||
<pattern>%d %p (%file:%line\)- %m%n</pattern>
|
||||
-->
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
|
||||
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是demo.log -->
|
||||
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过1KB时,对当前日志进行分割 重命名 -->
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
|
||||
<File>logs/novel-front.log</File>
|
||||
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
|
||||
<!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
|
||||
<!-- 文件名:logs/demo.2017-12-05.0.log -->
|
||||
<fileNamePattern>logs/debug.%d.%i.log</fileNamePattern>
|
||||
<!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
|
||||
<maxHistory>30</maxHistory>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成1KB看效果 -->
|
||||
<maxFileSize>10MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<!-- pattern节点,用来设置日志的输入格式 -->
|
||||
<pattern>
|
||||
%d %p (%file:%line\)- %m%n
|
||||
</pattern>
|
||||
<!-- 记录日志的编码:此处设置字符集 - -->
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- 控制台输出日志级别 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
|
||||
<!-- com.maijinjie.springboot 为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->
|
||||
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
|
||||
<logger name="com.java2nb" level="DEBUG">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</logger>
|
||||
</configuration>
|
@ -0,0 +1,23 @@
|
||||
<?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.java2nb.novel.mapper.FrontBookCommentMapper">
|
||||
|
||||
<select id="listCommentByPage" resultType="com.java2nb.novel.vo.BookCommentVO">
|
||||
select t1.id,t1.book_id,t1.comment_content,t1.reply_count,t1.create_time,t2.username create_user_name,t2.user_photo create_user_photo
|
||||
from book_comment t1 inner join user t2 on t1.create_user_id = t2.id
|
||||
<trim>
|
||||
<if test="bookId != null">
|
||||
and t1.book_id = #{bookId}
|
||||
</if>
|
||||
<if test="userId != null">
|
||||
and t1.create_user_id = #{userId}
|
||||
</if>
|
||||
</trim>
|
||||
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,63 @@
|
||||
<?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.java2nb.novel.mapper.FrontBookMapper">
|
||||
|
||||
<select id="searchByPage" parameterType="com.java2nb.novel.search.BookSP" resultType="com.java2nb.novel.vo.BookVO">
|
||||
select id,cat_id,cat_name,book_name,author_id,author_name,word_count,last_index_id,last_index_name,score,pic_url,book_status,last_index_update_time,book_desc
|
||||
from book
|
||||
<where>
|
||||
<if test="keyword != null and keyword != ''">
|
||||
and (book_name like concat('%',#{keyword},'%') or author_name like concat('%',#{keyword},'%'))
|
||||
</if>
|
||||
<if test="workDirection != null">
|
||||
and work_direction = #{workDirection}
|
||||
</if>
|
||||
<if test="catId != null">
|
||||
and cat_id = #{catId}
|
||||
</if>
|
||||
<if test="isVip != null">
|
||||
and is_vip = #{isVip}
|
||||
</if>
|
||||
<if test="bookStatus != null">
|
||||
and book_status = #{bookStatus}
|
||||
</if>
|
||||
<if test="wordCountMin != null">
|
||||
and word_count >= #{wordCountMin}
|
||||
</if>
|
||||
<if test="wordCountMax != null">
|
||||
and word_count <![CDATA[ < ]]> #{wordCountMax}
|
||||
</if>
|
||||
<if test="updateTimeMin != null">
|
||||
and last_index_update_time >= #{updateTimeMin}
|
||||
</if>
|
||||
</where>
|
||||
|
||||
</select>
|
||||
|
||||
<update id="addVisitCount" parameterType="long">
|
||||
update book set visit_count = visit_count + 1 where id = #{bookId}
|
||||
</update>
|
||||
|
||||
<select id="listRecBookByCatId" parameterType="int" resultType="com.java2nb.novel.entity.Book">
|
||||
select id,pic_url,book_name,book_desc
|
||||
from book
|
||||
where cat_id = #{catId}
|
||||
order by RAND() LIMIT 4
|
||||
</select>
|
||||
|
||||
|
||||
<update id="addCommentCount" parameterType="long">
|
||||
update book set comment_count = comment_count+1
|
||||
where id = #{bookId}
|
||||
</update>
|
||||
|
||||
<select id="queryNetworkPicBooks" resultType="com.java2nb.novel.entity.Book">
|
||||
select
|
||||
id,pic_url from book
|
||||
where pic_url like 'http://%' or pic_url like 'https://%'
|
||||
limit #{offset},#{limit}
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,15 @@
|
||||
<?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.java2nb.novel.mapper.FrontBookSettingMapper">
|
||||
|
||||
<select id="listVO" resultType="com.java2nb.novel.vo.BookSettingVO">
|
||||
select t1.book_id,t1.type,t1.sort,t2.book_name,t2.author_name,t2.pic_url,t2.book_desc,t2.score
|
||||
from book_setting t1 inner join book t2
|
||||
on t1.book_id = t2.id
|
||||
order by t1.sort
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,15 @@
|
||||
<?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.java2nb.novel.mapper.FrontUserBookshelfMapper">
|
||||
|
||||
<select id="listBookShelf" parameterType="long" resultType="com.java2nb.novel.vo.BookShelfVO">
|
||||
select t1.book_id,t1.pre_content_id,t2.book_name,t2.cat_id,t2.cat_name,t2.last_index_id,t2.last_index_name,t2.last_index_update_time
|
||||
from user_bookshelf t1 inner join book t2 on t1.book_id = t2.id and t1.user_id = #{userId}
|
||||
order by t1.create_time desc
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,15 @@
|
||||
<?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.java2nb.novel.mapper.FrontUserReadHistoryMapper">
|
||||
|
||||
<select id="listReadHistory" parameterType="long" resultType="com.java2nb.novel.vo.BookReadHistoryVO">
|
||||
select t1.book_id,t1.pre_content_id,t2.book_name,t2.cat_id,t2.cat_name,t2.last_index_id,t2.last_index_name,t2.last_index_update_time
|
||||
from user_read_history t1 inner join book t2 on t1.book_id = t2.id and t1.user_id = #{userId}
|
||||
order by t1.create_time desc
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
26
novel-front/src/main/resources/static/css/about.css
Normal file
@ -0,0 +1,26 @@
|
||||
@charset "utf-8";
|
||||
.userBox { width: 998px; border: 1px solid #eaeaea; margin: 0 auto 50px; background: #fff }
|
||||
.my_l { width: 198px; float: left; font-size: 13px;
|
||||
padding-top: 20px; }
|
||||
.my_l li a { display: block; height: 48px; line-height: 48px; padding-left: 40px; border-left: 2px solid transparent; font-size: 14px; margin: 0 0 2px; }
|
||||
.my_l li .on { border-left: 2px solid #f80; background: #f8f8f8 }
|
||||
.my_r { width: 739px; padding: 30px; float: right; border-left: 1px solid #ededed; min-height: 470px; background: #fff }
|
||||
.my_r .title { padding: 15px 0 }
|
||||
.my_r h4 { font-size: 15px; color: #666; font-weight: bold }
|
||||
.newsBox { }
|
||||
.news_list .dot { width: 4px; height: 4px; border-radius: 50%; background-color: #999; display: inline-block; margin: 0 10px 3px 0; }
|
||||
.news_list li { padding: 0 0 20px; margin-bottom: 20px; border-bottom: 1px solid #f5f5f5 }
|
||||
.news_list li h5 { font-size: 14px }
|
||||
.news_list li p { color: #999; padding-top: 15px }
|
||||
.news_nav { color: #999; padding: 0px 0; line-height: 2.5; }
|
||||
.news_nav a { font: 12px/1 "Microsoft YaHei"; margin: 0 5px; }
|
||||
.news_title { text-align: center; border-bottom: 1px solid #eee; margin: 30px auto 40px; }
|
||||
.news_title h2 { font-size: 20px; }
|
||||
.news_title .from { color: #999; display: block; margin: 20px 0; }
|
||||
.news_title .time { margin-left: 20px }
|
||||
.news_info { padding: 0 60px; line-height: 28px; font-size: 14px; min-height:400px }
|
||||
.news_info p { margin-bottom: 30px }
|
||||
.aboutBox h2 { font-size:16px; margin-bottom:15px }
|
||||
.about_info { line-height: 28px; font-size: 14px; min-height:400px }
|
||||
.about_info p, .about_info h4 { margin-bottom: 10px }
|
||||
.news_info img { max-width: 100% }
|
235
novel-front/src/main/resources/static/css/base.css
Normal file
@ -0,0 +1,235 @@
|
||||
@charset "utf-8";
|
||||
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, p, a, blockquote, th { margin: 0; padding: 0 }
|
||||
h1, h2, h3, h4, h5, h6 { font-size: 14px }
|
||||
ol, ul, li { list-style: none outside none }
|
||||
table { border-collapse: collapsse; border-spacing: 0 }
|
||||
fieldset, img { border: 0 none }
|
||||
/*html { background: ##f5f5f5 }*/
|
||||
body { background: #f5f5f5; color: #333; font: 12px/1.5 PingFangSC-Regular,HelveticaNeue-Light,'Helvetica Neue Light','Microsoft YaHei',sans-serif,"宋体"; text-align: left }
|
||||
input::-moz-focus-inner {
|
||||
border:none;
|
||||
padding:0
|
||||
}
|
||||
a img { border: none }
|
||||
a { outline: none; color: #333; text-decoration: none }
|
||||
a:hover, .topBar a:hover, .red, .record_list li:hover .read_link a { color: #f70 }
|
||||
.red1 { color: #ff4040 }
|
||||
.unlink { text-decoration: underline }
|
||||
.blue { color: #5fc3f3 }
|
||||
.green { color: #360 }
|
||||
.black { color: #000 }
|
||||
.black3 { color: #333 }
|
||||
.black6 { color: #666 }
|
||||
.black9 { color: #999 }
|
||||
.ccc { color: #ccc }
|
||||
.orange { color: #f60 }
|
||||
.font12 { font-size: 12px!important }
|
||||
.font14 { font-size: 14px!important }
|
||||
.font16 { font-size: 16px!important }
|
||||
.font18 { font-size: 18px!important }
|
||||
.font20 { font-size: 20px!important }
|
||||
.font26 { font-size: 26px!important }
|
||||
.ellipsis {overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: keep-all }
|
||||
textarea { resize: none; outline: none; border: 1px solid #CCC; font: 12px/1.8 "microsoft yahei", Arial; padding-left: 5px }
|
||||
input { outline: none; border: none; /* padding-left: 5px; font-size: 13px;*/ font-family: "microsoft yahei", Arial; *background:none
|
||||
}
|
||||
i, em, cite { font-style: normal }
|
||||
.layui-inline, input, label { vertical-align: middle }
|
||||
button, input, optgroup, select, textarea { color: inherit; font: inherit; margin: 0; outline: 0 }
|
||||
button, select { text-transform: none }
|
||||
/*select { -webkit-appearance: none; border: none }*/
|
||||
input { line-height: normal }
|
||||
input[type=checkbox], input[type=radio] { box-sizing: border-box; padding: 0 }
|
||||
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { height:auto }
|
||||
input[type=search] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box }
|
||||
input[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration { -webkit-appearance:none }
|
||||
input[type="submit"], input[type="reset"], input[type="button"], button { -webkit-appearance: none }
|
||||
:-moz-placeholder { color: #999 }
|
||||
::-moz-placeholder { color: #999 }
|
||||
input:-ms-input-placeholder, textarea:-ms-input-placeholder { color: #999 }
|
||||
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder { color: #999 }
|
||||
.cf { zoom: 1 }
|
||||
.cf:before, .cf:after { content: ""; display: table; display: block; font-size: 0; height: 0; line-height: 0; clear: both; visibility: hidden }
|
||||
.cf:after { clear: both }
|
||||
.clear { clear: both }
|
||||
.tl { text-align: left }
|
||||
.tc { text-align: center }
|
||||
.tr { text-align: right }
|
||||
.fl { float: left }
|
||||
.fr { float: right }
|
||||
.block { display: block }
|
||||
.none, .hidden { display: none }
|
||||
/*base end*/
|
||||
.channelWrap { background: #fff; border-radius: 6px; padding: 20px; margin-bottom: 20px }
|
||||
.channelWrap.channelBanner { padding-bottom: 14px }
|
||||
.wrap_left { width: 750px }
|
||||
.wrap_right { width: 250px }
|
||||
.wrap_inner { padding: 20px; border-radius: 6px; background: #fff; }
|
||||
.wrap_bg { border-radius: 6px; background: #fff; }
|
||||
.pad20 { padding: 20px }
|
||||
.pad20_nobt { padding: 20px 20px 0 }
|
||||
.topBar { width: 100%; background: #fbfaf8; border-bottom: 1px solid #eae6e2; height: 35px; line-height: 35px }
|
||||
.box_center { width: 1020px; margin: 0 auto }
|
||||
.top_l { float: left }
|
||||
.top_r { float: right }
|
||||
.topBar .line { display: inline-block; padding: 0 12px; color: #e5d9da }
|
||||
.topBar a { display: inline-block; color: #8C8C8C }
|
||||
.topBar a.on { color: #333 }
|
||||
.topMain { height: 92px; background: #fff; overflow: hidden }
|
||||
.logo { width: 198px; float: left; padding: 23px 130px 0 0; display: block }
|
||||
.logo img { width: auto; height: 48px }
|
||||
.searchBar { width: 342px; margin-top: 27px; overflow: hidden }
|
||||
.searchBar .search/*, .searchBar .hotword*/ { width: 342px; overflow: hidden }
|
||||
.searchBar .s_int { width: 250px; padding: 0 14px 0 18px; height: 36px; line-height: 36px\9; vertical-align: middle; border: 1px solid #f80; border-right: none; color: #333; float: left; border-radius: 20px 0 0 20px; font-size: 14px; /*background: #fff;*/ background: 0 0 }
|
||||
/*.searchBar .s_btn { width: 78px; height: 38px; line-height: 38px; background: #f65167; color: #fff; font-size: 16px; text-align: center; float: left; cursor: pointer; padding: 0 }
|
||||
.searchBar .s_btn:hover { background:#E23249 }*/
|
||||
.searchBar .search_btn { float: left;
|
||||
width: 58px;
|
||||
height: 38px;
|
||||
text-align: center;
|
||||
border-radius: 0 20px 20px 0;
|
||||
background-color: #f80; cursor: pointer; }
|
||||
.searchBar .search_btn .icon { width: 18px; height: 18px; display: block; margin: 9px auto 0; background: url(../images/search.png) no-repeat; background-size:cover; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/search.png', sizingMethod='scale'); }
|
||||
|
||||
/*.hotword { padding-top: 3px }
|
||||
.hotword a, .hotword span { color: #999; margin: 0 6px 0 5px }
|
||||
.hotword a:hover { color: #666 }*/
|
||||
.bookShelf { margin-top: 27px; padding-left: 20px; overflow: hidden }
|
||||
.bookShelf .sj_link { height: 38px; line-height: 38px; padding-left: 30px; font-size: 15px; color: #404040; background: url(../images/icon_sj.png) no-repeat 6px 50%; float: left }
|
||||
.bookShelf .user_link { height: 38px; line-height: 38px; padding-left: 20px; font-size: 15px; color: #404040; float: right }
|
||||
.bookShelf .user_head { width: 26px; height: 26px; border-radius: 50%; float: left; margin: 6px 5px 0 0 }
|
||||
.bookShelf .user_name { max-width: 100px; display: inline-block }
|
||||
.bookShelf .line { float: left; color: #ccc }
|
||||
/*.bookShelf img { position: absolute; top: 17px; left: 17px; z-index: 10 }*/
|
||||
.mainNav { width: 100%; height: 48px; background: #f80; margin-bottom: 20px }
|
||||
.mainNav .nav li { float: left }
|
||||
.mainNav .nav li a { float: left; height: 44px; line-height: 48px; color: #fff; font-size: 16px; margin: 0 34px; border-bottom: 2px solid #f80; transition: color .3s,background-color .3s,border .3s }
|
||||
.mainNav .nav li.on a, .mainNav .nav li a:hover { border-bottom: 2px solid rgba(255,255,255,.8) }
|
||||
.footer { padding: 0 0 20px; /*margin-top: 20px; background: #fbfaf8; border-top: 1px solid #e0e0e0; */text-align: center; font-size: 12px }
|
||||
.copyright ul li { color: #999; line-height: 26px }
|
||||
.copyright .menu { padding: 2px 0 6px; font-size: 12px }
|
||||
.copyright .line { display: inline-block; padding: 0 12px; color: #e5d9da }
|
||||
.copyright p { margin-top: 10px; color: #999 }
|
||||
.code_bar img { margin-left: 66px }
|
||||
.rBar { float: right; width: 268px }
|
||||
.btn_gray, .btn_red, .btn_ora, .btn_ora_white, .btn_red1 { border-radius: 20px; font-size: 15px; display: inline-block; text-align: center; cursor: pointer; /*padding: 0 34px; height: 34px; line-height: 34px;*/ padding: 11px 36px; line-height: 1; }
|
||||
.btn_gray { border: 1px solid #dedede; background: #fafafa; }
|
||||
.btn_red, .btn_ora { border: 1px solid #f80; background: #f80; color: #fff }
|
||||
.btn_red1 { border: 1px solid #ff4040; background: #ff4040; color: #fff }
|
||||
.btn_ora_white { border: 1px solid #f80; color: #f80 }
|
||||
.btn_ora_white:hover { background: #fefaf6 }
|
||||
.btn_link { padding: 2px 6px; background: #f80; color: #fff; border-radius: 2px }
|
||||
.btn_gray:hover { background: #f0f0f0; color: #333 }
|
||||
.btn_ora:hover, .btn_red:hover, .btn_link:hover { background: #f70; color: #fff }
|
||||
.btn_red1:hover { background: #fc2525; color: #fff }
|
||||
.pay_Checkout .btn_red, .btn_big {
|
||||
font-size: 16px;
|
||||
padding: 15px 0;
|
||||
border-radius: 4px;
|
||||
width: 196px; }
|
||||
i.vip { width: 26px; height: 14px; text-align: center; line-height: 14px; font-size: 11px; color: #fff; background: #fe8034; border-radius: 2px; margin: 13px 0 0 3px; display: inline-block; transform: scale(0.88); }
|
||||
i.vip_b { width: 36px; height: 22px; text-align: center; line-height: 22px; font-size: 15px; color: #fff; background: #f70; border-radius: 4px; margin-left: 5px; display: inline-block; vertical-align: 3px }
|
||||
.pageBox { text-align: center; padding: 20px 0 }
|
||||
.pageBox a, .pageBox span { display: inline-block; color: #999; padding: 6px 10px; margin: 0 5px; border-radius: 4px; font-size: 14px; line-height: 1 }
|
||||
.pageBox .current, .pageBox a:hover { background: #f80; color: #fff }
|
||||
.top_nearread { display: inline-block; position: relative; margin-right: 10px; float:left }
|
||||
.top_nearread .nearread { padding: 0 9px }
|
||||
.top_nearread .nearread.on { border-left: 1px solid #d9d9d9; border-right: 1px solid #d9d9d9; background: #FFF; padding: 0 8px; height: 36px; position: relative; z-index: 8 }
|
||||
.icon_down { display: inline-block; vertical-align: middle; margin: 2px 0 0 5px; width: 0px; height: 0px; overflow: hidden; border-width: 4px; border-style: solid dashed dashed; border-color: #7f7f7f transparent transparent; }
|
||||
.book_record { width: 382px; position: absolute; top: 0; right: 0; z-index: 9 }
|
||||
.record_box { width: 380px; background: #fff; margin-top:35px; border: 1px solid #d9d9d9 }
|
||||
.book_record .sp { width:77px; height:6px; background:#fff; position:absolute; top:32px; right:1px }
|
||||
.record_title { padding: 14px 10px }
|
||||
.record_title a { border: 1px solid #dedede; background: #fafafa; border-radius: 2px; font-size: 12px; padding: 6px 12px; line-height: 1; margin-right: 14px }
|
||||
.record_title a.on { border: 1px solid #f65167; background: #f65167; color: #fff }
|
||||
.record_box .all { display: block; height: 28px; line-height: 28px; text-align: center; background: #f6f6f6 }
|
||||
.record_list ul { margin-bottom: 10px }
|
||||
.record_list li { clear: both; padding: 10px; line-height: 1; overflow: hidden }
|
||||
.record_list li:hover { background: #f6f6f6 }
|
||||
.record_list li .cover { width: 50px; height: 63px; background: #f6f6f6 }
|
||||
.record_list li .cover img { width: 100%; height: 100%; }
|
||||
.record_list a { display: inline; color: #333 }
|
||||
.record_list .book_intro { width: 300px; height: 65px; padding-left: 10px; position: relative; }
|
||||
.record_list .book_intro p { height: 20px; line-height: 20px; overflow: hidden; color: #999; }
|
||||
.record_list .book_intro .p1 { font-size: 14px; }
|
||||
.record_list .book_intro .p2 { margin: 2px 0; white-space: nowrap; text-overflow: ellipsis }
|
||||
.record_list .book_intro .p3 { }
|
||||
.record_list .book_intro i.vip { margin:0 0 0 3px }
|
||||
.record_list .read_link a { color: #fff }
|
||||
.manBody {}
|
||||
.manBody .mainNav { background:#3e3d43 }
|
||||
.manBody .searchBar .s_int { border: 1px solid #878689; border-right:none; background-position:8px -22px }
|
||||
.manBody .mainNav .nav li.on a, .manBody .mainNav .nav li a:hover { background:#313035 }
|
||||
.nav_sub { margin-bottom: 16px }
|
||||
.nav_sub a { padding: 0 6px }
|
||||
|
||||
.copyright .menu a { color: #666; font-size: 12px }
|
||||
.copyright .menu a:hover, .bookShelf .sj_link:hover { color: #f70 }
|
||||
|
||||
.rightList .more, .more_bar { margin: 1px 0; height: 34px; line-height: 34px; border-radius: 1px; background-color: #f7f7f7; text-align: center }
|
||||
.rightList .more a, .more_bar a { display: block; color: #666 }
|
||||
.header, .footer { min-width: 1020px }
|
||||
|
||||
/*base*/
|
||||
.noborder { border: 0!important }
|
||||
.nomargin { margin: 0!important }
|
||||
.ml { margin-left: 12px }
|
||||
.mr { margin-right: 12px }
|
||||
.ml5 { margin-left: 5px }
|
||||
.ml10 { margin-left: 10px }
|
||||
.ml15 { margin-left: 15px }
|
||||
.ml20 { margin-left: 20px }
|
||||
.mr5 { margin-right: 5px }
|
||||
.mr10 { margin-right: 10px }
|
||||
.mr15 { margin-right: 15px }
|
||||
.mr20 { margin-right: 20px }
|
||||
.mt5 { margin-top: 5px }
|
||||
.mt10 { margin-top: 10px }
|
||||
.mt15 { margin-top: 15px }
|
||||
.mt20 { margin-top: 20px }
|
||||
.mb5 { margin-bottom: 5px }
|
||||
.mb10 { margin-bottom: 10px }
|
||||
.mb15 { margin-bottom: 15px }
|
||||
.mb20 { margin-bottom: 20px }
|
||||
.mb50 { margin-bottom: 50px }
|
||||
.pointer { cursor: pointer }
|
||||
.notindent { text-indent: inherit!important }
|
||||
.vm { vertical-align: middle!important }
|
||||
.border_t { border-top: 1px solid #eee }
|
||||
.border_b { border-bottom: 1px solid #eee }
|
||||
.border_l { border-left: 1px solid #eee }
|
||||
.border_r { border-right: 1px solid #eee }
|
||||
.layui-laypage-curr{
|
||||
background: #f80;
|
||||
}
|
||||
.layui-laypage-curr em {
|
||||
color: #fff;
|
||||
}
|
||||
.layui-disabled, .layui-disabled:hover {
|
||||
color: #d2d2d2 !important;
|
||||
cursor: not-allowed !important
|
||||
}
|
||||
|
||||
#noFeedbackNote {
|
||||
line-height: 400px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
#txtDescription {
|
||||
/*width: 900px;*/
|
||||
height: 288px;
|
||||
margin: 20px auto 20px;
|
||||
padding: 10px;
|
||||
|
||||
|
||||
/*新增样式*/
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #eee;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.userBox {
|
||||
margin: 0 auto
|
||||
}
|
155
novel-front/src/main/resources/static/css/book.css
Normal file
@ -0,0 +1,155 @@
|
||||
@charset "utf-8";
|
||||
.Interaction_tab a, .Interaction_tab a .icon, .Interaction_tab a.fr .icon, .dashang_bar .l_bar .list li, .btn_pc, .btn_flw, .fansBox .fans_bg, .icon_hg { background: url(../images/icon_interation.png) no-repeat }
|
||||
.InteractionBox { padding: 15px 14px 11px }
|
||||
.Interaction_tab a { width: 339px; height: 60px; line-height: 60px; font-size: 14px; color: #000 }
|
||||
/*.Interaction_tab a:hover, .Interaction_tab a.on { background-position: 0 -60px; color: #000 }*/
|
||||
.Interaction_tab a .icon { width: 38px; height: 60px; float: left; margin: 0 10px 0 64px; background-position: -348px 0 }
|
||||
.Interaction_tab a.fr .icon { background-position: -348px -60px }
|
||||
.Interaction_tab h4 { font-size: 17px; margin-right: 8px; display: inline }
|
||||
.InteractionBox .l_bar, .InteractionBox .r_bar { width: 335px; margin: 0 2px; float: left }
|
||||
.InteractionBox .r_bar .time { padding-right: 1px }
|
||||
.InteractionBox .l_bar .tit { padding: 22px 14px 0 4px }
|
||||
.InteractionBox .l_bar .tit .red, .InteractionBox .r_bar .tit .red { padding: 0 5px }
|
||||
.InteractionBox .l_bar .tit .fl { font-size: 17px }
|
||||
.InteractionBox .l_bar .tit .fr { padding-top: 7px }
|
||||
.dashang_bar .l_bar .list { padding-top: 20px }
|
||||
.dashang_bar .l_bar .list li { width: 90px; height: 134px; line-height: 1; float: left; margin: 0 20px 0 6px; text-align: center; background-position: 0 -130px }
|
||||
.dashang_bar .l_bar .list li img { width: 60px; height: 60px; background: #fff; margin: 35px 15px 10px; border-radius: 50%; box-shadow: 0 1px 0 rgba(0,0,0,.3) }
|
||||
.dashang_bar .l_bar .list li .user_name { line-height: 1!important; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; display: block; padding: 0 10px }
|
||||
.dashang_bar .l_bar .list .li_1 { }
|
||||
.dashang_bar .l_bar .list .li_2 { background-position: -100px -130px }
|
||||
.dashang_bar .l_bar .list .li_3 { background-position: -200px -130px; margin-right: 0 }
|
||||
.InteractionBox .r_bar .tit { padding: 14px 1px 12px 1px }
|
||||
.InteractionBox .r_bar .tit strong { display: block; font-size: 13px }
|
||||
.InteractionBox .r_bar .list, .InteractionBox .r_bar .sum { margin: 0 1px }
|
||||
.InteractionBox .r_bar .list li { height: 27px; line-height: 27px; overflow: hidden; border-top: 1px dotted #ccc; color: #999 }
|
||||
.InteractionBox .r_bar .list li .user_name { margin-right: 8px }
|
||||
.InteractionBox .r_bar .sum { border-top: 1px dotted #ccc; line-height: 34px }
|
||||
.btn_pc, .btn_flw { width: 140px; height: 44px; display: inline-block; background-position: 0 -270px }
|
||||
.btn_flw { width: 122px; background-position: -150px -270px }
|
||||
.flower_bar .l_bar .list { padding: 0 14px 0 4px }
|
||||
.flower_bar .l_bar li { padding: 15px 0 6px; overflow: hidden; clear: both }
|
||||
.flower_bar .l_bar .book_intro { width: 265px }
|
||||
.flower_bar .l_bar .cover img { width: 45px; height: 56px; background: #f6f6f6; margin: 2px 16px 0 0 }
|
||||
.flower_bar .l_bar .book_intro .txt { height: 38px; line-height: 18px; padding-top: 2px; color: #999; overflow: hidden; display: block }
|
||||
.r_fansBrank .book_intro { float: inherit!important }
|
||||
.user_level1, .user_level2, .user_level3, .user_level4, .user_level5, .user_level6, .user_level7, .user_level8, .user_level9, .user_level10, .user_level11 { width: 30px; height: 16px; line-height: 16px; text-align: center; border-radius: 2px; margin: 11px 0 0; color: #fff }
|
||||
.user_level1 { background: #d0d0d0 }
|
||||
.user_level2 { background: #c0c0c0 }
|
||||
.user_level3 { background: #b4b3b3 }
|
||||
.user_level4 { background: #a0dfe6 }
|
||||
.user_level5 { background: #77d2db }
|
||||
.user_level6 { background: #b4d894 }
|
||||
.user_level7 { background: #94c766 }
|
||||
.user_level8 { background: #ffc24c }
|
||||
.user_level9 { background: #ffa800 }
|
||||
.user_level10 { background: #ff6e26 }
|
||||
.user_level11 { background: #ff0000 }
|
||||
/*固定悬浮图层*/
|
||||
.readPopup { border: 1px solid #D9D9D9; border-radius: 3px; background: #FFF; box-shadow: 0 1px 2px #999; overflow: hidden; padding-bottom: 20px; z-index: 9999; position: fixed; left: 50%; top: 50% }
|
||||
.icon_check { position: absolute; width: 29px; height: 25px; right: -1px; top: -1px; z-index: 2; background: url(../images/icon_readpage.png) no-repeat 0 -142px }
|
||||
.on .icon_check { display: block }
|
||||
.closePopup { position: absolute; top: 20px; right: 20px; width: 16px; height: 15px; background: url(../images/icon_readpage.png) no-repeat -43px -126px }
|
||||
.chapterBox { width: 600px; margin-left: -300px; margin-top: -260px }
|
||||
.chapterBox .scrollWrap { height: 540px }
|
||||
/*弹窗内容*/
|
||||
.popupTit h2 { text-align: center; letter-spacing: 15px; color: #333; font: 700 20px/30px "Microsoft Yahei"; margin: 30px 0 }
|
||||
.popupTit h3 { font-size: 16px; margin: 15px 20px }
|
||||
.scrollWrap { overflow-y: scroll; position: relative }
|
||||
.dirWrap { padding: 0 40px }
|
||||
.scrollWrap h3 { padding-left: 26px; font-size: 14px; background: #e6e6e6; height: 30px; line-height: 30px; font-weight: normal; position: relative; cursor: pointer; margin: 0 0 15px; border-radius: 3px }
|
||||
.readPopup .tc .btn_gray { margin-left: 30px }
|
||||
/*捧场、送鲜花*/
|
||||
.pcBox, .flowerBox { width: 500px; margin-left: -251px; margin-top: -215px }
|
||||
.propsList { padding: 15px 0 10px 20px }
|
||||
.propsList li { float: left; cursor: pointer; margin: 0 8px 16px; text-align: center }
|
||||
.propWrap { width: 134px; height: 54px; line-height: 54px; text-align: center; font-size: 15px; color: #000; display: block; border: 1px solid #e6e6e6; background: #fafafa; position: relative }
|
||||
.on .propWrap, .propWrap:hover { width: 132px; height: 52px; line-height: 52px; color: #f70; border: 2px solid #f80; background: #fff }
|
||||
.propsList li i { display: none; line-height: 1 }
|
||||
.propsList li .propsBox { padding-top: 20px }
|
||||
.have_num { padding: 0 30px 10px; font-size: 14px; color: #999 }
|
||||
.have_num .red { margin: 0 4px }
|
||||
.popup_text { width: 418px; height: 62px; padding: 8px 10px; margin: 8px 30px 20px; color: #555; border: 1px solid #e6e6e6; }
|
||||
/*消息提示*/
|
||||
.newsTipBox { width: 400px; padding-bottom: 30px; margin-left: -200px; margin-top: -105px }
|
||||
.tipWrap { padding: 30px; font-size: 14px }
|
||||
/*遮罩层*/
|
||||
.maskBox { position: fixed; left: 0; top: 0; z-index: 995; width: 100%; height: 100%; background: black; filter: alpha(opacity=30); opacity: 0.3; animation: mask 2s ease-out 0s 1 normal }
|
||||
@keyframes mask { 0% {
|
||||
filter:alpha(opacity=0);
|
||||
opacity:0
|
||||
}
|
||||
100% {
|
||||
filter:alpha(opacity=30);
|
||||
opacity:0.3
|
||||
}
|
||||
}
|
||||
.fansBox { width: 998px; border: 1px solid #eaeaea }
|
||||
.fansHead { height: 54px; line-height: 54px; margin: 0 14px; border-bottom: 1px solid #eaeaea; font-weight: normal }
|
||||
.fansHead h2 { font-size: 20px; font-weight: normal }
|
||||
.fansCon { padding: 20px }
|
||||
.fansCon .r_bar { width: 204px }
|
||||
.fansCon .cover { width: 200px; height: 250px; background: #f6f6f6; border: 1px solid #ebebeb; padding: 1px; }
|
||||
.fansCon .btn_red { width: 202px; margin: 2px 0 14px; padding: 10px 0 }
|
||||
.fansCon .l_bar { width: 750px }
|
||||
.fansCon .l_bar .list1 { padding-top: 4px }
|
||||
.fansCon .list1 li { width: 33%; line-height: 1; float: left }
|
||||
.fansCon .list1 .fans_bg { width: 90px; height: 112px; background-position: 0 -320px; position: relative; margin-right: 18px }
|
||||
.fansCon .list1 .fans_bg img { width: 60px; height: 60px; background: #fff; margin: 39px 15px 0; border-radius: 50%; box-shadow: 0 1px 0 rgba(0,0,0,.3) }
|
||||
.fansCon .list1 h5 { font-size: 16px; padding: 9px 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
||||
.fansCon .list1 li .user_name { line-height: 1!important }
|
||||
.fansCon .list1 .li_2 .fans_bg { background-position: -100px -320px }
|
||||
.fansCon .list1 .li_3 .fans_bg { background-position: -200px -320px }
|
||||
.fansCon .fans_info { width: 136px; font-size: 14px }
|
||||
.fansCon .fans_info .fans_pointer { padding: 14px 0 22px }
|
||||
.fans_level span { padding: 1px 10px 2px }
|
||||
.icon_hg { width: 30px; height: 30px; display: inline-block; background-position: -300px -320px; position: absolute; top: -13px; right: -13px }
|
||||
.fansCon .list2 { padding: 0 }
|
||||
.fansCon .list2 li { width: 250px; float: left; height: 59px; padding: 0 0 19px; display: inline }
|
||||
.fansCon .list2 .num { font: 16px/59px "microsoft yahei", Arial, "宋体"; width: 32px; color: #666; font-weight: bold }
|
||||
.fansCon .list2 .img { width: 40px; height: 40px; margin-top: 10px; position: relative }
|
||||
.fansCon .list2 .img img { width: 100%; height: 100%; border-radius: 50% }
|
||||
.fansCon .list2 .img span { display: block; margin: 0; position: absolute; left: 5px; bottom: 0 }
|
||||
.fansCon .list2 .msg { display: inline; width: 164px; padding: 8px 0 0 12px; }
|
||||
.fansCon .list2 .msg h4 { line-height: 24px; font-weight: normal; font-size: 16px; overflow: hidden; height: 24px; white-space: nowrap; text-overflow: ellipsis; }
|
||||
.fansCon .list2 .msg p { font-size: 12px; line-height: 16px; color: #999; }
|
||||
.fansTop { margin-bottom: 8px; border-bottom: 1px solid #eaeaea }
|
||||
.fans_tab { width: 1005px; overflow: hidden; }
|
||||
.fans_tab ul { float: left; width: 280px; margin-right: 55px; }
|
||||
.fans_tab li { line-height: 39px; overflow: hidden; font-size: 14px; height: 39px; border-bottom: 1px solid #ebebeb; }
|
||||
.fans_tab li .num { float: left; width: 40px; color: #666; }
|
||||
.fans_tab li a { float: left; overflow: hidden; width: 200px; white-space: nowrap; text-overflow: ellipsis; }
|
||||
.fans_tab li .fans_level { float: left; font-size: 12px; width: 40px; text-align: right; color: #999; }
|
||||
.fansRule dl { padding: 20px 20px 30px }
|
||||
.fansRule dt { line-height: 24px; margin-bottom: 6px; font-size: 16px; }
|
||||
.fansRule dd { font-size: 12px; line-height: 20px; margin-bottom: 16px; color: #777; }
|
||||
.fansRule table { width: 100%; border-collapse: collapse; }
|
||||
.fansRule table th, .fansRule table td { font-weight: 400; min-width: 40px; padding: 12px 0; text-align: left; border-top: 1px solid #ebebeb; border-bottom: 1px solid #ebebeb; }
|
||||
.fansRule ol li { list-style-type: decimal; list-style-position: inside; }
|
||||
.InteractionBox .l_bar, .flower_bar .l_bar { display: none }
|
||||
.dashang_bar { float: left }
|
||||
.flower_bar { float: right }
|
||||
.author_head { text-align: center }
|
||||
.author_head .head img { width:64px; height:64px; border-radius: 50%; background:#f6f6f6; display: block; margin: 0 auto }
|
||||
.author_head .msg { margin-top: -4px }
|
||||
.author_head .msg h4 { font-size:14px; line-height:2.4 }
|
||||
.icon_qyzz { padding: 5px; line-height:1; background:#f70; color:#fff; border-radius:3px; display:inline-block }
|
||||
.author_intro, .author_book { border-top:1px dotted #e0e0e0 }
|
||||
.author_intro h4,.author_book h4 { font-weight: normal; font-size: 12px; padding:10px 0 5px }
|
||||
.author_intro .intro_txt, .author_book .book_txt { line-height:1.8; padding-bottom:10px }
|
||||
.author_book .rightList ul { padding:0 }
|
||||
|
||||
|
||||
.tj_bar .cover { float: left; display: block; margin-right: 10px }
|
||||
.tj_bar .cover img { width: 64px; height: auto; background: #f6f6f6 }
|
||||
.tj_bar .book_intro { padding: 15px 0; clear: both; word-break: break-all; zoom: 1; overflow: hidden }
|
||||
.tj_bar .dec { width: 136px; float: right }
|
||||
.tj_bar .book_intro .book_name { display: block; font-size: 14px; line-height: 1; white-space: nowrap; text-overflow: ellipsis; overflow: hidden }
|
||||
.tj_bar .book_intro .txt { height: 54px; line-height: 1.5; color: #808080; overflow: hidden; display: block; margin-top: 10px; }
|
||||
.tj_bar li { border-bottom: 1px solid #eee }
|
||||
.tj_bar li:last-child { border: none }
|
||||
.tj_bar li:last-child .book_intro { padding: 15px 0 2px }
|
||||
|
||||
.friend_link { display: none }
|
||||
.footer { background: #fff; padding: 16px 0 20px }
|
||||
|
1
novel-front/src/main/resources/static/css/layer.css
Normal file
@ -0,0 +1 @@
|
||||
.layermbox{position:absolute;left:0;top:0;width:100%;z-index:19891014}.layermmain,.laymshade{position:fixed;left:0;top:0;width:100%;height:100%}.layermbtn span,.layermchild{display:inline-block;position:relative}.laymshade{background-color:rgba(0,0,0,.5);pointer-events:auto}.layermmain{display:table;font-family:Helvetica,arial,sans-serif;pointer-events:none}.layermmain .section{display:table-cell;vertical-align:middle;text-align:center}.layermchild{text-align:left;background-color:#fff;font-size:14px;border-radius:6px;box-shadow:0 0 8px rgba(0,0,0,.1);pointer-events:auto;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.18s;animation-duration:.18s}.layermborder{border:1px solid #999}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.layermanim{animation-name:bounceIn;-webkit-animation-name:bounceIn}.layermbox0 .layermchild{max-width:260px;min-width:150px}.layermbox1 .layermchild{border:none;border-radius:0}.layermbox2 .layermchild{width:auto;max-width:260px;min-width:40px;border:none;background-color:rgba(0,0,0,.6);color:#fff}.layermchild h3{padding:0 45px 0 10px;height:50px;line-height:50px;font-size:16px;font-weight:400;border-radius:5px 5px 0 0;border-bottom:1px solid #EBEBEB}.layermbtn span,.layermchild h3{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layermcont{padding:20px 15px;line-height:22px;border-radius:5px}.layermbox1 .layermcont{padding:0}.layermbox2 .layermcont{text-align:center;padding:30px 30px 0;line-height:0}.layermbox2 .layermcont i{width:1.5rem;height:1.5rem;margin-left:8px;display:inline-block;background-color:#fff;border-radius:100%;-webkit-animation:bouncedelay 1.4s infinite ease-in-out;animation:bouncedelay 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}@-webkit-keyframes bouncedelay{0%,100%,80%{-webkit-transform:scale(0)}40%{-webkit-transform:scale(1)}}@keyframes bouncedelay{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.layermbox2 .layermcont i:first-child{margin-left:0;-webkit-animation-delay:-.32s;animation-delay:-.32s}.layermbox2 .layermcont i.laymloadtwo{-webkit-animation-delay:-.16s;animation-delay:-.16s}.layermbox2 .layermcont>div{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layermbtn{position:relative;height:40px;line-height:40px;font-size:0;text-align:center;border-top:1px solid #EBEBEB}.layermbtn span{width:50%;text-align:center;font-size:14px;cursor:pointer;border-radius:0 5px 0 0}.layermbtn span:first-child{height:39px;background-color:#fff;border-radius:0 0 0 5px}.layermbtn:before{content:'\20';position:absolute;width:1px;height:39px;left:50%;top:0;background-color:#EBEBEB}.layermend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layermend::after,.layermend::before{position:absolute;left:5px;top:13px;content:'';width:20px;height:2px;background-color:rgba(0,0,0,.3);transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layermend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}
|
245
novel-front/src/main/resources/static/css/main.css
Normal file
@ -0,0 +1,245 @@
|
||||
@charset "utf-8";
|
||||
.items_txt .author a, .updateTable .author a { cursor: text }
|
||||
.friend_link { padding: 12px 0 0; line-height: 2.4; text-align: center }
|
||||
.friend_link a { margin: 0 10px; display: inline-block }
|
||||
/*.leftBox, .rightBox, .rightBox2 { margin-bottom: 14px }
|
||||
.channelBanner .leftBox, .channelBanner .rightBox { height: 334px; overflow: hidden }*/
|
||||
.channelPic .leftBox, .channelPic .rightBox { /*height: 515px; */overflow: hidden }
|
||||
.channelTable .leftBox { /*height: 1046px;*/ overflow: hidden }
|
||||
.scBigImg img, .rightList li.on .cover img, .itemsList .items_img img { box-shadow: 0 0 1px rgba(0,0,0,.05) }
|
||||
.scBigImg:hover img, .rightList li.on .cover a:hover img, .itemsList .items_img:hover img { box-shadow: 0 0 1px rgb(0,0,0,.25) }
|
||||
.leftBox { width: 720px; float: left; /*border: 1px solid #EAEAEA*/ }
|
||||
.sliderContent { width: 306px; float: left; /*margin: 16px 0 16px 14px;*/ position: relative }
|
||||
.scSmallImg { position: absolute; top: 0px; right: 0px; /*height: 335px*/ }
|
||||
.scSmallImg li { height: 65px; margin-bottom: 8px; border: 2px solid #fff }
|
||||
.scSmallImg li.on { border: 2px solid #FF7800 }
|
||||
.scSmallImg img { width: auto; height: 65px; cursor: pointer; filter: alpha(opacity=60); -moz-opacity: 0.6; opacity: 0.6 }
|
||||
.scSmallImg li.on img { filter: alpha(opacity=100); -moz-opacity: 1; opacity: 1 }
|
||||
.scBigImg dd { display: none }
|
||||
.scBigImg dd.on { display: block }
|
||||
.scBigImg img { width: 240px; height: 300px; background: #f6f6f6 }
|
||||
.hot_articles { width: 396px; float: right; padding: 0 2px }
|
||||
.hot_articles dl { padding: 0 4px 8px; border-bottom: 1px dotted #eae6e2 }
|
||||
.hot_articles .hot_recommend { margin-bottom: 12px; }
|
||||
.hot_articles dt { /*height: 40px; line-height: 40px;*/ padding-bottom: 7px; text-align: center; font-size: 16px; font-weight: 600; line-height: 1.8 }
|
||||
.hot_articles dt a { color: #F70 }
|
||||
.hot_articles dd { line-height: 30px; font-size: 14px; overflow: hidden }
|
||||
.hot_articles dd a { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
|
||||
.hot_articles .hot_recommend dd a { width: 49%; padding-right: 1%; float: left; }
|
||||
.hot_articles .hot_notice dd a { padding-right: 1%; }
|
||||
.hot_articles span.tit { color: #f70; margin-right: 6px }
|
||||
.hot_articles .hot_notice { border: none }
|
||||
.hot_articles .line { padding: 0 14px; color: #eee }
|
||||
.rightBox { width: 240px; float: right; /*border: 1px solid #EAEAEA;*/ position: relative }
|
||||
.rightBox .title, .wrap_right_cont .title { /*height: 48px; margin: 0 14px;*/ border-bottom: 1px solid #e0e0e0 }
|
||||
.rightBox .title h3, .wrap_right_cont .title h3 { line-height: 1; padding-bottom: 14px; display: inline-block; font-size: 20px; font-weight: 600; /*border-bottom: 4px solid transparent*/ }
|
||||
/*.rightBox .title h3.on { border-color: #f80 }*/
|
||||
.rightList ul { padding: 0 }
|
||||
.rightList li { /*border-bottom: 1px dotted #e0e0e0; height: 37px; line-height: 37px;*/ overflow: hidden; position: relative; vertical-align: middle }
|
||||
.rightList li:last-child { border: none }
|
||||
.rightList .book_name { font-size: 14px; height: 34px; line-height: 34px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden }
|
||||
.rightList .book_intro { background: #f7f7f7; border: 1px solid #eee; clear: both; padding: 8px; word-break: break-all; zoom: 1; overflow: hidden; display: none }
|
||||
.rightList .cover, .rightList .book_intro .txt { display: none }
|
||||
.rightList li.on { height: auto; padding: 4px 0; border: none }
|
||||
.rightList li.on .book_intro { display: block }
|
||||
.rightList li.on .cover { float: left; display: block }
|
||||
.rightList li.on .cover img { width: 60px; height: auto; background: #f6f6f6; margin-right: 9px }
|
||||
.rightList li.on .book_intro .name { line-height: 26px; height: 26px; display: block; overflow: hidden }
|
||||
.rightList_nobor ul { padding: 4px 14px 10px }
|
||||
.rightList_nobor li { height: auto; padding: 10px 0!important; border: none }
|
||||
.book_intro .author { color: #999; display: block; line-height: 30px }
|
||||
.book_intro .class { color: #999; display: block; line-height: 1 }
|
||||
.rightList .on .book_intro .txt { height: 72px; line-height: 1.5; color: #808080; overflow: hidden; display: block }
|
||||
|
||||
.rightList li i, .rankTable .rank i { width: 17px; height: 17px; line-height: 17px; text-align: center; background-color: #999; color: #fff; vertical-align: middle; display: inline-block; font-size: 12px; }
|
||||
.rightList li i { float: left; margin: 8px 7px 0 0; }
|
||||
.rankTable .rank i { margin: 1px 1px 0 }
|
||||
/*.rightList li.on i { position: absolute; top: 12px; left: 0; margin: 0; display:none }*/
|
||||
.rightList li.num1 i, .rankTable .rank .num1 { background-color: #fc7403 }
|
||||
.rightList li.num2 i, .rankTable .rank .num2 { background-color: #f79415 }
|
||||
.rightList li.num3 i, .rankTable .rank .num3 { background-color: #ffa95e }
|
||||
.rightList li.num1 i,.rightList li.num2 i,.rightList li.num3 i { display:block }
|
||||
/*.rightList .more{ margin: 1px 0; height: 34px; line-height: 34px; border-radius: 1px; background-color: #f7f7f7; text-align: center }
|
||||
.rightList .more a{ display: block; color: #666 }*/
|
||||
.leftBox .title { border-bottom: 1px solid #e9e9e9 }
|
||||
.leftBox .title h2 { line-height: 1; padding-bottom: 14px; display: inline-block; font-size: 20px; font-weight: 600; /*border-bottom: 4px solid transparent*/ }
|
||||
.picRecommend { width: 720px; padding: 12px 0 0 }
|
||||
.itemsList { width: 50%; float: left; padding: 17px 0 }
|
||||
.itemsList .items_img { float: left; margin-right: 14px }
|
||||
.itemsList .items_img img { width: 96px; height: 120px; background: #f6f6f6 }
|
||||
.items_txt { width: 230px; float: left; /*padding-right: 20px;*/ }
|
||||
.items_txt h4 { height: 20px; line-height: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: keep-all; margin-bottom: 8px; font-size: 16px; font-weight: normal }
|
||||
.items_txt .author { margin: 8px 0 }
|
||||
.items_txt .author a { color: #a6a6a6 }
|
||||
.items_txt .intro { margin-top: 8px; line-height: 1.5; height: 54px; overflow: hidden }
|
||||
.searchTipBar { color: #333; font-size: 14px; padding: 1px 7px 16px 7px }
|
||||
.leftBox .updateTable { width: 718px; }
|
||||
.updateTable { color: #999 }
|
||||
.updateTable table { width: 100%; margin-bottom: 14px; }
|
||||
.updateTable th, .updateTable td { height: 41px; line-height: 41px; vertical-align: middle; padding-left: 1px; text-align: left }
|
||||
.updateTable th { font-weight: normal; font-size: 14px; }
|
||||
.updateTable td { border-top: 1px solid #eee }
|
||||
.updateTable .style { width: 74px; font-size: 14px; }
|
||||
.updateTable .name { width: 192px; padding-right: 10px; font-size: 14px; }
|
||||
.updateTable .name a, .updateTable .chapter a { max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: keep-all }
|
||||
.updateTable .chapter { padding-right: 5px }
|
||||
.updateTable .chapter a { max-width: 200px; float: left; color: #666 }
|
||||
.updateTable .author { width: 82px; text-align: left }
|
||||
.updateTable .time { width: 82px; text-align: center }
|
||||
.updateTable .word { width: 60px; padding-right: 10px; text-align: right }
|
||||
.updateTable .rank { width: 2.5em; padding-right: 10px; text-align: center }
|
||||
.updateTable .name a, .updateTable .chapter a, .updateTable .author a { height: 41px; line-height: 41px; display: inline-block; overflow: hidden }
|
||||
.rankBox { padding-bottom: 14px; height: auto!important }
|
||||
.rankTable th { background: #f9f9f9; color: #333 }
|
||||
.rankTable td { border: none; height: 40px; line-height: 40px }
|
||||
.rankTable tr:nth-child(2n) td { background: #fafafa }
|
||||
.rankTable .chapter a { max-width: 176px }
|
||||
.classTable { font-size: 14px }
|
||||
.classTable .rank { width: 60px; }
|
||||
.classTable .rank i { float: inherit; margin: 0; color: #fff }
|
||||
.classTable .style { width: 100px; }
|
||||
.classTable .name { width: 250px; }
|
||||
.classTable .name a, .classTable .chapter a { max-width: 90% }
|
||||
.classTable .author { width: 120px }
|
||||
.classTable .word { width: 80px; padding-right: 15px }
|
||||
.rightBox2 { width: 266px; float: right; border: 1px solid #EAEAEA; position: relative; overflow: hidden }
|
||||
.rightBox2 .title h3 { height: 45px; line-height: 48px; padding: 0 30px; font-size: 18px; font-weight: normal; color: #ff758f; border-bottom: 4px solid #ff758f }
|
||||
.rightList2 li { vertical-align: middle }
|
||||
.rightList2 li a { display: block; /*padding: 0 30px;*/ height: 47px; line-height: 47px; font-size: 16px; overflow: hidden; border-top: 1px dotted #eee; }
|
||||
.rightList2 li:first-child a { border: none }
|
||||
.rightList2 li a.on, .rightList2 li a:hover { color: #f70 }
|
||||
.so_tag { /*padding: 4px 14px 0;*/ font-size: 14px; padding: 5px 0 }
|
||||
.so_tag li { padding: 0 0 24px; /*border-bottom: 1px solid #eee*/ }
|
||||
.so_tag li:last-child { padding: 0 0 4px }
|
||||
.so_tag li .tit, .so_tag li a { line-height: 1; padding: 3px 7px; margin-right: 12px }
|
||||
.so_tag li .tit { color: #999 }
|
||||
.so_tag li a.on, .so_tag li a:hover { color: #f70 }
|
||||
.so_tag li .so_girl { display: inline-block }
|
||||
.so_tag li .so_boy { display: inline-block/*; margin: 8px 0 0 140px;*/ }
|
||||
|
||||
/*.payBox { width: 998px; border: 1px solid #eaeaea }*/
|
||||
.payHead { height: 36px; line-height: 36px; padding: 20px 0 30px; margin: 0 24px; font-size: 16px; border-bottom: 1px solid #eaeaea }
|
||||
.payHead .user_name { margin-right: 25px }
|
||||
.payHead .btn_gray { font-size: 14px; padding: 10px 20px; margin-left: 20px }
|
||||
.payFoot { line-height: 2.4; padding: 30px 0 40px; margin: 0 24px; font-size: 13px; color: #999; border-top: 1px solid #eee; }
|
||||
.payCon { margin: 0 24px }
|
||||
.payCon h5 { font-size: 16px; font-weight: normal; padding: 28px 0 2px }
|
||||
.pay_way { padding-bottom: 5px }
|
||||
.pay_way li { width: 196px; text-align: center; border: 2px solid #eee; border-radius: 4px; margin: 20px 26px 3px 0; float: left; cursor: pointer; line-height: 1 }
|
||||
.pay_way li.on { border-color: #f80 }
|
||||
.pay_way li .pay_pic { width: 180px; margin: 12px auto; }
|
||||
.pay_way li strong { font-size: 24px; display: block; line-height: 1; padding: 20px 0 5px }
|
||||
.pay_way li .pay_mn { display: table-cell; width: 196px; height: 40px; vertical-align: middle; line-height: 1.2; padding-bottom: 12px; font-size: 14px; text-align: center }
|
||||
.pay_way li .pay_mn em.red { display: block }
|
||||
.pay_Checkout { padding: 20px 0; font-size: 14px; line-height: 1.8; }
|
||||
.pay_Checkout .btn_red { margin: 20px 0; }
|
||||
|
||||
.payResultBox { padding: 90px 40px 160px; text-align: center }
|
||||
.payResultBox h3 { font-size: 38px; line-height: 1; padding-bottom: 30px; }
|
||||
.payResultBox .list { display: inline-block; padding-bottom: 15px;}
|
||||
.payResultBox .list li { font-size: 16px; line-height: 36px }
|
||||
.payResultImg { width: 60px;
|
||||
margin-right: 12px;
|
||||
vertical-align: middle; }
|
||||
/*.bookCover, .reply_bar { padding: 14px }*/
|
||||
.bookCover .book_cover { width: 200px; display: block; height: auto; margin-right: 25px; float: left; position: relative; overflow: hidden; box-shadow: 0 1px 6px rgba(0,0,0,.3), 0 0 5px #f9f2e9 inset; transition: color .3s,background-color .3s,border .3s;
|
||||
}
|
||||
.bookCover .cover { width: 100%; height: 100%; background: #f6f6f6;
|
||||
-webkit-transition: -webkit-transform .3s ease-out;
|
||||
-moz-transition: -moz-transform .3s ease-out;
|
||||
-ms-transition: -ms-transform .3s ease-out;
|
||||
transition: transform .3s ease-out;
|
||||
}
|
||||
.bookCover .cover:hover {
|
||||
-webkit-transform: scale(1.05);
|
||||
-moz-transform: scale(1.05);
|
||||
-o-transform: scale(1.05);
|
||||
transform: scale(1.05) }
|
||||
.book_info { width: 755px; float: left }
|
||||
.book_info h1 { font-size: 25px; display: inline-block; line-height: 1; }
|
||||
.book_info .author { font-size: 14px; margin-left: 20px; color: #444 }
|
||||
.book_info .list { padding: 15px 0 20px }
|
||||
.book_info .list li { line-height: 26px; color: #666 }
|
||||
.book_info .list li .item { width: 20%; display: inline-block }
|
||||
/*目录页*/
|
||||
.book_info1 { text-align: center; padding: 10px 0 15px }
|
||||
.book_info1 .tit { padding: 10px 0 20px }
|
||||
.book_info1 h1 { font-size: 28px; display: inline-block }
|
||||
.book_info1 .list { padding: 5px 0; font-size: 14px }
|
||||
.book_info1 .list li { line-height: 26px; color: #999 }
|
||||
.book_info1 .list li span { display: inline-block; margin: 0 15px }
|
||||
.dirWrap { padding-bottom: 30px }
|
||||
.dirWrap h3 { padding-left: 6px; font-size: 14px; background: #f9f9f9; height: 40px; line-height: 40px; font-weight: normal; position: relative; cursor: pointer; margin: 0 0 5px; border-radius: 3px }
|
||||
.dirList { overflow: hidden; padding-bottom: 20px }
|
||||
.dirList li { float: left; width: 265px; padding-left: 5px; padding-right: 30px; height: 40px; line-height: 40px; overflow: hidden; border-bottom: 1px dotted #ddd; *zoom:1; font-size: 14px
|
||||
}
|
||||
.dirList li a { float: left; text-overflow: ellipsis; overflow: hidden; white-space: nowrap }
|
||||
.dirList li i.red { padding-left: 5px }
|
||||
.book_info .intro_txt { height: 96px; min-height: 96px; line-height: 24px; font-size: 14px; position: relative; margin-bottom: 26px; overflow: hidden }
|
||||
.book_info .intro_txt em.black9 { font-weight: bold; color: #333; display: block; }
|
||||
/*.book_info .intro_txt p { text-indent:2em }*/
|
||||
.icon_show, .icon_hide { display:inline-block; color:#2972cc; height: 24px; padding:0 2px 0 10px; text-indent: 0; text-align: center; font-size: 12px; position: absolute; right: 0; bottom: 0; background: #fff }
|
||||
.icon_show i, .icon_hide i { display:inline-block; width:12px; height:12px; background:url(../images/icon_dt.png) no-repeat 0 2px; margin-right: 4px; *vertical-align:middle }
|
||||
.icon_hide i { background-position:-12px 2px }
|
||||
.icon_hide { display: none }
|
||||
.btns .btn_red, .btns .btn_ora, .btns .btn_addsj { margin-right: 24px }
|
||||
.book_tit { /*height: 48px; line-height: 48px; margin: 0 14px;*/ border-bottom: 1px solid #eee; overflow: hidden; padding-bottom: 14px; line-height: 1.2 }
|
||||
.book_tit .fl { font-size: 14px; color: #666 }
|
||||
.book_tit .fl h3 { font-size: 20px; color: #333; margin-right: 5px; display: inline }
|
||||
.book_tit .fr { font-size: 13px }
|
||||
.bookChapter .list { padding: 8px 0 }
|
||||
.bookChapter .list li { line-height: 36px; overflow: hidden }
|
||||
.zj_yl { color: #999; font-size: 13px }
|
||||
/*.bookChapter .list li .zj { width: 50%; float: left }
|
||||
.bookChapter .list li .zj_1 a { color: #f60 }*/
|
||||
|
||||
|
||||
|
||||
/*.commentBar { padding: 0 14px }*/
|
||||
.comment_list { padding: 20px 0; border-bottom: 1px solid #eee }
|
||||
.comment_list:last-child { border: none }
|
||||
.comment_list .user_heads { /*width: 54px; height: 54px; float: left;*/ position:relative; margin-right: 20px }
|
||||
.comment_list .user_head { width: 50px; height: 50px; border-radius: 50%; background: #f6f6f6 }
|
||||
.comment_list .user_heads span { display: block; margin: 0; position: absolute; left: 12px; bottom: 0 }
|
||||
.comment_list ul { width: 640px }
|
||||
.comment_list .li_0 { font-family: "宋体" }
|
||||
.comment_list .li_0 strong { font-size: 14px; color: #f00 }
|
||||
.comment_list .li_1 { overflow: hidden }
|
||||
.comment_list .user_name { color: #ed4259 }
|
||||
.comment_list .li_2 { padding: 6px 0 }
|
||||
.comment_list .li_3 { color: #999 }
|
||||
.comment_list .reply { padding-left: 12px }
|
||||
.comment_list .num { color: #ed4259; margin: 0 3px }
|
||||
.comment_list .li_4 { line-height: 34px; padding-top: 8px; margin-top: 15px; border-top: 1px solid #eaeaea }
|
||||
.no_comment { padding: 70px 14px 115px; color: #CCCCCC; text-align: center; font-size: 14px; }
|
||||
.pl_bar li { display: block }
|
||||
.pl_bar .name { color: #666; padding-top: 2px; font-size: 14px }
|
||||
.pl_bar .dec { font-size: 14px; line-height: 1.8; padding: 12px 0 }
|
||||
.pl_bar .other { line-height: 24px; color: #999; font-size: 13px }
|
||||
.pl_bar .other a { display: inline-block; color: #999 }
|
||||
.pl_bar .reply { padding-left: 22px; background: url(../images/icon_reply.png) no-repeat 0 2px }
|
||||
.reply_bar .tit { line-height: 52px; font-size: 13px }
|
||||
.replay_text { width: 100%; height: 110px; border: 1px solid #eaeaea; border-radius: 5px; padding: 10px; box-sizing: border-box; font-size: 14px; box-shadow: 0 0 4px 2px hsla(0,0%,92%,.35); }
|
||||
.replay_text:hover { background: #fff }
|
||||
.reply_btn { padding: 17px 0 19px; overflow: hidden }
|
||||
.reply_bar .reply_btn { padding-bottom: 4px }
|
||||
.reply_btn .btn_red { padding: 10px 20px; font-size: 14px }
|
||||
.reply_btn .fr { margin-top: 8px }
|
||||
.write_bar { padding: 1rem 0; margin: 0 1rem }
|
||||
.write_comment { padding: 1rem; background: #f6f6f6; min-height: 16rem }
|
||||
.write_comment .text { width: 100%; min-height: 10rem; border: 1px solid #ddd; font-size: 0.875rem; line-height: 1.8; margin-bottom: 1rem }
|
||||
.book_comment_tit { font-size: 24px; padding: 20px 15px 10px 15px }
|
||||
.page_bar { padding: 1rem 0; margin: 0 1rem; border-top: 1px solid #eee }
|
||||
.page_bar li { width: 33.3%; float: left; text-align: center }
|
||||
.page_bar li a, .page_bar li .select_page { display: block; height: 2rem; line-height: 2rem; font-size: 0.875rem; border: 1px solid #eee; background: #fff; box-sizing: border-box }
|
||||
.page_bar .previous a { margin-right: 1rem }
|
||||
.page_bar .next a { margin-left: 1rem }
|
||||
.page_bar li .select_page { width: 100% }
|
||||
.icon_jh, .icon_zd { text-align: center; margin: 2px 5px 0 0; color: #fff; font-size: 12px; padding: 3px 3px; line-height: 1; display: inline-block; background: #ed4259; border-radius: 2px }
|
||||
.icon_zd { background: #4a90e2 }
|
||||
|
||||
|
||||
.hot_notice span, .items_txt .intro a, .updateTable .author a, .updateTable .style a, .updateTable .time a, .updateTable th { color: #888 }
|
||||
.items_txt .intro a:hover, .rightList .more a:hover, .updateTable .style a:hover, .rightList .on .book_intro .txt:hover { color: #f70 }
|
||||
.icon_show:hover, .icon_hide:hover { color: #2972cc }
|
||||
.channelChapterlist { min-height: 600px }
|
181
novel-front/src/main/resources/static/css/read.css
Normal file
@ -0,0 +1,181 @@
|
||||
@charset "utf-8";
|
||||
a { color: #333 }
|
||||
a:hover, .redFont, .current, .bookNav a:hover, .textinfo a:hover { color: #f70 }
|
||||
.read_menu li a, .closePopup, .menu_left li a span, .menu_right li a span, .icon_check, .icon_yb { background: url(../images/icon_readpage.png) no-repeat }
|
||||
/* 阅读页背景 */
|
||||
body { /*background-color: #4a4a4a;*/ color: #333; font-family: "Microsoft YaHei" }
|
||||
.topMain { box-shadow: 0 1px 4px rgba(0,0,0,.1); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#66ffffff,endColorstr=#66ffffff); background: none; background: rgba(255,255,255,.4) }
|
||||
.read_style_6 .topMain { border-bottom: 1px solid #444; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#0cffffff,endColorstr=#0cffffff); background: rgba(255,255,255,.05) }
|
||||
/*颜色:浅黄白、护眼绿、粉色、浅黄、浅灰、夜间黑*/
|
||||
body, .read_style_1 { background-color: #ebe5d8 }
|
||||
.read_style_2 { background-color: #cbdec9 }
|
||||
.read_style_3 { background-color: #edd4d4 }
|
||||
.read_style_4 { background-color: #e0cfa3 }
|
||||
.read_style_5 { background-color: #d3d3d3 }
|
||||
.read_style_6 { background-color: #0e0f0f }
|
||||
.read_style_1 .textbox, .read_style_1 .read_menu li a, .read_style_1 .haveRead, .read_style_1 .nextPageBox a { background-color: rgb(244, 241, 234) }/*浅黄白*/
|
||||
.read_style_2 .textbox, .read_style_2 .read_menu li a, .read_style_2 .haveRead, .read_style_2 .nextPageBox a { background-color: rgb(224, 235, 223) }/*护眼绿*/
|
||||
.read_style_3 .textbox, .read_style_3 .read_menu li a, .read_style_3 .haveRead, .read_style_3 .nextPageBox a { background-color: rgb(244, 229, 229) }/*粉色*/
|
||||
.read_style_4 .textbox, .read_style_4 .read_menu li a, .read_style_4 .haveRead, .read_style_4 .nextPageBox a { background-color: rgb(236, 226, 200) }/*浅黄*/
|
||||
.read_style_5 .textbox, .read_style_5 .read_menu li a, .read_style_5 .haveRead, .read_style_5 .nextPageBox a { background-color: rgb(229, 229, 229) }/*浅灰*/
|
||||
.read_style_6 .textbox, .read_style_6 .read_menu li a, .read_style_6 .haveRead, .read_style_6 .nextPageBox a { background-color: rgb(39, 39, 39) }/*夜间黑*/
|
||||
.read_style_1 .textbox, .read_style_1 .read_menu li a, .read_style_1 .haveRead, .read_style_1 .nextPageBox a { background-color: rgba(255, 255, 255,.45) }
|
||||
.read_style_2 .textbox, .read_style_2 .read_menu li a, .read_style_2 .haveRead, .read_style_2 .nextPageBox a, .read_style_3 .textbox, .read_style_3 .read_menu li a, .read_style_3 .haveRead, .read_style_3 .nextPageBox a, .read_style_4 .textbox, .read_style_4 .read_menu li a, .read_style_4 .haveRead, .read_style_4 .nextPageBox a, .read_style_5 .textbox, .read_style_5 .read_menu li a, .read_style_5 .haveRead, .read_style_5 .nextPageBox a { background-color: rgba(255, 255, 255,.4) }
|
||||
.read_style_6 .textbox, .read_style_6 .read_menu li a, .read_style_6 .haveRead, .read_style_6 .nextPageBox a { background-color: rgba(255, 255, 255,.1) }
|
||||
.read_style_1 .author_say, .read_style_1 .orderBox, .read_style_2 .author_say, .read_style_2 .orderBox, .read_style_3 .author_say, .read_style_3 .orderBox, .read_style_4 .author_say, .read_style_4 .orderBox, .read_style_5 .author_say, .read_style_5 .orderBox { background-color: #fcfbfa; background-color: rgba(255,255,255,.75) }
|
||||
/*.read_style_1 .nextPageBox a { border-color: #e0e0e0 }
|
||||
.read_style_2 .nextPageBox a { border-color: #bad7b7 }
|
||||
.read_style_3 .nextPageBox a { border-color: #e5d3d3 }
|
||||
.read_style_4 .nextPageBox a { border-color: #e0dcd0 }
|
||||
.read_style_5 .nextPageBox a { border-color: #d3d3d3 }
|
||||
.read_style_6 .nextPageBox a { border-color: #555 }*/
|
||||
.read_style_6 .author_say, .read_style_6 .orderBox, .read_style_6 .textbox, .read_style_6 .book_title h1, .read_style_6 .read_menu li, .read_style_6 .haveRead, .read_style_6 .haveRead a, .read_style_6 .topMain a, .read_style_6 .searchBar .s_int, .read_style_6 .bookNav, .read_style_6 .bookNav a, .read_style_6 .textinfo, .read_style_6 .textinfo a, .read_style_6 .textinfo span, .read_style_6 .read_menu li a b { color: #999; box-shadow: none }
|
||||
.read_style_6 .bookNav, .read_style_6 .author_say, .read_style_6 .orderBox, .read_style_6 .payFoot { border-color: #444!important }
|
||||
.readBody { height: 100% }
|
||||
.readMain { margin: 0 auto; position: relative; z-index: 3; width: 900px }
|
||||
/* 左右菜单栏 */
|
||||
.menu_left { width: 60px; z-index: 20; position: absolute; top: 60px; left: 50%; margin-left: -511px }
|
||||
.menu_right { width: 60px; z-index: 20; position: absolute; bottom: 81px; right: 50%; margin-right: -511px; display: none }
|
||||
.read_menu li { box-shadow: 0 0 1px 0 rgba(0,0,0,.05); margin-bottom: 1px; width: 60px; position: relative }
|
||||
.read_menu li a { display: block; width: 60px; height: 60px; position: relative; /*background-color: #fff;*/ opacity: 0.95 }
|
||||
.read_menu li a i { display: none; width: 60px; text-align: center; color: #999; font-size: 13px; line-height: 1.5; padding-top: 20px }
|
||||
.read_menu li a b { font-weight: 400; display: block; height: 60px; width: 60px; text-align: center; line-height: 90px; color: rgba(0,0,0,.5); }
|
||||
.menu_left li a:hover, .menu_right li a:hover { opacity: 1 }
|
||||
.menu_left li a span, .menu_right li a span { background-position: -1px -126px; width: 6px; height: 6px; top: 13px; right: 13px; position: absolute }
|
||||
.menu_left li a.ico_catalog { background-position: -60px -10px }
|
||||
.menu_left li a.ico_page { background-position: 2px -10px }
|
||||
.menu_left li a.ico_comment { background-position: -122px -65px }
|
||||
.menu_left li a.ico_phone { background-position: -304px -10px }
|
||||
.menu_left li a.ico_shelf, .menu_left li a.ico_shelfed { background-position: -182px -10px }
|
||||
.menu_left li a.ico_setup { background-position: -122px -10px }
|
||||
.menu_left li a.ico_pc { background-position: 1px -62px }
|
||||
.menu_left li a.ico_flower { background-position: -62px -64px }
|
||||
.menu_right li a.ico_pagePrev { background-position: -184px -60px }
|
||||
.menu_right li a.ico_pageNext { background-position: -243px -60px }
|
||||
.menu_right li a.ico_goTop { background-position: -304px -56px }
|
||||
.menu_right li a.ico_pagePrev:hover, .menu_right li a.ico_pageNext:hover, .menu_right li a.ico_goTop:hover { background-image: none }
|
||||
.menu_right li a:hover i { display: block }
|
||||
/* 正文栏 */
|
||||
.textbox { border-radius: 2px; width: 98%; margin: 0 auto 20px; padding-bottom: 40px; box-shadow: 0 0 1px 0 rgba(0,0,0,.25); color: #111; }
|
||||
.bookNav { width: 99%; margin: 0 auto; padding: 18px 0 12px; line-height: 2.5; /*border-bottom: 1px dotted rgba(0,0,0,.1)*/ }
|
||||
.bookNav a { font: 12px/1 "Microsoft YaHei"; margin: 0 5px }
|
||||
.readWrap { margin: 0 auto; width: 100% }
|
||||
.book_title { width: 90%; margin: 0 auto; padding-bottom: 15px; position: relative }
|
||||
.book_title h1 { padding: 60px 0 30px; font: 26px/1 "Microsoft YaHei"; color: #000; text-align: center }
|
||||
.textinfo { color: rgba(0,0,0,.5); font: 12px/1.8 "Microsoft YaHei"; text-align: center; position: relative }
|
||||
.textinfo a, .textinfo span { color: rgba(0,0,0,.5); margin-right: 15px; display: inline-block; vertical-align: middle; margin-top: -3px; *margin-top:-1px;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
||||
.readBox { width: 90%; margin: 0 auto; line-height: 2; font-size: 16px; padding: 10px 0 60px; /*min-height: 469px;*/ word-wrap: break-word; word-break: break-word }
|
||||
.readBox p { line-height: 2; margin-top: 1em; text-indent: 2em; }
|
||||
.orderBox { width: 90%; margin: 0 auto 10px; padding: 40px 0; font-size: 14px; min-height: 330px; border: 1px solid rgba(0,0,0,.1); border-radius: 2px; }
|
||||
.orderBox h3 { padding: 0 50px; font: 18px/1 "Microsoft YaHei"; margin: 25px 0 }
|
||||
.order_list { padding: 0 50px; line-height: 2.6; }
|
||||
.order_list .btns { padding: 20px 0 }
|
||||
/* 作者的话 */
|
||||
.author_say { margin: 35px auto 10px; width: 90%; min-height: 70px; border-radius: 3px; background: url(../images/author_say.png) no-repeat; border: 1px solid #e3e3e3/*rgba(0,0,0,.1)*/ }
|
||||
.say_bar { padding: 14px 14px 14px 74px; font-size: 14px }
|
||||
/* 翻页 */
|
||||
.nextPageBox { margin: 30px auto; text-align: center; width: 98% }
|
||||
.nextPageBox a { width: 26%; height: 58px; line-height: 58px; font-size: 18px; display: inline-block; border-radius: 3px; text-align: center; /*background: rgba(255,255,255,0.5);*/ opacity:.95; border: 1px solid rgba(0,0,0,.1); }
|
||||
.nextPageBox a.prev, .nextPageBox a.dir { margin-right: 40px }
|
||||
.nextPageBox a:hover { /*background: rgba(255,255,255,.8);*/ opacity:1; color: #333 }
|
||||
.read_style_6 .nextPageBox a { color:#999; border:none }
|
||||
/*固定悬浮图层*/
|
||||
.readPopup { border: 1px solid #D9D9D9; border-radius: 3px; background: #FFF; box-shadow: 0 1px 2px #999; overflow: hidden; padding-bottom: 20px; z-index: 9999; position: fixed; left: 50%; top: 50% }
|
||||
.icon_check { position: absolute; width: 29px; height: 25px; right: -1px; top: -1px; z-index: 2; background-position: 0 -142px }
|
||||
.closePopup { position: absolute; top: 20px; right: 20px; width: 16px; height: 15px; background-posion: -43px -126px }
|
||||
.chapterBox { width: 600px; margin-left: -300px; margin-top: -260px }
|
||||
.chapterBox .scrollWrap { height: 540px }
|
||||
/*弹窗内容*/
|
||||
.popupTit h2 { text-align: center; letter-spacing: 15px; color: #333; font: 700 20px/30px "Microsoft Yahei"; margin: 30px 0 }
|
||||
.popupTit h3 { font-size: 16px; margin: 15px 20px }
|
||||
.scrollWrap { overflow-y: scroll; position: relative }
|
||||
.dirWrap { padding: 0 40px }
|
||||
.scrollWrap h3 { padding-left: 26px; font-size: 14px; background: #e6e6e6; height: 30px; line-height: 30px; font-weight: normal; position: relative; cursor: pointer; margin: 0 0 15px; border-radius: 3px }
|
||||
.readPopup .tc .btn_gray { margin-left: 30px }
|
||||
/* 目录 */
|
||||
.dirList { overflow: hidden; *zoom:1
|
||||
}
|
||||
.dirList li { float: left; width: 40%; padding-left: 26px; height: 40px; line-height: 40px; overflow: hidden; margin-right: 20px; *zoom:1
|
||||
}
|
||||
.dirList li a { float: left; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; width: 220px }
|
||||
/* 加书架 */
|
||||
.readTipBox { width: 400px; padding-bottom: 30px; margin-left: -200px; margin-top: -105px }
|
||||
.tipWrap { padding: 30px }
|
||||
/* 设置 */
|
||||
.setupBox { width: 480px; margin-left: -240px; margin-top: -130px }
|
||||
.setupList { padding: 5px 40px }
|
||||
.setupList li { font-size: 14px; padding: 15px 0 }
|
||||
.setupList li a { display: inline-block; vertical-align: middle; margin: 0 6px; text-align: center }
|
||||
.readTheme a { width: 34px; height: 34px; border-radius: 50%; position: relative; border:1px solid rgba(0,0,0,.1) }
|
||||
.readTheme .white { background-color: #faf6ed; margin-left: 15px }
|
||||
.readTheme .green { background-color: #e2efe2 }
|
||||
/*.readTheme .blue { background-color: #E8FDFE }*/
|
||||
.readTheme .pink { background-color: #FDD9D9 }
|
||||
.readTheme .yellow { background-color: #F1DEBD }
|
||||
.readTheme .gray { background-color: #eee }
|
||||
.readTheme .night { background-color: #666 }
|
||||
/*.readTheme a.current, .readTheme a:hover { box-shadow: 1px 3px 5px #aaa }*/
|
||||
.read_style_1 .readTheme .white, .read_style_2 .readTheme .green, .read_style_3 .readTheme .pink, .read_style_4 .readTheme .yellow, .read_style_5 .readTheme .gray, .read_style_6 .readTheme .night { border-color: #f80 }
|
||||
.setBtn a { border: 1px solid #D9D9D9; width: 53px; height: 28px; line-height: 28px; box-shadow: 0 1px 1px #ECECEC; border-radius: 3px }
|
||||
.setBtn .act { color: #CC2931 }
|
||||
.setFont .setSimsun { font-family: Simsun; font-size: 13px }
|
||||
.setFont .setKs { font-family: kaiti; font-size: 15px }
|
||||
.setupList li.fontSize a { text-align: center; margin: 0; font-size: 16px; width: 70px; box-shadow: 0 1px 0 #ECECEC }
|
||||
.setupList li.fontSize a.small { margin-left: 8px; border-right: none; border-radius: 3px 0 0 3px }
|
||||
.setupList li.fontSize a.big { border-left: none; border-radius: 0 3px 3px 0 }
|
||||
.setupList li.fontSize .current_font { display: inline-block; padding: 0 22px; border: 1px solid #D9D9D9; height: 28px; line-height: 28px; box-shadow: 0 1px 1px #ECECEC; vertical-align: middle }
|
||||
/* 手机阅读 */
|
||||
.qrBox { width: 280px; margin-left: -140px; margin-top: -120px }
|
||||
.qrList { text-align: center; width: 166px; margin: 30px auto 15px }
|
||||
.qr_img { width: 160px; height: 160px; margin: 0 auto 10px; display: block }
|
||||
.qrCodeBox p { color: #999 }
|
||||
/*遮罩层*/
|
||||
.maskBox { position: fixed; left: 0; top: 0; z-index: 995; width: 100%; height: 100%; background: black; filter: alpha(opacity=20); opacity: 0.2; animation: mask 2s ease-out 0s 1 normal }
|
||||
@keyframes mask { 0% {
|
||||
filter:alpha(opacity=0);
|
||||
opacity:0
|
||||
}
|
||||
100% {
|
||||
filter:alpha(opacity=20);
|
||||
opacity:0.2
|
||||
}
|
||||
}
|
||||
.pc_bar { padding: 30px 0 10px; text-align: center; position: relative; }
|
||||
.icon_pc { box-shadow: 0 1px 1px rgba(0,0,0,.3); padding: 3px; display: inline-block; border-radius: 50%; }
|
||||
.icon_pc span { width: 96px; height: 96px; line-height: 1; border-radius: 50%; display: inline-block; background-color: #f80; color: #fefefe; font-size: 22px; letter-spacing: 0px; text-align: center; }
|
||||
.icon_pc:hover span { background: #ed4259 }
|
||||
.icon_yb { width: 37px; height: 27px; display: block; background-position: 0 -173px; margin: 19px auto 7px }
|
||||
.icon_pc em { filter: alpha(opacity=90); -moz-opacity: 0.9; opacity: 0.9; }
|
||||
.read_dz { height:40px; line-height:40px; border-radius:40px; padding:0 22px; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#0c000000,endColorstr=#0c000000); background:rgba(0,0,0,.07); display:block; position:absolute; bottom:35px; right:50px; color:#444; font-size:18px }
|
||||
.read_dz:hover { color:#444; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#19000000,endColorstr=#19000000); background:rgba(0,0,0,.1) }
|
||||
.read_dz i { width:25px; height:25px; display:inline-block; position:relative; top:4px; margin-right:6px; background:url(../images/icon_readdz.png) no-repeat }
|
||||
.read_style_6 .read_dz { color:#aaa }
|
||||
.read_dz.on { color:#f70; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#0cff8800,endColorstr=#0cff8800); background:rgba(255,136,0,.05) }
|
||||
.read_dz.on i { background-position:-30px 0 }
|
||||
.haveRead { border-radius: 2px; /*background: #fff;*/ width: 98%; margin:0 auto 20px; }
|
||||
.haveRead h4 { padding: 25px 40px 0; font-weight: normal }
|
||||
.haveRead ul { padding: 0 15px 10px }
|
||||
.haveRead li { float: left; width: 124px; margin: 15px 23px }
|
||||
.haveRead .items_img { display: block }
|
||||
.haveRead .items_img img { width: 120px; height: 150px; background: #f6f6f6; border: 1px solid #ebebeb; padding: 1px; }
|
||||
.haveRead .items_img:hover img { border-color: #ccc }
|
||||
.haveRead .items_link { white-space: nowrap; text-overflow: ellipsis; width: 124px; overflow: hidden; height: 30px; line-height: 30px; display: block; }
|
||||
.payFoot { line-height: 2.4; padding: 30px 0 20px; margin: 10px 50px 0; font-size: 13px; color: #808080; border-top: 1px solid #eee }
|
||||
.readBanner { width: 98%; padding-top: 25px }
|
||||
.readBanner img { max-width: 100% }
|
||||
.read_style_6 .readBanner img, .read_style_6 .haveRead .items_img img { filter:alpha(opacity=80); opacity: .8 }
|
||||
:root .topMain { filter: none }
|
||||
|
||||
/*全本订阅*/
|
||||
.order_bar { text-align:center; padding-bottom: 30px }
|
||||
.order_zj { width: 178px; padding:15px 0; margin:0 14px; display:inline-block; transition: width .3s; border: 1px solid #d8d8d8; background: rgba(255,255,255,.7);border-radius: 4px }
|
||||
.order_zj:hover { color:#333; background: rgba(255,255,255,.2); border-color:#d1d1d1 }
|
||||
.order_zj h4 { font-size:18px; font-weight:normal }
|
||||
.order_zj .price { font-size:12px; padding-top:6px }
|
||||
.order_zj .price .red { margin-left:5px }
|
||||
.order_allzj { background:#f80; color:#fff; border-color:#f80 }
|
||||
.order_allzj .red { color:#fff }
|
||||
.order_allzj:hover { color:#fff; background:#f70; border-color:#f70 }
|
||||
.order_tip { padding:25px 0 10px; color:#999; font-size:13px }
|
||||
.dqye { font-size:15px }
|
137
novel-front/src/main/resources/static/css/user.css
Normal file
@ -0,0 +1,137 @@
|
||||
@charset "utf-8";
|
||||
.updateTable .style a { color:#999 }
|
||||
.updateTable .author a { color:#999; cursor:text }
|
||||
.bind, .updateTable .style a:hover { color:#f65167 }
|
||||
.userBox { /*width: 998px; border: 1px solid #eaeaea;*/ margin:0 auto 50px; background: #fff; border-radius: 6px }
|
||||
.channelViewhistory .userBox { margin: 0 auto }
|
||||
.user_l { width:350px; float:left; padding:100px 124px }
|
||||
.user_l h3 { font-size:23px; font-weight:normal; line-height:1; text-align: center }
|
||||
.user_l #LabErr { color:#ff4040; display:block; height:40px; line-height:40px; text-align: center; font-size: 14px }
|
||||
.user_l .log_list { width:350px }
|
||||
.user_l .s_input { margin-bottom:25px; font-size:14px }
|
||||
.s_input { width:348px; height:38px; line-height:38px\9; vertical-align:middle; border:1px solid #ddd; border-radius:2px }
|
||||
.icon_name, .icon_key, .icon_code { width:312px; padding-left:36px; background:url(../images/icon_user.png) no-repeat 13px 13px }
|
||||
.icon_key { background-position: 13px -51px }
|
||||
.icon_code { background-position: 13px -117px; width:200px; float:left }
|
||||
.code_pic { height:38px; float:right }
|
||||
.btn_phone { height:40px; width:100px; float:right; cursor:pointer; padding:0; text-align:center; border-radius:2px; background:#dfdfdf }
|
||||
.log_code { *padding-bottom:25px }
|
||||
.user_l .btn_red { width:100%; font-size:19px; padding:12px }
|
||||
.autologin { color:#999; line-height:1; margin-bottom:18px }
|
||||
.autologin em { vertical-align:2px; margin-left:4px }
|
||||
.user_r { width:259px; margin:80px 0; padding:20px 70px; border-left:1px dotted #e3e3e3; float:right; text-align:center }
|
||||
.user_r .tit { font-size:16px; line-height:1; padding: 6px 0 25px }
|
||||
.user_r .btn_ora { padding:10px 34px }
|
||||
.fast_login { padding:60px 0 0 }
|
||||
.fast_list { text-align:center; padding:0.5rem }
|
||||
.fast_list li { display:inline-block; *display:inline; zoom:1 }
|
||||
.fast_list li .img { width:48px; height:48px; margin:20px 0 5px }
|
||||
.fast_list li a:hover { opacity:0.8; filter: alpha(opacity=80); -moz-opacity: 0.8 }
|
||||
.fast_list li span { display:block }
|
||||
.fast_list .login_qq { margin:0 42px }
|
||||
.fast_list .login_wb a { color:#f55c5b }
|
||||
.fast_list .login_qq a { color:#51b7ff }
|
||||
.fast_list .login_wx a { color:#66d65e }
|
||||
.fast_tit { position:relative; overflow:hidden }
|
||||
.fast_tit .lines { position:absolute; top:50%; left:0; width:100%; height:1px; line-height:1; background:#eaeaea }
|
||||
.fast_tit .title { background:#fff; font-size:16px; padding:3px 14px; position:relative; display:inline-block; z-index:999 }
|
||||
/*userinfo*/
|
||||
.my_l { width:198px; float:left; font-size: 13px; padding-top: 20px; }
|
||||
.my_l li a { display:block; height:42px; line-height:42px; padding-left:62px; border-left:4px solid #fff; background:url(../images/icon_user.png) no-repeat; margin-bottom:5px; color: #666 }
|
||||
.my_l li .on { background-color:#fafafa; border-left:2px solid #f80; color:#000; border-radius: 0 2px 2px 0 }
|
||||
.my_l .link_1 { background-position:32px -188px }
|
||||
.my_l .link_2 { background-position:32px -230px }
|
||||
.my_l .link_3 { background-position:32px -272px }
|
||||
.my_l .link_4 { background-position:32px -314px }
|
||||
.my_l .link_5 { background-position:32px -356px }
|
||||
.my_l .link_6 { background-position:32px -397px }
|
||||
.my_l .link_7 { background-position:32px -440px }
|
||||
.my_l .link_8 { background-position:32px -481px }
|
||||
.my_r { width:739px; padding:0 30px 30px; float:right; border-left:1px solid #efefef; min-height:470px }
|
||||
.my_info { padding:30px 0 5px }
|
||||
.user_big_head { /*width:110px; height:110px; padding:4px; border:1px solid #eaeaea;*/ margin-right:30px; float:left; width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%; }
|
||||
.my_r .my_name { font-size:18px; line-height:1; padding:5px 0 12px 0 }
|
||||
.my_r .s_input { width:318px; padding:0 10px }
|
||||
.my_list li { line-height:28px }
|
||||
.my_list li i, .my_list li em.red { margin-right:6px }
|
||||
.my_list .binded { color:#999; margin-left:6px }
|
||||
.my_list .btn_link { margin-left:12px }
|
||||
.mytab_list li { line-height:30px; padding:10px 0; font-size:14px }
|
||||
.mytab_list li .tit { width:70px; color: #aaa; text-align:right; display:inline-block; margin-right:18px }
|
||||
.mytab_list .user_img { width:48px; height:48px; vertical-align:middle; border-radius:50% }
|
||||
.my_bookshelf .title { padding:20px 0 15px; line-height:30px }
|
||||
.my_bookshelf h4 { font-size:14px; color:#666 }
|
||||
.my_bookshelf h2 { font-size:18px; font-weight:normal }
|
||||
.updateTable { width: 739px; color: #999 }
|
||||
.updateTable table { width: 100%; margin-bottom:14px }
|
||||
.updateTable th, .updateTable td { height: 40px; line-height: 40px; vertical-align: middle; padding-left: 6px; font-weight:normal; text-align:left }
|
||||
.updateTable th { background:#f9f9f9; color:#333; border-top:1px solid #eee }
|
||||
.updateTable td { height:40px; line-height:40px }
|
||||
.updateTable .style { width:80px; padding-left:10px }
|
||||
.updateTable .name { width: 178px; padding-right: 10px }
|
||||
.updateTable .name a, .updateTable .chapter a { max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
||||
.updateTable .chapter { padding-right: 5px }
|
||||
.updateTable .chapter a { max-width:220px; float: left }
|
||||
.updateTable .author { width: 72px; text-align: left }
|
||||
.updateTable .goread { width: 80px; text-align:center }
|
||||
.updateTable .time { width: 86px }
|
||||
.updateTable .word { width: 64px; padding-right:10px; text-align: right }
|
||||
.updateTable .rank { width: 30px; padding-right:10px; text-align: center }
|
||||
.updateTable .name a, .updateTable .chapter a, .updateTable .author a { height: 40px; line-height: 40px; display: inline-block; overflow: hidden }
|
||||
.updateTable tr:nth-child(2n) td { background:#fafafa }
|
||||
.dataTable { width: 739px }
|
||||
.dataTable table { width: 100%; margin-bottom:14px; border-collapse:collapse }
|
||||
.dataTable th, .dataTable td { height: 40px; line-height: 40px; vertical-align: middle; padding:0 10px; font-weight:normal; text-align:center; border:1px solid #eaeaea }
|
||||
.dataTable th { background:#f8f8f8 }
|
||||
.nodate { border-top: 1px solid #eaeaea; padding:60px 0 }
|
||||
.viewhistoryBox { /*padding: 0 30px 30px; */ padding: 0 20px 10px }
|
||||
.viewhistoryBox .updateTable { width:100% }
|
||||
/*.btn_gray, .btn_red, .btn_ora { font-size:14px; padding:8px 28px }*/
|
||||
.book_tit { height: 48px; line-height:48px; margin: 0 14px; border-bottom: 1px solid #eaeaea; overflow:hidden }
|
||||
.book_tit .fl { font-size:14px; color:#999 }
|
||||
.book_tit .fl h3 { font-size:18px; color:#333; font-weight:normal; margin-right:5px; display:inline }
|
||||
.book_tit .fr { font-size:14px }
|
||||
|
||||
.commentBar, .feedback_list { border-top:1px solid #eee; margin-bottom:15px }
|
||||
/*.comment_list { padding: 16px 0; border-bottom: 1px solid #eee }
|
||||
.comment_list .user_head { width:54px; height:54px; border-radius:50%; float: left; margin-right: 14px }
|
||||
.comment_list .li_1 { overflow: hidden }
|
||||
.comment_list .user_name { color: #ed4259 }
|
||||
.comment_list .li_2 { padding:3px 0; color:#999 }
|
||||
.comment_list .li_3, .comment_list .li_4 { margin-left:68px }
|
||||
.comment_list .reply { padding-left: 12px }
|
||||
.comment_list .num { color: #ed4259; margin: 0 3px }
|
||||
.comment_list .li_4 { line-height:34px; padding-top:8px; margin-top:15px; border-top:1px solid #eaeaea }
|
||||
.comment_list .li_4 .more { background:#f7f7f7; border-radius:2px; color:#ed4259; text-align:center }*/
|
||||
.no_contet { padding:190px 0 40px; text-align:center; color:#999; border-top:1px solid #eee }
|
||||
.no_comment { background:url(../images/no_comment.png) no-repeat center 80px }
|
||||
|
||||
.comment_list { padding: 20px 0; border-bottom: 1px solid #eee }
|
||||
.comment_list:last-child { border: none }
|
||||
.comment_list .user_heads { /*width: 54px; height: 54px; float: left;*/ position:relative; margin-right: 20px }
|
||||
.comment_list .user_head { width: 50px; height: 50px; border-radius: 50%; background: #f6f6f6 }
|
||||
.comment_list .user_heads span { display: block; margin: 0; position: absolute; left: 12px; bottom: 0 }
|
||||
.comment_list ul { /*width: 640px;*/ width: 660px; }
|
||||
.comment_list .li_0 { font-family: "宋体" }
|
||||
.comment_list .li_0 strong { font-size: 14px; color: #f00 }
|
||||
.comment_list .li_1 { overflow: hidden }
|
||||
.comment_list .user_name { color: #ed4259 }
|
||||
.comment_list .li_2 { padding: 6px 0 }
|
||||
.comment_list .li_3 { color: #999 }
|
||||
.comment_list .reply { padding-left: 12px }
|
||||
.comment_list .num { color: #ed4259; margin: 0 3px }
|
||||
.comment_list .li_4 { line-height: 34px; padding-top: 8px; margin-top: 15px; border-top: 1px solid #eaeaea }
|
||||
.pl_bar li { display: block }
|
||||
.pl_bar .name { color: #666; padding-top: 2px; font-size: 14px }
|
||||
.pl_bar .dec { font-size: 14px; line-height: 1.8; padding: 12px 0 }
|
||||
.pl_bar .other { line-height: 24px; color: #999; font-size: 13px }
|
||||
.pl_bar .other a { display: inline-block; color: #999 }
|
||||
.pl_bar .reply { padding-left: 22px; background: url(../images/icon_reply.png) no-repeat 0 2px }
|
||||
/*.no_comment { padding: 70px 14px 115px; color: #CCCCCC; text-align: center; font-size: 14px; }*/
|
||||
.reply_bar {
|
||||
background: #f9f9f9;
|
||||
border: 1px solid #eee; border-radius: 6px;
|
||||
padding: 10px;
|
||||
line-height: 1.8;}
|
BIN
novel-front/src/main/resources/static/images/author_head.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
novel-front/src/main/resources/static/images/icon_dt.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
novel-front/src/main/resources/static/images/icon_readpage.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
novel-front/src/main/resources/static/images/icon_reply.png
Normal file
After Width: | Height: | Size: 679 B |
BIN
novel-front/src/main/resources/static/images/icon_sj.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
novel-front/src/main/resources/static/images/icon_user.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
novel-front/src/main/resources/static/images/login_qq.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
novel-front/src/main/resources/static/images/login_weibo.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
novel-front/src/main/resources/static/images/login_weixin.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
novel-front/src/main/resources/static/images/logo.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
novel-front/src/main/resources/static/images/logo_white.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
novel-front/src/main/resources/static/images/man.png
Normal file
After Width: | Height: | Size: 788 B |
BIN
novel-front/src/main/resources/static/images/no_comment.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
novel-front/src/main/resources/static/images/search.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
novel-front/src/main/resources/static/images/smlcover.png
Normal file
After Width: | Height: | Size: 390 KiB |
@ -0,0 +1 @@
|
||||
var authorInfoV3={"LogoImg":null,"Notes":null,"UId":0}
|
196
novel-front/src/main/resources/static/javascript/bookclass.js
Normal file
@ -0,0 +1,196 @@
|
||||
var bClass = {
|
||||
"total": 16,
|
||||
"rows": [{
|
||||
"BId": 1,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "玄幻",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 2,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "都市",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 3,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "仙侠",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 4,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "奇幻",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 5,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "历史",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 6,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "军事",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 7,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "游戏",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 8,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "竞技",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 9,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "科幻",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 10,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "武侠",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 11,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "同人",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 12,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "灵异",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 13,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "现代言情",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 14,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "古代言情",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 15,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "幻想言情",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}, {
|
||||
"BId": 16,
|
||||
"BookTotal": null,
|
||||
"ClassId": null,
|
||||
"IsShow": null,
|
||||
"Ld": null,
|
||||
"Name": "青春校园",
|
||||
"ParentId": null,
|
||||
"Rank": null,
|
||||
"Remark": null,
|
||||
"SexClass": null,
|
||||
"Status": null
|
||||
}]
|
||||
}
|
308
novel-front/src/main/resources/static/javascript/bookdetail.js
Normal file
@ -0,0 +1,308 @@
|
||||
var BookDetail = {
|
||||
wepDomain: 'java2nb.com',
|
||||
msgStyle: 'background-color:#333; color:#fff; text-align:center; border:none; font-size:20px; padding:10px;',
|
||||
reShowCover: function () {
|
||||
//$(".cCover").height($(".cDetail").height());
|
||||
//$(".cCover").width($(".cDetail").width());
|
||||
},
|
||||
DescriptionMore: function (sClass) {
|
||||
if (sClass == "") {
|
||||
if ($("#pDesMore").html().length > 150) {
|
||||
$("#divDescription").html($("#pDesMore").html().substring(0, 150) + "<a href=\"javascript:void(0);\" class=\"info_txt_more\" onclick=\"javascript:BookDetail.DescriptionMore('down');\">展开<img src=\"../images/arrow_d.png\" /></a>");
|
||||
} else {
|
||||
$("#divDescription").html($("#pDesMore").html());
|
||||
}
|
||||
} else {
|
||||
$("#divDescription").html($("#pDesMore").html() + "<a href=\"javascript:void(0);\" class=\"info_txt_more\" onclick=\"javascript:BookDetail.DescriptionMore('');\">收起<img src=\"../images/arrow_t.png\" /></a>");
|
||||
}
|
||||
},
|
||||
AddFavorites: function (BId, CId, layerStatus) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/user/addToBookShelf",
|
||||
data: {'bookId': $("#bookId").val(), 'preContentId': $("#preContentId").val()},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
if (layerStatus == 1) {
|
||||
$("#cFavs").html("<a class=\"ico_shelf\" href=\"javascript:void(0);\"><b>已收藏</b></a>");
|
||||
jQuery.cookie("u-faorites", "1");
|
||||
}
|
||||
else {
|
||||
$("#cFavs").html("<a class=\"btn_ora_white btn_addsj\" href=\"javascript:void(0);\">已在书架</a>");
|
||||
}
|
||||
|
||||
|
||||
} else if (data.code == 1001) {
|
||||
//未登录
|
||||
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
|
||||
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
},
|
||||
error: function () {
|
||||
layer.alert('网络异常');
|
||||
}
|
||||
})
|
||||
},
|
||||
GetFavorites: function (BId) {
|
||||
if (jQuery.cookie("u-faorites") == null) {
|
||||
} else {
|
||||
if (jQuery.cookie("u-faorites") == "1") {
|
||||
$("#cFavs").html("<a class=\"ico_shelf\" href=\"javascript:void(0);\"><b>已加书架</b></a>");
|
||||
}
|
||||
}
|
||||
/*BookDetail.SetWholeTip();*/
|
||||
},
|
||||
GetUserBookLevel: function (idList, bId) {
|
||||
if (idList.length > 2) {
|
||||
}
|
||||
},
|
||||
GetUserLevel: function (mTotal) {
|
||||
if (mTotal != undefined) {
|
||||
var iTotal = parseInt(mTotal);
|
||||
if (iTotal < 500) {
|
||||
return ["user_level1", "见习"];
|
||||
} else if (iTotal < 2000) {
|
||||
return ["user_level2", "学徒"];
|
||||
} else if (iTotal < 5000) {
|
||||
return ["user_level3", "弟子"];
|
||||
} else if (iTotal < 10000) {
|
||||
return ["user_level4", "执事"];
|
||||
} else if (iTotal < 20000) {
|
||||
return ["user_level5", "舵主"];
|
||||
} else if (iTotal < 30000) {
|
||||
return ["user_level6", "堂主"];
|
||||
} else if (iTotal < 40000) {
|
||||
return ["user_level7", "护法"];
|
||||
} else if (iTotal < 50000) {
|
||||
return ["user_level8", "长老"];
|
||||
} else if (iTotal < 70000) {
|
||||
return ["user_level9", "掌门"];
|
||||
} else if (iTotal < 100000) {
|
||||
return ["user_level10", "宗师"];
|
||||
} else {
|
||||
return ["user_level11", "盟主"];
|
||||
}
|
||||
} else {
|
||||
return ["user_level1", "见习"];
|
||||
}
|
||||
},
|
||||
SaveComment: function (cmtBId, cmtCId, cmtDetail) {
|
||||
if(!isLogin){
|
||||
layer.alert('请先登陆');
|
||||
return;
|
||||
}
|
||||
var cmtDetailTemp = cmtDetail.replace(/(^\s*)/g, "");
|
||||
if (cmtDetailTemp == '') {
|
||||
layer.alert('评论内容必须填写');
|
||||
return;
|
||||
}
|
||||
if (cmtDetailTemp.length < 5) {
|
||||
layer.alert('评论内容必须大于5个字');
|
||||
return;
|
||||
}
|
||||
if (cmtDetail.length < 5) {
|
||||
layer.alert('评论内容必须大于5个字');
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/book/addBookComment",
|
||||
data: {'bookId': $("#bookId").val(), 'commentContent': cmtDetail},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
$('#txtComment').val("")
|
||||
layer.alert('评价成功!');
|
||||
loadCommentList();
|
||||
|
||||
} else if (data.code == 1001) {
|
||||
//未登录
|
||||
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
|
||||
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
},
|
||||
error: function () {
|
||||
layer.alert('网络异常');
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
GetFavoritesBook: function (BId) {
|
||||
},
|
||||
GetMoneyFlower: function () {
|
||||
},
|
||||
AddAgreeTotal: function (AId, objs) {
|
||||
},
|
||||
RelationBook: function () {
|
||||
relationStep++;
|
||||
var bListCount = 0;
|
||||
var bList = $("#relationBookList div");
|
||||
bListCount = bList.length;
|
||||
var sStep = 0, eStep = 2;
|
||||
if (bListCount > relationStep * 3) {
|
||||
sStep = relationStep * 3;
|
||||
eStep = sStep + 2;
|
||||
if (sStep > bListCount - 1) {
|
||||
eStep = bListCount;
|
||||
}
|
||||
} else {
|
||||
relationStep = -1;
|
||||
}
|
||||
for (var i = 0; i < bListCount; i++) {
|
||||
if (i >= sStep && i <= eStep) {
|
||||
bList[i].style.display = "";
|
||||
} else {
|
||||
bList[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
},
|
||||
Click: function (bId) {
|
||||
//BookDetail.DescriptionMore("");
|
||||
},
|
||||
ClickChapter: function (bId, cId, isVip) {
|
||||
if (isVip == 1) {
|
||||
var m = Math.floor(6 * Math.random());
|
||||
if (m == 3) {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
},
|
||||
SetReadFont: function (fonts) {
|
||||
var cFont = parseInt($("#cFonts").html());
|
||||
fonts = cFont + fonts;
|
||||
if (fonts < 8) {
|
||||
fonts = 8;
|
||||
}
|
||||
if (fonts > 48) {
|
||||
fonts = 48;
|
||||
}
|
||||
localStorage.setItem("fonts", fonts);
|
||||
$(".readBox").css("font-size", fonts + "px");
|
||||
$("#cFonts").html(fonts);
|
||||
$("#ChapterBody").attr("class","article-content font"+fonts);
|
||||
BookDetail.reShowCover();
|
||||
},
|
||||
SetBackUpColor: function (colorNum) {
|
||||
localStorage.setItem("colorNum", colorNum);
|
||||
document.body.className = 'read_style_' + colorNum;
|
||||
|
||||
},
|
||||
SetReadFontFamily: function (fontNum) {
|
||||
localStorage.setItem("fontNum", fontNum);
|
||||
BookDetail.SetReadFontFamilyClear(fontNum);
|
||||
},
|
||||
SetReadFontFamilyClear: function (fontNum) {
|
||||
$("#setup_font_yahei").removeClass("current");
|
||||
$("#setup_font_simsun").removeClass("current");
|
||||
$("#setup_font_ks").removeClass("current");
|
||||
if (fontNum == 1) {
|
||||
$("#setup_font_simsun").addClass("current");
|
||||
$(".readBox").css("font-family", "Simsun");
|
||||
} else if (fontNum == 2) {
|
||||
$("#setup_font_ks").addClass("current");
|
||||
$(".readBox").css("font-family", "kaiti");
|
||||
} else {
|
||||
$("#setup_font_yahei").addClass("current");
|
||||
$(".readBox").css("font-family", "microsoft yahei");
|
||||
}
|
||||
},
|
||||
GetReadSet: function (bid, cid, preId, nextId, crank) {
|
||||
/*$(".nextPageBox .prev,.ico_pagePrev").click(function () {
|
||||
if (preId > 0) {
|
||||
location.href = '/book/' + bid + '/' + preId + '.html';
|
||||
}
|
||||
else {
|
||||
location.href = '/book/chapterlist-' + bid + '.html';
|
||||
}
|
||||
});
|
||||
|
||||
$(".nextPageBox .next,.ico_pageNext").click(function () {
|
||||
if (nextId > 0) {
|
||||
location.href = '/book/' + bid + '/' + nextId + '.html';
|
||||
}
|
||||
else {
|
||||
location.href = '/book/chapterlist-' + bid + '.html';
|
||||
}
|
||||
});*/
|
||||
$(window).bind('keydown',
|
||||
function (e) {
|
||||
if (e.keyCode == 37) {
|
||||
if (preId > 0) {
|
||||
location.href = '/book/' + bid + '/' + preId + '.html';
|
||||
} else {
|
||||
location.href = '/book/chapterlist-' + bid + '.html';
|
||||
}
|
||||
} else if (e.keyCode == 39) {
|
||||
if (nextId > 0) {
|
||||
location.href = '/book/' + bid + '/' + nextId + '.html';
|
||||
} else {
|
||||
location.href = '/book/chapterlist-' + bid + '.html';
|
||||
}
|
||||
}
|
||||
});
|
||||
BookDetail.SetReadHistory(bid, cid, crank);
|
||||
},
|
||||
SetReadHistory: function (bid, cid, crank) {
|
||||
var strHistory = jQuery.cookie("wapviewhistory");
|
||||
if (strHistory != null) {
|
||||
var r = new RegExp('b' + bid + '\\\|(.*?),', 'g');
|
||||
strHistory = strHistory.replace(r, '')
|
||||
strHistory = 'b' + bid + '|' + cid + '|' + crank + ',' + strHistory;
|
||||
if (strHistory.length > 500) {
|
||||
strHistory = strHistory.substring(0, 500);
|
||||
strHistory = strHistory.substring(0, strHistory.lastIndexOf(','));
|
||||
strHistory = strHistory + ',';
|
||||
}
|
||||
} else {
|
||||
strHistory = 'b' + bid + '|' + cid + '|' + crank + ',';
|
||||
}
|
||||
jQuery.cookie("wapviewhistory", strHistory, {path: '/', domain: BookDetail.wepDomain, expires: 365});
|
||||
},
|
||||
formatDate: function (now, types) {
|
||||
if (now != null && now != "") {
|
||||
var dateN = new Date(+/\d+/.exec(now)[0]);
|
||||
var year = dateN.getFullYear();
|
||||
var month = dateN.getMonth() + 1;
|
||||
var date = dateN.getDate();
|
||||
var hour = dateN.getHours();
|
||||
var minute = dateN.getMinutes();
|
||||
var second = dateN.getSeconds();
|
||||
if (typeof (types) != "undefined" && types != null) {
|
||||
return year + "-" + month + "-" + date;
|
||||
} else if (hour == 0 && minute == 0 && second == 0) {
|
||||
return year + "-" + month + "-" + date;
|
||||
} else {
|
||||
return year + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + second;
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
SetWholeTip: function () {
|
||||
var str = '<li>1、此书为全网优质作品,按照整本定价折扣销售,购买之后可以阅读该书全部章节。</li>';
|
||||
str += '<li>2、支付屋币即可阅读收费章节,没有屋币的需要先充值。</li>';
|
||||
str += '<li>3、QQ、微信、微博3种账号之间的数据不互通,如果你发现充值成功但没有屋币到账,请切换账号查看是否充到了别的账号中。</li>';
|
||||
if ($("#HidIsWholeBook").val() == "1") {
|
||||
$(".tip_list").html(str);
|
||||
}
|
||||
},
|
||||
SetDZChapter: function (bId, cId, isDianZan) {
|
||||
if (isDianZan == 1) {
|
||||
/*是点赞,设置点赞数+1和不可点状态*/
|
||||
var dzData = parseInt($("#read_dz_bar a").text()) + 1;
|
||||
$("#read_dz_bar").html('<a class="read_dz on" href="javascript:void(0)"><i></i>' + dzData + '</a>');
|
||||
}
|
||||
}
|
||||
}
|
||||
var rand = {};
|
||||
rand.get = function (begin, end) {
|
||||
return Math.floor(Math.random() * (end - begin)) + begin;
|
||||
}
|
125
novel-front/src/main/resources/static/javascript/common.js
Normal file
@ -0,0 +1,125 @@
|
||||
var needLoginPath = ['/user/favorites.html','/user/comment.html','/user/feedback.html',
|
||||
'/user/feedback_list.html','/user/read_history.html','/user/set_name.html',
|
||||
'/user/set_password.html','/user/set_sex.html','/user/setup.html','/user/userinfo.html'];
|
||||
var isLogin = false;
|
||||
var url = window.location.search;
|
||||
//key(需要检索的键)
|
||||
function getSearchString(key) {
|
||||
var str = url;
|
||||
str = str.substring(1, str.length); // 获取URL中?之后的字符(去掉第一位的问号)
|
||||
// 以&分隔字符串,获得类似name=xiaoli这样的元素数组
|
||||
var arr = str.split("&");
|
||||
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
var tmp_arr = arr[i].split("=");
|
||||
if(tmp_arr[0] == key){
|
||||
return decodeURIComponent(tmp_arr[1]);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
var keyword = getSearchString("k");
|
||||
if(keyword != undefined) {
|
||||
$("#searchKey").val(keyword);
|
||||
$("#workDirection").remove();
|
||||
$("#idGirl").remove();
|
||||
}
|
||||
|
||||
function searchByK(k){
|
||||
if(!k){
|
||||
window.location.href='/book/bookclass.html?k='+encodeURIComponent(document.getElementById("searchKey").value)
|
||||
}else{
|
||||
window.location.href='/book/bookclass.html?k='+encodeURIComponent(k)
|
||||
}
|
||||
}
|
||||
$("#searchKey").keypress(function (even) {
|
||||
if (even.which == 13) {
|
||||
even.stopPropagation();
|
||||
//enter键按下
|
||||
searchByK();
|
||||
}
|
||||
});
|
||||
Array.prototype.indexOf = function (val) {
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (this[i] == val) return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
var token = $.cookie('Authorization');
|
||||
if(!token){
|
||||
if(needLoginPath.indexOf(window.location.pathname) != -1){
|
||||
location.href = '/user/login.html?originUrl='+decodeURIComponent(location.href);
|
||||
}
|
||||
|
||||
$(".user_link").html("<i class=\"line mr20\">|</i><a href=\"/user/login.html\" class=\"mr15\">登录</a><a href=\"/user/register.html\" >注册</a>");
|
||||
}else{
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/user/refreshToken",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.code == 200){
|
||||
$(".user_link").html("<i class=\"line mr20\">|</i>" +
|
||||
"<a href=\"/user/userinfo.html\" class=\"mr15\">"+data.data.username+"</a>" +
|
||||
"<a href=\"javascript:logout()\" >退出</a>");
|
||||
;
|
||||
if("/user/login.html" == window.location.pathname){
|
||||
var orginUrl = getSearchString("originUrl");
|
||||
window.location.href = orginUrl == undefined || orginUrl.isBlank() ? "/" : orginUrl;
|
||||
return;
|
||||
}
|
||||
isLogin = true;
|
||||
if(localStorage.getItem("autoLogin") == 1){
|
||||
$.cookie('Authorization', data.data.token, { expires: 7 ,path: '/' });
|
||||
}else {
|
||||
$.cookie('Authorization', data.data.token,{ path: '/' });
|
||||
}
|
||||
}else{
|
||||
if(needLoginPath.indexOf(window.location.pathname) != -1){
|
||||
location.href = '/user/login.html';
|
||||
}
|
||||
$(".user_link").html("<i class=\"line mr20\">|</i><a href=\"/user/login.html\" class=\"mr15\">登录</a><a href=\"/user/register.html\" >注册</a>");
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.alert('网络异常');
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
String.prototype.isPhone = function () {
|
||||
var strTemp = /^1[3|4|5|6|7|8|9][0-9]{9}$/;
|
||||
if (strTemp.test(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
String.prototype.isBlank = function () {
|
||||
if(this == null || $.trim(this) == ""){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
String.prototype.isNickName = function () {
|
||||
var strTemp = /^[\u4E00-\u9FA5A-Za-z0-9_]+$/;
|
||||
if (strTemp.test(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function logout() {
|
||||
$.cookie('Authorization', null,{ path: '/' });
|
||||
location.reload();
|
||||
}
|
153
novel-front/src/main/resources/static/javascript/header.js
Normal file
@ -0,0 +1,153 @@
|
||||
var $C = function (objName) {
|
||||
if (typeof (document.getElementById(objName)) != "object")
|
||||
{ return null; }
|
||||
else
|
||||
{ return document.getElementById(objName); }
|
||||
}
|
||||
jQuery.cookie = function (name, value, options) {
|
||||
if (typeof value != 'undefined') {
|
||||
options = options || {};
|
||||
if (value === null) {
|
||||
value = '';
|
||||
options.expires = -1;
|
||||
}
|
||||
var expires = '';
|
||||
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
||||
var date;
|
||||
if (typeof options.expires == 'number') {
|
||||
date = new Date();
|
||||
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
||||
} else {
|
||||
date = options.expires;
|
||||
}
|
||||
expires = '; expires=' + date.toUTCString();
|
||||
}
|
||||
var path = options.path ? '; path=' + options.path : '';
|
||||
var domain = options.domain ? '; domain=' + options.domain : '';
|
||||
var secure = options.secure ? '; secure' : '';
|
||||
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
||||
} else {
|
||||
var cookieValue = null;
|
||||
if (document.cookie && document.cookie != '') {
|
||||
var cookies = document.cookie.split(';');
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = jQuery.trim(cookies[i]);
|
||||
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
};
|
||||
$(function () {
|
||||
|
||||
|
||||
$(".rightList li").mouseover(function () {
|
||||
//$($(this).parent()).children().each(function () {
|
||||
// $(this).removeClass("on");
|
||||
//});
|
||||
//$(this).addClass("on");
|
||||
});
|
||||
$(".rightList_nobor li").mouseover(function () {
|
||||
$($(this).parent()).children().each(function () {
|
||||
$(this).addClass("on");
|
||||
});
|
||||
});
|
||||
|
||||
$("#headerUserHistoryBtn").mouseover(function () {
|
||||
HeaderShowUtil.headerShowHistory();
|
||||
});
|
||||
$("#headerUserHistory").mouseleave(function () {
|
||||
HeaderShowUtil.headerHideHistory();
|
||||
});
|
||||
});
|
||||
function getNote() {
|
||||
}
|
||||
function goPage(cpage) {
|
||||
location.href = '?page=' + cpage;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function isWeiXin() {
|
||||
var ua = window.navigator.userAgent.toLowerCase();
|
||||
if (ua.indexOf("micromessenger") > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var HeaderShowUtil = {
|
||||
headerShowHistory: function (obj) {
|
||||
if ($("#headerUserHistory").html().length < 10) {
|
||||
var rStr = '<div class="record_box">';
|
||||
rStr += ' <div class="record_title" id="hdShowTitle"><a href="javascript:void(0);" class="record_tit1 on" onclick="javascript:HeaderShowUtil.headerShowHistoryLog(this);">最近阅读</a><a href="javascript:void(0);" class="record_tit2" onclick="javascript:HeaderShowUtil.headerShowFavLog(this);">我的书架</a></div>';
|
||||
rStr += ' <div class="record_list record_list1" id="hdShowHistory">';
|
||||
rStr += ' <ul>';
|
||||
rStr += ' </ul>';
|
||||
rStr += ' <a class="all" href="/" >查看全部</a>';
|
||||
rStr += ' </div>';
|
||||
rStr += ' <div class="record_list record_list2" style="display:none" id="hsShowFav">';
|
||||
rStr += ' <ul>';
|
||||
rStr += ' </ul>';
|
||||
rStr += ' <a class="all" href="/" >查看全部</a>';
|
||||
rStr += ' </div>';
|
||||
rStr += ' <p class="sp"></p>';
|
||||
rStr += ' </div>';
|
||||
$("#headerUserHistory").html(rStr);
|
||||
}
|
||||
$("#headerUserHistory").show();
|
||||
$("#headerUserHistoryBtn").addClass("on");
|
||||
HeaderShowUtil.headerShowHistoryLog();
|
||||
},
|
||||
headerHideHistory: function () {
|
||||
$("#headerUserHistory").hide();
|
||||
$("#headerUserHistoryBtn").removeClass("on");
|
||||
},
|
||||
headerShowHistoryLog: function (obj) {
|
||||
if (obj != undefined) {
|
||||
$("#hdShowTitle a").removeClass("on");
|
||||
$(obj).addClass("on");
|
||||
$("#hdShowHistory").show();
|
||||
$("#hsShowFav").hide();
|
||||
}
|
||||
var cookieHistory = jQuery.cookie("wapviewhistory");
|
||||
if (cookieHistory != undefined && cookieHistory.length > 0) {
|
||||
var bList, bIdList;
|
||||
var bIdArray = new Array();
|
||||
var cookieList = cookieHistory.split(',');
|
||||
for (var i = 0; i < cookieList.length && i < 3; i++) {
|
||||
var str = cookieList[i];
|
||||
if (str.indexOf('|') > 0) {
|
||||
bList = str.split('|');
|
||||
if (bList.length == 3) {
|
||||
bIdList += ',' + bList[0].replace("b", "");
|
||||
bIdArray[bList[0].replace("b", "")] = bList[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$("#hdShowHistory ul").html("<li>暂无看书历史</li>");
|
||||
}
|
||||
},
|
||||
headerShowFavLog: function (obj) {
|
||||
$("#hdShowTitle a").removeClass("on");
|
||||
$(obj).addClass("on");
|
||||
$("#hsShowFav").show();
|
||||
$("#hdShowHistory").hide();
|
||||
var rStr = '';
|
||||
var uname = jQuery.cookie("waplogname");
|
||||
if (uname != undefined && uname != "") {
|
||||
}
|
||||
else {
|
||||
rStr = '<li><a href="/user/login.html">请先登录</a></li>';
|
||||
$("#hsShowFav ul").html(rStr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
2
novel-front/src/main/resources/static/javascript/jquery-1.8.0.min.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/*! layer mobile-v1.6 弹层组件移动版 License LGPL http://layer.layui.com/mobile By 贤心 */
|
||||
;!function(a){"use strict";var b="";b=b?b:document.scripts[document.scripts.length-1].src.match(/[\s\S]*\//)[0];var c=document,d="querySelectorAll",e="getElementsByClassName",f=function(a){return c[d](a)};document.head.appendChild(function(){var a=c.createElement("link");return a.href=b+"need/layer.css",a.type="text/css",a.rel="styleSheet",a.id="layermcss",a}());var g={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:!0};a.ready={extend:function(a){var b=JSON.parse(JSON.stringify(g));for(var c in a)b[c]=a[c];return b},timer:{},end:{}},ready.touch=function(a,b){var c;return/Android|iPhone|SymbianOS|Windows Phone|iPad|iPod/.test(navigator.userAgent)?(a.addEventListener("touchmove",function(){c=!0},!1),void a.addEventListener("touchend",function(a){a.preventDefault(),c||b.call(this,a),c=!1},!1)):void a.addEventListener("click",function(a){b.call(this,a)},!1)};var h=0,i=["layermbox"],j=function(a){var b=this;b.config=ready.extend(a),b.view()};j.prototype.view=function(){var a=this,b=a.config,d=c.createElement("div");a.id=d.id=i[0]+h,d.setAttribute("class",i[0]+" "+i[0]+(b.type||0)),d.setAttribute("index",h);var g=function(){var a="object"==typeof b.title;return b.title?'<h3 style="'+(a?b.title[1]:"")+'">'+(a?b.title[0]:b.title)+'</h3><button class="layermend"></button>':""}(),j=function(){var a,c=(b.btn||[]).length;return 0!==c&&b.btn?(a='<span type="1">'+b.btn[0]+"</span>",2===c&&(a='<span type="0">'+b.btn[1]+"</span>"+a),'<div class="layermbtn">'+a+"</div>"):""}();if(b.fixed||(b.top=b.hasOwnProperty("top")?b.top:100,b.style=b.style||"",b.style+=" top:"+(c.body.scrollTop+b.top)+"px"),2===b.type&&(b.content='<i></i><i class="laymloadtwo"></i><i></i><div>'+(b.content||"")+"</div>"),d.innerHTML=(b.shade?"<div "+("string"==typeof b.shade?'style="'+b.shade+'"':"")+' class="laymshade"></div>':"")+'<div class="layermmain" '+(b.fixed?"":'style="position:static;"')+'><div class="section"><div class="layermchild '+(b.className?b.className:"")+" "+(b.type||b.shade?"":"layermborder ")+(b.anim?"layermanim":"")+'" '+(b.style?'style="'+b.style+'"':"")+">"+g+'<div class="layermcont">'+b.content+"</div>"+j+"</div></div></div>",!b.type||2===b.type){var l=c[e](i[0]+b.type),m=l.length;m>=1&&k.close(l[0].getAttribute("index"))}document.body.appendChild(d);var n=a.elem=f("#"+a.id)[0];b.success&&b.success(n),a.index=h++,a.action(b,n)},j.prototype.action=function(a,b){var c=this;if(a.time&&(ready.timer[c.index]=setTimeout(function(){k.close(c.index)},1e3*a.time)),a.title){var d=b[e]("layermend")[0],f=function(){a.cancel&&a.cancel(),k.close(c.index)};ready.touch(d,f)}var g=function(){var b=this.getAttribute("type");0==b?(a.no&&a.no(),k.close(c.index)):a.yes?a.yes(c.index):k.close(c.index)};if(a.btn)for(var h=b[e]("layermbtn")[0].children,i=h.length,j=0;i>j;j++)ready.touch(h[j],g);if(a.shade&&a.shadeClose){var l=b[e]("laymshade")[0];ready.touch(l,function(){k.close(c.index,a.end)})}a.end&&(ready.end[c.index]=a.end)};var k={v:"1.6",index:h,open:function(a){var b=new j(a||{});return b.index},close:function(a){var b=f("#"+i[0]+a)[0];b&&(b.innerHTML="",c.body.removeChild(b),clearTimeout(ready.timer[a]),delete ready.timer[a],"function"==typeof ready.end[a]&&ready.end[a](),delete ready.end[a])},closeAll:function(){for(var a=c[e](i[0]),b=0,d=a.length;d>b;b++)k.close(0|a[0].getAttribute("index"))}};"function"==typeof define?define(function(){return k}):a.layer=k}(window);
|
239
novel-front/src/main/resources/static/javascript/need/layer.css
Normal file
@ -0,0 +1,239 @@
|
||||
.layermbox {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 19891014
|
||||
}
|
||||
|
||||
.layermmain, .laymshade {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%
|
||||
}
|
||||
|
||||
.layermbtn span, .layermchild {
|
||||
display: inline-block;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.laymshade {
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
pointer-events: auto
|
||||
}
|
||||
|
||||
.layermmain {
|
||||
display: table;
|
||||
font-family: Helvetica, arial, sans-serif;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.layermmain .section {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.layermchild {
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, .1);
|
||||
pointer-events: auto;
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
-webkit-animation-duration: .18s;
|
||||
animation-duration: .18s
|
||||
}
|
||||
|
||||
.layermborder {
|
||||
border: 1px solid #999
|
||||
}
|
||||
|
||||
@-webkit-keyframes bounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.5);
|
||||
transform: scale(.5)
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
.layermanim {
|
||||
animation-name: bounceIn;
|
||||
-webkit-animation-name: bounceIn
|
||||
}
|
||||
|
||||
.layermbox0 .layermchild {
|
||||
max-width: 260px;
|
||||
min-width: 150px
|
||||
}
|
||||
|
||||
.layermbox1 .layermchild {
|
||||
border: none;
|
||||
border-radius: 0
|
||||
}
|
||||
|
||||
.layermbox2 .layermchild {
|
||||
width: auto;
|
||||
max-width: 260px;
|
||||
min-width: 40px;
|
||||
border: none;
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.layermchild h3 {
|
||||
padding: 0 45px 0 10px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
border-radius: 5px 5px 0 0;
|
||||
border-bottom: 1px solid #EBEBEB
|
||||
}
|
||||
|
||||
.layermbtn span, .layermchild h3 {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.layermcont {
|
||||
padding: 20px 15px;
|
||||
line-height: 22px;
|
||||
border-radius: 5px
|
||||
}
|
||||
|
||||
.layermbox1 .layermcont {
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.layermbox2 .layermcont {
|
||||
text-align: center;
|
||||
padding: 30px 30px 0;
|
||||
line-height: 0
|
||||
}
|
||||
|
||||
.layermbox2 .layermcont i {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
margin-left: 8px;
|
||||
display: inline-block;
|
||||
background-color: #fff;
|
||||
border-radius: 100%;
|
||||
-webkit-animation: bouncedelay 1.4s infinite ease-in-out;
|
||||
animation: bouncedelay 1.4s infinite ease-in-out;
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both
|
||||
}
|
||||
|
||||
@-webkit-keyframes bouncedelay {
|
||||
0%, 100%, 80% {
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
40% {
|
||||
-webkit-transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bouncedelay {
|
||||
0%, 100%, 80% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
40% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
.layermbox2 .layermcont i:first-child {
|
||||
margin-left: 0;
|
||||
-webkit-animation-delay: -.32s;
|
||||
animation-delay: -.32s
|
||||
}
|
||||
|
||||
.layermbox2 .layermcont i.laymloadtwo {
|
||||
-webkit-animation-delay: -.16s;
|
||||
animation-delay: -.16s
|
||||
}
|
||||
|
||||
.layermbox2 .layermcont > div {
|
||||
line-height: 22px;
|
||||
padding-top: 7px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.layermbtn {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 0;
|
||||
text-align: center;
|
||||
border-top: 1px solid #EBEBEB
|
||||
}
|
||||
|
||||
.layermbtn span {
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border-radius: 0 5px 0 0
|
||||
}
|
||||
|
||||
.layermbtn span:first-child {
|
||||
height: 39px;
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 0 5px
|
||||
}
|
||||
|
||||
.layermbtn:before {
|
||||
content: '\20';
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 39px;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
background-color: #EBEBEB
|
||||
}
|
||||
|
||||
.layermend {
|
||||
position: absolute;
|
||||
right: 7px;
|
||||
top: 10px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 0;
|
||||
font-weight: 400;
|
||||
background: 0 0;
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
font-size: 30px
|
||||
}
|
||||
|
||||
.layermend::after, .layermend::before {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: 13px;
|
||||
content: '';
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
transform: rotate(45deg);
|
||||
-webkit-transform: rotate(45deg);
|
||||
border-radius: 3px
|
||||
}
|
||||
|
||||
.layermend::after {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg)
|
||||
}
|
167
novel-front/src/main/resources/static/javascript/ufans.js
Normal file
@ -0,0 +1,167 @@
|
||||
var uFans = {
|
||||
startSupportRead: function () {
|
||||
var uname = jQuery.cookie("waplogname");
|
||||
if (uname != undefined && uname != "") {
|
||||
if (spmymoney == 0) {
|
||||
}
|
||||
else {
|
||||
uFans.startSupport();
|
||||
}
|
||||
}
|
||||
else {
|
||||
layer.open({
|
||||
content: '请先登录',
|
||||
style: BookDetail.msgStyle,
|
||||
time: 2
|
||||
});
|
||||
}
|
||||
},
|
||||
startSupport: function () {
|
||||
var rStr = '<a class="closePopup" href="javascript:void(0);" onclick="javascript:uFans.closeBox();"></a>';
|
||||
rStr += '<div class="popupTit">';
|
||||
rStr += ' <h3>我要捧场作品</h3>';
|
||||
rStr += '</div>';
|
||||
rStr += '<div class="propsList cf">';
|
||||
rStr += ' <ul>';
|
||||
rStr += ' <li vals="100">';
|
||||
rStr += ' <a class="propWrap" href="javascript:void(0);">';
|
||||
rStr += ' <i class="icon_check"></i>';
|
||||
rStr += ' <span class="propsBox">100屋币</span>';
|
||||
rStr += ' </a>';
|
||||
rStr += ' </li>';
|
||||
rStr += ' <li class="on" vals="500">';
|
||||
rStr += ' <a class="propWrap" href="javascript:void(0);">';
|
||||
rStr += ' <i class="icon_check"></i>';
|
||||
rStr += ' <span class="propsBox">500屋币</span>';
|
||||
rStr += ' </a>';
|
||||
rStr += ' </li>';
|
||||
rStr += ' <li vals="2000">';
|
||||
rStr += ' <a class="propWrap" href="javascript:void(0);">';
|
||||
rStr += ' <i class="icon_check"></i>';
|
||||
rStr += ' <span class="propsBox">2000屋币</span>';
|
||||
rStr += ' </a>';
|
||||
rStr += ' </li>';
|
||||
rStr += ' <li vals="5000">';
|
||||
rStr += ' <a class="propWrap" href="javascript:void(0);">';
|
||||
rStr += ' <i class="icon_check"></i>';
|
||||
rStr += ' <span class="propsBox">5000屋币</span>';
|
||||
rStr += ' </a>';
|
||||
rStr += ' </li>';
|
||||
rStr += ' <li vals="10000">';
|
||||
rStr += ' <a class="propWrap" href="javascript:void(0);">';
|
||||
rStr += ' <i class="icon_check"></i>';
|
||||
rStr += ' <span class="propsBox">10000屋币</span>';
|
||||
rStr += ' </a>';
|
||||
rStr += ' </li>';
|
||||
rStr += ' <li vals="100000">';
|
||||
rStr += ' <a class="propWrap" href="javascript:void(0);">';
|
||||
rStr += ' <i class="icon_check"></i>';
|
||||
rStr += ' <span class="propsBox">100000屋币</span>';
|
||||
rStr += ' </a>';
|
||||
rStr += ' </li>';
|
||||
rStr += ' </ul>';
|
||||
rStr += '</div>';
|
||||
rStr += '<p class="have_num">当前剩余<span class="red">' + spmymoney + '</span>屋币 本次捧场<span class="red" id="pcTotal">500</span>屋币<a class="red" href="../pay/" >[充值]</a></p>';
|
||||
rStr += '<p><textarea class="popup_text" id="sendSupportNote" placeholder="感谢您的捧场,留句话鼓励作者吧!"></textarea></p>';
|
||||
rStr += '<p class="tc"><a class="btn_red btn_send_pc" href="javascript:void(0);" onclick="javascript:uFans.SendSupport();">立即捧场</a></p>';
|
||||
$("#showPC").html(rStr);
|
||||
$("#showPC").show();
|
||||
$(".maskBox").show();
|
||||
$(".pcBox .propsList li").click(function () {
|
||||
$(".pcBox .propsList li").removeClass("on");
|
||||
$(this).addClass("on");
|
||||
$("#pcTotal").html($(this).attr("vals"));
|
||||
})
|
||||
},
|
||||
closeBox: function () {
|
||||
$(".pcBox,.flowerBox,.newsTipBox,.maskBox").hide();
|
||||
},
|
||||
SendSupport: function () {
|
||||
var uname = jQuery.cookie("waplogname");
|
||||
if (uname != undefined && uname != "") {
|
||||
var moneyTotal = spmymoney;
|
||||
var moneySupport = parseInt($("#pcTotal").html());
|
||||
var sendNote = $("#sendSupportNote").val();
|
||||
var clearSendNote = sendNote.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g, "");
|
||||
if (sendNote == "") {
|
||||
layer.open({
|
||||
content: '感谢您的捧场,留句话鼓励作者吧!',
|
||||
style: BookDetail.msgStyle,
|
||||
time: 2
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (clearSendNote.length<5)
|
||||
{
|
||||
layer.open({
|
||||
content: '评论最少5个字符!',
|
||||
style: BookDetail.msgStyle,
|
||||
time: 2
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (moneyTotal >= moneySupport) {
|
||||
var BId = currentBId;
|
||||
}
|
||||
else {
|
||||
layer.open({
|
||||
content: '屋币余额不足',
|
||||
style: BookDetail.msgStyle,
|
||||
time: 2
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
layer.open({
|
||||
content: '请先登录',
|
||||
style: BookDetail.msgStyle,
|
||||
time: 2
|
||||
});
|
||||
}
|
||||
},
|
||||
GetSupport: function (BId) {
|
||||
},
|
||||
GetFlower: function (BId) {
|
||||
},
|
||||
showNote: function (noteClass) {
|
||||
uFans.closeBox();
|
||||
$(".maskBox").show();
|
||||
var rStr = '<a class="closePopup" href="javascript:void(0);" onclick="javascript:uFans.closeBox();"></a>';
|
||||
rStr += '<div class="popupTit">';
|
||||
rStr += ' <h3>消息提示</h3>';
|
||||
rStr += '</div>';
|
||||
if (noteClass == 'pc') {
|
||||
rStr += '<div class="tipWrap suc_txt_pc">捧场作品成功!</div>';
|
||||
}
|
||||
else {
|
||||
rStr += '<div class="tipWrap suc_txt_flw">点赞作品成功!</div>';
|
||||
}
|
||||
rStr += '<div class="tc">';
|
||||
rStr += ' <a href="javascript:void(0);" class="btn_red btn_sure" onclick="javascript:uFans.closeBox();">确定</a>';
|
||||
rStr += '</div>';
|
||||
$("#showNote").html(rStr);
|
||||
$("#showNote").show();
|
||||
},
|
||||
formatDateTime: function (now) {
|
||||
if (now != null && now != "") {
|
||||
var dateN = new Date(+/\d+/.exec(now)[0]);
|
||||
var year = dateN.getFullYear();
|
||||
var month = dateN.getMonth() + 1;
|
||||
var date = dateN.getDate();
|
||||
var hour = dateN.getHours();
|
||||
var minute = dateN.getMinutes();
|
||||
var second = dateN.getSeconds();
|
||||
minute = parseInt(minute) < 10 ? "0" + minute : minute;
|
||||
|
||||
if (hour == 0 && minute == 0 && second == 0) {
|
||||
return year + "-" + month + "-" + date;
|
||||
}
|
||||
else {
|
||||
return month + "-" + date + " " + hour + ":" + minute;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
77
novel-front/src/main/resources/static/javascript/user.js
Normal file
@ -0,0 +1,77 @@
|
||||
var UserUtil = {
|
||||
msgStyle: 'background-color:#333; color:#fff; text-align:center; border:none; font-size:20px; padding:10px;',
|
||||
GetFavoritesNew: function () {
|
||||
var bIdList = "";
|
||||
$(".book_list").each(function () {
|
||||
bIdList += "," + $(this).attr("vals");
|
||||
});
|
||||
if (bIdList != "") {
|
||||
}
|
||||
},
|
||||
GetHistory: function () {
|
||||
var bIdList = "";
|
||||
$(".book_list").each(function () {
|
||||
bIdList += "," + $(this).attr("vals");
|
||||
});
|
||||
if (bIdList != "") {
|
||||
}
|
||||
},
|
||||
GetChapterInfo: function () {
|
||||
var cIdList = "";
|
||||
$(".showCName").each(function () {
|
||||
cIdList += "," + $(this).attr("vals");
|
||||
});
|
||||
if (cIdList != "") {
|
||||
}
|
||||
},
|
||||
SignDay: function () {
|
||||
if (!signed) {
|
||||
signed = true;
|
||||
}
|
||||
},
|
||||
SignDayStatus: function () {
|
||||
},
|
||||
RegSendSms: function () {
|
||||
var mob = $("#txtUName").val();
|
||||
var cCode = $("#TxtChkCode").val();
|
||||
if (mob != "" && cCode != "") {
|
||||
$("#btnSendSms").attr("disabled", "disabled");
|
||||
$("#txtUName").attr("readonly", "true");
|
||||
}
|
||||
else {
|
||||
layer.open({
|
||||
content: '手机号码和验证码必须填写',
|
||||
style: UserUtil.msgStyle,
|
||||
time: 2
|
||||
});
|
||||
}
|
||||
},
|
||||
GetPassSendSms: function () {
|
||||
var mob = $("#txtMobile").val();
|
||||
var cCode = $("#TxtChkCode").val();
|
||||
if (mob != "" && cCode != "") {
|
||||
$("#btnSendSms").attr("disabled", "disabled");
|
||||
$("#txtMobile").attr("readonly", "true");
|
||||
}
|
||||
else {
|
||||
layer.open({
|
||||
content: '手机号码和验证码必须填写',
|
||||
style: UserUtil.msgStyle,
|
||||
time: 2
|
||||
});
|
||||
}
|
||||
},
|
||||
RegSmsWait: function () {
|
||||
if (secondStep > 0) {
|
||||
$("#btnSendSms").val("重新发送(" + secondStep + ")");
|
||||
secondStep--;
|
||||
setTimeout("UserUtil.RegSmsWait()", 1000);
|
||||
}
|
||||
else {
|
||||
secondStep = 180;
|
||||
$("#btnSendSms").val("重新获取验证码");
|
||||
$("#btnSendSms").removeAttr("disabled");
|
||||
$("#txtUName").removeAttr("readonly");
|
||||
}
|
||||
}
|
||||
}
|
5018
novel-front/src/main/resources/static/layui/css/layui.css
Normal file
@ -0,0 +1,2 @@
|
||||
/** layui-v2.4.5 MIT License By https://www.layui.com */
|
||||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}
|
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,919 @@
|
||||
/** layui-v2.4.5 MIT License By https://www.layui.com */
|
||||
.layui-layer-imgbar, .layui-layer-imgtit a, .layui-layer-tab .layui-layer-title span, .layui-layer-title {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
html #layuicss-layer {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 1989px
|
||||
}
|
||||
|
||||
.layui-layer, .layui-layer-shade {
|
||||
position: fixed;
|
||||
_position: absolute;
|
||||
pointer-events: auto
|
||||
}
|
||||
|
||||
.layui-layer-shade {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
_height: expression(document.body.offsetHeight+"px")
|
||||
}
|
||||
|
||||
.layui-layer {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
top: 150px;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
-webkit-background-clip: content;
|
||||
border-radius: 2px;
|
||||
box-shadow: 1px 1px 50px rgba(0, 0, 0, .3)
|
||||
}
|
||||
|
||||
.layui-layer-close {
|
||||
position: absolute
|
||||
}
|
||||
|
||||
.layui-layer-content {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.layui-layer-border {
|
||||
border: 1px solid #B2B2B2;
|
||||
border: 1px solid rgba(0, 0, 0, .1);
|
||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, .2)
|
||||
}
|
||||
|
||||
.layui-layer-load {
|
||||
background: url(loading-1.gif) center center no-repeat #eee
|
||||
}
|
||||
|
||||
.layui-layer-ico {
|
||||
background: url(icon.png) no-repeat
|
||||
}
|
||||
|
||||
.layui-layer-btn a, .layui-layer-dialog .layui-layer-ico, .layui-layer-setwin a {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
vertical-align: top
|
||||
}
|
||||
|
||||
.layui-layer-move {
|
||||
display: none;
|
||||
position: fixed;
|
||||
*position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: move;
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
background-color: #fff;
|
||||
z-index: 2147483647
|
||||
}
|
||||
|
||||
.layui-layer-resize {
|
||||
position: absolute;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
cursor: se-resize
|
||||
}
|
||||
|
||||
.layer-anim {
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
-webkit-animation-duration: .3s;
|
||||
animation-duration: .3s
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-bounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.5);
|
||||
transform: scale(.5)
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-bounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.5);
|
||||
-ms-transform: scale(.5);
|
||||
transform: scale(.5)
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-00 {
|
||||
-webkit-animation-name: layer-bounceIn;
|
||||
animation-name: layer-bounceIn
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-zoomInDown {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.1) translateY(-2000px);
|
||||
transform: scale(.1) translateY(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out
|
||||
}
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(.475) translateY(60px);
|
||||
transform: scale(.475) translateY(60px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-zoomInDown {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.1) translateY(-2000px);
|
||||
-ms-transform: scale(.1) translateY(-2000px);
|
||||
transform: scale(.1) translateY(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out
|
||||
}
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(.475) translateY(60px);
|
||||
-ms-transform: scale(.475) translateY(60px);
|
||||
transform: scale(.475) translateY(60px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-01 {
|
||||
-webkit-animation-name: layer-zoomInDown;
|
||||
animation-name: layer-zoomInDown
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-fadeInUpBig {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(2000px);
|
||||
transform: translateY(2000px)
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-fadeInUpBig {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(2000px);
|
||||
-ms-transform: translateY(2000px);
|
||||
transform: translateY(2000px)
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0)
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-02 {
|
||||
-webkit-animation-name: layer-fadeInUpBig;
|
||||
animation-name: layer-fadeInUpBig
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-zoomInLeft {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.1) translateX(-2000px);
|
||||
transform: scale(.1) translateX(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out
|
||||
}
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(.475) translateX(48px);
|
||||
transform: scale(.475) translateX(48px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-zoomInLeft {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.1) translateX(-2000px);
|
||||
-ms-transform: scale(.1) translateX(-2000px);
|
||||
transform: scale(.1) translateX(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out
|
||||
}
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(.475) translateX(48px);
|
||||
-ms-transform: scale(.475) translateX(48px);
|
||||
transform: scale(.475) translateX(48px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-03 {
|
||||
-webkit-animation-name: layer-zoomInLeft;
|
||||
animation-name: layer-zoomInLeft
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-rollIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateX(-100%) rotate(-120deg);
|
||||
transform: translateX(-100%) rotate(-120deg)
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateX(0) rotate(0);
|
||||
transform: translateX(0) rotate(0)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-rollIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateX(-100%) rotate(-120deg);
|
||||
-ms-transform: translateX(-100%) rotate(-120deg);
|
||||
transform: translateX(-100%) rotate(-120deg)
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateX(0) rotate(0);
|
||||
-ms-transform: translateX(0) rotate(0);
|
||||
transform: translateX(0) rotate(0)
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-04 {
|
||||
-webkit-animation-name: layer-rollIn;
|
||||
animation-name: layer-rollIn
|
||||
}
|
||||
|
||||
@keyframes layer-fadeIn {
|
||||
0% {
|
||||
opacity: 0
|
||||
}
|
||||
100% {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-05 {
|
||||
-webkit-animation-name: layer-fadeIn;
|
||||
animation-name: layer-fadeIn
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-shake {
|
||||
0%, 100% {
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0)
|
||||
}
|
||||
10%, 30%, 50%, 70%, 90% {
|
||||
-webkit-transform: translateX(-10px);
|
||||
transform: translateX(-10px)
|
||||
}
|
||||
20%, 40%, 60%, 80% {
|
||||
-webkit-transform: translateX(10px);
|
||||
transform: translateX(10px)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-shake {
|
||||
0%, 100% {
|
||||
-webkit-transform: translateX(0);
|
||||
-ms-transform: translateX(0);
|
||||
transform: translateX(0)
|
||||
}
|
||||
10%, 30%, 50%, 70%, 90% {
|
||||
-webkit-transform: translateX(-10px);
|
||||
-ms-transform: translateX(-10px);
|
||||
transform: translateX(-10px)
|
||||
}
|
||||
20%, 40%, 60%, 80% {
|
||||
-webkit-transform: translateX(10px);
|
||||
-ms-transform: translateX(10px);
|
||||
transform: translateX(10px)
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-06 {
|
||||
-webkit-animation-name: layer-shake;
|
||||
animation-name: layer-shake
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0
|
||||
}
|
||||
100% {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layer-title {
|
||||
padding: 0 80px 0 20px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
background-color: #F8F8F8;
|
||||
border-radius: 2px 2px 0 0
|
||||
}
|
||||
|
||||
.layui-layer-setwin {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
*right: 0;
|
||||
top: 15px;
|
||||
font-size: 0;
|
||||
line-height: initial
|
||||
}
|
||||
|
||||
.layui-layer-setwin a {
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
_overflow: hidden
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-min cite {
|
||||
position: absolute;
|
||||
width: 14px;
|
||||
height: 2px;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
margin-top: -1px;
|
||||
background-color: #2E2D3C;
|
||||
cursor: pointer;
|
||||
_overflow: hidden
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-min:hover cite {
|
||||
background-color: #2D93CA
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-max {
|
||||
background-position: -32px -40px
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-max:hover {
|
||||
background-position: -16px -40px
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-maxmin {
|
||||
background-position: -65px -40px
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-maxmin:hover {
|
||||
background-position: -49px -40px
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close1 {
|
||||
background-position: 1px -40px;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close1:hover {
|
||||
opacity: .7
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close2 {
|
||||
position: absolute;
|
||||
right: -28px;
|
||||
top: -28px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-left: 0;
|
||||
background-position: -149px -31px;
|
||||
*right: -18px;
|
||||
_display: none
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close2:hover {
|
||||
background-position: -180px -31px
|
||||
}
|
||||
|
||||
.layui-layer-btn {
|
||||
text-align: right;
|
||||
padding: 0 15px 12px;
|
||||
pointer-events: auto;
|
||||
user-select: none;
|
||||
-webkit-user-select: none
|
||||
}
|
||||
|
||||
.layui-layer-btn a {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
margin: 5px 5px 0;
|
||||
padding: 0 15px;
|
||||
border: 1px solid #dedede;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
border-radius: 2px;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.layui-layer-btn a:hover {
|
||||
opacity: .9;
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.layui-layer-btn a:active {
|
||||
opacity: .8
|
||||
}
|
||||
|
||||
.layui-layer-btn .layui-layer-btn0 {
|
||||
border-color: #f70;
|
||||
background-color: #f70;
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.layui-layer-btn-l {
|
||||
text-align: left
|
||||
}
|
||||
|
||||
.layui-layer-btn-c {
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.layui-layer-dialog {
|
||||
min-width: 260px
|
||||
}
|
||||
|
||||
.layui-layer-dialog .layui-layer-content {
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
line-height: 24px;
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto
|
||||
}
|
||||
|
||||
.layui-layer-dialog .layui-layer-content .layui-layer-ico {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 15px;
|
||||
_left: -40px;
|
||||
width: 30px;
|
||||
height: 30px
|
||||
}
|
||||
|
||||
.layui-layer-ico1 {
|
||||
background-position: -30px 0
|
||||
}
|
||||
|
||||
.layui-layer-ico2 {
|
||||
background-position: -60px 0
|
||||
}
|
||||
|
||||
.layui-layer-ico3 {
|
||||
background-position: -90px 0
|
||||
}
|
||||
|
||||
.layui-layer-ico4 {
|
||||
background-position: -120px 0
|
||||
}
|
||||
|
||||
.layui-layer-ico5 {
|
||||
background-position: -150px 0
|
||||
}
|
||||
|
||||
.layui-layer-ico6 {
|
||||
background-position: -180px 0
|
||||
}
|
||||
|
||||
.layui-layer-rim {
|
||||
border: 6px solid #8D8D8D;
|
||||
border: 6px solid rgba(0, 0, 0, .3);
|
||||
border-radius: 5px;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.layui-layer-msg {
|
||||
min-width: 180px;
|
||||
border: 1px solid #D3D4D3;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.layui-layer-hui {
|
||||
min-width: 100px;
|
||||
background-color: #000;
|
||||
filter: alpha(opacity=60);
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
color: #fff;
|
||||
border: none
|
||||
}
|
||||
|
||||
.layui-layer-hui .layui-layer-content {
|
||||
padding: 12px 25px;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.layui-layer-dialog .layui-layer-padding {
|
||||
padding: 20px 20px 20px 55px;
|
||||
text-align: left
|
||||
}
|
||||
|
||||
.layui-layer-page .layui-layer-content {
|
||||
position: relative;
|
||||
overflow: auto
|
||||
}
|
||||
|
||||
.layui-layer-iframe .layui-layer-btn, .layui-layer-page .layui-layer-btn {
|
||||
padding-top: 10px
|
||||
}
|
||||
|
||||
.layui-layer-nobg {
|
||||
background: 0 0
|
||||
}
|
||||
|
||||
.layui-layer-iframe iframe {
|
||||
display: block;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.layui-layer-loading {
|
||||
border-radius: 100%;
|
||||
background: 0 0;
|
||||
box-shadow: none;
|
||||
border: none
|
||||
}
|
||||
|
||||
.layui-layer-loading .layui-layer-content {
|
||||
width: 60px;
|
||||
height: 24px;
|
||||
background: url(loading-0.gif) no-repeat
|
||||
}
|
||||
|
||||
.layui-layer-loading .layui-layer-loading1 {
|
||||
width: 37px;
|
||||
height: 37px;
|
||||
background: url(loading-1.gif) no-repeat
|
||||
}
|
||||
|
||||
.layui-layer-ico16, .layui-layer-loading .layui-layer-loading2 {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(loading-2.gif) no-repeat
|
||||
}
|
||||
|
||||
.layui-layer-tips {
|
||||
background: 0 0;
|
||||
box-shadow: none;
|
||||
border: none
|
||||
}
|
||||
|
||||
.layui-layer-tips .layui-layer-content {
|
||||
position: relative;
|
||||
line-height: 22px;
|
||||
min-width: 12px;
|
||||
padding: 8px 15px;
|
||||
font-size: 12px;
|
||||
_float: left;
|
||||
border-radius: 2px;
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, .2);
|
||||
background-color: #000;
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.layui-layer-tips .layui-layer-close {
|
||||
right: -2px;
|
||||
top: -1px
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsG {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-width: 8px;
|
||||
border-color: transparent;
|
||||
border-style: dashed;
|
||||
*overflow: hidden
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsB, .layui-layer-tips i.layui-layer-TipsT {
|
||||
left: 5px;
|
||||
border-right-style: solid;
|
||||
border-right-color: #000
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsT {
|
||||
bottom: -8px
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsB {
|
||||
top: -8px
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsL, .layui-layer-tips i.layui-layer-TipsR {
|
||||
top: 5px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #000
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsR {
|
||||
left: -8px
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsL {
|
||||
right: -8px
|
||||
}
|
||||
|
||||
.layui-layer-lan[type=dialog] {
|
||||
min-width: 280px
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-title {
|
||||
background: #4476A7;
|
||||
color: #fff;
|
||||
border: none
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-btn {
|
||||
padding: 5px 10px 10px;
|
||||
text-align: right;
|
||||
border-top: 1px solid #E9E7E7
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-btn a {
|
||||
background: #fff;
|
||||
border-color: #E9E7E7;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-btn .layui-layer-btn1 {
|
||||
background: #C9C5C5
|
||||
}
|
||||
|
||||
.layui-layer-molv .layui-layer-title {
|
||||
background: #009f95;
|
||||
color: #fff;
|
||||
border: none
|
||||
}
|
||||
|
||||
.layui-layer-molv .layui-layer-btn a {
|
||||
background: #009f95;
|
||||
border-color: #009f95
|
||||
}
|
||||
|
||||
.layui-layer-molv .layui-layer-btn .layui-layer-btn1 {
|
||||
background: #92B8B1
|
||||
}
|
||||
|
||||
.layui-layer-iconext {
|
||||
background: url(icon-ext.png) no-repeat
|
||||
}
|
||||
|
||||
.layui-layer-prompt .layui-layer-input {
|
||||
display: block;
|
||||
width: 230px;
|
||||
height: 36px;
|
||||
margin: 0 auto;
|
||||
line-height: 30px;
|
||||
padding-left: 10px;
|
||||
border: 1px solid #e6e6e6;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.layui-layer-prompt textarea.layui-layer-input {
|
||||
width: 300px;
|
||||
height: 100px;
|
||||
line-height: 20px;
|
||||
padding: 6px 10px
|
||||
}
|
||||
|
||||
.layui-layer-prompt .layui-layer-content {
|
||||
padding: 20px
|
||||
}
|
||||
|
||||
.layui-layer-prompt .layui-layer-btn {
|
||||
padding-top: 0
|
||||
}
|
||||
|
||||
.layui-layer-tab {
|
||||
box-shadow: 1px 1px 50px rgba(0, 0, 0, .4)
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title {
|
||||
padding-left: 0;
|
||||
overflow: visible
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title span {
|
||||
position: relative;
|
||||
float: left;
|
||||
min-width: 80px;
|
||||
max-width: 260px;
|
||||
padding: 0 20px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title span.layui-this {
|
||||
height: 43px;
|
||||
border-left: 1px solid #eee;
|
||||
border-right: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
z-index: 10
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title span:first-child {
|
||||
border-left: none
|
||||
}
|
||||
|
||||
.layui-layer-tabmain {
|
||||
line-height: 24px;
|
||||
clear: both
|
||||
}
|
||||
|
||||
.layui-layer-tabmain .layui-layer-tabli {
|
||||
display: none
|
||||
}
|
||||
|
||||
.layui-layer-tabmain .layui-layer-tabli.layui-this {
|
||||
display: block
|
||||
}
|
||||
|
||||
.layui-layer-photos {
|
||||
-webkit-animation-duration: .8s;
|
||||
animation-duration: .8s
|
||||
}
|
||||
|
||||
.layui-layer-photos .layui-layer-content {
|
||||
overflow: hidden;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.layui-layer-photos .layui-layer-phimg img {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
vertical-align: top
|
||||
}
|
||||
|
||||
.layui-layer-imgbar, .layui-layer-imguide {
|
||||
display: none
|
||||
}
|
||||
|
||||
.layui-layer-imgnext, .layui-layer-imgprev {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 27px;
|
||||
_width: 44px;
|
||||
height: 44px;
|
||||
margin-top: -22px;
|
||||
outline: 0;
|
||||
blr: expression(this.onFocus=this.blur())
|
||||
}
|
||||
|
||||
.layui-layer-imgprev {
|
||||
left: 10px;
|
||||
background-position: -5px -5px;
|
||||
_background-position: -70px -5px
|
||||
}
|
||||
|
||||
.layui-layer-imgprev:hover {
|
||||
background-position: -33px -5px;
|
||||
_background-position: -120px -5px
|
||||
}
|
||||
|
||||
.layui-layer-imgnext {
|
||||
right: 10px;
|
||||
_right: 8px;
|
||||
background-position: -5px -50px;
|
||||
_background-position: -70px -50px
|
||||
}
|
||||
|
||||
.layui-layer-imgnext:hover {
|
||||
background-position: -33px -50px;
|
||||
_background-position: -120px -50px
|
||||
}
|
||||
|
||||
.layui-layer-imgbar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background-color: rgba(0, 0, 0, .8);
|
||||
background-color: #000 \9;
|
||||
filter: Alpha(opacity=80);
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
font-size: 0
|
||||
}
|
||||
|
||||
.layui-layer-imgtit * {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
vertical-align: top;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.layui-layer-imgtit a {
|
||||
max-width: 65%;
|
||||
overflow: hidden;
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.layui-layer-imgtit a:hover {
|
||||
color: #fff;
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
.layui-layer-imgtit em {
|
||||
padding-left: 10px;
|
||||
font-style: normal
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-bounceOut {
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.7);
|
||||
transform: scale(.7)
|
||||
}
|
||||
30% {
|
||||
-webkit-transform: scale(1.05);
|
||||
transform: scale(1.05)
|
||||
}
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-bounceOut {
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.7);
|
||||
-ms-transform: scale(.7);
|
||||
transform: scale(.7)
|
||||
}
|
||||
30% {
|
||||
-webkit-transform: scale(1.05);
|
||||
-ms-transform: scale(1.05);
|
||||
transform: scale(1.05)
|
||||
}
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-close {
|
||||
-webkit-animation-name: layer-bounceOut;
|
||||
animation-name: layer-bounceOut;
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
-webkit-animation-duration: .2s;
|
||||
animation-duration: .2s
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
.layui-layer-iframe {
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 701 B |
After Width: | Height: | Size: 1.7 KiB |
@ -0,0 +1,96 @@
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>聊天记录</title>
|
||||
|
||||
<link rel="stylesheet" href="http://local.res.layui.com/layui/src/css/layui.css">
|
||||
<style>
|
||||
body .layim-chat-main{height: auto;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="layim-chat-main">
|
||||
<ul id="LAY_view"></ul>
|
||||
</div>
|
||||
|
||||
<div id="LAY_page" style="margin: 0 10px;"></div>
|
||||
|
||||
|
||||
<textarea title="消息模版" id="LAY_tpl" style="display:none;">
|
||||
{{# layui.each(d.data, function(index, item){
|
||||
if(item.id == parent.layui.layim.cache().mine.id){ }}
|
||||
<li class="layim-chat-mine"><div class="layim-chat-user"><img src="{{ item.avatar }}"><cite><i>{{ layui.data.date(item.timestamp) }}</i>{{ item.username }}</cite></div><div class="layim-chat-text">{{ layui.layim.content(item.content) }}</div></li>
|
||||
{{# } else { }}
|
||||
<li><div class="layim-chat-user"><img src="{{ item.avatar }}"><cite>{{ item.username }}<i>{{ layui.data.date(item.timestamp) }}</i></cite></div><div class="layim-chat-text">{{ layui.layim.content(item.content) }}</div></li>
|
||||
{{# }
|
||||
}); }}
|
||||
</textarea>
|
||||
|
||||
<!--
|
||||
上述模版采用了 laytpl 语法,不了解的同学可以去看下文档:http://www.layui.com/doc/modules/laytpl.html
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<script src="http://local.res.layui.com/layui/src/layui.js"></script>
|
||||
<script>
|
||||
layui.use(['layim', 'laypage'], function(){
|
||||
var layim = layui.layim
|
||||
,layer = layui.layer
|
||||
,laytpl = layui.laytpl
|
||||
,$ = layui.jquery
|
||||
,laypage = layui.laypage;
|
||||
|
||||
//聊天记录的分页此处不做演示,你可以采用laypage,不了解的同学见文档:http://www.layui.com/doc/modules/laypage.html
|
||||
|
||||
|
||||
//开始请求聊天记录
|
||||
var param = location.search //获得URL参数。该窗口url会携带会话id和type,他们是你请求聊天记录的重要凭据
|
||||
|
||||
//实际使用时,下述的res一般是通过Ajax获得,而此处仅仅只是演示数据格式
|
||||
,res = {
|
||||
code: 0
|
||||
,msg: ''
|
||||
,data: [{
|
||||
username: '纸飞机'
|
||||
,id: 100000
|
||||
,avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
|
||||
,timestamp: 1480897882000
|
||||
,content: 'face[抱抱] face[心] 你好啊小美女'
|
||||
}, {
|
||||
username: 'Z_子晴'
|
||||
,id: 108101
|
||||
,avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
|
||||
,timestamp: 1480897892000
|
||||
,content: '你没发错吧?face[微笑]'
|
||||
},{
|
||||
username: 'Z_子晴'
|
||||
,id: 108101
|
||||
,avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
|
||||
,timestamp: 1480897898000
|
||||
,content: '你是谁呀亲。。我爱的是贤心!我爱的是贤心!我爱的是贤心!重要的事情要说三遍~'
|
||||
},{
|
||||
username: 'Z_子晴'
|
||||
,id: 108101
|
||||
,avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
|
||||
,timestamp: 1480897908000
|
||||
,content: '注意:这些都是模拟数据,实际使用时,需将其中的模拟接口改为你的项目真实接口。\n该模版文件所在目录(相对于layui.js):\n/css/modules/layim/html/chatlog.html'
|
||||
}]
|
||||
}
|
||||
|
||||
//console.log(param)
|
||||
|
||||
var html = laytpl(LAY_tpl.value).render({
|
||||
data: res.data
|
||||
});
|
||||
$('#LAY_view').html(html);
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>发现</title>
|
||||
|
||||
<link rel="stylesheet" href="http://local.res.layui.com/layui/src/css/layui.css">
|
||||
<style>
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="margin: 15px;">
|
||||
<blockquote class="layui-elem-quote">此为自定义的【查找】页面,因需求不一,所以官方暂不提供该模版结构与样式,实际使用时,可移至该文件到你的项目中,对页面自行把控。
|
||||
<br>文件所在目录(相对于layui.js):/css/modules/layim/html/find.html</blockquote>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="http://local.res.layui.com/layui/src/layui.js"></script>
|
||||
<script>
|
||||
layui.use(['layim', 'laypage'], function(){
|
||||
var layim = layui.layim
|
||||
,layer = layui.layer
|
||||
,laytpl = layui.laytpl
|
||||
,$ = layui.jquery
|
||||
,laypage = layui.laypage;
|
||||
|
||||
//一些添加好友请求之类的交互参见文档
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,87 @@
|
||||
{
|
||||
"code": 0,
|
||||
"pages": 1,
|
||||
"data": [
|
||||
{
|
||||
"id": 76,
|
||||
"content": "申请添加你为好友",
|
||||
"uid": 168,
|
||||
"from": 166488,
|
||||
"from_group": 0,
|
||||
"type": 1,
|
||||
"remark": "有问题要问",
|
||||
"href": null,
|
||||
"read": 1,
|
||||
"time": "刚刚",
|
||||
"user": {
|
||||
"id": 166488,
|
||||
"avatar": "http://q.qlogo.cn/qqapp/101235792/B704597964F9BD0DB648292D1B09F7E8/100",
|
||||
"username": "李彦宏",
|
||||
"sign": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 75,
|
||||
"content": "申请添加你为好友",
|
||||
"uid": 168,
|
||||
"from": 347592,
|
||||
"from_group": 0,
|
||||
"type": 1,
|
||||
"remark": "你好啊!",
|
||||
"href": null,
|
||||
"read": 1,
|
||||
"time": "刚刚",
|
||||
"user": {
|
||||
"id": 347592,
|
||||
"avatar": "http://q.qlogo.cn/qqapp/101235792/B78751375E0531675B1272AD994BA875/100",
|
||||
"username": "麻花疼",
|
||||
"sign": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 62,
|
||||
"content": "雷军 拒绝了你的好友申请",
|
||||
"uid": 168,
|
||||
"from": null,
|
||||
"from_group": null,
|
||||
"type": 1,
|
||||
"remark": null,
|
||||
"href": null,
|
||||
"read": 1,
|
||||
"time": "10天前",
|
||||
"user": {
|
||||
"id": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 60,
|
||||
"content": "马小云 已经同意你的好友申请",
|
||||
"uid": 168,
|
||||
"from": null,
|
||||
"from_group": null,
|
||||
"type": 1,
|
||||
"remark": null,
|
||||
"href": null,
|
||||
"read": 1,
|
||||
"time": "10天前",
|
||||
"user": {
|
||||
"id": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 61,
|
||||
"content": "贤心 已经同意你的好友申请",
|
||||
"uid": 168,
|
||||
"from": null,
|
||||
"from_group": null,
|
||||
"type": 1,
|
||||
"remark": null,
|
||||
"href": null,
|
||||
"read": 1,
|
||||
"time": "10天前",
|
||||
"user": {
|
||||
"id": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,208 @@
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>消息盒子</title>
|
||||
|
||||
<link rel="stylesheet" href="../../../layui.css?v=1">
|
||||
<style>
|
||||
.layim-msgbox{margin: 15px;}
|
||||
.layim-msgbox li{position: relative; margin-bottom: 10px; padding: 0 130px 10px 60px; padding-bottom: 10px; line-height: 22px; border-bottom: 1px dotted #e2e2e2;}
|
||||
.layim-msgbox .layim-msgbox-tips{margin: 0; padding: 10px 0; border: none; text-align: center; color: #999;}
|
||||
.layim-msgbox .layim-msgbox-system{padding: 0 10px 10px 10px;}
|
||||
.layim-msgbox li p span{padding-left: 5px; color: #999;}
|
||||
.layim-msgbox li p em{font-style: normal; color: #FF5722;}
|
||||
|
||||
.layim-msgbox-avatar{position: absolute; left: 0; top: 0; width: 50px; height: 50px;}
|
||||
.layim-msgbox-user{padding-top: 5px;}
|
||||
.layim-msgbox-content{margin-top: 3px;}
|
||||
.layim-msgbox .layui-btn-small{padding: 0 15px; margin-left: 5px;}
|
||||
.layim-msgbox-btn{position: absolute; right: 0; top: 12px; color: #999;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ul class="layim-msgbox" id="LAY_view"></ul>
|
||||
|
||||
<div style="margin: 0 15px;">
|
||||
<blockquote class="layui-elem-quote">注意:这些都是模拟数据,实际使用时,需将其中的模拟接口改为你的项目真实接口。
|
||||
<br>该模版文件所在目录(相对于layui.js):/css/modules/layim/html/msgbox.html</blockquote>
|
||||
</div>
|
||||
|
||||
<textarea title="消息模版" id="LAY_tpl" style="display:none;">
|
||||
{{# layui.each(d.data, function(index, item){
|
||||
if(item.from){ }}
|
||||
<li data-uid="{{ item.from }}" data-fromGroup="{{ item.from_group }}">
|
||||
<a href="/u/{{ item.from }}/" >
|
||||
<img src="{{ item.user.avatar }}" class="layui-circle layim-msgbox-avatar">
|
||||
</a>
|
||||
<p class="layim-msgbox-user">
|
||||
<a href="/u/{{ item.from }}/" >{{ item.user.username||'' }}</a>
|
||||
<span>{{ item.time }}</span>
|
||||
</p>
|
||||
<p class="layim-msgbox-content">
|
||||
{{ item.content }}
|
||||
<span>{{ item.remark ? '附言: '+item.remark : '' }}</span>
|
||||
</p>
|
||||
<p class="layim-msgbox-btn">
|
||||
<button class="layui-btn layui-btn-small" data-type="agree">同意</button>
|
||||
<button class="layui-btn layui-btn-small layui-btn-primary" data-type="refuse">拒绝</button>
|
||||
</p>
|
||||
</li>
|
||||
{{# } else { }}
|
||||
<li class="layim-msgbox-system">
|
||||
<p><em>系统:</em>{{ item.content }}<span>{{ item.time }}</span></p>
|
||||
</li>
|
||||
{{# }
|
||||
}); }}
|
||||
</textarea>
|
||||
|
||||
<!--
|
||||
上述模版采用了 laytpl 语法,不了解的同学可以去看下文档:http://www.layui.com/doc/modules/laytpl.html
|
||||
-->
|
||||
|
||||
|
||||
<script src="../../../../layui.js?v=1"></script>
|
||||
<script>
|
||||
layui.use(['layim', 'flow'], function(){
|
||||
var layim = layui.layim
|
||||
,layer = layui.layer
|
||||
,laytpl = layui.laytpl
|
||||
,$ = layui.jquery
|
||||
,flow = layui.flow;
|
||||
|
||||
var cache = {}; //用于临时记录请求到的数据
|
||||
|
||||
//请求消息
|
||||
var renderMsg = function(page, callback){
|
||||
|
||||
//实际部署时,请将下述 getmsg.json 改为你的接口地址
|
||||
|
||||
$.get('getmsg.json', {
|
||||
page: page || 1
|
||||
}, function(res){
|
||||
if(res.code != 0){
|
||||
return layer.msg(res.msg);
|
||||
}
|
||||
|
||||
//记录来源用户信息
|
||||
layui.each(res.data, function(index, item){
|
||||
cache[item.from] = item.user;
|
||||
});
|
||||
|
||||
callback && callback(res.data, res.pages);
|
||||
});
|
||||
};
|
||||
|
||||
//消息信息流
|
||||
flow.load({
|
||||
elem: '#LAY_view' //流加载容器
|
||||
,isAuto: false
|
||||
,end: '<li class="layim-msgbox-tips">暂无更多新消息</li>'
|
||||
,done: function(page, next){ //加载下一页
|
||||
renderMsg(page, function(data, pages){
|
||||
var html = laytpl(LAY_tpl.value).render({
|
||||
data: data
|
||||
,page: page
|
||||
});
|
||||
next(html, page < pages);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//打开页面即把消息标记为已读
|
||||
/*
|
||||
$.post('/message/read', {
|
||||
type: 1
|
||||
});
|
||||
*/
|
||||
|
||||
//操作
|
||||
var active = {
|
||||
//同意
|
||||
agree: function(othis){
|
||||
var li = othis.parents('li')
|
||||
,uid = li.data('uid')
|
||||
,from_group = li.data('fromGroup')
|
||||
,user = cache[uid];
|
||||
|
||||
//选择分组
|
||||
parent.layui.layim.setFriendGroup({
|
||||
type: 'friend'
|
||||
,username: user.username
|
||||
,avatar: user.avatar
|
||||
,group: parent.layui.layim.cache().friend //获取好友分组数据
|
||||
,submit: function(group, index){
|
||||
|
||||
//将好友追加到主面板
|
||||
parent.layui.layim.addList({
|
||||
type: 'friend'
|
||||
,avatar: user.avatar //好友头像
|
||||
,username: user.username //好友昵称
|
||||
,groupid: group //所在的分组id
|
||||
,id: uid //好友ID
|
||||
,sign: user.sign //好友签名
|
||||
});
|
||||
parent.layer.close(index);
|
||||
othis.parent().html('已同意');
|
||||
|
||||
|
||||
//实际部署时,请开启下述注释,并改成你的接口地址
|
||||
/*
|
||||
$.post('/im/agreeFriend', {
|
||||
uid: uid //对方用户ID
|
||||
,from_group: from_group //对方设定的好友分组
|
||||
,group: group //我设定的好友分组
|
||||
}, function(res){
|
||||
if(res.code != 0){
|
||||
return layer.msg(res.msg);
|
||||
}
|
||||
|
||||
//将好友追加到主面板
|
||||
parent.layui.layim.addList({
|
||||
type: 'friend'
|
||||
,avatar: user.avatar //好友头像
|
||||
,username: user.username //好友昵称
|
||||
,groupid: group //所在的分组id
|
||||
,id: uid //好友ID
|
||||
,sign: user.sign //好友签名
|
||||
});
|
||||
parent.layer.close(index);
|
||||
othis.parent().html('已同意');
|
||||
});
|
||||
*/
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//拒绝
|
||||
,refuse: function(othis){
|
||||
var li = othis.parents('li')
|
||||
,uid = li.data('uid');
|
||||
|
||||
layer.confirm('确定拒绝吗?', function(index){
|
||||
$.post('/im/refuseFriend', {
|
||||
uid: uid //对方用户ID
|
||||
}, function(res){
|
||||
if(res.code != 0){
|
||||
return layer.msg(res.msg);
|
||||
}
|
||||
layer.close(index);
|
||||
othis.parent().html('<em>已拒绝</em>');
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$('body').on('click', '.layui-btn', function(){
|
||||
var othis = $(this), type = othis.data('type');
|
||||
active[type] ? active[type].call(this, othis) : '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 18 KiB |