Compare commits

...

3 Commits

Author SHA1 Message Date
bb2d95ad75 Merge pull request #71 from a100488/task_updateCrawlSource
feat(新增编辑规则测试规则): 新增编辑规则测试规则
2021-12-24 15:46:00 +08:00
e6b60bb0a8 feat(新增编辑规则测试规则): 新增编辑规则测试规则2 2021-12-24 15:41:32 +08:00
3a44d14149 feat(新增编辑规则测试规则): 新增编辑规则测试规则 2021-12-24 13:41:25 +08:00
72 changed files with 1925 additions and 737 deletions

View File

@ -1,4 +1,4 @@
[![index]( https://z3.ax1x.com/2021/11/11/IwNJAg.jpg )]( https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console )
[![index]( https://s1.ax1x.com/2020/07/03/NOSA5q.jpg )]( https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console )
# 小说精品屋-plus
@ -35,7 +35,6 @@ Gitee仓库地址 https://gitee.com/novel_dev_team/novel-cloud
- [x] 移动站与PC站站点分离浏览器自动识别跳转
- [x] PC站UI更新
- [x] 支持前端模版自定义内置多套模版
- [x] 可拓展的多种方式存储小说内容内置数据库分表存储和TXT文本存储
- [x] 新闻模块
- [x] 排行榜
- [x] 小说评论模块
@ -291,10 +290,6 @@ docker安装教程[点击前往](https://my.oschina.net/java2nb/blog/4271989)
[点击前往官网查看](https://xiongxyang.gitee.io/service.htm)
#### 微信交流群
微信群二维码会过期所以每周在公众号更新一次请关注公众号**IT进阶**回复关键词**微信群**获取
问问题的三要素
1. 说明背景使用了哪个模块要做什么

View File

@ -1,3 +0,0 @@
alter table book_index add column storage_type varchar(10) NOT NULL DEFAULT 'db' COMMENT '存储方式' after book_price ;

View File

@ -1841,6 +1841,3 @@ delete from sys_menu where menu_id = 202;
INSERT INTO crawl_source(`id`, `source_name`, `crawl_rule`, `source_status`, `create_time`, `update_time`) VALUES (16, 'i笔趣阁', '{\"bookListUrl\":\"http://m.ibiquge.net/xclass/{catId}/{page}.html\",\"catIdRule\":{\"catId1\":\"1\",\"catId2\":\"2\",\"catId3\":\"3\",\"catId4\":\"4\",\"catId5\":\"6\",\"catId6\":\"5\",\"catId7\":\"7\"},\"bookIdPatten\":\"href=\\\"/(\\\\d+_\\\\d+)/\\\"\",\"pagePatten\":\"value=\\\"(\\\\d+)/\\\\d+\\\"\",\"totalPagePatten\":\"value=\\\"\\\\d+/(\\\\d+)\\\"\",\"bookDetailUrl\":\"http://m.ibiquge.net/{bookId}/\",\"bookNamePatten\":\"<span class=\\\"title\\\">([^/]+)</span>\",\"authorNamePatten\":\"<a href=\\\"/author/\\\\d+/\\\">([^/]+)</a>\",\"picUrlPatten\":\"<img src=\\\"([^>]+)\\\"\\\\s+onerror=\\\"this.src=\",\"picUrlPrefix\":\"http://m.ibiquge.net\",\"statusPatten\":\">状态:([^/]+)</li>\",\"bookStatusRule\":{\"连载\":0,\"完结\":1},\"visitCountPatten\":\">点击:(\\\\d+)</li>\",\"descStart\":\"<p class=\\\"review\\\">\",\"descEnd\":\"</p>\",\"bookIndexUrl\":\"http://www.ibiquge.net/{bookId}/\",\"bookIndexStart\":\"正文</dt>\",\"indexIdPatten\":\"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/\\\\d+_\\\\d+/(\\\\d+)\\\\.html\\\">[^/]+</a>\",\"indexNamePatten\":\"<a\\\\s+style=\\\"\\\"\\\\s+href=\\\"/\\\\d+_\\\\d+/\\\\d+\\\\.html\\\">([^/]+)</a>\",\"bookContentUrl\":\"http://www.ibiquge.net/{bookId}/{indexId}.html\",\"contentStart\":\"</p>\",\"contentEnd\":\"<div align=\\\"center\\\">\"}', 0, '2021-02-04 21:31:23', '2021-02-04 21:31:23');
alter table news add column `read_count` BIGINT NOT NULL DEFAULT '0' COMMENT '阅读量' after content;
alter table book_index add column storage_type varchar(10) NOT NULL DEFAULT 'db' COMMENT '存储方式' after book_price ;

View File

@ -5,7 +5,7 @@
<groupId>com.java2nb</groupId>
<artifactId>novel-admin</artifactId>
<version>3.6.1</version>
<version>3.5.4</version>
<packaging>jar</packaging>
<name>novel-admin</name>
@ -106,7 +106,7 @@
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
<version>1.7.0</version>
</dependency>
<!-- shiro ehcache -->
<dependency>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>novel</artifactId>
<groupId>com.java2nb</groupId>
<version>3.6.1</version>
<version>3.5.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -103,6 +103,12 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.dynamic-sql</groupId>
<artifactId>mybatis-dynamic-sql</artifactId>
@ -123,24 +129,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.github.xxyopen</groupId>
<artifactId>xxy-model</artifactId>
<version>${xxyopen.version}</version>
</dependency>
<dependency>
<groupId>io.github.xxyopen</groupId>
<artifactId>xxy-web</artifactId>
<version>${xxyopen.version}</version>
</dependency>
<dependency>
<groupId>io.github.xxyopen</groupId>
<artifactId>xxy-util</artifactId>
<version>${xxyopen.version}</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,46 @@
package com.java2nb.novel.core.advice;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.enums.ResponseStatus;
import com.java2nb.novel.core.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 通用的异常处理器
*
* @author 11797*/
@Slf4j
@RestControllerAdvice(basePackages = "com.java2nb.novel.controller")
public class CommonExceptionHandler {
/**
* 处理后台数据校验异常
* */
@ExceptionHandler(BindException.class)
public ResultBean handlerBindException(BindException e){
log.error(e.getMessage(),e);
return ResultBean.fail(ResponseStatus.PARAM_ERROR);
}
/**
* 处理业务异常
* */
@ExceptionHandler(BusinessException.class)
public ResultBean handlerBusinessException(BusinessException e){
log.error(e.getMessage(),e);
return ResultBean.fail(e.getResStatus());
}
/**
* 处理系统异常
* */
@ExceptionHandler(Exception.class)
public ResultBean handlerException(Exception e){
log.error(e.getMessage(),e);
return ResultBean.error();
}
}

View File

@ -0,0 +1,53 @@
package com.java2nb.novel.core.bean;
import com.github.pagehelper.PageInfo;
import lombok.Data;
import java.util.List;
/**
* 封装通用分页数据,接收PageHelper、SpringData等框架的分页数据转换成通用的PageBean对象
* @author xiongxiaoyang
* @version 1.0
* @since 2021/2/4
* @param <T> 分页集合类型
*/
@Data
public class PageBean<T> {
private Integer pageNum;
private Integer pageSize;
private Long total;
private List<? extends T> list;
/**
* 该构造函数用于PageHelper工具进行分页查询的场景
* 接收PageHelper分页后的list
*/
public PageBean(List<T> list){
PageInfo<T> pageInfo = new PageInfo<>(list);
this.pageNum = pageInfo.getPageNum();
this.pageSize = pageInfo.getPageSize();
this.total = pageInfo.getTotal();
this.list = pageInfo.getList();
}
/**
* 该构造函数用于通用分页查询的场景
* 接收普通分页数据和普通集合
*/
public PageBean(Integer pageNum, Integer pageSize, Long total, List<T> list) {
this.pageNum = pageNum;
this.pageSize = pageSize;
this.total = total;
this.list = list;
}
//TODO 使用其他的分页工具或框架进行分页查询的场景
}

View File

@ -0,0 +1,73 @@
package com.java2nb.novel.core.bean;
import com.java2nb.novel.core.enums.ResponseStatus;
import lombok.Data;
import java.io.Serializable;
/**
* 自定义响应结构
*
* @param <T>
* @author 11797
*/
@Data
public class ResultBean<T> implements Serializable {
private static final long serialVersionUID = 1L;
private int code = ResponseStatus.OK.getCode();
/**
* 响应消息
*/
private String msg = ResponseStatus.OK.getMsg();
/**
* 响应中的数据
*/
private T data;
private ResultBean() {
}
private ResultBean(ResponseStatus responseStatus) {
this.code = responseStatus.getCode();
this.msg = responseStatus.getMsg();
}
private ResultBean(T data) {
this.data = data;
}
/**
* 业务处理成功,无数据返回
*/
public static ResultBean<Void> ok() {
return new ResultBean<>();
}
/**
* 业务处理成功,有数据返回
*/
public static <T> ResultBean<T> ok(T data) {
return new ResultBean<>(data);
}
/**
* 业务处理失败
*/
public static ResultBean<Void> fail(ResponseStatus responseStatus) {
return new ResultBean<>(responseStatus);
}
/**
* 系统错误
*/
public static ResultBean<Void> error() {
return new ResultBean<>(ResponseStatus.ERROR);
}
}

View File

@ -65,4 +65,8 @@ public interface CacheKey {
* 累积的小说点击量
* */
String BOOK_ADD_VISIT_COUNT = "bookAddVisitCount";
/**
* 测试爬虫规则缓存
*/
String BOOK_TEST_PARSE = "testParse";
}

View File

@ -1,6 +1,5 @@
package com.java2nb.novel.core.enums;
import io.github.xxyopen.model.resp.IResultCode;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@ -12,7 +11,27 @@ import lombok.NoArgsConstructor;
@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum ResponseStatus implements IResultCode {
public enum ResponseStatus {
/**
* 请求成功
* */
OK(200,"SUCCESS"),
/**
* 服务器异常
* */
ERROR(500,"未知异常,请联系管理员!"),
/**
* 参数错误
* */
PARAM_ERROR(400,"非法参数!"),
/**
* 拒绝访问
* */
FORBIDDEN(403,"拒绝访问!"),
/**

View File

@ -0,0 +1,22 @@
package com.java2nb.novel.core.exception;
import com.java2nb.novel.core.enums.ResponseStatus;
import lombok.Data;
/**
* 自定义业务异常,用于处理用户请求时,业务错误时抛出
*/
@Data
public class BusinessException extends RuntimeException {
private ResponseStatus resStatus;
public BusinessException(ResponseStatus resStatus) {
//不调用父类Throwable的fillInStackTrace()方法生成栈追踪信息,提高应用性能
//构造器之间的调用必须在第一行
super(resStatus.getMsg(), null, false, false);
this.resStatus = resStatus;
}
}

View File

@ -0,0 +1,33 @@
package com.java2nb.novel.core.utils;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;
/**
* Bean操作工具类
* @author Administrator
*/
public class BeanUtil {
/**
* 复制集合对象属性值,生成新类型集合
* @param source 源集合
* @param targetClass 目标集合类型
* @return 新集合
* */
@SneakyThrows
public static <T> List<T> copyList(List<? super T> source,Class<T> targetClass){
List<T> target = new ArrayList<>(source.size());
for( int i = 0 ; i < source.size() ; i++){
Object sourceItem = source.get(i);
T targetItem = targetClass.newInstance();
BeanUtils.copyProperties(sourceItem,targetItem);
target.add(targetItem);
}
return target;
}
}

View File

@ -1,6 +1,5 @@
package com.java2nb.novel.core.utils;
import io.github.xxyopen.util.UUIDUtil;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
@ -20,7 +19,6 @@ import java.util.Objects;
/**
* 文件操作工具类
*
* @author 11797
*/
@UtilityClass
@ -29,8 +27,8 @@ public class FileUtil {
/**
* 网络图片转本地
*/
public String network2Local(String picSrc, String picSavePath, String visitPrefix) {
* */
public String network2Local(String picSrc,String picSavePath,String visitPrefix) {
InputStream input = null;
OutputStream out = null;
try {
@ -55,41 +53,45 @@ public class FileUtil {
}
out.flush();
if (ImageIO.read(picFile) == null) {
if( ImageIO.read(picFile) == null){
picSrc = "/images/default.gif";
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}catch (Exception e){
log.error(e.getMessage(),e);
picSrc = "/images/default.gif";
} finally {
closeStream(input, out);
}finally {
if(input != null){
try {
input.close();
} catch (IOException e) {
log.error(e.getMessage(),e);
}finally {
if(out != null){
try {
out.close();
} catch (IOException e) {
log.error(e.getMessage(),e);
}
}
}
}
}
return picSrc;
}
@SneakyThrows
private void closeStream(InputStream input, OutputStream out) {
if (input != null) {
input.close();
}
if (out != null) {
out.close();
}
}
/**
* 判断文件是否为图片
*
* @param file 需要判断的文件
* @return true:是图片false:不是图片
*/
* */
@SneakyThrows
public boolean isImage(File file) {
public boolean isImage(File file){
BufferedImage bi = ImageIO.read(file);
@ -98,27 +100,6 @@ public class FileUtil {
}
public void writeContentToFile(String fileSavePath, String fileSrc, String content) {
OutputStream out = null;
try {
File file = new File(fileSavePath + fileSrc);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
out = new FileOutputStream(file);
out.write(content.getBytes());
byte[] b = new byte[4096];
out.flush();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("文件写入失败");
} finally {
closeStream(null, out);
}
}
}

View File

@ -0,0 +1,163 @@
package com.java2nb.novel.core.utils;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
/**
* <p>名称IdWorker.java</p>
* <p>描述分布式自增长ID</p>
* <pre>
* Twitter的 Snowflake JAVA实现方案
* </pre>
* 核心代码为其IdWorker这个类实现其原理结构如下我分别用一个0表示一位用—分割开部分的作用
* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
* 在上面的字符串中第一位为未使用实际上也可作为long的符号位接下来的41位为毫秒级时间
* 然后5位datacenter标识位5位机器ID并不算标识符实际是为线程标识
* 然后12位该毫秒内的当前毫秒内的计数加起来刚好64位为一个Long型。
* 这样的好处是整体上按照时间自增排序并且整个分布式系统内不会产生ID碰撞由datacenter和机器ID作区分
* 并且效率较高经测试snowflake每秒能够产生26万ID左右完全满足需要。
* <p>
* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
*
*/
public class IdWorker {
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
private final static long twepoch = 1288834974657L;
// 机器标识位数
private final static long workerIdBits = 5L;
// 数据中心标识位数
private final static long datacenterIdBits = 5L;
// 机器ID最大值
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
// 数据中心ID最大值
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
// 毫秒内自增位
private final static long sequenceBits = 12L;
// 机器ID偏左移12位
private final static long workerIdShift = sequenceBits;
// 数据中心ID左移17位
private final static long datacenterIdShift = sequenceBits + workerIdBits;
// 时间毫秒左移22位
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
/* 上次生产id时间戳 */
private static long lastTimestamp = -1L;
// 0并发控制
private long sequence = 0L;
private final long workerId;
// 数据标识id部分
private final long datacenterId;
public IdWorker(){
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
* @param workerId
* 工作机器ID
* @param datacenterId
* 序列号
*/
public IdWorker(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
* 获取下一个ID
*
* @return
*/
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
// 当前毫秒内,则+1
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
// 当前毫秒内计数满了,则等待下一秒
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// ID偏移组合生成最终的ID并返回ID
long nextId = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift) | sequence;
return nextId;
}
private long tilNextMillis(final long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
/**
* <p>
* 获取 maxWorkerId
* </p>
*/
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuffer mpid = new StringBuffer();
mpid.append(datacenterId);
String name = ManagementFactory.getRuntimeMXBean().getName();
if (!name.isEmpty()) {
/*
* GET jvmPid
*/
mpid.append(name.split("@")[0]);
}
/*
* MAC + PID 的 hashcode 获取16个低位
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
/**
* <p>
* 数据标识id部分
* </p>
*/
protected static long getDatacenterId(long maxDatacenterId) {
long id = 0L;
try {
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
id = 1L;
} else {
byte[] mac = network.getHardwareAddress();
id = ((0x000000FF & (long) mac[mac.length - 1])
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
id = id % (maxDatacenterId + 1);
}
} catch (Exception e) {
System.out.println(" getDatacenterId: " + e.getMessage());
}
return id;
}
}

View File

@ -0,0 +1,61 @@
package com.java2nb.novel.core.utils;
import lombok.SneakyThrows;
import sun.misc.BASE64Encoder;
import java.security.MessageDigest;
/**
* @author 11797
*/
public class MD5Util {
private static final String DEFAUL_CHARSET = "utf-8" ;
private static String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n += 256;
}
int d1 = n / 16;
int d2 = n % 16;
return HEX_DIGITS[d1] + HEX_DIGITS[d2];
}
@SneakyThrows
public static String MD5Encode(String origin,String charsetname) {
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname)) {
return byteArrayToHexString(md.digest(origin
.getBytes()));
} else {
return byteArrayToHexString(md.digest(origin
.getBytes(charsetname)));
}
}
@SneakyThrows
public static String MD5New(String str) {
//首先利用MD5算法将密码加密变成等长字节
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] b1 = md.digest(str.getBytes());
//将等长字节利用Base64算法转换成字符串
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(b1);
}
private static final String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
}

View File

@ -0,0 +1,52 @@
package com.java2nb.novel.core.utils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author Administrator
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
/**
* 获取applicationContext
* */
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
* */
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean
* */
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
* */
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}

View File

@ -0,0 +1,26 @@
package com.java2nb.novel.core.utils;
/**
* 线程工具类
* @author Administrator
*/
public class ThreadUtil {
/**
* 根据线程ID获取线程
* */
public static Thread findThread(long threadId) {
ThreadGroup group = Thread.currentThread().getThreadGroup();
while(group != null) {
Thread[] threads = new Thread[(int)(group.activeCount() * 1.2)];
int count = group.enumerate(threads, true);
for(int i = 0; i < count; i++) {
if(threadId == threads[i].getId()) {
return threads[i];
}
}
group = group.getParent();
}
return null;
}
}

View File

@ -0,0 +1,96 @@
package com.java2nb.novel.core.utils;
import java.util.UUID;
/**
* @author Administrator
*/
public class UUIDUtil {
public static final String[] CHARS = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z" };
/**
* 生成指定长度的uuid
*
* @param length
* @return
*/
private static String getUUID(int length, UUID uuid) {
int groupLength = 32 / length;
StringBuilder sb = new StringBuilder();
String id = uuid.toString().replace("-", "");
for (int i = 0; i < length; i++) {
String str = id.substring(i * groupLength, i * groupLength + groupLength);
int x = Integer.parseInt(str, 16);
sb.append(CHARS[x % 0x3E]);
}
return sb.toString();
}
/**
* 8位UUID
*
* @return
*/
public static String getUUID8() {
return getUUID(8, UUID.randomUUID());
}
/**
* 8位UUID
*
* @return
*/
public static String getUUID8(byte[] bytes) {
return getUUID(8, UUID.nameUUIDFromBytes(bytes));
}
/**
* 8位UUID
*
* @return
*/
public static String getUUID8(String fromString) {
return getUUID(8, UUID.fromString(fromString));
}
/**
* 16位UUID
*
* @return
*/
public static String getUUID16() {
return getUUID(16, UUID.randomUUID());
}
/**
* 16位UUID
*
* @return
*/
public static String getUUID16(String fromString) {
return getUUID(16, UUID.fromString(fromString));
}
/**
* 16位UUID
*
* @return
*/
public static String getUUID16(byte[] bytes) {
return getUUID(16, UUID.nameUUIDFromBytes(bytes));
}
/**
* 32位UUID
*
* @return
*/
public static String getUUID32() {
return UUID.randomUUID().toString().replace("-", "");
}
}

View File

@ -0,0 +1,11 @@
package com.java2nb.novel.core.valid;
/**
* 新增数据的校验分组
* @author xiongxiaoyang
*/
public interface AddGroup {
}

View File

@ -0,0 +1,11 @@
package com.java2nb.novel.core.valid;
/**
* 更新数据的校验分组
* @author xiongxiaoyang
*/
public interface UpdateGroup {
}

View File

@ -25,9 +25,6 @@ public class BookIndex {
@Generated("org.mybatis.generator.api.MyBatisGenerator")
private Integer bookPrice;
@Generated("org.mybatis.generator.api.MyBatisGenerator")
private String storageType;
@Generated("org.mybatis.generator.api.MyBatisGenerator")
private Date createTime;
@ -104,16 +101,6 @@ public class BookIndex {
this.bookPrice = bookPrice;
}
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public String getStorageType() {
return storageType;
}
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public void setStorageType(String storageType) {
this.storageType = storageType == null ? null : storageType.trim();
}
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public Date getCreateTime() {
return createTime;

View File

@ -1,11 +1,11 @@
package com.java2nb.novel.entity;
import io.github.xxyopen.web.valid.AddGroup;
import io.github.xxyopen.web.valid.UpdateGroup;
import com.java2nb.novel.core.valid.AddGroup;
import com.java2nb.novel.core.valid.UpdateGroup;
import java.util.Date;
import javax.annotation.Generated;
import javax.validation.constraints.*;
import java.util.Date;
public class User {

View File

@ -31,9 +31,6 @@ public final class BookIndexDynamicSqlSupport {
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public static final SqlColumn<Integer> bookPrice = bookIndex.bookPrice;
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public static final SqlColumn<String> storageType = bookIndex.storageType;
@Generated("org.mybatis.generator.api.MyBatisGenerator")
public static final SqlColumn<Date> createTime = bookIndex.createTime;
@ -56,8 +53,6 @@ public final class BookIndexDynamicSqlSupport {
public final SqlColumn<Integer> bookPrice = column("book_price", JDBCType.INTEGER);
public final SqlColumn<String> storageType = column("storage_type", JDBCType.VARCHAR);
public final SqlColumn<Date> createTime = column("create_time", JDBCType.TIMESTAMP);
public final SqlColumn<Date> updateTime = column("update_time", JDBCType.TIMESTAMP);

View File

@ -37,47 +37,46 @@ import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils;
@Mapper
public interface BookIndexMapper {
@Generated("org.mybatis.generator.api.MyBatisGenerator")
BasicColumn[] selectList = BasicColumn.columnList(id, bookId, indexNum, indexName, wordCount, isVip, bookPrice, storageType, createTime, updateTime);
BasicColumn[] selectList = BasicColumn.columnList(id, bookId, indexNum, indexName, wordCount, isVip, bookPrice, createTime, updateTime);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@SelectProvider(type=SqlProviderAdapter.class, method="select")
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
long count(SelectStatementProvider selectStatement);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@DeleteProvider(type=SqlProviderAdapter.class, method="delete")
@DeleteProvider(type = SqlProviderAdapter.class, method = "delete")
int delete(DeleteStatementProvider deleteStatement);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@InsertProvider(type=SqlProviderAdapter.class, method="insert")
@InsertProvider(type = SqlProviderAdapter.class, method = "insert")
int insert(InsertStatementProvider<BookIndex> insertStatement);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@InsertProvider(type=SqlProviderAdapter.class, method="insertMultiple")
@InsertProvider(type = SqlProviderAdapter.class, method = "insertMultiple")
int insertMultiple(MultiRowInsertStatementProvider<BookIndex> multipleInsertStatement);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@SelectProvider(type=SqlProviderAdapter.class, method="select")
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
@ResultMap("BookIndexResult")
Optional<BookIndex> selectOne(SelectStatementProvider selectStatement);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@SelectProvider(type=SqlProviderAdapter.class, method="select")
@Results(id="BookIndexResult", value = {
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="book_id", property="bookId", jdbcType=JdbcType.BIGINT),
@Result(column="index_num", property="indexNum", jdbcType=JdbcType.INTEGER),
@Result(column="index_name", property="indexName", jdbcType=JdbcType.VARCHAR),
@Result(column="word_count", property="wordCount", jdbcType=JdbcType.INTEGER),
@Result(column="is_vip", property="isVip", jdbcType=JdbcType.TINYINT),
@Result(column="book_price", property="bookPrice", jdbcType=JdbcType.INTEGER),
@Result(column="storage_type", property="storageType", jdbcType=JdbcType.VARCHAR),
@Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="update_time", property="updateTime", jdbcType=JdbcType.TIMESTAMP)
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
@Results(id = "BookIndexResult", value = {
@Result(column = "id", property = "id", jdbcType = JdbcType.BIGINT, id = true),
@Result(column = "book_id", property = "bookId", jdbcType = JdbcType.BIGINT),
@Result(column = "index_num", property = "indexNum", jdbcType = JdbcType.INTEGER),
@Result(column = "index_name", property = "indexName", jdbcType = JdbcType.VARCHAR),
@Result(column = "word_count", property = "wordCount", jdbcType = JdbcType.INTEGER),
@Result(column = "is_vip", property = "isVip", jdbcType = JdbcType.TINYINT),
@Result(column = "book_price", property = "bookPrice", jdbcType = JdbcType.INTEGER),
@Result(column = "create_time", property = "createTime", jdbcType = JdbcType.TIMESTAMP),
@Result(column = "update_time", property = "updateTime", jdbcType = JdbcType.TIMESTAMP)
})
List<BookIndex> selectMany(SelectStatementProvider selectStatement);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@UpdateProvider(type=SqlProviderAdapter.class, method="update")
@UpdateProvider(type = SqlProviderAdapter.class, method = "update")
int update(UpdateStatementProvider updateStatement);
@Generated("org.mybatis.generator.api.MyBatisGenerator")
@ -107,7 +106,6 @@ public interface BookIndexMapper {
.map(wordCount).toProperty("wordCount")
.map(isVip).toProperty("isVip")
.map(bookPrice).toProperty("bookPrice")
.map(storageType).toProperty("storageType")
.map(createTime).toProperty("createTime")
.map(updateTime).toProperty("updateTime")
);
@ -123,7 +121,6 @@ public interface BookIndexMapper {
.map(wordCount).toProperty("wordCount")
.map(isVip).toProperty("isVip")
.map(bookPrice).toProperty("bookPrice")
.map(storageType).toProperty("storageType")
.map(createTime).toProperty("createTime")
.map(updateTime).toProperty("updateTime")
);
@ -139,7 +136,6 @@ public interface BookIndexMapper {
.map(wordCount).toPropertyWhenPresent("wordCount", record::getWordCount)
.map(isVip).toPropertyWhenPresent("isVip", record::getIsVip)
.map(bookPrice).toPropertyWhenPresent("bookPrice", record::getBookPrice)
.map(storageType).toPropertyWhenPresent("storageType", record::getStorageType)
.map(createTime).toPropertyWhenPresent("createTime", record::getCreateTime)
.map(updateTime).toPropertyWhenPresent("updateTime", record::getUpdateTime)
);
@ -181,7 +177,6 @@ public interface BookIndexMapper {
.set(wordCount).equalTo(record::getWordCount)
.set(isVip).equalTo(record::getIsVip)
.set(bookPrice).equalTo(record::getBookPrice)
.set(storageType).equalTo(record::getStorageType)
.set(createTime).equalTo(record::getCreateTime)
.set(updateTime).equalTo(record::getUpdateTime);
}
@ -195,7 +190,6 @@ public interface BookIndexMapper {
.set(wordCount).equalToWhenPresent(record::getWordCount)
.set(isVip).equalToWhenPresent(record::getIsVip)
.set(bookPrice).equalToWhenPresent(record::getBookPrice)
.set(storageType).equalToWhenPresent(record::getStorageType)
.set(createTime).equalToWhenPresent(record::getCreateTime)
.set(updateTime).equalToWhenPresent(record::getUpdateTime);
}
@ -209,7 +203,6 @@ public interface BookIndexMapper {
.set(wordCount).equalTo(record::getWordCount)
.set(isVip).equalTo(record::getIsVip)
.set(bookPrice).equalTo(record::getBookPrice)
.set(storageType).equalTo(record::getStorageType)
.set(createTime).equalTo(record::getCreateTime)
.set(updateTime).equalTo(record::getUpdateTime)
.where(id, isEqualTo(record::getId))
@ -225,7 +218,6 @@ public interface BookIndexMapper {
.set(wordCount).equalToWhenPresent(record::getWordCount)
.set(isVip).equalToWhenPresent(record::getIsVip)
.set(bookPrice).equalToWhenPresent(record::getBookPrice)
.set(storageType).equalToWhenPresent(record::getStorageType)
.set(createTime).equalToWhenPresent(record::getCreateTime)
.set(updateTime).equalToWhenPresent(record::getUpdateTime)
.where(id, isEqualTo(record::getId))

View File

@ -71,7 +71,3 @@ sharding:
content:
save:
storage: db #存储介质db数据库filetxt文本
path: /Users/xiongxiaoyang/books #txt小说文本保存路径

View File

@ -74,10 +74,7 @@ logging:
content:
save:
storage: db #存储介质db数据库filetxt文本
path: /Users/xiongxiaoyang/books #txt小说文本保存路径

View File

@ -44,7 +44,7 @@
</javaClientGenerator>
<!--生成全部表tableName设为%-->
<table tableName="book_index"/>
<table tableName="news"/>
<!-- 指定数据库表 -->
<!--<table schema="jly" tableName="job_position" domainObjectName="JobPositionTest"/>-->

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>novel</artifactId>
<groupId>com.java2nb</groupId>
<version>3.6.1</version>
<version>3.5.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -31,29 +31,6 @@
<build>
<plugins>
<!-- 将相同groupId的依赖模块打包进来 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>${project.groupId}:*:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<!--打包时去除第三方依赖-->
<groupId>org.springframework.boot</groupId>
@ -85,7 +62,6 @@
<excludeTransitive>false</excludeTransitive>
<stripVersion>false</stripVersion>
<includeScope>runtime</includeScope>
<excludeGroupIds>${project.groupId}</excludeGroupIds>
</configuration>
</execution>
</executions>

View File

@ -1,14 +1,26 @@
package com.java2nb.novel.controller;
import io.github.xxyopen.model.page.PageBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.java2nb.novel.core.bean.PageBean;
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.crawl.CrawlParser;
import com.java2nb.novel.core.crawl.RuleBean;
import com.java2nb.novel.core.utils.HttpUtil;
import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource;
import com.java2nb.novel.service.CrawlService;
import io.github.xxyopen.model.resp.RestResult;
import com.java2nb.novel.utils.Constants;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Administrator
*/
@ -19,15 +31,15 @@ public class CrawlController {
private final CrawlService crawlService;
private final CacheService cacheService;
/**
* 新增爬虫源
* */
@PostMapping("addCrawlSource")
public RestResult<Void> addCrawlSource(CrawlSource source){
public ResultBean<Void> addCrawlSource(CrawlSource source){
crawlService.addCrawlSource(source);
return RestResult.ok();
return ResultBean.ok();
}
@ -35,30 +47,93 @@ public class CrawlController {
* 爬虫源分页列表查询
* */
@GetMapping("listCrawlByPage")
public RestResult<PageBean<CrawlSource>> listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
public ResultBean<PageBean<CrawlSource>> listCrawlByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
return ResultBean.ok(crawlService.listCrawlByPage(page,pageSize));
}
/**
* 获取爬虫源
* */
@GetMapping("getCrawlSource/{id}")
public ResultBean<CrawlSource> getCrawlSource(@PathVariable("id") Integer id){
CrawlSource crawlSource= crawlService.getCrawlSource(id);
return ResultBean.ok(crawlSource);
return RestResult.ok(crawlService.listCrawlByPage(page,pageSize));
}
/**
* 测试规则
* @param rule
* @param url
* @param isRefresh
* @return
*/
@PostMapping("testParse")
public ResultBean<Object> testParse(String rule,String url,String isRefresh){
Map<String,Object> resultMap=new HashMap<>();
String html =null;
if(url.startsWith("https://")||url.startsWith("http://")){
String refreshCache="1";
if(!refreshCache.equals(isRefresh)) {
Object cache = cacheService.getObject(CacheKey.BOOK_TEST_PARSE + url);
if (cache == null) {
isRefresh="1";
}else {
html = (String) cache;
}
}
if(refreshCache.equals(isRefresh)){
html = HttpUtil.getByHttpClientWithChrome(url);
if (html != null) {
cacheService.setObject(CacheKey.BOOK_TEST_PARSE + url, html, 60 * 10);
}else{
resultMap.put("msg","html is null");
return ResultBean.ok(resultMap);
}
}
}else{
resultMap.put("html","url is null");
return ResultBean.ok(resultMap);
}
Pattern pattern = Pattern.compile(rule);
Matcher matcher = pattern.matcher(html);
boolean isFind = matcher.find();
resultMap.put("是否匹配",isFind);
if(isFind){
resultMap.put("匹配结果",matcher.group(1));
}
// resultMap.put("url",url);
return ResultBean.ok(resultMap);
}
/**
* 修改爬虫源
* */
@PostMapping("updateCrawlSource")
public ResultBean<Void> updateCrawlSource(CrawlSource source){
crawlService.updateCrawlSource(source);
return ResultBean.ok();
}
/**
* 开启或停止爬虫
* */
@PostMapping("openOrCloseCrawl")
public RestResult<Void> openOrCloseCrawl(Integer sourceId,Byte sourceStatus){
public ResultBean<Void> openOrCloseCrawl(Integer sourceId,Byte sourceStatus){
crawlService.openOrCloseCrawl(sourceId,sourceStatus);
return RestResult.ok();
return ResultBean.ok();
}
/**
* 新增单本采集任务
* */
@PostMapping("addCrawlSingleTask")
public RestResult<Void> addCrawlSingleTask(CrawlSingleTask singleTask){
public ResultBean<Void> addCrawlSingleTask(CrawlSingleTask singleTask){
crawlService.addCrawlSingleTask(singleTask);
return RestResult.ok();
return ResultBean.ok();
}
@ -66,20 +141,20 @@ public class CrawlController {
* 单本采集任务分页列表查询
* */
@GetMapping("listCrawlSingleTaskByPage")
public RestResult<PageBean<CrawlSingleTask>> listCrawlSingleTaskByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
public ResultBean<PageBean<CrawlSingleTask>> listCrawlSingleTaskByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize){
return RestResult.ok(crawlService.listCrawlSingleTaskByPage(page,pageSize));
return ResultBean.ok(crawlService.listCrawlSingleTaskByPage(page,pageSize));
}
/**
* 删除采集任务
* */
@DeleteMapping("delCrawlSingleTask/{id}")
public RestResult<Void> delCrawlSingleTask(@PathVariable("id") Long id){
public ResultBean<Void> delCrawlSingleTask(@PathVariable("id") Long id){
crawlService.delCrawlSingleTask(id);
return RestResult.ok();
return ResultBean.ok();
}

View File

@ -5,7 +5,6 @@ import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.utils.Constants;
import io.github.xxyopen.util.IdWorker;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -27,7 +26,7 @@ import static java.util.regex.Pattern.compile;
@Slf4j
public class CrawlParser {
private static final IdWorker idWorker = IdWorker.INSTANCE;
private static final IdWorker idWorker = new IdWorker();
private static final RestTemplate restTemplate = RestTemplateUtil.getInstance("utf-8");
@ -139,7 +138,7 @@ public class CrawlParser {
handler.handle(book);
}
public static boolean parseBookIndexAndContent(String sourceBookId, Book book, RuleBean ruleBean, Map<Integer, BookIndex> existBookIndexMap, CrawlBookChapterHandler handler) {
public static void parseBookIndexAndContent(String sourceBookId, Book book, RuleBean ruleBean, Map<Integer, BookIndex> existBookIndexMap, CrawlBookChapterHandler handler) {
Date currentDate = new Date();
@ -275,7 +274,7 @@ public class CrawlParser {
setBookContentList(contentList);
}});
return true;
return;
}
@ -285,7 +284,6 @@ public class CrawlParser {
setBookIndexList(new ArrayList<>(0));
setBookContentList(new ArrayList<>(0));
}});
return false;
}

View File

@ -3,9 +3,9 @@ package com.java2nb.novel.core.schedule;
import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService;
import com.java2nb.novel.core.utils.ThreadUtil;
import com.java2nb.novel.entity.CrawlSource;
import com.java2nb.novel.service.CrawlService;
import io.github.xxyopen.util.ThreadUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;

View File

@ -1,16 +0,0 @@
package com.java2nb.novel.service;
import com.java2nb.novel.entity.BookContent;
import java.util.List;
public interface BookContentService {
void saveBookContent(List<BookContent> bookContentList,Long bookId);
void saveBookContent(BookContent bookContent,Long bookId);
void updateBookContent(BookContent bookContent,Long bookId);
}

View File

@ -1,6 +1,7 @@
package com.java2nb.novel.service;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.crawl.RuleBean;
import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource;
@ -18,7 +19,11 @@ public interface CrawlService {
* */
void addCrawlSource(CrawlSource source);
/**
* 修改爬虫源
* @param source
*/
void updateCrawlSource(CrawlSource source);
/**
* 爬虫源分页列表
* @param page 当前页码
@ -106,4 +111,11 @@ public interface CrawlService {
* @param status 采集状态
* */
void updateCrawlSingleTask(CrawlSingleTask task, Byte status);
/**
* 获取采集规则详细
* @param id
* @return
*/
CrawlSource getCrawlSource(Integer id);
}

View File

@ -4,12 +4,10 @@ import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.mapper.*;
import com.java2nb.novel.service.BookContentService;
import com.java2nb.novel.service.BookService;
import com.java2nb.novel.utils.Constants;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -39,10 +37,7 @@ public class BookServiceImpl implements BookService {
private final CrawlBookIndexMapper bookIndexMapper;
private final Map<String, BookContentService> bookContentServiceMap;
@Value("${content.save.storage}")
private String storageType;
private final BookContentMapper bookContentMapper;
@Override
@ -51,7 +46,7 @@ public class BookServiceImpl implements BookService {
return bookMapper.count(countFrom(BookDynamicSqlSupport.book).where(BookDynamicSqlSupport.bookName, isEqualTo(bookName))
.and(BookDynamicSqlSupport.authorName, isEqualTo(authorName))
.build()
.render(RenderingStrategies.MYBATIS3)) > 0;
.render(RenderingStrategies.MYBATIS3))>0;
}
@ -62,7 +57,7 @@ public class BookServiceImpl implements BookService {
.equalTo(sourceId)
.set(crawlBookId)
.equalTo(bookId)
.where(BookDynamicSqlSupport.id, isEqualTo(id))
.where(BookDynamicSqlSupport.id,isEqualTo(id))
.build()
.render(RenderingStrategies.MYBATIS3));
}
@ -79,9 +74,9 @@ public class BookServiceImpl implements BookService {
@Transactional(rollbackFor = Exception.class)
@Override
public void saveBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList) {
if (!queryIsExistByBookNameAndAuthorName(book.getBookName(), book.getAuthorName())) {
if(!queryIsExistByBookNameAndAuthorName(book.getBookName(),book.getAuthorName())) {
if (bookIndexList.size() > 0) {
if(bookIndexList.size()>0) {
//保存小说主表
@ -89,11 +84,8 @@ public class BookServiceImpl implements BookService {
bookMapper.insertSelective(book);
//批量保存目录和内容
bookIndexList.forEach(bookIndex -> {
bookIndex.setStorageType(storageType);
});
bookIndexMapper.insertMultiple(bookIndexList);
bookContentServiceMap.get(storageType).saveBookContent(bookContentList, book.getId());
bookContentMapper.insertMultiple(bookContentList);
}
}
@ -104,7 +96,7 @@ public class BookServiceImpl implements BookService {
@Override
public List<Book> queryNeedUpdateBook(Date startDate, int limit) {
List<Book> books = bookMapper.queryNeedUpdateBook(startDate, limit);
if (books.size() > 0) {
if(books.size()>0) {
//更新最后抓取时间为当前时间
bookMapper.updateCrawlLastTime(books, new Date());
}
@ -113,9 +105,9 @@ public class BookServiceImpl implements BookService {
@Override
public Map<Integer, BookIndex> queryExistBookIndexMap(Long bookId) {
List<BookIndex> bookIndexs = bookIndexMapper.selectMany(select(BookIndexDynamicSqlSupport.id, BookIndexDynamicSqlSupport.indexNum, BookIndexDynamicSqlSupport.indexName, BookIndexDynamicSqlSupport.wordCount, BookIndexDynamicSqlSupport.storageType)
List<BookIndex> bookIndexs = bookIndexMapper.selectMany(select(BookIndexDynamicSqlSupport.id,BookIndexDynamicSqlSupport.indexNum,BookIndexDynamicSqlSupport.indexName,BookIndexDynamicSqlSupport.wordCount)
.from(BookIndexDynamicSqlSupport.bookIndex)
.where(BookIndexDynamicSqlSupport.bookId, isEqualTo(bookId))
.where(BookIndexDynamicSqlSupport.bookId,isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3));
if (bookIndexs.size() > 0) {
@ -132,15 +124,19 @@ public class BookServiceImpl implements BookService {
BookContent bookContent = bookContentList.get(i);
if (!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
if(!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
//插入
bookIndex.setStorageType(storageType);
bookIndexMapper.insertSelective(bookIndex);
bookContentServiceMap.get(storageType).saveBookContent(bookContent, book.getId());
} else {
bookContentMapper.insertSelective(bookContent);
}else{
//更新
bookIndexMapper.updateByPrimaryKeySelective(bookIndex);
bookContentServiceMap.get(existBookIndexMap.get(bookIndex.getIndexNum()).getStorageType()).updateBookContent(bookContent, book.getId());
bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent)
.set(BookContentDynamicSqlSupport.content)
.equalTo(bookContent.getContent())
.where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
.build()
.render(RenderingStrategies.MYBATIS3));
}
@ -149,7 +145,7 @@ public class BookServiceImpl implements BookService {
//更新小说主表
book.setBookName(null);
book.setAuthorName(null);
if (Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
if(Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
book.setVisitCount(null);
}
bookMapper.updateByPrimaryKeySelective(book);
@ -172,7 +168,7 @@ public class BookServiceImpl implements BookService {
.build()
.render(RenderingStrategies.MYBATIS3));
if (books.size() > 0) {
if(books.size()>0){
return books.get(0);
}

View File

@ -2,17 +2,17 @@ package com.java2nb.novel.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService;
import com.java2nb.novel.core.crawl.CrawlParser;
import com.java2nb.novel.core.crawl.RuleBean;
import com.java2nb.novel.core.enums.ResponseStatus;
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
import io.github.xxyopen.util.IdWorker;
import io.github.xxyopen.util.ThreadUtil;
import io.github.xxyopen.web.exception.BusinessException;
import io.github.xxyopen.web.util.BeanUtil;
import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.core.utils.IdWorker;
import com.java2nb.novel.core.utils.SpringUtil;
import com.java2nb.novel.core.utils.ThreadUtil;
import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.CrawlSingleTask;
import com.java2nb.novel.entity.CrawlSource;
@ -24,7 +24,6 @@ import com.java2nb.novel.service.BookService;
import com.java2nb.novel.service.CrawlService;
import com.java2nb.novel.vo.CrawlSingleTaskVO;
import com.java2nb.novel.vo.CrawlSourceVO;
import io.github.xxyopen.web.util.SpringUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ -40,6 +39,7 @@ import java.util.regex.Pattern;
import static com.java2nb.novel.core.utils.HttpUtil.getByHttpClientWithChrome;
import static com.java2nb.novel.mapper.CrawlSourceDynamicSqlSupport.*;
import static com.java2nb.novel.mapper.CrawlSourceDynamicSqlSupport.id;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
@ -70,7 +70,24 @@ public class CrawlServiceImpl implements CrawlService {
crawlSourceMapper.insertSelective(source);
}
@Override
public void updateCrawlSource(CrawlSource source) {
if(source.getId()!=null){
Optional<CrawlSource> opt=crawlSourceMapper.selectByPrimaryKey(source.getId());
if(opt.isPresent()) {
CrawlSource crawlSource =opt.get();
if (crawlSource.getSourceStatus() == (byte) 1) {
//关闭
openOrCloseCrawl(crawlSource.getId(),(byte)0);
}
Date currentDate = new Date();
crawlSource.setUpdateTime(currentDate);
crawlSource.setCrawlRule(source.getCrawlRule());
crawlSource.setSourceName(source.getSourceName());
crawlSourceMapper.updateByPrimaryKey(crawlSource);
}
}
}
@Override
public PageBean<CrawlSource> listCrawlByPage(int page, int pageSize) {
PageHelper.startPage(page, pageSize);
@ -80,7 +97,7 @@ public class CrawlServiceImpl implements CrawlService {
.build()
.render(RenderingStrategies.MYBATIS3);
List<CrawlSource> crawlSources = crawlSourceMapper.selectMany(render);
PageBean<CrawlSource> pageBean = PageBuilder.build(crawlSources);
PageBean<CrawlSource> pageBean = new PageBean<>(crawlSources);
pageBean.setList(BeanUtil.copyList(crawlSources, CrawlSourceVO.class));
return pageBean;
}
@ -139,18 +156,23 @@ public class CrawlServiceImpl implements CrawlService {
@Override
public CrawlSource queryCrawlSource(Integer sourceId) {
SelectStatementProvider render = select(CrawlSourceDynamicSqlSupport.sourceStatus, CrawlSourceDynamicSqlSupport.crawlRule)
SelectStatementProvider render = select(id, sourceName, sourceStatus, createTime, updateTime,crawlRule)
.from(crawlSource)
.where(id, isEqualTo(sourceId))
.build()
.render(RenderingStrategies.MYBATIS3);
return crawlSourceMapper.selectMany(render).get(0);
List<CrawlSource> list= crawlSourceMapper.selectMany(render);
if(list!=null&&list.size()>0){
return list.get(0);
}
return null;
}
@Override
public void addCrawlSingleTask(CrawlSingleTask singleTask) {
if (bookService.queryIsExistByBookNameAndAuthorName(singleTask.getBookName(), singleTask.getAuthorName())) {
if(bookService.queryIsExistByBookNameAndAuthorName(singleTask.getBookName(),singleTask.getAuthorName())){
throw new BusinessException(ResponseStatus.BOOK_EXISTS);
}
@ -169,7 +191,7 @@ public class CrawlServiceImpl implements CrawlService {
.build()
.render(RenderingStrategies.MYBATIS3);
List<CrawlSingleTask> crawlSingleTasks = crawlSingleTaskMapper.selectMany(render);
PageBean<CrawlSingleTask> pageBean = PageBuilder.build(crawlSingleTasks);
PageBean<CrawlSingleTask> pageBean = new PageBean<>(crawlSingleTasks);
pageBean.setList(BeanUtil.copyList(crawlSingleTasks, CrawlSingleTaskVO.class));
return pageBean;
}
@ -184,7 +206,7 @@ public class CrawlServiceImpl implements CrawlService {
List<CrawlSingleTask> list = crawlSingleTaskMapper.selectMany(select(CrawlSingleTaskDynamicSqlSupport.crawlSingleTask.allColumns())
.from(CrawlSingleTaskDynamicSqlSupport.crawlSingleTask)
.where(CrawlSingleTaskDynamicSqlSupport.taskStatus, isEqualTo((byte) 2))
.where(CrawlSingleTaskDynamicSqlSupport.taskStatus,isEqualTo((byte)2))
.orderBy(CrawlSingleTaskDynamicSqlSupport.createTime)
.limit(1)
.build()
@ -196,9 +218,9 @@ public class CrawlServiceImpl implements CrawlService {
@Override
public void updateCrawlSingleTask(CrawlSingleTask task, Byte status) {
byte excCount = task.getExcCount();
excCount += 1;
excCount+=1;
task.setExcCount(excCount);
if (status == 1 || excCount == 5) {
if(status == 1 || excCount == 5){
//当采集成功或者采集次数等于5则更新采集最终状态并停止采集
task.setTaskStatus(status);
}
@ -206,6 +228,16 @@ public class CrawlServiceImpl implements CrawlService {
}
@Override
public CrawlSource getCrawlSource(Integer id) {
Optional<CrawlSource> opt=crawlSourceMapper.selectByPrimaryKey(id);
if(opt.isPresent()) {
CrawlSource crawlSource =opt.get();
return crawlSource;
}
return null;
}
/**
* 解析分类列表
*/
@ -220,7 +252,7 @@ public class CrawlServiceImpl implements CrawlService {
try {
if (StringUtils.isNotBlank(ruleBean.getCatIdRule().get("catId" + catId))) {
if(StringUtils.isNotBlank(ruleBean.getCatIdRule().get("catId" + catId))) {
//拼接分类URL
String catBookListUrl = ruleBean.getBookListUrl()
.replace("{catId}", ruleBean.getCatIdRule().get("catId" + catId))
@ -236,7 +268,7 @@ public class CrawlServiceImpl implements CrawlService {
//1.阻塞过程(使用了 sleep,同步锁的 wait,socket 中的 receiver,accept 等方法时)
//捕获中断异常InterruptedException来退出线程。
//2.非阻塞过程中通过判断中断标志来退出线程。
if (Thread.currentThread().isInterrupted()) {
if(Thread.currentThread().isInterrupted()){
return;
}
@ -263,8 +295,8 @@ public class CrawlServiceImpl implements CrawlService {
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}catch (Exception e){
log.error(e.getMessage(),e);
}
page += 1;
@ -279,7 +311,7 @@ public class CrawlServiceImpl implements CrawlService {
final AtomicBoolean parseResult = new AtomicBoolean(false);
CrawlParser.parseBook(ruleBean, bookId, book -> {
if (book.getBookName() == null || book.getAuthorName() == null) {
if(book.getBookName() == null || book.getAuthorName() == null){
return;
}
//这里只做新书入库,查询是否存在这本书
@ -300,18 +332,17 @@ public class CrawlServiceImpl implements CrawlService {
book.setCrawlBookId(bookId);
book.setCrawlSourceId(sourceId);
book.setCrawlLastTime(new Date());
book.setId(IdWorker.INSTANCE.nextId());
book.setId(new IdWorker().nextId());
//解析章节目录
boolean parseIndexContentResult = CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0), chapter -> {
CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0),chapter -> {
bookService.saveBookAndIndexAndContent(book, chapter.getBookIndexList(), chapter.getBookContentList());
});
parseResult.set(parseIndexContentResult);
} else {
//只更新书籍的爬虫相关字段
bookService.updateCrawlProperties(existBook.getId(), sourceId, bookId);
parseResult.set(true);
}
parseResult.set(true);
});
return parseResult.get();

View File

@ -1,43 +0,0 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.mapper.BookContentDynamicSqlSupport;
import com.java2nb.novel.mapper.BookContentMapper;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.update;
@Service(value = "db")
@RequiredArgsConstructor
public class DbBookContentServiceImpl implements BookContentService {
private final BookContentMapper bookContentMapper;
@Override
public void saveBookContent(List<BookContent> bookContentList,Long bookId) {
bookContentMapper.insertMultiple(bookContentList);
}
@Override
public void saveBookContent(BookContent bookContent,Long bookId) {
bookContentMapper.insertSelective(bookContent);
}
@Override
public void updateBookContent(BookContent bookContent,Long bookId) {
bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent)
.set(BookContentDynamicSqlSupport.content)
.equalTo(bookContent.getContent())
.where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
.build()
.render(RenderingStrategies.MYBATIS3));
}
}

View File

@ -1,35 +0,0 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.core.utils.FileUtil;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@Service(value = "txt")
@RequiredArgsConstructor
public class FileBookContentServiceImpl implements BookContentService {
@Value("${content.save.path}")
private String fileSavePath;
@Override
public void saveBookContent(List<BookContent> bookContentList,Long bookId) {
bookContentList.forEach(bookContent -> saveBookContent(bookContent,bookId));
}
@Override
public void saveBookContent(BookContent bookContent,Long bookId) {
FileUtil.writeContentToFile(fileSavePath,"/"+bookId+"/"+bookContent.getIndexId()+".txt",bookContent.getContent());
}
@Override
public void updateBookContent(BookContent bookContent,Long bookId) {
FileUtil.writeContentToFile(fileSavePath,"/"+bookId+"/"+bookContent.getIndexId()+".txt",bookContent.getContent());
}
}

View File

@ -30,6 +30,7 @@
<ul class="log_list">
<li><a class="link_1" href="/">爬虫源管理</a></li>
<li><a class="link_1 on" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
</ul>

View File

@ -30,6 +30,7 @@
<ul class="log_list">
<li><a class="link_1" href="/">爬虫源管理</a></li>
<li><a class="link_1 on" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
<!-- <li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
</ul>

View File

@ -30,6 +30,7 @@
<ul class="log_list">
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
</ul>

View File

@ -29,6 +29,7 @@
<ul class="log_list">
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
<!-- <li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
</ul>
@ -38,7 +39,7 @@
<div class="my_bookshelf">
<div class="title cf">
<h2 class="fl">爬虫源列表</h2>
<div class="fr"><a href="/crawl/crawlSource_add.html" class="btn_red">增加爬虫源</a></div>
<div class="fr"><a href="/crawl/crawlSource_add.html" class="btn_red">增加爬虫源</a>
</div>
<div id="divData" class="updateTable">
@ -119,8 +120,8 @@
<script language="javascript" type="text/javascript">
search(1, 10);
var pageCrawlSourceList=null;
function search(curr, limit) {
$.ajax({
type: "get",
url: "/crawl/listCrawlByPage",
@ -129,6 +130,7 @@
success: function (data) {
if (data.code == 200) {
var crawlSourceList = data.data.list;
pageCrawlSourceList=data.data.list;
if (crawlSourceList.length > 0) {
var crawlSourceListHtml = "";
for(var i=0;i<crawlSourceList.length;i++){
@ -147,7 +149,9 @@
" <td class=\"goread\" id='sourceStatus"+crawlSource.id+"'>"+(crawlSource.sourceStatus==0?'停止运行':'正在运行')+
" </td>\n" +
" <td class=\"goread\" id='opt"+crawlSource.id+"'><a href='javascript:openOrStopCrawl("+crawlSource.id+","+crawlSource.sourceStatus+")'>"+(crawlSource.sourceStatus==0?'开启':'关闭')+" </a></td> </tr>");
" <td class=\"goread\" id='opt"+crawlSource.id+"'><a href='javascript:openOrStopCrawl("+crawlSource.id+","+crawlSource.sourceStatus+")'>"+(crawlSource.sourceStatus==0?'开启':'关闭')+" </a>" +
"<a href='javascript:updateCrawlSource("+crawlSource.id+")'>修改 </a>" +
"</td> </tr>");
}
$("#crawlSourceList").html(crawlSourceListHtml);
@ -196,7 +200,12 @@
})
}
function updateCrawlSource(crawlSourceId){
localStorage.setItem("crawlSourceId",crawlSourceId);
window.location.href="/crawl/crawlSource_update.html";
}
function openOrStopCrawl(sourceId,status) {

View File

@ -0,0 +1,171 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>爬虫管理系统-小说精品屋</title>
<link rel="stylesheet" href="/css/base.css?v=1"/>
<link rel="stylesheet" href="/css/user.css"/>
</head>
</head>
<body class="">
<div class="header">
<div class="mainNav" id="mainNav">
<div class="box_center cf"
style="text-align: center;height: 44px;line-height: 48px;color: #fff;font-size: 16px;">
小说精品屋爬虫管理
</div>
</div>
</div>
<div class="main box_center cf">
<div class="userBox cf">
<div class="my_l">
<ul class="log_list">
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
</ul>
</div>
<div class="my_r">
<div class="my_bookshelf">
<div class="userBox cf">
<form method="post" action="./register.html" id="form2">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKLTIzNjMxNDQxNw9kFgJmD2QWAmYPFgIeBFRleHQFqAE8YSBocmVmPSIvc2VhcmNoLmFzcHg/c2VhcmNoS2V5PeWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqyIgdGFyZ2V0PSJfYmxhbmsiPuWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqzwvYT5kZOquoASBvnvPbc/TYIQiLhSPJ8GKnYQrmk7jGhb5AC5Q">
</div>
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="23AA6834">
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
value="/wEdAAVece19BIZ9HiByRfHz3pfnqKSXUE1UN51mNFrIuw38c3Y2+Mc6SrnAqio3oCKbxYZZ1lS+gZUZKpbsAea8j7ASAv40DHFcQ/NE7tJUnABeyQ3d9sFDIcFCYNqlVtprfLoh4JFy0U+R/CcMuyAiWTz7">
</div>
<div class="user_l">
<div></div>
<h3>爬虫源信息填写示例均为顶点小说网dingdiann.com</h3>
<ul class="log_list">
<li><span id="LabErr"></span></li>
示例:<b>http://m.xdingdiann.com/sort/{catId}/{page}.html</b> ({catId}代表分类ID{page}代表分页页码)
<li><input type="text" id="url" class="s_input icon_key"
placeholder="url"></li>
示例:<b>value=\"(\\d+)/\\d+\"</b>
<li><input type="text" id="rule" class="s_input icon_name" placeholder="规则"></li>
示例:<b>1强制刷新 空或0使用缓存</b>
<li><input type="text" id="isRefresh" class="s_input icon_name" placeholder="是否强制刷新"></li>
<li><textarea rows="20" cols="100" id="resultMap"></textarea></li>
<li><input type="button" onclick="testCrawlSource()" name="btnRegister" value="测试"
id="btnRegister" class="btn_red"></li>
</ul>
</div>
</form>
</div>
<!--<div id="divData" class="updateTable">
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th class="name">
爬虫源(已开启的爬虫源)
</th>
<th class="chapter">
成功爬取数量websocket实现
</th>
<th class="time">
目标爬取数量
</th>
<th class="goread">
状态(正在运行,已停止)(一次只能运行一个爬虫源)
</th>
<th class="goread">
操作(启动,停止)
</th>
</tr>
</thead>
<tbody id="bookShelfList">
</tbody>
</table>
<div class="pageBox cf" id="shellPage">
</div>
</div>-->
</div>
</div>
</div>
</div>
</body>
<script src="/javascript/jquery-1.8.0.min.js" type="text/javascript"></script>
<script src="/layui/layui.all.js" type="text/javascript"></script>
<script src="/javascript/header.js" type="text/javascript"></script>
<script src="/javascript/user.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function load() {
var testParseUrl= localStorage.getItem("testParseUrl");
$("#url").val(testParseUrl);
var testParseRule=localStorage.getItem("testParseRule");
$("#rule").val(testParseRule);
}
function testCrawlSource() {
var data = {};
var isRefresh = $("#isRefresh").val();
data.isRefresh = isRefresh;
var rule = $("#rule").val();
if (rule.length == 0) {
layer.alert("正则必填");
return false;
}
data.rule = rule;
var url = $("#url").val();
if (url.length == 0) {
layer.alert("url必填");
return false;
}
data.url = url;
localStorage.setItem("testParseUrl",url);
localStorage.setItem("testParseRule",rule);
$.ajax({
type: "POST",
url: "/crawl/testParse",
data: data,
dataType: "json",
success: function (data) {
if (data.code == 200) {
$("#resultMap").val(JSON.stringify(data.data));
} else {
layer.alert(data.msg);
}
},
error: function () {
layer.alert('网络异常');
}
})
}
</script>
</html>

View File

@ -0,0 +1,522 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>爬虫管理系统-小说精品屋</title>
<link rel="stylesheet" href="/css/base.css?v=1"/>
<link rel="stylesheet" href="/css/user.css"/>
</head>
</head>
<body class="">
<div class="header">
<div class="mainNav" id="mainNav">
<div class="box_center cf"
style="text-align: center;height: 44px;line-height: 48px;color: #fff;font-size: 16px;">
小说精品屋爬虫管理
</div>
</div>
</div>
<div class="main box_center cf">
<div class="userBox cf">
<div class="my_l">
<ul class="log_list">
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
<li><a class="link_1" href="/crawl/crawlSingleTask_list.html">单本采集管理</a></li>
<li><a class="link_1" href="/crawl/crawlSource_test.html" target="_blank" >规则测试</a></li>
<!--<li><a class="link_1 " href="/user/userinfo.html">批量小说爬取</a></li>
<li><a class="link_4 " href="/user/favorites.html">单本小说爬取</a></li>-->
</ul>
</div>
<div class="my_r">
<div class="my_bookshelf">
<div class="userBox cf">
<form method="post" action="./register.html" id="form2">
<input type="hidden" name="id" id="sourceId"/>
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKLTIzNjMxNDQxNw9kFgJmD2QWAmYPFgIeBFRleHQFqAE8YSBocmVmPSIvc2VhcmNoLmFzcHg/c2VhcmNoS2V5PeWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqyIgdGFyZ2V0PSJfYmxhbmsiPuWWu+Wuiembr++8jOeLhOazve+8jOeBteW8gu+8jOWJjeS4luS7iueUn++8jOWGpeeOi+msvOWkqzwvYT5kZOquoASBvnvPbc/TYIQiLhSPJ8GKnYQrmk7jGhb5AC5Q">
</div>
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="23AA6834">
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
value="/wEdAAVece19BIZ9HiByRfHz3pfnqKSXUE1UN51mNFrIuw38c3Y2+Mc6SrnAqio3oCKbxYZZ1lS+gZUZKpbsAea8j7ASAv40DHFcQ/NE7tJUnABeyQ3d9sFDIcFCYNqlVtprfLoh4JFy0U+R/CcMuyAiWTz7">
</div>
<div class="user_l">
<div></div>
<h3>爬虫源信息填写示例均为顶点小说网dingdiann.com</h3>
<ul class="log_list">
<li><span id="LabErr"></span></li>
示例:<b>新顶点小说网</b>
<li><input type="text" id="sourceName" class="s_input icon_name" placeholder="源站名"></li>
<!--示例:<b>https://m.xdingdiann.com/sort/0/1.html</b>
<li><input type="text" id="updateBookListUrl" class="s_input icon_key"
placeholder="小说更新列表url"></li>-->
示例:<b>http://m.xdingdiann.com/sort/{catId}/{page}.html</b> ({catId}代表分类ID{page}代表分页页码)
<li><input type="text" id="bookListUrl" class="s_input icon_key"
placeholder="分类列表页URL规则"></li>
示例:<b>1</b>
<li><input type="text" id="catId1" class="s_input icon_key" placeholder="玄幻奇幻分类ID"></li>
示例:<b>2</b>
<li><input type="text" id="catId2" class="s_input icon_key" placeholder="武侠仙侠分类ID"></li>
示例:<b>3</b>
<li><input type="text" id="catId3" class="s_input icon_key" placeholder="都市言情分类ID"></li>
示例:<b>4</b>
<li><input type="text" id="catId4" class="s_input icon_key" placeholder="历史军事分类ID"></li>
示例:<b>5</b>
<li><input type="text" id="catId5" class="s_input icon_key" placeholder="科幻灵异分类ID"></li>
示例:<b>6</b>
<li><input type="text" id="catId6" class="s_input icon_key" placeholder="网游竞技分类ID"></li>
示例:<b>7</b>
<li><input type="text" id="catId7" class="s_input icon_key" placeholder="女生频道分类ID"></li>
示例:<b>href="/ddk(\d+)/"</b>
<li><input type="text" id="bookIdPatten" class="s_input icon_key"
placeholder="列表页小说ID正则表达式"></li>
<b>value="(\d+)/\d+"</b>
<li><input type="text" id="pagePatten" class="s_input icon_key"
placeholder="列表页当前分页页码正则表达式"></li>
<b>value="\d+/(\d+)"</b>
<li><input type="text" id="totalPagePatten" class="s_input icon_key"
placeholder="列表页分页总页数正则表达式"></li>
<b>http://m.xdingdiann.com/ddk{bookId}</b> (bookId代表小说ID)
<li><input type="text" id="bookDetailUrl" class="s_input icon_key"
placeholder="详情页URL规则"></li>
示例:<b>&lt;p class="title"&gt;([^/]+)&lt;/p&gt;</b>
<li><input type="text" id="bookNamePatten" class="s_input icon_key"
placeholder="小说名的正则表达式"></li>
示例:<b>作者:([^/]+)<</b>
<li><input type="text" id="authorNamePatten" class="s_input icon_key"
placeholder="小说作者的正则表达式"></li>
示例:<b>&lt;img src="([^>]+)"\s+onerror="this.src=</b>
<li><input type="text" id="picUrlPatten" class="s_input icon_key"
placeholder="小说图片路径的正则表达式"></li>
<b>可空,适用于图片路径为相对路径的源站,加上小说图片路径,则为完整的可访问的图片路径</b>
<li><input type="text" id="picUrlPrefix" class="s_input icon_key"
placeholder="小说图片访问路径前缀"></li>
示例:<b>状态:([^/]+)&lt;/li&gt;</b>
<li><input type="text" id="statusPatten" class="s_input icon_key"
placeholder="小说状态的正则表达式"></li>
示例:<b>连载</b>
<li><input type="text" id="bookStatus0" class="s_input icon_key"
placeholder="连载中的小说在此网站的具体表现值"></li>
示例:<b>完结</b>
<li><input type="text" id="bookStatus1" class="s_input icon_key"
placeholder="全本小说在此网站的具体表现值"></li>
示例:<b>&lt;div\s+class="score"&gt;(\d+\.\d+)分&lt;/div&gt;</b>
<li><input type="text" id="scorePatten" class="s_input icon_key"
placeholder="小说评分的正则表达式"></li>
示例:<b></b>
<li><input type="text" id="visitCountPatten" class="s_input icon_key"
placeholder="小说点击量的正则表达式"></li>
示例:<b>&lt;p class="review"&gt;</b>
<li><input type="text" id="descStart" class="s_input icon_key"
placeholder="小说简介开始截取字符串"></li>
示例:<b>&lt;/p&gt;</b>
<li><input type="text" id="descEnd" class="s_input icon_key" placeholder="小说简介结束截取字符串">
</li>
示例:<b>更新:(\d+-\d+-\d+\s\d+:\d+:\d+)&lt;/a&gt;</b>
<li><input type="text" id="upadateTimePatten" class="s_input icon_key"
placeholder="小说更新时间的正则表达式"></li>
示例:<b>yyyy-MM-dd HH:mm:ss</b>
<li><input type="text" id="upadateTimeFormatPatten" class="s_input icon_key"
placeholder="小说更新时间在此网站的显示模式"></li>
示例:<b>http://m.xdingdiann.com/ddk{bookId}/all.html</b> (bookId代表小说ID)
<li><input type="text" id="bookIndexUrl" class="s_input icon_key"
placeholder="小说目录页的URL规则"></li>
<b>可空,适用于最新章节列表和全部章节列表在同一个页面的源站</b>
<li><input type="text" id="bookIndexStart" class="s_input icon_key"
placeholder="小说目录页内容开始截取字符串"></li>
示例:<b>&lt;a\s+style=""\s+href="/ddk\d+/(\d+)\.html"&gt;[^/]+&lt;/a&gt;</b>
<li><input type="text" id="indexIdPatten" class="s_input icon_key"
placeholder="目录页目录ID正则表达式"></li>
示例:<b>&lt;a\s+style=""\s+href="/ddk\d+/\d+\.html"&gt;([^/]+)&lt;/a&gt;</b>
<li><input type="text" id="indexNamePatten" class="s_input icon_key"
placeholder="目录页目录名的正则表达式"></li>
示例:<b>http://m.xdingdiann.com/ddk{bookId}/{indexId}.html</b>
(bookId代表小说ID,{indexId}代表目录ID)
<li><input type="text" id="bookContentUrl" class="s_input icon_key"
placeholder="小说内容页的URL规则"></li>
示例:<b>id="content"></b>
<li><input type="text" id="contentStart" class="s_input icon_key"
placeholder="小说内容开始截取字符串"></li>
示例:<b>&lt;script&gt;</b>
<li><input type="text" id="contentEnd" class="s_input icon_key"
placeholder="小说内容结束截取字符串"></li>
<li><input type="button" onclick="updateCrawlSource()" name="btnRegister" value="提交"
id="btnRegister" class="btn_red"></li>
</ul>
</div>
</form>
</div>
<!--<div id="divData" class="updateTable">
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th class="name">
爬虫源(已开启的爬虫源)
</th>
<th class="chapter">
成功爬取数量websocket实现
</th>
<th class="time">
目标爬取数量
</th>
<th class="goread">
状态(正在运行,已停止)(一次只能运行一个爬虫源)
</th>
<th class="goread">
操作(启动,停止)
</th>
</tr>
</thead>
<tbody id="bookShelfList">
</tbody>
</table>
<div class="pageBox cf" id="shellPage">
</div>
</div>-->
</div>
</div>
</div>
</div>
</body>
<script src="/javascript/jquery-1.8.0.min.js" type="text/javascript"></script>
<script src="/layui/layui.all.js" type="text/javascript"></script>
<script src="/javascript/header.js" type="text/javascript"></script>
<script src="/javascript/user.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function load(){
var crawlSourceId = localStorage.getItem("crawlSourceId")
if(crawlSourceId!=null){
$.ajax({
type: "GET",
url: "/crawl/getCrawlSource/"+crawlSourceId,
dataType: "json",
success: function (data) {
if (data.code == 200) {
loadPage(data.data);
} else if (data.code == 1001) {
//未登录
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
}else {
layer.alert(data.msg);
}
},
error: function () {
layer.alert('网络异常');
}
})
}
}
function loadPage(data){
$("#sourceId").val(data.id);
$("#sourceName").val(data.sourceName);
if(data.crawlRule){
var crawlRule= JSON.parse(data.crawlRule);
$("#bookListUrl").val(crawlRule.bookListUrl);
var catIdRule = crawlRule.catIdRule;
try{
for (var i = 1; i <= 7; i++) {
$("#catId" + i).val(catIdRule["catId" + i]);
}
}catch(e){
}
$("#bookIdPatten").val(crawlRule.bookIdPatten);
$("#pagePatten").val(crawlRule.pagePatten);
$("#totalPagePatten").val(crawlRule.totalPagePatten);
$("#bookDetailUrl").val(crawlRule.bookDetailUrl);
$("#bookNamePatten").val(crawlRule.bookNamePatten);
$("#authorNamePatten").val(crawlRule.authorNamePatten);
$("#picUrlPatten").val(crawlRule.picUrlPatten);
$("#picUrlPrefix").val(crawlRule.picUrlPrefix);
$("#statusPatten").val(crawlRule.statusPatten);
try{
var bookStatusRule = crawlRule.bookStatusRule;
var i=0;
for(var key in bookStatusRule){
$("#bookStatus" + i).val(key);
i++;
}
}catch (e) {
}
$("#scorePatten").val(crawlRule.scorePatten);
$("#visitCountPatten").val(crawlRule.visitCountPatten);
$("#descStart").val(crawlRule.descStart);
$("#descEnd").val(crawlRule.descEnd);
$("#upadateTimePatten").val(crawlRule.upadateTimePatten);
$("#upadateTimeFormatPatten").val(crawlRule.upadateTimeFormatPatten);
$("#bookIndexUrl").val(crawlRule.bookIndexUrl);
$("#bookIndexStart").val(crawlRule.bookIndexStart);
$("#indexIdPatten").val(crawlRule.indexIdPatten);
$("#indexNamePatten").val(crawlRule.indexNamePatten);
$("#bookContentUrl").val(crawlRule.bookContentUrl);
$("#contentStart").val(crawlRule.contentStart);
$("#contentEnd").val(crawlRule.contentEnd);
}
}
load();
function updateCrawlSource() {
var crawlRule = {};
var sourceId =$("#sourceId").val();
var sourceName = $("#sourceName").val();
if (sourceName.length == 0) {
layer.alert("源站名必填");
return false;
}
var bookListUrl = $("#bookListUrl").val();
if (bookListUrl.length == 0) {
layer.alert("分类列表页URL规则必填");
return false;
}
crawlRule.bookListUrl = bookListUrl;
var catIdRule = {};
for (var i = 1; i <= 7; i++) {
var catId = $("#catId" + i).val();
if (catId.length > 0) {
catIdRule["catId" + i] = catId;
}
}
if (Object.keys(catIdRule).length == 0) {
layer.alert("分类ID至少要填一项");
return false;
}
crawlRule.catIdRule = catIdRule;
var bookIdPatten = $("#bookIdPatten").val();
if (bookIdPatten.length == 0) {
layer.alert("列表页小说ID正则表达式必填");
return false;
}
crawlRule.bookIdPatten = bookIdPatten;
var pagePatten = $("#pagePatten").val();
if (pagePatten.length > 0) {
crawlRule.pagePatten = pagePatten;
}
var totalPagePatten = $("#totalPagePatten").val();
if (totalPagePatten.length > 0) {
crawlRule.totalPagePatten = totalPagePatten;
}
var bookDetailUrl = $("#bookDetailUrl").val();
if (bookDetailUrl.length == 0) {
layer.alert("详情页URL规则必填");
return false;
}
crawlRule.bookDetailUrl = bookDetailUrl;
var bookNamePatten = $("#bookNamePatten").val();
if (bookNamePatten.length == 0) {
layer.alert("小说名的正则表达式必填");
return false;
}
crawlRule.bookNamePatten = bookNamePatten;
var authorNamePatten = $("#authorNamePatten").val();
if (authorNamePatten.length == 0) {
layer.alert("小说作者的正则表达式必填");
return false;
}
crawlRule.authorNamePatten = authorNamePatten;
var picUrlPatten = $("#picUrlPatten").val();
if (picUrlPatten.length > 0) {
crawlRule.picUrlPatten = picUrlPatten;
}
var picUrlPrefix = $("#picUrlPrefix").val();
if (picUrlPrefix.length > 0) {
crawlRule.picUrlPrefix = picUrlPrefix;
}
var statusPatten = $("#statusPatten").val();
if (statusPatten.length > 0) {
crawlRule.statusPatten = statusPatten;
}
var bookStatusRule = {};
for (var i = 0; i <= 1; i++) {
var bookStatus = $("#bookStatus" + i).val();
if (bookStatus.length > 0) {
bookStatusRule[bookStatus] = i;
}
}
crawlRule.bookStatusRule = bookStatusRule;
var scorePatten = $("#scorePatten").val();
if (scorePatten.length > 0) {
crawlRule.scorePatten = scorePatten;
}
var visitCountPatten = $("#visitCountPatten").val();
if (visitCountPatten.length > 0) {
crawlRule.visitCountPatten = visitCountPatten;
}
var descStart = $("#descStart").val();
if (descStart.length == 0) {
layer.alert("小说简介开始截取字符串必填");
return false;
}
crawlRule.descStart = descStart;
var descEnd = $("#descEnd").val();
if (descEnd.length == 0) {
layer.alert("小说简介结束截取字符串必填");
return false;
}
crawlRule.descEnd = descEnd;
var upadateTimePatten = $("#upadateTimePatten").val();
if (upadateTimePatten.length > 0) {
crawlRule.upadateTimePatten = upadateTimePatten;
}
var upadateTimeFormatPatten = $("#upadateTimeFormatPatten").val();
if (upadateTimeFormatPatten.length > 0) {
crawlRule.upadateTimeFormatPatten = upadateTimeFormatPatten;
}
var bookIndexUrl = $("#bookIndexUrl").val();
if (bookIndexUrl.length == 0) {
layer.alert("小说目录页的URL规则必填");
return false;
}
crawlRule.bookIndexUrl = bookIndexUrl;
var bookIndexStart = $("#bookIndexStart").val();
if (bookIndexStart.length > 0) {
crawlRule.bookIndexStart = bookIndexStart;
}
var indexIdPatten = $("#indexIdPatten").val();
if (indexIdPatten.length == 0) {
layer.alert("小说目录页的目录ID正则表达式必填");
return false;
}
crawlRule.indexIdPatten = indexIdPatten;
var indexNamePatten = $("#indexNamePatten").val();
if (indexNamePatten.length == 0) {
layer.alert("小说目录页的目录名正则表达式必填");
return false;
}
crawlRule.indexNamePatten = indexNamePatten;
var bookContentUrl = $("#bookContentUrl").val();
if (bookContentUrl.length == 0) {
layer.alert("小说内容页的URL规则必填");
return false;
}
crawlRule.bookContentUrl = bookContentUrl;
var contentStart = $("#contentStart").val();
if (contentStart.length == 0) {
layer.alert("小说内容开始截取字符串必填");
return false;
}
crawlRule.contentStart = contentStart;
var contentEnd = $("#contentEnd").val();
if (contentEnd.length == 0) {
layer.alert("小说内容结束截取字符串必填");
return false;
}
crawlRule.contentEnd = contentEnd;
$.ajax({
type: "POST",
url: "/crawl/updateCrawlSource",
data: {'id':sourceId,'sourceName': sourceName, 'crawlRule': JSON.stringify(crawlRule)},
dataType: "json",
success: function (data) {
if (data.code == 200) {
window.location.href = '/crawl/crawlSource_list.html';
} else {
layer.alert(data.msg);
}
},
error: function () {
layer.alert('网络异常');
}
})
}
</script>
</html>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>novel</artifactId>
<groupId>com.java2nb</groupId>
<version>3.6.1</version>
<version>3.5.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -97,29 +97,6 @@
<!-- </build>-->
<build>
<plugins>
<!-- 将相同groupId的依赖模块打包进来 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>${project.groupId}:*:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<!--打包时去除第三方依赖-->
<groupId>org.springframework.boot</groupId>
@ -151,7 +128,6 @@
<excludeTransitive>false</excludeTransitive>
<stripVersion>false</stripVersion>
<includeScope>runtime</includeScope>
<excludeGroupIds>${project.groupId}</excludeGroupIds>
</configuration>
</execution>
</executions>

View File

@ -1,6 +1,7 @@
package com.java2nb.novel;
import com.github.tobato.fastdfs.FdfsClientConfig;
import io.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -1,11 +1,10 @@
package com.java2nb.novel.controller;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.enums.ResponseStatus;
import io.github.xxyopen.model.resp.RestResult;
import io.github.xxyopen.web.exception.BusinessException;
import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.entity.Author;
import com.java2nb.novel.entity.AuthorIncome;
import com.java2nb.novel.entity.AuthorIncomeDetail;
@ -36,25 +35,25 @@ public class AuthorController extends BaseController{
* 校验笔名是否存在
* */
@GetMapping("checkPenName")
public RestResult<Boolean> checkPenName(String penName){
public ResultBean<Boolean> checkPenName(String penName){
return RestResult.ok(authorService.checkPenName(penName));
return ResultBean.ok(authorService.checkPenName(penName));
}
/**
* 作家发布小说分页列表查询
* */
@GetMapping("listBookByPage")
public RestResult<PageBean<Book>> listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize , HttpServletRequest request){
public ResultBean<PageBean<Book>> listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize , HttpServletRequest request){
return RestResult.ok(bookService.listBookPageByUserId(getUserDetails(request).getId(),page,pageSize));
return ResultBean.ok(bookService.listBookPageByUserId(getUserDetails(request).getId(),page,pageSize));
}
/**
* 发布小说
* */
@PostMapping("addBook")
public RestResult<Void> addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){
public ResultBean<Void> addBook(@RequestParam("bookDesc") String bookDesc,Book book,HttpServletRequest request){
Author author = checkAuthor(request);
@ -65,20 +64,20 @@ public class AuthorController extends BaseController{
//发布小说
bookService.addBook(book,author.getId(),author.getPenName());
return RestResult.ok();
return ResultBean.ok();
}
/**
* 更新小说状态,上架或下架
* */
@PostMapping("updateBookStatus")
public RestResult<Void> updateBookStatus(Long bookId,Byte status,HttpServletRequest request){
public ResultBean<Void> updateBookStatus(Long bookId,Byte status,HttpServletRequest request){
Author author = checkAuthor(request);
//更新小说状态,上架或下架
bookService.updateBookStatus(bookId,status,author.getId());
return RestResult.ok();
return ResultBean.ok();
}
@ -87,28 +86,28 @@ public class AuthorController extends BaseController{
* 删除章节
*/
@DeleteMapping("deleteIndex/{indexId}")
public RestResult<Void> deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
public ResultBean<Void> deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
Author author = checkAuthor(request);
//删除章节
bookService.deleteIndex(indexId, author.getId());
return RestResult.ok();
return ResultBean.ok();
}
/**
* 更新章节名
*/
@PostMapping("updateIndexName")
public RestResult<Void> updateIndexName(Long indexId, String indexName, HttpServletRequest request) {
public ResultBean<Void> updateIndexName(Long indexId, String indexName, HttpServletRequest request) {
Author author = checkAuthor(request);
//更新章节名
bookService.updateIndexName(indexId, indexName, author.getId());
return RestResult.ok();
return ResultBean.ok();
}
@ -118,7 +117,7 @@ public class AuthorController extends BaseController{
* 发布章节内容
*/
@PostMapping("addBookContent")
public RestResult<Void> addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) {
public ResultBean<Void> addBookContent(Long bookId, String indexName, String content,Byte isVip, HttpServletRequest request) {
Author author = checkAuthor(request);
content = content.replaceAll("\\n", "<br>")
@ -126,14 +125,14 @@ public class AuthorController extends BaseController{
//发布章节内容
bookService.addBookContent(bookId, indexName, content,isVip, author.getId());
return RestResult.ok();
return ResultBean.ok();
}
/**
* 查询章节内容
*/
@GetMapping("queryIndexContent/{indexId}")
public RestResult<String> queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
public ResultBean<String> queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
Author author = checkAuthor(request);
@ -142,14 +141,14 @@ public class AuthorController extends BaseController{
content = content.replaceAll("<br>", "\n")
.replaceAll("&nbsp;", " ");
return RestResult.ok(content);
return ResultBean.ok(content);
}
/**
* 更新章节内容
*/
@PostMapping("updateBookContent")
public RestResult<Void> updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) {
public ResultBean<Void> updateBookContent(Long indexId, String indexName, String content, HttpServletRequest request) {
Author author = checkAuthor(request);
content = content.replaceAll("\\n", "<br>")
@ -157,17 +156,17 @@ public class AuthorController extends BaseController{
//更新章节内容
bookService.updateBookContent(indexId, indexName, content, author.getId());
return RestResult.ok();
return ResultBean.ok();
}
/**
* 修改小说封面
*/
@PostMapping("updateBookPic")
public RestResult<Void> updateBookPic(@RequestParam("bookId") Long bookId,@RequestParam("bookPic") String bookPic,HttpServletRequest request) {
public ResultBean<Void> updateBookPic(@RequestParam("bookId") Long bookId,@RequestParam("bookPic") String bookPic,HttpServletRequest request) {
Author author = checkAuthor(request);
bookService.updateBookPic(bookId,bookPic, author.getId());
return RestResult.ok();
return ResultBean.ok();
}
@ -175,14 +174,14 @@ public class AuthorController extends BaseController{
* 作家日收入统计数据分页列表查询
* */
@GetMapping("listIncomeDailyByPage")
public RestResult<PageBean<AuthorIncomeDetail>> listIncomeDailyByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
public ResultBean<PageBean<AuthorIncomeDetail>> listIncomeDailyByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
@RequestParam(value = "limit", defaultValue = "10") int pageSize ,
@RequestParam(value = "bookId", defaultValue = "0") Long bookId,
@RequestParam(value = "startTime",defaultValue = "2020-05-01") Date startTime,
@RequestParam(value = "endTime",defaultValue = "2030-01-01") Date endTime,
HttpServletRequest request){
return RestResult.ok(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime));
return ResultBean.ok(authorService.listIncomeDailyByPage(page,pageSize,getUserDetails(request).getId(),bookId,startTime,endTime));
}
@ -190,12 +189,12 @@ public class AuthorController extends BaseController{
* 作家月收入统计数据分页列表查询
* */
@GetMapping("listIncomeMonthByPage")
public RestResult<PageBean<AuthorIncome>> listIncomeMonthByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
public ResultBean<PageBean<AuthorIncome>> listIncomeMonthByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
@RequestParam(value = "limit", defaultValue = "10") int pageSize ,
@RequestParam(value = "bookId", defaultValue = "0") Long bookId,
HttpServletRequest request){
return RestResult.ok(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId));
return ResultBean.ok(authorService.listIncomeMonthByPage(page,pageSize,getUserDetails(request).getId(),bookId));
}
private Author checkAuthor(HttpServletRequest request) {

View File

@ -1,20 +1,19 @@
package com.java2nb.novel.controller;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean;
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.BookCategory;
import com.java2nb.novel.entity.BookComment;
import com.java2nb.novel.entity.BookIndex;
import com.java2nb.novel.service.BookContentService;
import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO;
import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.service.BookService;
import com.java2nb.novel.vo.BookVO;
import io.github.xxyopen.model.page.PageBean;
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
import io.github.xxyopen.model.resp.RestResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
@ -33,157 +32,158 @@ import java.util.Map;
@RestController
@Slf4j
@RequiredArgsConstructor
public class BookController extends BaseController {
public class BookController extends BaseController{
private final BookService bookService;
private final RabbitTemplate rabbitTemplate;
private final Map<String, BookContentService> bookContentServiceMap;
@Value("${spring.rabbitmq.enable}")
private Integer enableMq;
/**
* 查询首页小说设置列表数据
*/
* */
@GetMapping("listBookSetting")
public RestResult<Map<Byte, List<BookSettingVO>>> listBookSetting() {
return RestResult.ok(bookService.listBookSettingVO());
public ResultBean<Map<Byte, List<BookSettingVO>>> listBookSetting(){
return ResultBean.ok(bookService.listBookSettingVO());
}
/**
* 查询首页点击榜单数据
*/
* */
@GetMapping("listClickRank")
public RestResult<List<Book>> listClickRank() {
return RestResult.ok(bookService.listClickRank());
public ResultBean<List<Book>> listClickRank(){
return ResultBean.ok(bookService.listClickRank());
}
/**
* 查询首页新书榜单数据
*/
* */
@GetMapping("listNewRank")
public RestResult<List<Book>> listNewRank() {
return RestResult.ok(bookService.listNewRank());
public ResultBean<List<Book>> listNewRank(){
return ResultBean.ok(bookService.listNewRank());
}
/**
* 查询首页更新榜单数据
*/
* */
@GetMapping("listUpdateRank")
public RestResult<List<BookVO>> listUpdateRank() {
return RestResult.ok(bookService.listUpdateRank());
public ResultBean<List<BookVO>> listUpdateRank(){
return ResultBean.ok(bookService.listUpdateRank());
}
/**
* 查询小说分类列表
*/
* */
@GetMapping("listBookCategory")
public RestResult<List<BookCategory>> listBookCategory() {
return RestResult.ok(bookService.listBookCategory());
public ResultBean<List<BookCategory>> listBookCategory(){
return ResultBean.ok(bookService.listBookCategory());
}
/**
* 分页搜索
*/
* */
@GetMapping("searchByPage")
public RestResult<?> searchByPage(BookSpVO bookSP, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "20") int pageSize) {
return RestResult.ok(bookService.searchByPage(bookSP, page, pageSize));
public ResultBean<?> searchByPage(BookSpVO bookSP, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "20") int pageSize){
return ResultBean.ok(bookService.searchByPage(bookSP,page,pageSize));
}
/**
* 查询小说详情信息
*/
* */
@GetMapping("queryBookDetail/{id}")
public RestResult<Book> queryBookDetail(@PathVariable("id") Long id) {
return RestResult.ok(bookService.queryBookDetail(id));
public ResultBean<Book> queryBookDetail(@PathVariable("id") Long id){
return ResultBean.ok(bookService.queryBookDetail(id));
}
/**
* 查询小说排行信息
*/
* */
@GetMapping("listRank")
public RestResult<List<Book>> listRank(@RequestParam(value = "type", defaultValue = "0") Byte type, @RequestParam(value = "limit", defaultValue = "30") Integer limit) {
return RestResult.ok(bookService.listRank(type, limit));
public ResultBean<List<Book>> 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 RestResult<Void> addVisitCount(Long bookId) {
if (enableMq == 1) {
public ResultBean<Void> addVisitCount(Long bookId){
if(enableMq == 1) {
rabbitTemplate.convertAndSend("ADD-BOOK-VISIT-EXCHANGE", null, bookId);
} else {
}else {
bookService.addVisitCount(bookId, 1);
}
return RestResult.ok();
return ResultBean.ok();
}
/**
* 查询章节相关信息
*/
* */
@GetMapping("queryBookIndexAbout")
public RestResult<Map<String, Object>> queryBookIndexAbout(Long bookId, Long lastBookIndexId) {
Map<String, Object> data = new HashMap<>(2);
data.put("bookIndexCount", bookService.queryIndexCount(bookId));
BookIndex bookIndex = bookService.queryBookIndex(lastBookIndexId);
String lastBookContent = bookContentServiceMap.get(bookIndex.getStorageType()).queryBookContent(bookId,lastBookIndexId).getContent();
if (lastBookContent.length() > 42) {
lastBookContent = lastBookContent.substring(0, 42);
public ResultBean<Map<String,Object>> queryBookIndexAbout(Long bookId,Long lastBookIndexId) {
Map<String,Object> data = new HashMap<>(2);
data.put("bookIndexCount",bookService.queryIndexCount(bookId));
String lastBookContent = bookService.queryBookContent(lastBookIndexId).getContent();
if(lastBookContent.length()>42){
lastBookContent=lastBookContent.substring(0,42);
}
data.put("lastBookContent", lastBookContent);
return RestResult.ok(data);
data.put("lastBookContent",lastBookContent);
return ResultBean.ok(data);
}
/**
* 根据分类id查询同类推荐书籍
*/
* */
@GetMapping("listRecBookByCatId")
public RestResult<List<Book>> listRecBookByCatId(Integer catId) {
return RestResult.ok(bookService.listRecBookByCatId(catId));
public ResultBean<List<Book>> listRecBookByCatId(Integer catId) {
return ResultBean.ok(bookService.listRecBookByCatId(catId));
}
/**
* 分页查询书籍评论列表
*/
*分页查询书籍评论列表
* */
@GetMapping("listCommentByPage")
public RestResult<PageBean<BookCommentVO>> listCommentByPage(@RequestParam("bookId") Long bookId, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize) {
return RestResult.ok(bookService.listCommentByPage(null, bookId, page, pageSize));
public ResultBean<PageBean<BookCommentVO>> listCommentByPage(@RequestParam("bookId") Long bookId, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize) {
return ResultBean.ok(bookService.listCommentByPage(null,bookId,page,pageSize));
}
/**
* 新增评价
*/
* */
@PostMapping("addBookComment")
public RestResult<?> addBookComment(BookComment comment, HttpServletRequest request) {
public ResultBean<?> addBookComment(BookComment comment, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
bookService.addBookComment(userDetails.getId(), comment);
return RestResult.ok();
bookService.addBookComment(userDetails.getId(),comment);
return ResultBean.ok();
}
/**
* 根据小说ID查询小说前十条最新更新目录集合
*/
* */
@GetMapping("queryNewIndexList")
public RestResult<List<BookIndex>> queryNewIndexList(Long bookId) {
return RestResult.ok(bookService.queryIndexList(bookId, "index_num desc", 1, 10));
public ResultBean<List<BookIndex>> queryNewIndexList(Long bookId){
return ResultBean.ok(bookService.queryIndexList(bookId,"index_num desc",1,10));
}
/**
* 目录页
*/
* */
@GetMapping("/queryIndexList")
public RestResult<PageBean<BookIndex>> indexList(Long bookId, @RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, @RequestParam(value = "orderBy", defaultValue = "index_num desc") String orderBy) {
return RestResult.ok(PageBuilder.build(bookService.queryIndexList(bookId, orderBy, page, pageSize)));
public ResultBean<PageBean<BookIndex>> indexList(Long bookId,@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,@RequestParam(value = "orderBy",defaultValue = "index_num desc") String orderBy) {
return ResultBean.ok(new PageBean<>(bookService.queryIndexList(bookId,orderBy,page,pageSize)));
}
}

View File

@ -1,13 +1,12 @@
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 io.github.xxyopen.model.resp.RestResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@ -41,9 +40,9 @@ public class CacheController {
* @param type 缓存类型1首页书籍推荐2首页新闻3首页友情链接
* */
@GetMapping("refresh/{pass}/{type}")
public RestResult<Void> refreshCache(@PathVariable("type") Byte type, @PathVariable("pass") String pass){
public ResultBean<Void> refreshCache(@PathVariable("type") Byte type, @PathVariable("pass") String pass){
if(!cacheManagerPass.equals(pass)){
return RestResult.fail(ResponseStatus.PASSWORD_ERROR);
return ResultBean.fail(ResponseStatus.PASSWORD_ERROR);
}
switch (type){
case 1:{
@ -70,7 +69,7 @@ public class CacheController {
}
return RestResult.ok();
return ResultBean.ok();
}

View File

@ -1,14 +1,13 @@
package com.java2nb.novel.controller;
import com.java2nb.novel.core.bean.ResultBean;
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.Constants;
import com.java2nb.novel.core.utils.FileUtil;
import com.java2nb.novel.core.utils.RandomValidateCodeUtil;
import io.github.xxyopen.model.resp.RestResult;
import io.github.xxyopen.util.UUIDUtil;
import io.github.xxyopen.web.exception.BusinessException;
import com.java2nb.novel.core.utils.UUIDUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ -20,8 +19,9 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.*;
import java.util.Date;
import java.util.Objects;
/**
* @author 11797
@ -64,7 +64,7 @@ public class FileController {
@SneakyThrows
@ResponseBody
@PostMapping("/picUpload")
RestResult<String> upload(@RequestParam("file") MultipartFile file) {
ResultBean<String> upload(@RequestParam("file") MultipartFile file) {
Date currentDate = new Date();
String savePath =
Constants.LOCAL_PIC_PREFIX + DateUtils.formatDate(currentDate, "yyyy") + "/" +
@ -86,7 +86,7 @@ public class FileController {
saveFile.delete();
throw new BusinessException(ResponseStatus.FILE_NOT_IMAGE);
};
return RestResult.ok(savePath + "/" + saveFileName);
return ResultBean.ok(savePath + "/" + saveFileName);
}

View File

@ -1,12 +1,12 @@
package com.java2nb.novel.controller;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.entity.FriendLink;
import com.java2nb.novel.service.FriendLinkService;
import io.github.xxyopen.model.resp.RestResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -27,8 +27,8 @@ public class FriendLinkController {
* 查询首页友情链接
* */
@GetMapping("listIndexLink")
public RestResult<List<FriendLink>> listIndexLink(){
return RestResult.ok(friendLinkService.listIndexLink());
public ResultBean<List<FriendLink>> listIndexLink(){
return ResultBean.ok(friendLinkService.listIndexLink());
}

View File

@ -1,10 +1,10 @@
package com.java2nb.novel.controller;
import com.github.pagehelper.PageInfo;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.ResultBean;
import com.java2nb.novel.entity.News;
import com.java2nb.novel.service.NewsService;
import io.github.xxyopen.model.resp.RestResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@ -26,25 +26,25 @@ public class NewsController {
* 查询首页新闻
* */
@GetMapping("listIndexNews")
public RestResult<List<News>> listIndexNews(){
return RestResult.ok(newsService.listIndexNews());
public ResultBean<List<News>> listIndexNews(){
return ResultBean.ok(newsService.listIndexNews());
}
/**
* 分页查询新闻列表
* */
@GetMapping("listByPage")
public RestResult<PageBean<News>> listByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize){
return RestResult.ok(newsService.listByPage(page,pageSize));
public ResultBean<PageBean<News>> listByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize){
return ResultBean.ok(newsService.listByPage(page,pageSize));
}
/**
* 增加新闻阅读量
* */
@PostMapping("addReadCount")
public RestResult<Void> addReadCount(@RequestParam(value = "newsId") Integer newsId){
public ResultBean<Void> addReadCount(@RequestParam(value = "newsId") Integer newsId){
newsService.addReadCount(newsId);
return RestResult.ok();
return ResultBean.ok();
}

View File

@ -1,17 +1,16 @@
package com.java2nb.novel.controller;
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.core.valid.AddGroup;
import com.java2nb.novel.core.valid.UpdateGroup;
import com.java2nb.novel.entity.User;
import com.java2nb.novel.entity.UserBuyRecord;
import com.java2nb.novel.service.BookService;
import com.java2nb.novel.service.UserService;
import io.github.xxyopen.model.resp.RestResult;
import io.github.xxyopen.web.valid.AddGroup;
import io.github.xxyopen.web.valid.UpdateGroup;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -42,7 +41,7 @@ public class UserController extends BaseController {
* 登陆
*/
@PostMapping("login")
public RestResult<Map<String, Object>> login(User user) {
public ResultBean<Map<String, Object>> login(User user) {
//登陆
UserDetails userDetails = userService.login(user);
@ -50,7 +49,7 @@ public class UserController extends BaseController {
Map<String, Object> data = new HashMap<>(1);
data.put("token", jwtTokenUtil.generateToken(userDetails));
return RestResult.ok(data);
return ResultBean.ok(data);
}
@ -59,12 +58,12 @@ public class UserController extends BaseController {
* 注册
*/
@PostMapping("register")
public RestResult<?> register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) {
public ResultBean<?> register(@Validated({AddGroup.class}) User user, @RequestParam(value = "velCode", defaultValue = "") String velCode) {
//判断验证码是否正确
if (!velCode.equals(cacheService.get(RandomValidateCodeUtil.RANDOM_CODE_KEY))) {
return RestResult.fail(ResponseStatus.VEL_CODE_ERROR);
return ResultBean.fail(ResponseStatus.VEL_CODE_ERROR);
}
//注册
@ -72,7 +71,7 @@ public class UserController extends BaseController {
Map<String, Object> data = new HashMap<>(1);
data.put("token", jwtTokenUtil.generateToken(userDetails));
return RestResult.ok(data);
return ResultBean.ok(data);
}
@ -82,7 +81,7 @@ public class UserController extends BaseController {
* 刷新token
*/
@PostMapping("refreshToken")
public RestResult<?> refreshToken(HttpServletRequest request) {
public ResultBean<?> refreshToken(HttpServletRequest request) {
String token = getToken(request);
if (jwtTokenUtil.canRefresh(token)) {
token = jwtTokenUtil.refreshToken(token);
@ -91,10 +90,10 @@ public class UserController extends BaseController {
UserDetails userDetail = jwtTokenUtil.getUserDetailsFromToken(token);
data.put("username", userDetail.getUsername());
data.put("nickName", userDetail.getNickName());
return RestResult.ok(data);
return ResultBean.ok(data);
} else {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
}
@ -103,131 +102,131 @@ public class UserController extends BaseController {
* 查询小说是否已加入书架
*/
@GetMapping("queryIsInShelf")
public RestResult<?> queryIsInShelf(Long bookId, HttpServletRequest request) {
public ResultBean<?> queryIsInShelf(Long bookId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return RestResult.ok(userService.queryIsInShelf(userDetails.getId(), bookId));
return ResultBean.ok(userService.queryIsInShelf(userDetails.getId(), bookId));
}
/**
* 加入书架
* */
@PostMapping("addToBookShelf")
public RestResult<Void> addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
public ResultBean<Void> addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
userService.addToBookShelf(userDetails.getId(),bookId,preContentId);
return RestResult.ok();
return ResultBean.ok();
}
/**
* 移出书架
* */
@DeleteMapping("removeFromBookShelf/{bookId}")
public RestResult<?> removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) {
public ResultBean<?> removeFromBookShelf(@PathVariable("bookId") Long bookId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
userService.removeFromBookShelf(userDetails.getId(),bookId);
return RestResult.ok();
return ResultBean.ok();
}
/**
* 分页查询书架
* */
@GetMapping("listBookShelfByPage")
public RestResult<?> listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
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 RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return RestResult.ok(userService.listBookShelfByPage(userDetails.getId(),page,pageSize));
return ResultBean.ok(userService.listBookShelfByPage(userDetails.getId(),page,pageSize));
}
/**
* 分页查询阅读记录
* */
@GetMapping("listReadHistoryByPage")
public RestResult<?> listReadHistoryByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize,HttpServletRequest request) {
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 RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return RestResult.ok(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize));
return ResultBean.ok(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize));
}
/**
* 添加阅读记录
* */
@PostMapping("addReadHistory")
public RestResult<?> addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
public ResultBean<?> addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
userService.addReadHistory(userDetails.getId(),bookId,preContentId);
return RestResult.ok();
return ResultBean.ok();
}
/**
* 添加反馈
* */
@PostMapping("addFeedBack")
public RestResult<?> addFeedBack(String content, HttpServletRequest request) {
public ResultBean<?> addFeedBack(String content, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
userService.addFeedBack(userDetails.getId(),content);
return RestResult.ok();
return ResultBean.ok();
}
/**
* 分页查询我的反馈列表
* */
@GetMapping("listUserFeedBackByPage")
public RestResult<?> listUserFeedBackByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize, HttpServletRequest request){
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 RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return RestResult.ok(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize));
return ResultBean.ok(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize));
}
/**
* 查询个人信息
* */
@GetMapping("userInfo")
public RestResult<?> userInfo(HttpServletRequest request) {
public ResultBean<?> userInfo(HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return RestResult.ok(userService.userInfo(userDetails.getId()));
return ResultBean.ok(userService.userInfo(userDetails.getId()));
}
/**
* 更新个人信息
* */
@PostMapping("updateUserInfo")
public RestResult<?> updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) {
public ResultBean<?> updateUserInfo(@Validated({UpdateGroup.class}) User user, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
userService.updateUserInfo(userDetails.getId(),user);
if(user.getNickName() != null){
userDetails.setNickName(user.getNickName());
Map<String, Object> data = new HashMap<>(1);
data.put("token", jwtTokenUtil.generateToken(userDetails));
return RestResult.ok(data);
return ResultBean.ok(data);
}
return RestResult.ok();
return ResultBean.ok();
}
@ -235,28 +234,28 @@ public class UserController extends BaseController {
* 更新密码
* */
@PostMapping("updatePassword")
public RestResult<?> updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
public ResultBean<?> updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
if(!(StringUtils.isNotBlank(newPassword1) && newPassword1.equals(newPassword2))){
RestResult.fail(ResponseStatus.TWO_PASSWORD_DIFF);
ResultBean.fail(ResponseStatus.TWO_PASSWORD_DIFF);
}
userService.updatePassword(userDetails.getId(),oldPassword,newPassword1);
return RestResult.ok();
return ResultBean.ok();
}
/**
* 分页查询用户书评
* */
@GetMapping("listCommentByPage")
public RestResult<?> listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) {
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 RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
return RestResult.ok(bookService.listCommentByPage(userDetails.getId(),null,page,pageSize));
return ResultBean.ok(bookService.listCommentByPage(userDetails.getId(),null,page,pageSize));
}
@ -264,14 +263,14 @@ public class UserController extends BaseController {
* 购买小说章节
* */
@PostMapping("buyBookIndex")
public RestResult<?> buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) {
public ResultBean<?> buyBookIndex(UserBuyRecord buyRecord, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(request);
if (userDetails == null) {
return RestResult.fail(ResponseStatus.NO_LOGIN);
return ResultBean.fail(ResponseStatus.NO_LOGIN);
}
buyRecord.setBuyAmount(bookService.queryBookIndex(buyRecord.getBookIndexId()).getBookPrice());
userService.buyBookIndex(userDetails.getId(),buyRecord);
return RestResult.ok();
return ResultBean.ok();
}

View File

@ -3,8 +3,6 @@ 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.*;
import io.github.xxyopen.util.UUIDUtil;
import io.github.xxyopen.web.util.SpringUtil;
import javax.servlet.*;
import javax.servlet.http.Cookie;

View File

@ -2,7 +2,6 @@ package com.java2nb.novel.core.utils;
import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService;
import io.github.xxyopen.web.util.SpringUtil;
/**
* 模板操作工具类

View File

@ -1,18 +1,20 @@
package com.java2nb.novel.page;
import com.java2nb.novel.controller.BaseController;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.utils.ThreadLocalUtil;
import com.java2nb.novel.entity.*;
import com.java2nb.novel.service.*;
import com.java2nb.novel.service.AuthorService;
import com.java2nb.novel.service.BookService;
import com.java2nb.novel.service.NewsService;
import com.java2nb.novel.service.UserService;
import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO;
import io.github.xxyopen.model.page.PageBean;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
@ -34,9 +36,6 @@ import java.util.concurrent.ThreadPoolExecutor;
@Controller
public class PageController extends BaseController {
@Value("${content.save.path}")
private String fileSavePath;
private final BookService bookService;
private final NewsService newsService;
@ -47,7 +46,6 @@ public class PageController extends BaseController {
private final ThreadPoolExecutor threadPoolExecutor;
private final Map<String, BookContentService> bookContentServiceMap;
@RequestMapping("{url}.html")
public String module(@PathVariable("url") String url) {
@ -176,7 +174,7 @@ public class PageController extends BaseController {
*/
@SneakyThrows
@RequestMapping("/book/{bookId}/{bookIndexId}.html")
public String bookContent(@PathVariable("bookId") Long bookId, @PathVariable("bookIndexId") Long bookIndexId, HttpServletRequest request, Model model) {
public String indexList(@PathVariable("bookId") Long bookId, @PathVariable("bookIndexId") Long bookIndexId, HttpServletRequest request, Model model) {
//加载小说基本信息线程
CompletableFuture<Book> bookCompletableFuture = CompletableFuture.supplyAsync(() -> {
//查询书籍
@ -209,10 +207,10 @@ public class PageController extends BaseController {
return nextBookIndexId;
}, threadPoolExecutor);
//加载小说内容信息线程,该线程在加载小说章节信息线程执行完毕后才执行
CompletableFuture<BookContent> bookContentCompletableFuture = bookIndexCompletableFuture.thenApplyAsync((bookIndex) -> {
//加载小说内容信息线程
CompletableFuture<BookContent> bookContentCompletableFuture = CompletableFuture.supplyAsync(() -> {
//查询内容
BookContent bookContent = bookContentServiceMap.get(bookIndex.getStorageType()).queryBookContent(bookId, bookIndexId);
BookContent bookContent = bookService.queryBookContent(bookIndexId);
log.debug("加载小说内容信息线程结束");
return bookContent;
}, threadPoolExecutor);

View File

@ -1,7 +1,7 @@
package com.java2nb.novel.service;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.entity.Author;
import com.java2nb.novel.entity.AuthorIncome;
import com.java2nb.novel.entity.AuthorIncomeDetail;

View File

@ -1,11 +0,0 @@
package com.java2nb.novel.service;
import com.java2nb.novel.entity.BookContent;
import java.util.List;
public interface BookContentService {
BookContent queryBookContent(Long bookId, Long bookIndexId);
}

View File

@ -1,7 +1,7 @@
package com.java2nb.novel.service;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.entity.*;
import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO;
@ -101,7 +101,6 @@ public interface BookService {
* @param bookIndexId 目录ID
* @return 书籍内容
* */
@Deprecated
BookContent queryBookContent(Long bookIndexId);
/**

View File

@ -1,7 +1,7 @@
package com.java2nb.novel.service;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.entity.News;
import com.java2nb.novel.vo.NewsVO;

View File

@ -1,8 +1,11 @@
package com.java2nb.novel.service;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.entity.Book;
import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.vo.BookVO;
import com.java2nb.novel.vo.EsBookVO;
/**
@ -23,5 +26,5 @@ public interface SearchService {
* @param pageSize 每页大小
* @return 分页信息
*/
io.github.xxyopen.model.page.PageBean<EsBookVO> searchBook(BookSpVO params, int page, int pageSize);
PageBean<EsBookVO> searchBook(BookSpVO params, int page, int pageSize);
}

View File

@ -1,7 +1,7 @@
package com.java2nb.novel.service;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.entity.UserBuyRecord;
import com.java2nb.novel.entity.UserFeedback;

View File

@ -1,12 +1,11 @@
package com.java2nb.novel.service.impl;
import com.github.pagehelper.PageHelper;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService;
import com.java2nb.novel.core.enums.ResponseStatus;
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
import io.github.xxyopen.web.exception.BusinessException;
import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.entity.Author;
import com.java2nb.novel.entity.AuthorIncome;
import com.java2nb.novel.entity.AuthorIncomeDetail;
@ -174,7 +173,7 @@ public class AuthorServiceImpl implements AuthorService {
@Override
public PageBean<AuthorIncomeDetail> listIncomeDailyByPage(int page, int pageSize, Long userId, Long bookId, Date startTime, Date endTime) {
PageHelper.startPage(page, pageSize);
return PageBuilder.build(authorIncomeDetailMapper.selectMany(
return new PageBean<>(authorIncomeDetailMapper.selectMany(
select(AuthorIncomeDetailDynamicSqlSupport.incomeDate, AuthorIncomeDetailDynamicSqlSupport.incomeAccount
, AuthorIncomeDetailDynamicSqlSupport.incomeCount, AuthorIncomeDetailDynamicSqlSupport.incomeNumber)
.from(AuthorIncomeDetailDynamicSqlSupport.authorIncomeDetail)
@ -191,7 +190,7 @@ public class AuthorServiceImpl implements AuthorService {
@Override
public PageBean<AuthorIncome> listIncomeMonthByPage(int page, int pageSize, Long userId, Long bookId) {
PageHelper.startPage(page, pageSize);
return PageBuilder.build(authorIncomeMapper.selectMany(select(AuthorIncomeDynamicSqlSupport.incomeMonth
return new PageBean<>(authorIncomeMapper.selectMany(select(AuthorIncomeDynamicSqlSupport.incomeMonth
, AuthorIncomeDynamicSqlSupport.preTaxIncome
, AuthorIncomeDynamicSqlSupport.afterTaxIncome
, AuthorIncomeDynamicSqlSupport.payStatus

View File

@ -2,12 +2,15 @@ package com.java2nb.novel.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService;
import com.java2nb.novel.core.config.BookPriceProperties;
import com.java2nb.novel.core.enums.ResponseStatus;
import io.github.xxyopen.web.util.BeanUtil;
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.IdWorker;
import com.java2nb.novel.core.utils.StringUtil;
import com.java2nb.novel.entity.Book;
import com.java2nb.novel.entity.*;
@ -20,10 +23,6 @@ import com.java2nb.novel.vo.BookCommentVO;
import com.java2nb.novel.vo.BookSettingVO;
import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.vo.BookVO;
import io.github.xxyopen.model.page.PageBean;
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
import io.github.xxyopen.util.IdWorker;
import io.github.xxyopen.web.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ -217,7 +216,8 @@ public class BookServiceImpl implements BookService {
if (StringUtils.isNotBlank(params.getSort())) {
OrderByHelper.orderBy(params.getSort() + " desc");
}
return PageBuilder.build(bookMapper.searchByPage(params));
return new PageBean<>(bookMapper.searchByPage(params));
}
@ -262,7 +262,7 @@ public class BookServiceImpl implements BookService {
@Override
public BookIndex queryBookIndex(Long bookIndexId) {
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.id, BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.indexNum, BookIndexDynamicSqlSupport.indexName, BookIndexDynamicSqlSupport.wordCount,BookIndexDynamicSqlSupport.bookPrice, BookIndexDynamicSqlSupport.updateTime, BookIndexDynamicSqlSupport.isVip,BookIndexDynamicSqlSupport.storageType)
SelectStatementProvider selectStatement = select(BookIndexDynamicSqlSupport.id, BookIndexDynamicSqlSupport.bookId, BookIndexDynamicSqlSupport.indexNum, BookIndexDynamicSqlSupport.indexName, BookIndexDynamicSqlSupport.wordCount,BookIndexDynamicSqlSupport.bookPrice, BookIndexDynamicSqlSupport.updateTime, BookIndexDynamicSqlSupport.isVip)
.from(bookIndex)
.where(BookIndexDynamicSqlSupport.id, isEqualTo(bookIndexId))
.build()
@ -388,7 +388,7 @@ public class BookServiceImpl implements BookService {
public PageBean<BookCommentVO> listCommentByPage(Long userId, Long bookId, int page, int pageSize) {
PageHelper.startPage(page, pageSize);
OrderByHelper.orderBy("t1.create_time desc");
return PageBuilder.build(bookCommentMapper.listCommentByPage(userId, bookId));
return new PageBean<>(bookCommentMapper.listCommentByPage(userId, bookId));
}
@Transactional(rollbackFor = Exception.class)
@ -428,7 +428,7 @@ public class BookServiceImpl implements BookService {
} else {
//作者不存在,先创建作者
Date currentDate = new Date();
authorId = IdWorker.INSTANCE.nextId();
authorId = new IdWorker().nextId();
BookAuthor bookAuthor = new BookAuthor();
bookAuthor.setId(authorId);
bookAuthor.setPenName(authorName);
@ -496,16 +496,15 @@ public class BookServiceImpl implements BookService {
@Override
public PageBean<Book> listBookPageByUserId(Long userId, int page, int pageSize) {
Author author = authorService.queryAuthor(userId);
PageHelper.startPage(page, pageSize);
SelectStatementProvider selectStatement = select(id, bookName, picUrl, catName, visitCount, yesterdayBuy, lastIndexUpdateTime, updateTime, wordCount, lastIndexName, status)
.from(book)
.where(authorId, isEqualTo(author.getId()))
.where(authorId, isEqualTo(authorService.queryAuthor(userId).getId()))
.orderBy(BookDynamicSqlSupport.createTime.descending())
.build()
.render(RenderingStrategies.MYBATIS3);
return PageBuilder.build(bookMapper.selectMany(selectStatement));
return new PageBean<>(bookMapper.selectMany(selectStatement));
}
@ -548,7 +547,7 @@ public class BookServiceImpl implements BookService {
//并不是更新自己的小说
return;
}
Long lastIndexId = IdWorker.INSTANCE.nextId();
Long lastIndexId = new IdWorker().nextId();
Date currentDate = new Date();
int wordCount = StringUtil.getStrValidWordCount(content);

View File

@ -1,33 +0,0 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.mapper.BookContentDynamicSqlSupport;
import com.java2nb.novel.mapper.BookContentMapper;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.springframework.stereotype.Service;
import static com.java2nb.novel.mapper.BookContentDynamicSqlSupport.bookContent;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
@Service(value = "db")
@RequiredArgsConstructor
public class DbBookContentServiceImpl implements BookContentService {
private final BookContentMapper bookContentMapper;
@Override
public BookContent queryBookContent(Long bookId, 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);
}
}

View File

@ -1,35 +0,0 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.entity.BookContent;
import com.java2nb.novel.service.BookContentService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.FileReader;
@Service(value = "txt")
@RequiredArgsConstructor
public class FileBookContentServiceImpl implements BookContentService {
@Value("${content.save.path}")
private String fileSavePath;
@SneakyThrows
@Override
public BookContent queryBookContent(Long bookId, Long bookIndexId) {
BufferedReader in = new BufferedReader(new FileReader(fileSavePath + "/" + bookId + "/" + bookIndexId + ".txt"));
StringBuffer sb = new StringBuffer();
String str;
while ((str = in.readLine()) != null) {
sb.append(str);
}
in.close();
return new BookContent() {{
setIndexId(bookIndexId);
setContent(sb.toString());
}};
}
}

View File

@ -1,6 +1,6 @@
package com.java2nb.novel.service.impl;
import io.github.xxyopen.web.util.BeanUtil;
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;

View File

@ -1,8 +1,8 @@
package com.java2nb.novel.service.impl;
import com.github.pagehelper.PageHelper;
import io.github.xxyopen.model.page.PageBean;
import io.github.xxyopen.web.util.BeanUtil;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.mapper.FrontNewsMapper;
import com.java2nb.novel.service.NewsService;
import com.java2nb.novel.core.cache.CacheKey;
@ -10,7 +10,6 @@ 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 io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
@ -70,7 +69,7 @@ public class NewsServiceImpl implements NewsService {
.build()
.render(RenderingStrategies.MYBATIS3);
List<News> news = newsMapper.selectMany(selectStatement);
PageBean<News> pageBean = PageBuilder.build(news);
PageBean<News> pageBean = new PageBean<>(news);
pageBean.setList(BeanUtil.copyList(news,NewsVO.class));
return pageBean;
}

View File

@ -2,13 +2,15 @@ package com.java2nb.novel.service.impl;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.xxyopen.model.page.PageBean;
import com.github.pagehelper.PageInfo;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.enums.ResponseStatus;
import io.github.xxyopen.util.StringUtil;
import io.github.xxyopen.web.exception.BusinessException;
import com.java2nb.novel.core.exception.BusinessException;
import com.java2nb.novel.core.utils.StringUtil;
import com.java2nb.novel.entity.Book;
import com.java2nb.novel.vo.BookSpVO;
import com.java2nb.novel.service.SearchService;
import com.java2nb.novel.vo.BookVO;
import com.java2nb.novel.vo.EsBookVO;
import io.searchbox.client.JestClient;
import io.searchbox.core.Count;
@ -198,7 +200,8 @@ public class SearchServiceImpl implements SearchService {
}
}
}
return new PageBean<>(page, pageSize, total.longValue(), bookList);
return new PageBean<>(page,pageSize,total.longValue(),bookList);
}
throw new BusinessException(ResponseStatus.ES_SEARCH_FAIL);
}

View File

@ -1,21 +1,20 @@
package com.java2nb.novel.service.impl;
import com.github.pagehelper.PageHelper;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.PageBean;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.core.utils.BeanUtil;
import com.java2nb.novel.entity.*;
import com.java2nb.novel.entity.User;
import com.java2nb.novel.service.UserService;
import com.java2nb.novel.core.enums.ResponseStatus;
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
import io.github.xxyopen.util.IdWorker;
import io.github.xxyopen.util.MD5Util;
import io.github.xxyopen.web.exception.BusinessException;
import com.java2nb.novel.core.exception.BusinessException;
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 io.github.xxyopen.web.util.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
@ -74,7 +73,7 @@ public class UserServiceImpl implements UserService {
User entity = new User();
BeanUtils.copyProperties(user,entity);
//数据库生成注册记录
Long id = IdWorker.INSTANCE.nextId();
Long id = new IdWorker().nextId();
entity.setId(id);
entity.setNickName(entity.getUsername());
Date currentDate = new Date();
@ -151,7 +150,7 @@ public class UserServiceImpl implements UserService {
@Override
public PageBean<BookShelfVO> listBookShelfByPage(Long userId, int page, int pageSize) {
PageHelper.startPage(page, pageSize);
return PageBuilder.build(userBookshelfMapper.listBookShelf(userId));
return new PageBean<>(userBookshelfMapper.listBookShelf(userId));
}
@Transactional(rollbackFor = Exception.class)
@ -212,7 +211,7 @@ public class UserServiceImpl implements UserService {
.build()
.render(RenderingStrategies.MYBATIS3);
List<UserFeedback> userFeedbacks = userFeedbackMapper.selectMany(selectStatement);
PageBean<UserFeedback> pageBean = PageBuilder.build(userFeedbacks);
PageBean<UserFeedback> pageBean = new PageBean<>(userFeedbacks);
pageBean.setList(BeanUtil.copyList(userFeedbacks,UserFeedbackVO.class));
return pageBean;
}
@ -230,7 +229,7 @@ public class UserServiceImpl implements UserService {
@Override
public PageBean<BookReadHistoryVO> listReadHistoryByPage(Long userId, int page, int pageSize) {
PageHelper.startPage(page, pageSize);
return PageBuilder.build(userReadHistoryMapper.listReadHistory(userId));
return new PageBean<>(userReadHistoryMapper.listReadHistory(userId));
}
@Override

View File

@ -1,5 +1,5 @@
server:
port: 8083
port: 8080
spring:
profiles:

View File

@ -147,10 +147,10 @@
<div style="text-align: center;height: 45px;line-height: 45px">
<a th:href="'/book/'+${book.id}+'/'+${firstBookIndexId}+'.html'" type="button" style="background-color:#ff8900!important" class="layui-btn layui-btn-sm layui-btn-radius">开始阅读</a>
<button type="button" id="cFavs" onclick="addInShell()" style="background-color:#ffA640!important" class="layui-btn layui-btn-sm layui-btn-radius ">加入书架</button>
<a th:href="'/book/'+${book.id}+'/'+${firstBookIndexId}+'.html'" type="button" class="layui-btn layui-btn-sm layui-btn-radius">开始阅读</a>
<button type="button" id="cFavs" onclick="addInShell()" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm">加入书架</button>
<button type="button" onclick="location.href='/user/favorites.html'" style="background-color:#ffBE73!important" class="layui-btn layui-btn-sm layui-btn-radius ">我的书架</button>
<button type="button" onclick="location.href='/user/favorites.html'" class="layui-btn layui-btn-sm layui-btn-radius layui-bg-cyan">我的书架</button>
<!--
<button type="button" onclick="downloadFile()" class="layui-btn layui-btn-sm layui-btn-radius layui-bg-normal">下载TXT</button>
-->

41
pom.xml
View File

@ -5,7 +5,7 @@
<groupId>com.java2nb</groupId>
<artifactId>novel</artifactId>
<version>3.6.1</version>
<version>3.5.4</version>
<modules>
<module>novel-common</module>
<module>novel-front</module>
@ -46,7 +46,6 @@
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<fastdfs-client.version>1.26.1-RELEASE</fastdfs-client.version>
<alipay-sdk-java.version>4.9.153.ALL</alipay-sdk-java.version>
<xxyopen.version>1.0.0</xxyopen.version>
</properties>
<dependencyManagement>
@ -76,22 +75,20 @@
</dependency>
</dependencies>
<!-- 如果maven无法解析io.github.xxyopen的依赖需要检查镜像mirror的配置 -->
<!-- mirror可以拦截对远程仓库的请求 , 改变对目标仓库的下载地址-->
<!-- 如果maven setting.xml中配置了镜像 , 而且镜像配置的规则中匹配到目标仓库时,
maven认为目标仓库被镜像了, 不会再去被镜像仓库下载依赖jar包, 而是直接去镜像仓库下载-->
<!-- <mirrorOf></mirrorOf>里配置需要拦截的仓库id-->
<!-- 如果填*就会拦截所有仓库-->
<!-- maven阿里的镜像使用的默认mirrorOf规则=*, 所有的仓库都被镜像需要改成 *,!oss -->
<!-- 另外需要注意的是由于镜像仓库完全屏蔽了被镜像仓库当镜像仓库不稳定或者停止服务的时候
Maven仍将无法访问被镜像仓库因而将无法下载依赖-->
<repositories>
<repository>
<id>ali</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</releases>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
@ -99,11 +96,17 @@
</repositories>
<pluginRepositories>
<pluginRepository>
<id>ali-plugin</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</releases>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>