Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
031398b625 | |||
976db9420e | |||
e33db86081 | |||
a4861996b5 | |||
48a70c2aca | |||
ea5c0e8bd1 | |||
b0c249cdca | |||
730fcb4c76 | |||
b976a00389 | |||
6d9b563583 | |||
bfb7d6cc5c | |||
9d4dc409c6 | |||
34d211afbf | |||
2d218076c4 | |||
674e4df84c | |||
331f56d112 | |||
f494aae2c7 | |||
2fc533f8ae | |||
82758271e3 | |||
4c82c2d720 | |||
4665b5c4b9 | |||
7bbabb3492 | |||
d6093d8182 | |||
f77792aa3c | |||
c62da9bb3a | |||
8a63cff0b5 | |||
07bed12fa5 | |||
0d6e0ffb06 | |||
e7005004bb | |||
ff68cdd829 | |||
b61dc4d0d5 | |||
98f1f804c3 | |||
5978d6cbcc | |||
ef290bed9c | |||
5543e5aa57 | |||
0332802fe5 | |||
a55f456b3d | |||
f6d66e69fb | |||
96960789e1 | |||
1998dcd460 | |||
a33d8f68a2 | |||
30959da038 | |||
5406783344 | |||
d84345918b | |||
a5394cb426 | |||
2275b85752 | |||
2062123edd | |||
255b3f8c4b | |||
00179359bd |
12
README.md
@ -57,9 +57,17 @@ novel-plus -- 父工程
|
||||
| Thymeleaf | 模板引擎
|
||||
| Layui | 前端 UI 框架
|
||||
|
||||
## 项目演示
|
||||
## 项目截图
|
||||
|
||||
https://www.bilibili.com/video/BV1Zo4y187Mi
|
||||
### 绿色主题模版
|
||||
|
||||
[](https://www.xxyopen.com/images/green_novel.png)
|
||||
[](https://www.xxyopen.com/images/resource/os/novel-plus/green3.png)
|
||||
[](https://www.xxyopen.com/images/resource/os/novel-plus/green2.png)
|
||||
|
||||
## 演示视频
|
||||
|
||||
https://www.bilibili.com/video/BV18e41197xs
|
||||
|
||||
## 增值服务
|
||||
|
||||
|
Before Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 411 KiB |
Before Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 263 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 461 KiB |
Before Width: | Height: | Size: 111 KiB |
Before Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 12 KiB |
BIN
assets/jk.png
Before Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 36 KiB |
BIN
assets/jk_wc.png
Before Width: | Height: | Size: 82 KiB |
BIN
assets/login.png
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 310 KiB |
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 223 KiB |
Before Width: | Height: | Size: 4.5 KiB |
BIN
assets/mini4.png
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 155 KiB |
Before Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 360 KiB |
Before Width: | Height: | Size: 357 KiB |
Before Width: | Height: | Size: 307 KiB |
Before Width: | Height: | Size: 929 KiB |
Before Width: | Height: | Size: 194 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 185 KiB |
Before Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 77 KiB |
BIN
assets/精品小说楼.png
Before Width: | Height: | Size: 764 KiB |
Before Width: | Height: | Size: 1.1 MiB |
116
doc/api/api.md
@ -1,116 +0,0 @@
|
||||
|
||||
<h1 class="curproject-name"> 小说精品屋-plus </h1>
|
||||
小说精品屋-plus接口
|
||||
|
||||
|
||||
# 作家模块
|
||||
|
||||
## 小说章节分页列表查询接口
|
||||
<a id=小说章节分页列表查询接口> </a>
|
||||
### 基本信息
|
||||
|
||||
**Path:** /book/queryIndexList
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**接口描述:**
|
||||
<p>作家后台章节管理页面需要请求该接口获取小说章节分页列表信息</p>
|
||||
|
||||
|
||||
### 请求参数
|
||||
**Query**
|
||||
|
||||
| 参数名称 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ |
|
||||
| bookId | 是 | 1334337530296893441 | 小说ID |
|
||||
| curr | 否 | 1 | 查询页码,默认1 |
|
||||
| limit | 否 | 5 | 分页大小,默认5 |
|
||||
|
||||
### 返回数据
|
||||
|
||||
<table>
|
||||
<thead class="ant-table-thead">
|
||||
<tr>
|
||||
<th key=name>名称</th><th key=type>类型</th><th key=required>是否必须</th><th key=default>默认值</th><th key=desc>备注</th><th key=sub>其他信息</th>
|
||||
</tr>
|
||||
</thead><tbody className="ant-table-tbody"><tr key=0-0><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> code</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应状态吗,200表示成功</span></td><td key=5></td></tr><tr key=0-1><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> msg</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应信息</span></td><td key=5></td></tr><tr key=0-2><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> data</span></td><td key=1><span>object</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应数据</span></td><td key=5></td></tr><tr key=0-2-0><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> total</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">总数量</span></td><td key=5></td></tr><tr key=0-2-1><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> list</span></td><td key=1><span>object []</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">章节数据集合</span></td><td key=5><p key=3><span style="font-weight: '700'">item 类型: </span><span>object</span></p></td></tr><tr key=0-2-1-0><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> id</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">章节ID</span></td><td key=5></td></tr><tr key=0-2-1-1><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> bookId</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">小说ID</span></td><td key=5></td></tr><tr key=0-2-1-2><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> indexName</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">章节名</span></td><td key=5></td></tr><tr key=0-2-1-3><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> isVip</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">是否收费,1:收费,0:免费</span></td><td key=5></td></tr><tr key=0-2-1-4><td key=0><span style="padding-left: 40px"><span style="color: #8c8a8a">├─</span> updateTime</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">更新时间</span></td><td key=5></td></tr><tr key=0-2-2><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> pageNum</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">页码</span></td><td key=5></td></tr><tr key=0-2-3><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> pageSize</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">分页大小</span></td><td key=5></td></tr><tr key=0-2-4><td key=0><span style="padding-left: 20px"><span style="color: #8c8a8a">├─</span> size</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">当前页数量</span></td><td key=5></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 小说章节删除接口
|
||||
<a id=小说章节删除接口> </a>
|
||||
### 基本信息
|
||||
|
||||
**Path:** /author/deleteIndex/{indexId}
|
||||
|
||||
**Method:** DELETE
|
||||
|
||||
**接口描述:**
|
||||
<p>作家后台章节管理页面点击删除按钮请求该接口删除小说章节内容</p>
|
||||
|
||||
|
||||
### 请求参数
|
||||
**Headers**
|
||||
|
||||
| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ | ------------ |
|
||||
| Content-Type | application/x-www-form-urlencoded | 是 | | |
|
||||
| Authorization | | 是 | eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2MDgzNDg0NzksInN1YiI6IntcImlkXCI6MTI1NTA2MDMyODMyMjAyNzUyMCxcInVzZXJuYW1lXCI6XCIxMzU2MDQyMTMyNFwiLFwibmlja05hbWVcIjpcIjEzNTYwNDIxMzI0XCJ9IiwiY3JlYXRlZCI6MTYwNzc0MzY3OTkxM30.0qhwis_zPb6t8wGNejMhDZ2iHCL9Tgh2UHd1gcQBCp8t6RW3ggSwtfo4l_RgMT_v8jOkLW91GzTVWlNnTE6LCA | 认证JWT,请求登录接口成功后返回 |
|
||||
**路径参数**
|
||||
|
||||
| 参数名称 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ |
|
||||
| indexId | 1337603246936645632 | 章节ID |
|
||||
|
||||
### 返回数据
|
||||
|
||||
<table>
|
||||
<thead class="ant-table-thead">
|
||||
<tr>
|
||||
<th key=name>名称</th><th key=type>类型</th><th key=required>是否必须</th><th key=default>默认值</th><th key=desc>备注</th><th key=sub>其他信息</th>
|
||||
</tr>
|
||||
</thead><tbody className="ant-table-tbody"><tr key=0-0><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> code</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应状态吗,200表示成功</span></td><td key=5></td></tr><tr key=0-1><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> msg</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应信息</span></td><td key=5></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 小说章节发布接口
|
||||
<a id=小说章节发布接口> </a>
|
||||
### 基本信息
|
||||
|
||||
**Path:** /author/addBookContent
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**接口描述:**
|
||||
<p>作家后台章节发布页面点击提交按钮请求该接口新增小说章节内容</p>
|
||||
|
||||
|
||||
### 请求参数
|
||||
**Headers**
|
||||
|
||||
| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ | ------------ |
|
||||
| Content-Type | application/x-www-form-urlencoded | 是 | | |
|
||||
| Authorization | | 是 | eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2MDgzNDg0NzksInN1YiI6IntcImlkXCI6MTI1NTA2MDMyODMyMjAyNzUyMCxcInVzZXJuYW1lXCI6XCIxMzU2MDQyMTMyNFwiLFwibmlja05hbWVcIjpcIjEzNTYwNDIxMzI0XCJ9IiwiY3JlYXRlZCI6MTYwNzc0MzY3OTkxM30.0qhwis_zPb6t8wGNejMhDZ2iHCL9Tgh2UHd1gcQBCp8t6RW3ggSwtfo4l_RgMT_v8jOkLW91GzTVWlNnTE6LCA | 认证JWT,请求登录接口成功后返回 |
|
||||
**Body**
|
||||
|
||||
| 参数名称 | 参数类型 | 是否必须 | 示例 | 备注 |
|
||||
| ------------ | ------------ | ------------ | ------------ | ------------ |
|
||||
| bookId | text | 是 | 1334337530296893441 | 小说ID |
|
||||
| indexName | text | 是 | 第六章未婚妻(下) | 章节名 |
|
||||
| content | text | 是 | 开始之时,李七夜还是生疏无比,那怕他对于刀术的所有奥义了然于胸,但是,他出刀之时依然会颤抖,无法达到妙及巅毫的要求。 | 章节内容 |
|
||||
| isVip | text | 是 | 1 | 是否收费,1:收费,0:免费 |
|
||||
|
||||
|
||||
|
||||
### 返回数据
|
||||
|
||||
<table>
|
||||
<thead class="ant-table-thead">
|
||||
<tr>
|
||||
<th key=name>名称</th><th key=type>类型</th><th key=required>是否必须</th><th key=default>默认值</th><th key=desc>备注</th><th key=sub>其他信息</th>
|
||||
</tr>
|
||||
</thead><tbody className="ant-table-tbody"><tr key=0-0><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> code</span></td><td key=1><span>number</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应状态吗,200表示成功</span></td><td key=5></td></tr><tr key=0-1><td key=0><span style="padding-left: 0px"><span style="color: #8c8a8a"></span> msg</span></td><td key=1><span>string</span></td><td key=2>必须</td><td key=3></td><td key=4><span style="white-space: pre-wrap">响应信息</span></td><td key=5></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
3
doc/sql/20240512.sql
Normal file
@ -0,0 +1,3 @@
|
||||
update crawl_source
|
||||
set crawl_rule = replace(crawl_rule, 'ibiquge.net', 'ibiquzw.org')
|
||||
where id = 16;
|
2
doc/sql/Dockerfile
Normal file
@ -0,0 +1,2 @@
|
||||
FROM mysql:8.0
|
||||
COPY novel_plus.sql /docker-entrypoint-initdb.d/init.sql
|
@ -1,6 +0,0 @@
|
||||
FROM java:8
|
||||
ADD novel-admin-1.0.0.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -jar /root/novel-admin-1.0.0.jar"]
|
@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.java2nb</groupId>
|
||||
<artifactId>novel-admin</artifactId>
|
||||
<version>4.2.0</version>
|
||||
<version>4.3.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>novel-admin</name>
|
||||
@ -296,6 +296,9 @@
|
||||
<zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>
|
||||
<zipfileset filemode="755" dir='${project.build.directory}/build/'/>
|
||||
</zip>
|
||||
|
||||
<copy file="${basedir}/src/main/build/docker/Dockerfile"
|
||||
tofile="${project.build.directory}/build/Dockerfile"/>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
9
novel-admin/src/main/build/docker/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM openjdk:8
|
||||
ADD novel-admin.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENV redishost = ""
|
||||
ENV redisport = ""
|
||||
ENV redispwd = ""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -Dspring.redis.host=${redishost} -Dspring.redis.port=${redisport} -Dspring.redis.password=${redispwd} -jar /root/novel-admin.jar"]
|
@ -68,6 +68,7 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/js/**", "anon");
|
||||
filterChainDefinitionMap.put("/fonts/**", "anon");
|
||||
filterChainDefinitionMap.put("/img/**", "anon");
|
||||
filterChainDefinitionMap.put("/favicon.ico", "anon");
|
||||
filterChainDefinitionMap.put("/docs/**", "anon");
|
||||
filterChainDefinitionMap.put("/layuimini/**", "anon");
|
||||
filterChainDefinitionMap.put("/upload/**", "anon");
|
||||
|
@ -12,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -83,7 +84,7 @@ public class FriendLinkController {
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("novel:friendLink:add")
|
||||
public R save(FriendLinkDO friendLink) {
|
||||
public R save(@Validated FriendLinkDO friendLink) {
|
||||
if (friendLinkService.save(friendLink) > 0) {
|
||||
redisTemplate.delete(CacheKey.INDEX_LINK_KEY);
|
||||
return R.ok();
|
||||
@ -98,7 +99,7 @@ public class FriendLinkController {
|
||||
@ResponseBody
|
||||
@RequestMapping("/update")
|
||||
@RequiresPermissions("novel:friendLink:edit")
|
||||
public R update(FriendLinkDO friendLink) {
|
||||
public R update(@Validated FriendLinkDO friendLink) {
|
||||
friendLinkService.update(friendLink);
|
||||
redisTemplate.delete(CacheKey.INDEX_LINK_KEY);
|
||||
return R.ok();
|
||||
|
@ -1,163 +1,175 @@
|
||||
package com.java2nb.novel.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.java2nb.common.jsonserializer.LongToStringSerializer;
|
||||
|
||||
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2023-04-14 15:12:25
|
||||
*/
|
||||
public class FriendLinkDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
//主键
|
||||
private Integer id;
|
||||
//链接名
|
||||
private String linkName;
|
||||
//链接url
|
||||
private String linkUrl;
|
||||
//排序号
|
||||
private Integer sort;
|
||||
//是否开启,0:不开启,1:开启
|
||||
private Integer isOpen;
|
||||
//创建人id
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long createUserId;
|
||||
//创建时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
//更新者用户id
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long updateUserId;
|
||||
//更新时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设置:主键
|
||||
*/
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* 获取:主键
|
||||
*/
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* 设置:链接名
|
||||
*/
|
||||
public void setLinkName(String linkName) {
|
||||
this.linkName = linkName;
|
||||
}
|
||||
/**
|
||||
* 获取:链接名
|
||||
*/
|
||||
public String getLinkName() {
|
||||
return linkName;
|
||||
}
|
||||
/**
|
||||
* 设置:链接url
|
||||
*/
|
||||
public void setLinkUrl(String linkUrl) {
|
||||
this.linkUrl = linkUrl;
|
||||
}
|
||||
/**
|
||||
* 获取:链接url
|
||||
*/
|
||||
public String getLinkUrl() {
|
||||
return linkUrl;
|
||||
}
|
||||
/**
|
||||
* 设置:排序号
|
||||
*/
|
||||
public void setSort(Integer sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
/**
|
||||
* 获取:排序号
|
||||
*/
|
||||
public Integer getSort() {
|
||||
return sort;
|
||||
}
|
||||
/**
|
||||
* 设置:是否开启,0:不开启,1:开启
|
||||
*/
|
||||
public void setIsOpen(Integer isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
}
|
||||
/**
|
||||
* 获取:是否开启,0:不开启,1:开启
|
||||
*/
|
||||
public Integer getIsOpen() {
|
||||
return isOpen;
|
||||
}
|
||||
/**
|
||||
* 设置:创建人id
|
||||
*/
|
||||
public void setCreateUserId(Long createUserId) {
|
||||
this.createUserId = createUserId;
|
||||
}
|
||||
/**
|
||||
* 获取:创建人id
|
||||
*/
|
||||
public Long getCreateUserId() {
|
||||
return createUserId;
|
||||
}
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
/**
|
||||
* 设置:更新者用户id
|
||||
*/
|
||||
public void setUpdateUserId(Long updateUserId) {
|
||||
this.updateUserId = updateUserId;
|
||||
}
|
||||
/**
|
||||
* 获取:更新者用户id
|
||||
*/
|
||||
public Long getUpdateUserId() {
|
||||
return updateUserId;
|
||||
}
|
||||
/**
|
||||
* 设置:更新时间
|
||||
*/
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
/**
|
||||
* 获取:更新时间
|
||||
*/
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
//主键
|
||||
private Integer id;
|
||||
//链接名
|
||||
private String linkName;
|
||||
//链接url
|
||||
@URL
|
||||
private String linkUrl;
|
||||
//排序号
|
||||
private Integer sort;
|
||||
//是否开启,0:不开启,1:开启
|
||||
private Integer isOpen;
|
||||
//创建人id
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long createUserId;
|
||||
//创建时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
//更新者用户id
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long updateUserId;
|
||||
//更新时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 设置:主键
|
||||
*/
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:主键
|
||||
*/
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:链接名
|
||||
*/
|
||||
public void setLinkName(String linkName) {
|
||||
this.linkName = linkName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:链接名
|
||||
*/
|
||||
public String getLinkName() {
|
||||
return linkName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:链接url
|
||||
*/
|
||||
public void setLinkUrl(String linkUrl) {
|
||||
this.linkUrl = linkUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:链接url
|
||||
*/
|
||||
public String getLinkUrl() {
|
||||
return linkUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:排序号
|
||||
*/
|
||||
public void setSort(Integer sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:排序号
|
||||
*/
|
||||
public Integer getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:是否开启,0:不开启,1:开启
|
||||
*/
|
||||
public void setIsOpen(Integer isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:是否开启,0:不开启,1:开启
|
||||
*/
|
||||
public Integer getIsOpen() {
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:创建人id
|
||||
*/
|
||||
public void setCreateUserId(Long createUserId) {
|
||||
this.createUserId = createUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:创建人id
|
||||
*/
|
||||
public Long getCreateUserId() {
|
||||
return createUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:更新者用户id
|
||||
*/
|
||||
public void setUpdateUserId(Long updateUserId) {
|
||||
this.updateUserId = updateUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:更新者用户id
|
||||
*/
|
||||
public Long getUpdateUserId() {
|
||||
return updateUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:更新时间
|
||||
*/
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:更新时间
|
||||
*/
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,12 @@ spring:
|
||||
profiles:
|
||||
active: dev
|
||||
|
||||
#上传文件的最大值(10M)
|
||||
#上传文件的最大值(100M)
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10485760
|
||||
|
||||
max-file-size: 100MB
|
||||
max-request-size: 100MB
|
||||
|
||||
devtools:
|
||||
restart:
|
||||
enabled: true
|
||||
|
BIN
novel-admin/src/main/resources/favicon.ico
Normal file
After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 8.9 KiB |
@ -23,7 +23,7 @@
|
||||
<div class="col-sm-8">
|
||||
<input id="linkUrl" name="linkUrl"
|
||||
class="form-control"
|
||||
type="text" required>
|
||||
type="url" required>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@
|
||||
<input id="linkUrl" name="linkUrl"
|
||||
th:value="${friendLink.linkUrl}"
|
||||
class="form-control"
|
||||
type="text" required>
|
||||
type="url" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>novel</artifactId>
|
||||
<groupId>com.java2nb</groupId>
|
||||
<version>4.2.0</version>
|
||||
<version>4.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -14,43 +14,48 @@ public class User {
|
||||
private Long id;
|
||||
|
||||
|
||||
@NotBlank(groups = {AddGroup.class},message="手机号不能为空!")
|
||||
@Pattern(groups = {AddGroup.class},regexp="^1[3|4|5|6|7|8|9][0-9]{9}$",message="手机号格式不正确!")
|
||||
@NotBlank(groups = {AddGroup.class}, message = "手机号不能为空!")
|
||||
@Pattern(groups = {AddGroup.class}, regexp = "^1[3|4|5|6|7|8|9][0-9]{9}$", message = "手机号格式不正确!")
|
||||
@Null(groups = {UpdateGroup.class})
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String username;
|
||||
|
||||
@NotBlank(groups = {AddGroup.class},message="密码不能为空!")
|
||||
@NotBlank(groups = {AddGroup.class}, message = "密码不能为空!")
|
||||
@Null(groups = {UpdateGroup.class})
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String password;
|
||||
|
||||
@Null(groups = {AddGroup.class})
|
||||
@Pattern(groups = {
|
||||
UpdateGroup.class}, regexp = "[\u4E00-\u9FA5A-Za-z0-9_]{1,11}", message = "昵称格式不正确!")
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String nickName;
|
||||
|
||||
@Null(groups = {AddGroup.class})
|
||||
@Pattern(groups = {
|
||||
UpdateGroup.class}, regexp = "^/localPic/\\d{4}/\\d{2}/\\d{2}/[A-Za-z0-9]+\\.(jpg|jpeg|swf|gif|png|JPG|JPEG|SWF|GIF|PNG)$", message = "只能上传图片格式的文件!")
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private String userPhoto;
|
||||
|
||||
@Null(groups = {AddGroup.class})
|
||||
@Min(value = 0,groups = {UpdateGroup.class})
|
||||
@Max(value = 1,groups = {UpdateGroup.class})
|
||||
@Min(value = 0, groups = {UpdateGroup.class})
|
||||
@Max(value = 1, groups = {UpdateGroup.class})
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Byte userSex;
|
||||
|
||||
@Null(groups = {AddGroup.class,UpdateGroup.class})
|
||||
@Null(groups = {AddGroup.class, UpdateGroup.class})
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Long accountBalance;
|
||||
|
||||
@Null(groups = {AddGroup.class,UpdateGroup.class})
|
||||
@Null(groups = {AddGroup.class, UpdateGroup.class})
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Byte status;
|
||||
|
||||
@Null(groups = {AddGroup.class,UpdateGroup.class})
|
||||
@Null(groups = {AddGroup.class, UpdateGroup.class})
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Date createTime;
|
||||
|
||||
@Null(groups = {AddGroup.class,UpdateGroup.class})
|
||||
@Null(groups = {AddGroup.class, UpdateGroup.class})
|
||||
@Generated("org.mybatis.generator.api.MyBatisGenerator")
|
||||
private Date updateTime;
|
||||
|
||||
|
@ -11,10 +11,11 @@ spring:
|
||||
generator:
|
||||
write-numbers-as-strings: true
|
||||
|
||||
#上传文件的最大值(1M)
|
||||
#上传文件的最大值(100M)
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 1048576
|
||||
max-file-size: 100MB
|
||||
max-request-size: 100MB
|
||||
|
||||
mybatis:
|
||||
configuration:
|
||||
|
@ -1,6 +0,0 @@
|
||||
FROM java:8
|
||||
ADD novel-crawl-1.1.0.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -jar /root/novel-crawl-1.1.0.jar"]
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>novel</artifactId>
|
||||
<groupId>com.java2nb</groupId>
|
||||
<version>4.2.0</version>
|
||||
<version>4.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -72,6 +72,9 @@
|
||||
<zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>
|
||||
<zipfileset filemode="755" dir='${project.build.directory}/build/'/>
|
||||
</zip>
|
||||
|
||||
<copy file="${basedir}/src/main/build/docker/Dockerfile"
|
||||
tofile="${project.build.directory}/build/Dockerfile"/>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
9
novel-crawl/src/main/build/docker/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM openjdk:8
|
||||
ADD novel-crawl.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENV redishost = ""
|
||||
ENV redisport = ""
|
||||
ENV redispwd = ""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -Dspring.redis.host=${redishost} -Dspring.redis.port=${redisport} -Dspring.redis.password=${redispwd} -jar /root/novel-crawl.jar"]
|
@ -53,8 +53,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
http.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/css/**").permitAll()
|
||||
.antMatchers("/favicon.ico").permitAll()
|
||||
.antMatchers("/**").hasRole("ADMIN")
|
||||
.and().formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll()
|
||||
.and().logout()
|
||||
.logoutUrl("/logout")
|
||||
.logoutSuccessUrl("/")
|
||||
.and().httpBasic();
|
||||
|
||||
}
|
||||
|
BIN
novel-crawl/src/main/resources/favicon.ico
Normal file
After Width: | Height: | Size: 162 KiB |
@ -1,100 +1,511 @@
|
||||
@charset "utf-8";
|
||||
.updateTable .style a { color:#999 }
|
||||
.updateTable .author a { color:#999; cursor:text }
|
||||
.bind, .updateTable .style a:hover { color:#f65167 }
|
||||
.userBox { /*width: 998px; border: 1px solid #eaeaea;*/ margin:0 auto 50px; background: #fff; border-radius: 6px }
|
||||
.channelViewhistory .userBox { margin: 0 auto }
|
||||
.user_l { width:350px; float:left; padding:50px 50px }
|
||||
.user_l h3 { font-size:23px; font-weight:normal; line-height:1; text-align: center }
|
||||
.user_l #LabErr { color:#ff4040; display:block; height:40px; line-height:40px; text-align: center; font-size: 14px }
|
||||
.user_l .log_list { width:350px }
|
||||
.user_l .s_input { margin-bottom:25px; font-size:14px }
|
||||
.s_input { width:348px; height:30px; line-height:38px\9; vertical-align:middle; border:1px solid #ddd; border-radius:2px }
|
||||
.icon_name, .icon_key, .icon_code { width:312px; padding-left:36px}
|
||||
.icon_key { background-position: 13px -51px }
|
||||
.icon_code { background-position: 13px -117px; width:200px; float:left }
|
||||
.code_pic { height:38px; float:right }
|
||||
.btn_phone { height:40px; width:100px; float:right; cursor:pointer; padding:0; text-align:center; border-radius:2px; background:#dfdfdf }
|
||||
.log_code { *padding-bottom:25px }
|
||||
.user_l .btn_red { width:100%; font-size:19px; padding:12px }
|
||||
.autologin { color:#999; line-height:1; margin-bottom:18px }
|
||||
.autologin em { vertical-align:2px; margin-left:4px }
|
||||
.user_r { width:259px; margin:80px 0; padding:20px 70px; border-left:1px dotted #e3e3e3; float:right; text-align:center }
|
||||
.user_r .tit { font-size:16px; line-height:1; padding: 6px 0 25px }
|
||||
.user_r .btn_ora { padding:10px 34px }
|
||||
.fast_login { padding:60px 0 0 }
|
||||
.fast_list { text-align:center; padding:0.5rem }
|
||||
.fast_list li { display:inline-block; *display:inline; zoom:1 }
|
||||
.fast_list li .img { width:48px; height:48px; margin:20px 0 5px }
|
||||
.fast_list li a:hover { opacity:0.8; filter: alpha(opacity=80); -moz-opacity: 0.8 }
|
||||
.fast_list li span { display:block }
|
||||
.fast_list .login_qq { margin:0 42px }
|
||||
.fast_list .login_wb a { color:#f55c5b }
|
||||
.fast_list .login_qq a { color:#51b7ff }
|
||||
.fast_list .login_wx a { color:#66d65e }
|
||||
.fast_tit { position:relative; overflow:hidden }
|
||||
.fast_tit .lines { position:absolute; top:50%; left:0; width:100%; height:1px; line-height:1; background:#eaeaea }
|
||||
.fast_tit .title { background:#fff; font-size:16px; padding:3px 14px; position:relative; display:inline-block; z-index:999 }
|
||||
/*userinfo*/
|
||||
.my_l { width:198px; float:left; font-size: 13px; padding-top: 20px; }
|
||||
.my_l li a { display:block; height:42px; line-height:42px; padding-left:62px; border-left:4px solid #fff; margin-bottom:5px; color: #666 }
|
||||
.my_l li .on { background-color:#fafafa; border-left:2px solid #f80; color:#000; border-radius: 0 2px 2px 0 }
|
||||
.my_l .link_1 { background-position:32px -188px }
|
||||
.my_l .link_2 { background-position:32px -230px }
|
||||
.my_l .link_3 { background-position:32px -272px }
|
||||
.my_l .link_4 { background-position:32px -314px }
|
||||
.my_l .link_5 { background-position:32px -356px }
|
||||
.my_l .link_6 { background-position:32px -397px }
|
||||
.my_l .link_7 { background-position:32px -440px }
|
||||
.my_l .link_8 { background-position:32px -481px }
|
||||
.my_r { width:739px; padding:0 30px 30px; float:right; border-left:1px solid #efefef; min-height:470px }
|
||||
.my_info { padding:30px 0 5px }
|
||||
.user_big_head { /*width:110px; height:110px; padding:4px; border:1px solid #eaeaea;*/ margin-right:30px; float:left; width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%; }
|
||||
.my_r .my_name { font-size:18px; line-height:1; padding:5px 0 12px 0 }
|
||||
.my_r .s_input { width:318px; padding:0 10px }
|
||||
.my_list li { line-height:28px }
|
||||
.my_list li i, .my_list li em.red { margin-right:6px }
|
||||
.my_list .binded { color:#999; margin-left:6px }
|
||||
.my_list .btn_link { margin-left:12px }
|
||||
.mytab_list li { line-height:30px; padding:10px 0; font-size:14px }
|
||||
.mytab_list li .tit { width:70px; color: #aaa; text-align:right; display:inline-block; margin-right:18px }
|
||||
.mytab_list .user_img { width:48px; height:48px; vertical-align:middle; border-radius:50% }
|
||||
.my_bookshelf .title { padding:20px 0 15px; line-height:30px }
|
||||
.my_bookshelf h4 { font-size:14px; color:#666 }
|
||||
.my_bookshelf h2 { font-size:18px; font-weight:normal }
|
||||
.updateTable { width: 739px; color: #999 }
|
||||
.updateTable table { width: 100%; margin-bottom:14px }
|
||||
.updateTable th, .updateTable td { height: 40px; line-height: 40px; vertical-align: middle; padding-left: 6px; font-weight:normal; text-align:left }
|
||||
.updateTable th { background:#f9f9f9; color:#333; border-top:1px solid #eee }
|
||||
.updateTable td { height:40px; line-height:40px }
|
||||
.updateTable .style { width:80px; padding-left:10px }
|
||||
.updateTable .name { width: 178px; padding-right: 10px }
|
||||
.updateTable .name a, .updateTable .chapter a { max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
||||
.updateTable .chapter { padding-right: 5px }
|
||||
.updateTable .chapter a { max-width:220px; float: left }
|
||||
.updateTable .author { width: 72px; text-align: left }
|
||||
.updateTable .goread { width: 80px; text-align:center }
|
||||
.updateTable .time { width: 86px }
|
||||
.updateTable .word { width: 64px; padding-right:10px; text-align: right }
|
||||
.updateTable .rank { width: 30px; padding-right:10px; text-align: center }
|
||||
.updateTable .name a, .updateTable .chapter a, .updateTable .author a { height: 40px; line-height: 40px; display: inline-block; overflow: hidden }
|
||||
.updateTable tr:nth-child(2n) td { background:#fafafa }
|
||||
.dataTable { width: 739px }
|
||||
.dataTable table { width: 100%; margin-bottom:14px; border-collapse:collapse }
|
||||
.dataTable th, .dataTable td { height: 40px; line-height: 40px; vertical-align: middle; padding:0 10px; font-weight:normal; text-align:center; border:1px solid #eaeaea }
|
||||
.dataTable th { background:#f8f8f8 }
|
||||
.nodate { border-top: 1px solid #eaeaea; padding:60px 0 }
|
||||
.viewhistoryBox { /*padding: 0 30px 30px; */ padding: 0 20px 10px }
|
||||
.viewhistoryBox .updateTable { width:100% }
|
||||
/*.btn_gray, .btn_red, .btn_ora { font-size:14px; padding:8px 28px }*/
|
||||
.book_tit { height: 48px; line-height:48px; margin: 0 14px; border-bottom: 1px solid #eaeaea; overflow:hidden }
|
||||
.book_tit .fl { font-size:14px; color:#999 }
|
||||
.book_tit .fl h3 { font-size:18px; color:#333; font-weight:normal; margin-right:5px; display:inline }
|
||||
.book_tit .fr { font-size:14px }
|
||||
.updateTable .style a {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.updateTable .author a {
|
||||
color: #999;
|
||||
cursor: text
|
||||
}
|
||||
|
||||
.bind, .updateTable .style a:hover {
|
||||
color: #f65167
|
||||
}
|
||||
|
||||
.userBox { /*width: 998px; border: 1px solid #eaeaea;*/
|
||||
margin: 0 auto 50px;
|
||||
background: #fff;
|
||||
border-radius: 6px
|
||||
}
|
||||
|
||||
.channelViewhistory .userBox {
|
||||
margin: 0 auto
|
||||
}
|
||||
|
||||
.user_l {
|
||||
width: 350px;
|
||||
float: left;
|
||||
padding: 50px 50px
|
||||
}
|
||||
|
||||
.user_l h3 {
|
||||
font-size: 23px;
|
||||
font-weight: normal;
|
||||
line-height: 1;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.user_l #LabErr {
|
||||
color: #ff4040;
|
||||
display: block;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.user_l .log_list {
|
||||
width: 350px
|
||||
}
|
||||
|
||||
.user_l .s_input {
|
||||
margin-bottom: 25px;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.s_input {
|
||||
width: 348px;
|
||||
height: 30px;
|
||||
line-height: 38px \9;
|
||||
vertical-align: middle;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 2px
|
||||
}
|
||||
|
||||
.icon_name, .icon_key, .icon_code {
|
||||
width: 312px;
|
||||
padding-left: 36px
|
||||
}
|
||||
|
||||
.icon_key {
|
||||
background-position: 13px -51px
|
||||
}
|
||||
|
||||
.icon_code {
|
||||
background-position: 13px -117px;
|
||||
width: 200px;
|
||||
float: left
|
||||
}
|
||||
|
||||
.code_pic {
|
||||
height: 38px;
|
||||
float: right
|
||||
}
|
||||
|
||||
.btn_phone {
|
||||
height: 40px;
|
||||
width: 100px;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
border-radius: 2px;
|
||||
background: #dfdfdf
|
||||
}
|
||||
|
||||
.log_code {
|
||||
*padding-bottom: 25px
|
||||
}
|
||||
|
||||
.user_l .btn_red {
|
||||
width: 100%;
|
||||
font-size: 19px;
|
||||
padding: 12px
|
||||
}
|
||||
|
||||
.autologin {
|
||||
color: #999;
|
||||
line-height: 1;
|
||||
margin-bottom: 18px
|
||||
}
|
||||
|
||||
.autologin em {
|
||||
vertical-align: 2px;
|
||||
margin-left: 4px
|
||||
}
|
||||
|
||||
.user_r {
|
||||
width: 259px;
|
||||
margin: 80px 0;
|
||||
padding: 20px 70px;
|
||||
border-left: 1px dotted #e3e3e3;
|
||||
float: right;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.user_r .tit {
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
padding: 6px 0 25px
|
||||
}
|
||||
|
||||
.user_r .btn_ora {
|
||||
padding: 10px 34px
|
||||
}
|
||||
|
||||
.fast_login {
|
||||
padding: 60px 0 0
|
||||
}
|
||||
|
||||
.fast_list {
|
||||
text-align: center;
|
||||
padding: 0.5rem
|
||||
}
|
||||
|
||||
.fast_list li {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
zoom: 1
|
||||
}
|
||||
|
||||
.fast_list li .img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin: 20px 0 5px
|
||||
}
|
||||
|
||||
.fast_list li a:hover {
|
||||
opacity: 0.8;
|
||||
filter: alpha(opacity=80);
|
||||
-moz-opacity: 0.8
|
||||
}
|
||||
|
||||
.fast_list li span {
|
||||
display: block
|
||||
}
|
||||
|
||||
.fast_list .login_qq {
|
||||
margin: 0 42px
|
||||
}
|
||||
|
||||
.fast_list .login_wb a {
|
||||
color: #f55c5b
|
||||
}
|
||||
|
||||
.fast_list .login_qq a {
|
||||
color: #51b7ff
|
||||
}
|
||||
|
||||
.fast_list .login_wx a {
|
||||
color: #66d65e
|
||||
}
|
||||
|
||||
.fast_tit {
|
||||
position: relative;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.fast_tit .lines {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
line-height: 1;
|
||||
background: #eaeaea
|
||||
}
|
||||
|
||||
.fast_tit .title {
|
||||
background: #fff;
|
||||
font-size: 16px;
|
||||
padding: 3px 14px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
z-index: 999
|
||||
}
|
||||
|
||||
/*userinfo*/
|
||||
.my_l {
|
||||
width: 198px;
|
||||
float: left;
|
||||
font-size: 13px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.my_l li a {
|
||||
display: block;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
padding-left: 62px;
|
||||
border-left: 4px solid #fff;
|
||||
margin-bottom: 5px;
|
||||
color: #666
|
||||
}
|
||||
|
||||
.my_l li .on {
|
||||
background-color: #fafafa;
|
||||
border-left: 2px solid #3eaf7c;
|
||||
color: #000;
|
||||
border-radius: 0 2px 2px 0
|
||||
}
|
||||
|
||||
.my_l .link_1 {
|
||||
background-position: 32px -188px
|
||||
}
|
||||
|
||||
.my_l .link_2 {
|
||||
background-position: 32px -230px
|
||||
}
|
||||
|
||||
.my_l .link_3 {
|
||||
background-position: 32px -272px
|
||||
}
|
||||
|
||||
.my_l .link_4 {
|
||||
background-position: 32px -314px
|
||||
}
|
||||
|
||||
.my_l .link_5 {
|
||||
background-position: 32px -356px
|
||||
}
|
||||
|
||||
.my_l .link_6 {
|
||||
background-position: 32px -397px
|
||||
}
|
||||
|
||||
.my_l .link_7 {
|
||||
background-position: 32px -440px
|
||||
}
|
||||
|
||||
.my_l .link_8 {
|
||||
background-position: 32px -481px
|
||||
}
|
||||
|
||||
.my_r {
|
||||
width: 739px;
|
||||
padding: 0 30px 30px;
|
||||
float: right;
|
||||
border-left: 1px solid #efefef;
|
||||
min-height: 470px
|
||||
}
|
||||
|
||||
.my_info {
|
||||
padding: 30px 0 5px
|
||||
}
|
||||
|
||||
.user_big_head { /*width:110px; height:110px; padding:4px; border:1px solid #eaeaea;*/
|
||||
margin-right: 30px;
|
||||
float: left;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.my_r .my_name {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
padding: 5px 0 12px 0
|
||||
}
|
||||
|
||||
.my_r .s_input {
|
||||
width: 318px;
|
||||
padding: 0 10px
|
||||
}
|
||||
|
||||
.my_list li {
|
||||
line-height: 28px
|
||||
}
|
||||
|
||||
.my_list li i, .my_list li em.red {
|
||||
margin-right: 6px
|
||||
}
|
||||
|
||||
.my_list .binded {
|
||||
color: #999;
|
||||
margin-left: 6px
|
||||
}
|
||||
|
||||
.my_list .btn_link {
|
||||
margin-left: 12px
|
||||
}
|
||||
|
||||
.mytab_list li {
|
||||
line-height: 30px;
|
||||
padding: 10px 0;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.mytab_list li .tit {
|
||||
width: 70px;
|
||||
color: #aaa;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
margin-right: 18px
|
||||
}
|
||||
|
||||
.mytab_list .user_img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
vertical-align: middle;
|
||||
border-radius: 50%
|
||||
}
|
||||
|
||||
.my_bookshelf .title {
|
||||
padding: 20px 0 15px;
|
||||
line-height: 30px
|
||||
}
|
||||
|
||||
.my_bookshelf h4 {
|
||||
font-size: 14px;
|
||||
color: #666
|
||||
}
|
||||
|
||||
.my_bookshelf h2 {
|
||||
font-size: 18px;
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
.updateTable {
|
||||
width: 739px;
|
||||
color: #999
|
||||
}
|
||||
|
||||
.updateTable table {
|
||||
width: 100%;
|
||||
margin-bottom: 14px
|
||||
}
|
||||
|
||||
.updateTable th, .updateTable td {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
vertical-align: middle;
|
||||
padding-left: 6px;
|
||||
font-weight: normal;
|
||||
text-align: left
|
||||
}
|
||||
|
||||
.updateTable th {
|
||||
background: #f9f9f9;
|
||||
color: #333;
|
||||
border-top: 1px solid #eee
|
||||
}
|
||||
|
||||
.updateTable td {
|
||||
height: 40px;
|
||||
line-height: 40px
|
||||
}
|
||||
|
||||
.updateTable .style {
|
||||
width: 80px;
|
||||
padding-left: 10px
|
||||
}
|
||||
|
||||
.updateTable .name {
|
||||
width: 178px;
|
||||
padding-right: 10px
|
||||
}
|
||||
|
||||
.updateTable .name a, .updateTable .chapter a {
|
||||
max-width: 168px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.updateTable .chapter {
|
||||
padding-right: 5px
|
||||
}
|
||||
|
||||
.updateTable .chapter a {
|
||||
max-width: 220px;
|
||||
float: left
|
||||
}
|
||||
|
||||
.updateTable .author {
|
||||
width: 72px;
|
||||
text-align: left
|
||||
}
|
||||
|
||||
.updateTable .goread {
|
||||
width: 80px;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.updateTable .time {
|
||||
width: 86px
|
||||
}
|
||||
|
||||
.updateTable .word {
|
||||
width: 64px;
|
||||
padding-right: 10px;
|
||||
text-align: right
|
||||
}
|
||||
|
||||
.updateTable .rank {
|
||||
width: 30px;
|
||||
padding-right: 10px;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.updateTable .name a, .updateTable .chapter a, .updateTable .author a {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
display: inline-block;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.updateTable tr:nth-child(2n) td {
|
||||
background: #fafafa
|
||||
}
|
||||
|
||||
.dataTable {
|
||||
width: 739px
|
||||
}
|
||||
|
||||
.dataTable table {
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
border-collapse: collapse
|
||||
}
|
||||
|
||||
.dataTable th, .dataTable td {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
vertical-align: middle;
|
||||
padding: 0 10px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
border: 1px solid #eaeaea
|
||||
}
|
||||
|
||||
.dataTable th {
|
||||
background: #f8f8f8
|
||||
}
|
||||
|
||||
.nodate {
|
||||
border-top: 1px solid #eaeaea;
|
||||
padding: 60px 0
|
||||
}
|
||||
|
||||
.viewhistoryBox { /*padding: 0 30px 30px; */
|
||||
padding: 0 20px 10px
|
||||
}
|
||||
|
||||
.viewhistoryBox .updateTable {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
/*.btn_gray, .btn_red, .btn_ora { font-size:14px; padding:8px 28px }*/
|
||||
.book_tit {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
margin: 0 14px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.book_tit .fl {
|
||||
font-size: 14px;
|
||||
color: #999
|
||||
}
|
||||
|
||||
.book_tit .fl h3 {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
font-weight: normal;
|
||||
margin-right: 5px;
|
||||
display: inline
|
||||
}
|
||||
|
||||
.book_tit .fr {
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.commentBar, .feedback_list {
|
||||
border-top: 1px solid #eee;
|
||||
margin-bottom: 15px
|
||||
}
|
||||
|
||||
.commentBar, .feedback_list { border-top:1px solid #eee; margin-bottom:15px }
|
||||
/*.comment_list { padding: 16px 0; border-bottom: 1px solid #eee }
|
||||
.comment_list .user_head { width:54px; height:54px; border-radius:50%; float: left; margin-right: 14px }
|
||||
.comment_list .li_1 { overflow: hidden }
|
||||
@ -105,33 +516,128 @@
|
||||
.comment_list .num { color: #ed4259; margin: 0 3px }
|
||||
.comment_list .li_4 { line-height:34px; padding-top:8px; margin-top:15px; border-top:1px solid #eaeaea }
|
||||
.comment_list .li_4 .more { background:#f7f7f7; border-radius:2px; color:#ed4259; text-align:center }*/
|
||||
.no_contet { padding:190px 0 40px; text-align:center; color:#999; border-top:1px solid #eee }
|
||||
.no_comment { background:url(../images/no_comment.png) no-repeat center 80px }
|
||||
.no_contet {
|
||||
padding: 190px 0 40px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
border-top: 1px solid #eee
|
||||
}
|
||||
|
||||
.no_comment {
|
||||
background: url(../images/no_comment.png) no-repeat center 80px
|
||||
}
|
||||
|
||||
.comment_list {
|
||||
padding: 20px 0;
|
||||
border-bottom: 1px solid #eee
|
||||
}
|
||||
|
||||
.comment_list:last-child {
|
||||
border: none
|
||||
}
|
||||
|
||||
.comment_list .user_heads { /*width: 54px; height: 54px; float: left;*/
|
||||
position: relative;
|
||||
margin-right: 20px
|
||||
}
|
||||
|
||||
.comment_list .user_head {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
background: #f6f6f6
|
||||
}
|
||||
|
||||
.comment_list .user_heads span {
|
||||
display: block;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
bottom: 0
|
||||
}
|
||||
|
||||
.comment_list ul { /*width: 640px;*/
|
||||
width: 660px;
|
||||
}
|
||||
|
||||
.comment_list .li_0 {
|
||||
font-family: "宋体"
|
||||
}
|
||||
|
||||
.comment_list .li_0 strong {
|
||||
font-size: 14px;
|
||||
color: #f00
|
||||
}
|
||||
|
||||
.comment_list .li_1 {
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.comment_list .user_name {
|
||||
color: #ed4259
|
||||
}
|
||||
|
||||
.comment_list .li_2 {
|
||||
padding: 6px 0
|
||||
}
|
||||
|
||||
.comment_list .li_3 {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.comment_list .reply {
|
||||
padding-left: 12px
|
||||
}
|
||||
|
||||
.comment_list .num {
|
||||
color: #ed4259;
|
||||
margin: 0 3px
|
||||
}
|
||||
|
||||
.comment_list .li_4 {
|
||||
line-height: 34px;
|
||||
padding-top: 8px;
|
||||
margin-top: 15px;
|
||||
border-top: 1px solid #eaeaea
|
||||
}
|
||||
|
||||
.pl_bar li {
|
||||
display: block
|
||||
}
|
||||
|
||||
.pl_bar .name {
|
||||
color: #666;
|
||||
padding-top: 2px;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.pl_bar .dec {
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
padding: 12px 0
|
||||
}
|
||||
|
||||
.pl_bar .other {
|
||||
line-height: 24px;
|
||||
color: #999;
|
||||
font-size: 13px
|
||||
}
|
||||
|
||||
.pl_bar .other a {
|
||||
display: inline-block;
|
||||
color: #999
|
||||
}
|
||||
|
||||
.pl_bar .reply {
|
||||
padding-left: 22px;
|
||||
background: url(../images/icon_reply.png) no-repeat 0 2px
|
||||
}
|
||||
|
||||
.comment_list { padding: 20px 0; border-bottom: 1px solid #eee }
|
||||
.comment_list:last-child { border: none }
|
||||
.comment_list .user_heads { /*width: 54px; height: 54px; float: left;*/ position:relative; margin-right: 20px }
|
||||
.comment_list .user_head { width: 50px; height: 50px; border-radius: 50%; background: #f6f6f6 }
|
||||
.comment_list .user_heads span { display: block; margin: 0; position: absolute; left: 12px; bottom: 0 }
|
||||
.comment_list ul { /*width: 640px;*/ width: 660px; }
|
||||
.comment_list .li_0 { font-family: "宋体" }
|
||||
.comment_list .li_0 strong { font-size: 14px; color: #f00 }
|
||||
.comment_list .li_1 { overflow: hidden }
|
||||
.comment_list .user_name { color: #ed4259 }
|
||||
.comment_list .li_2 { padding: 6px 0 }
|
||||
.comment_list .li_3 { color: #999 }
|
||||
.comment_list .reply { padding-left: 12px }
|
||||
.comment_list .num { color: #ed4259; margin: 0 3px }
|
||||
.comment_list .li_4 { line-height: 34px; padding-top: 8px; margin-top: 15px; border-top: 1px solid #eaeaea }
|
||||
.pl_bar li { display: block }
|
||||
.pl_bar .name { color: #666; padding-top: 2px; font-size: 14px }
|
||||
.pl_bar .dec { font-size: 14px; line-height: 1.8; padding: 12px 0 }
|
||||
.pl_bar .other { line-height: 24px; color: #999; font-size: 13px }
|
||||
.pl_bar .other a { display: inline-block; color: #999 }
|
||||
.pl_bar .reply { padding-left: 22px; background: url(../images/icon_reply.png) no-repeat 0 2px }
|
||||
/*.no_comment { padding: 70px 14px 115px; color: #CCCCCC; text-align: center; font-size: 14px; }*/
|
||||
.reply_bar {
|
||||
background: #f9f9f9;
|
||||
border: 1px solid #eee; border-radius: 6px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
line-height: 1.8;}
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
@ -457,8 +457,8 @@ html #layuicss-layer {
|
||||
}
|
||||
|
||||
.layui-layer-btn .layui-layer-btn0 {
|
||||
border-color: #f70;
|
||||
background-color: #f70;
|
||||
border-color: #3eaf7c;
|
||||
background-color: #3eaf7c;
|
||||
color: #fff
|
||||
}
|
||||
|
||||
|
@ -12,15 +12,7 @@
|
||||
</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 th:replace="crawl/header :: header">
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
@ -30,7 +22,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="/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>
|
||||
@ -47,7 +39,7 @@
|
||||
<h3>采集信息填写(示例均为笔趣阁:http://www.mcmssc.com)</h3>
|
||||
<ul class="log_list">
|
||||
<li><span id="LabErr"></span></li>
|
||||
<input type="hidden" id="sourceName" class="s_input icon_name" >
|
||||
<input type="hidden" id="sourceName" class="s_input icon_name">
|
||||
<b>采集源:</b>
|
||||
<li><select id="sourceId" class="s_input icon_key">
|
||||
</select></li>
|
||||
@ -99,16 +91,16 @@
|
||||
$.ajax({
|
||||
type: "get",
|
||||
url: "/crawl/listCrawlByPage",
|
||||
data: {'curr':1,'limit':100},
|
||||
data: {'curr': 1, 'limit': 100},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
var crawlSourceList = data.data.list;
|
||||
if (crawlSourceList.length > 0) {
|
||||
var crawlSourceListHtml = "";
|
||||
for(var i=0;i<crawlSourceList.length;i++){
|
||||
for (var i = 0; i < crawlSourceList.length; i++) {
|
||||
var crawlSource = crawlSourceList[i];
|
||||
crawlSourceListHtml+=("<option value=\""+crawlSource.id+"\">"+crawlSource.sourceName+"</option>");
|
||||
crawlSourceListHtml += ("<option value=\"" + crawlSource.id + "\">" + crawlSource.sourceName + "</option>");
|
||||
}
|
||||
$("#sourceId").html(crawlSourceListHtml);
|
||||
|
||||
@ -120,7 +112,7 @@
|
||||
//未登录
|
||||
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
|
||||
|
||||
}else {
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
@ -143,21 +135,21 @@
|
||||
|
||||
var sourceBookId = $("#sourceBookId").val();
|
||||
|
||||
if (!sourceBookId){
|
||||
if (!sourceBookId) {
|
||||
layer.alert("采集的源站小说ID不能为空");
|
||||
return;
|
||||
}
|
||||
|
||||
var bookName = $("#bookName").val();
|
||||
|
||||
if (!bookName){
|
||||
if (!bookName) {
|
||||
layer.alert("采集的小说名不能为空");
|
||||
return;
|
||||
}
|
||||
|
||||
var authorName = $("#authorName").val();
|
||||
|
||||
if (!authorName){
|
||||
if (!authorName) {
|
||||
layer.alert("采集的小说作者名不能为空");
|
||||
return;
|
||||
}
|
||||
@ -165,7 +157,14 @@
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/crawl/addCrawlSingleTask",
|
||||
data: {'sourceId': sourceId, 'sourceName': sourceName,'catId':catId,'sourceBookId' : sourceBookId,'bookName':bookName,'authorName':authorName},
|
||||
data: {
|
||||
'sourceId': sourceId,
|
||||
'sourceName': sourceName,
|
||||
'catId': catId,
|
||||
'sourceBookId': sourceBookId,
|
||||
'bookName': bookName,
|
||||
'authorName': authorName
|
||||
},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
|
@ -12,15 +12,7 @@
|
||||
</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 th:replace="crawl/header :: header">
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
@ -30,7 +22,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="/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>
|
||||
@ -151,7 +143,7 @@
|
||||
" " + crawlSource.excCount + "\n" +
|
||||
" </td>\n" +
|
||||
" <td class=\"goread\">\n" +
|
||||
" " + (crawlSource.taskStatus == 0 ? '采集失败' : (crawlSource.taskStatus == 1 ? '采集成功' : (crawlSource.excCount>0?'采集中':'排队中'))) + "\n" +
|
||||
" " + (crawlSource.taskStatus == 0 ? '采集失败' : (crawlSource.taskStatus == 1 ? '采集成功' : (crawlSource.excCount > 0 ? '采集中' : '排队中'))) + "\n" +
|
||||
" </td>\n" +
|
||||
" <td class=\"name\" valsc=\"291|2037554|1\">"
|
||||
+ crawlSource.createTime + "</td>\n" +
|
||||
@ -190,7 +182,7 @@
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
@ -207,7 +199,7 @@
|
||||
|
||||
$.ajax({
|
||||
type: "delete",
|
||||
url: "/crawl/delCrawlSingleTask/"+id,
|
||||
url: "/crawl/delCrawlSingleTask/" + id,
|
||||
data: {},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
|
@ -12,15 +12,7 @@
|
||||
</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 th:replace="crawl/header :: header">
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
@ -30,7 +22,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="/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>
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<!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>
|
||||
@ -7,19 +7,12 @@
|
||||
<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" />
|
||||
<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 th:replace="crawl/header :: header">
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
@ -29,9 +22,9 @@
|
||||
<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>-->
|
||||
<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>
|
||||
@ -40,6 +33,7 @@
|
||||
<div class="title cf">
|
||||
<h2 class="fl">爬虫源列表</h2>
|
||||
<div class="fr"><a href="/crawl/crawlSource_add.html" class="btn_red">增加爬虫源</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="divData" class="updateTable">
|
||||
@ -69,7 +63,6 @@
|
||||
<tbody id="crawlSourceList">
|
||||
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="pageBox cf" id="shellPage">
|
||||
@ -120,38 +113,39 @@
|
||||
<script language="javascript" type="text/javascript">
|
||||
search(1, 10);
|
||||
|
||||
var pageCrawlSourceList=null;
|
||||
var pageCrawlSourceList = null;
|
||||
|
||||
function search(curr, limit) {
|
||||
|
||||
$.ajax({
|
||||
type: "get",
|
||||
url: "/crawl/listCrawlByPage",
|
||||
data: {'curr':curr,'limit':limit},
|
||||
data: {'curr': curr, 'limit': limit},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
var crawlSourceList = data.data.list;
|
||||
pageCrawlSourceList=data.data.list;
|
||||
pageCrawlSourceList = data.data.list;
|
||||
if (crawlSourceList.length > 0) {
|
||||
var crawlSourceListHtml = "";
|
||||
for(var i=0;i<crawlSourceList.length;i++){
|
||||
for (var i = 0; i < crawlSourceList.length; i++) {
|
||||
var crawlSource = crawlSourceList[i];
|
||||
crawlSourceListHtml+=(" <tr class=\"book_list\" vals=\"291\">\n" +
|
||||
crawlSourceListHtml += (" <tr class=\"book_list\" vals=\"291\">\n" +
|
||||
" <td class=\"style bookclass\">\n" +
|
||||
" ["+(i+1)+"]\n" +
|
||||
" [" + (i + 1) + "]\n" +
|
||||
" </td>\n" +
|
||||
" <td class=\"chapter\">\n" +
|
||||
" "+crawlSource.sourceName+"</td>\n" +
|
||||
" " + crawlSource.sourceName + "</td>\n" +
|
||||
" <td class=\"name\" valsc=\"291|2037554|1\">"
|
||||
+crawlSource.createTime+"</td>\n" +
|
||||
+ crawlSource.createTime + "</td>\n" +
|
||||
" <td class=\"name\">\n" +
|
||||
" "+crawlSource.updateTime+"\n" +
|
||||
" " + crawlSource.updateTime + "\n" +
|
||||
" </td>\n" +
|
||||
" <td class=\"goread\" id='sourceStatus"+crawlSource.id+"'>"+(crawlSource.sourceStatus==0?'停止运行':'正在运行')+
|
||||
" <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>" +
|
||||
"<a href='javascript:updateCrawlSource("+crawlSource.id+")'>修改 </a>" +
|
||||
" <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);
|
||||
@ -190,7 +184,7 @@
|
||||
//未登录
|
||||
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
|
||||
|
||||
}else {
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
@ -201,31 +195,32 @@
|
||||
})
|
||||
|
||||
}
|
||||
function updateCrawlSource(crawlSourceId){
|
||||
|
||||
localStorage.setItem("crawlSourceId",crawlSourceId);
|
||||
window.location.href="/crawl/crawlSource_update.html";
|
||||
function updateCrawlSource(crawlSourceId) {
|
||||
|
||||
localStorage.setItem("crawlSourceId", crawlSourceId);
|
||||
window.location.href = "/crawl/crawlSource_update.html";
|
||||
|
||||
}
|
||||
|
||||
function openOrStopCrawl(sourceId,status) {
|
||||
function openOrStopCrawl(sourceId, status) {
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/crawl/openOrCloseCrawl",
|
||||
data: {'sourceId':sourceId,'sourceStatus':status==0?1:0},
|
||||
data: {'sourceId': sourceId, 'sourceStatus': status == 0 ? 1 : 0},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
|
||||
if(status == 0){
|
||||
if (status == 0) {
|
||||
//开启
|
||||
$("#sourceStatus"+sourceId).html("正在运行");
|
||||
$("#opt"+sourceId).html("<a href='javascript:openOrStopCrawl("+sourceId+","+1+")'>关闭</a>");
|
||||
}else{
|
||||
$("#sourceStatus" + sourceId).html("正在运行");
|
||||
$("#opt" + sourceId).html("<a href='javascript:openOrStopCrawl(" + sourceId + "," + 1 + ")'>关闭</a>");
|
||||
} else {
|
||||
//关闭
|
||||
$("#sourceStatus"+sourceId).html("停止运行");
|
||||
$("#opt"+sourceId).html("<a href='javascript:openOrStopCrawl("+sourceId+","+0+")'>开启</a>");
|
||||
$("#sourceStatus" + sourceId).html("停止运行");
|
||||
$("#opt" + sourceId).html("<a href='javascript:openOrStopCrawl(" + sourceId + "," + 0 + ")'>开启</a>");
|
||||
}
|
||||
|
||||
|
||||
@ -233,7 +228,7 @@
|
||||
//未登录
|
||||
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
|
||||
|
||||
}else {
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
@ -244,9 +239,6 @@
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
|
@ -12,15 +12,7 @@
|
||||
</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 th:replace="crawl/header :: header">
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
@ -28,9 +20,9 @@
|
||||
<div class="my_l">
|
||||
|
||||
<ul class="log_list">
|
||||
<li><a class="link_1 on" href="/">爬虫源管理</a></li>
|
||||
<li><a class="link_1" 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 on" 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>
|
||||
@ -64,12 +56,12 @@
|
||||
示例:<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><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>
|
||||
@ -120,11 +112,12 @@
|
||||
<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");
|
||||
var testParseUrl = localStorage.getItem("testParseUrl");
|
||||
$("#url").val(testParseUrl);
|
||||
var testParseRule = localStorage.getItem("testParseRule");
|
||||
$("#rule").val(testParseRule);
|
||||
}
|
||||
|
||||
function testCrawlSource() {
|
||||
|
||||
var data = {};
|
||||
@ -145,8 +138,8 @@
|
||||
}
|
||||
data.url = url;
|
||||
|
||||
localStorage.setItem("testParseUrl",url);
|
||||
localStorage.setItem("testParseRule",rule);
|
||||
localStorage.setItem("testParseUrl", url);
|
||||
localStorage.setItem("testParseRule", rule);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/crawl/testParse",
|
||||
|
@ -12,15 +12,7 @@
|
||||
</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 th:replace="crawl/header :: header">
|
||||
</div>
|
||||
|
||||
<div class="main box_center cf">
|
||||
@ -30,7 +22,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="/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>
|
||||
@ -204,12 +196,12 @@
|
||||
<script src="/javascript/user.js" type="text/javascript"></script>
|
||||
<script language="javascript" type="text/javascript">
|
||||
|
||||
function load(){
|
||||
function load() {
|
||||
var crawlSourceId = localStorage.getItem("crawlSourceId")
|
||||
if(crawlSourceId!=null){
|
||||
if (crawlSourceId != null) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/crawl/getCrawlSource/"+crawlSourceId,
|
||||
url: "/crawl/getCrawlSource/" + crawlSourceId,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
@ -218,7 +210,7 @@
|
||||
//未登录
|
||||
location.href = '/user/login.html?originUrl=' + decodeURIComponent(location.href);
|
||||
|
||||
}else {
|
||||
} else {
|
||||
layer.alert(data.msg);
|
||||
}
|
||||
|
||||
@ -229,20 +221,21 @@
|
||||
})
|
||||
}
|
||||
}
|
||||
function loadPage(data){
|
||||
|
||||
function loadPage(data) {
|
||||
$("#sourceId").val(data.id);
|
||||
$("#sourceName").val(data.sourceName);
|
||||
if(data.crawlRule){
|
||||
if (data.crawlRule) {
|
||||
|
||||
|
||||
var crawlRule= JSON.parse(data.crawlRule);
|
||||
var crawlRule = JSON.parse(data.crawlRule);
|
||||
$("#bookListUrl").val(crawlRule.bookListUrl);
|
||||
var catIdRule = crawlRule.catIdRule;
|
||||
try{
|
||||
try {
|
||||
for (var i = 1; i <= 7; i++) {
|
||||
$("#catId" + i).val(catIdRule["catId" + i]);
|
||||
}
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
}
|
||||
$("#bookIdPatten").val(crawlRule.bookIdPatten);
|
||||
$("#pagePatten").val(crawlRule.pagePatten);
|
||||
@ -253,14 +246,14 @@
|
||||
$("#picUrlPatten").val(crawlRule.picUrlPatten);
|
||||
$("#picUrlPrefix").val(crawlRule.picUrlPrefix);
|
||||
$("#statusPatten").val(crawlRule.statusPatten);
|
||||
try{
|
||||
try {
|
||||
var bookStatusRule = crawlRule.bookStatusRule;
|
||||
var i=0;
|
||||
for(var key in bookStatusRule){
|
||||
var i = 0;
|
||||
for (var key in bookStatusRule) {
|
||||
$("#bookStatus" + i).val(key);
|
||||
i++;
|
||||
}
|
||||
}catch (e) {
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
$("#scorePatten").val(crawlRule.scorePatten);
|
||||
@ -279,12 +272,13 @@
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
load();
|
||||
|
||||
function updateCrawlSource() {
|
||||
|
||||
var crawlRule = {};
|
||||
var sourceId =$("#sourceId").val();
|
||||
var sourceId = $("#sourceId").val();
|
||||
|
||||
var sourceName = $("#sourceName").val();
|
||||
if (sourceName.length == 0) {
|
||||
@ -498,7 +492,7 @@
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/crawl/updateCrawlSource",
|
||||
data: {'id':sourceId,'sourceName': sourceName, 'crawlRule': JSON.stringify(crawlRule)},
|
||||
data: {'id': sourceId, 'sourceName': sourceName, 'crawlRule': JSON.stringify(crawlRule)},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
|
28
novel-crawl/src/main/resources/templates/crawl/header.html
Normal file
@ -0,0 +1,28 @@
|
||||
<div th:fragment="header" 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;width: 100%">
|
||||
|
||||
小说精品屋爬虫管理
|
||||
<div style="text-align: center;height: 44px;line-height: 48px;font-size: 14px;float: right;padding-right: 20px">
|
||||
<a style="color: #fff;"
|
||||
href="/logout">
|
||||
|
||||
退出
|
||||
</a>
|
||||
</div>
|
||||
<div style="float: right;margin-right:5px;margin-top: 15px">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img"
|
||||
class="mr-3 iconify iconify--gitee icon-user-arrow-right" width="16" height="16"
|
||||
preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="M0 0h16v16H0z"></path>
|
||||
<path fill="currentColor" fill-rule="nonzero"
|
||||
d="M8 1.5a3.5 3.5 0 01.192 6.995L8 8.5a5.75 5.75 0 00-5.75 5.75.5.5 0 11-1 0 6.753 6.753 0 014.681-6.427A3.5 3.5 0 018 1.5zm6.996 10.767.003.041v.002l.001.011a.51.51 0 010 .006v.006l-.002.03a.502.502 0 01-.004.037l-.002.011a.39.39 0 01-.016.063.491.491 0 01-.053.114l-.028.039-.031.035.027-.03-.009.011-.017.02-.011.012-2.122 2.121a.5.5 0 01-.707-.707l1.268-1.268H9.5a.5.5 0 110-1h3.794l-1.269-1.267a.5.5 0 11.707-.708l2.122 2.122a.491.491 0 01.135.248l.005.037v-.006zM8 2.5a2.5 2.5 0 100 5 2.5 2.5 0 000-5z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -5,25 +5,55 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<title>Please sign in</title>
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
|
||||
<link href="/css/signin.css" rel="stylesheet" crossorigin="anonymous"/>
|
||||
<title>爬虫管理系统登录</title>
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link href="/css/signin.css" rel="stylesheet"/>
|
||||
<style>
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #3eaf7c;
|
||||
border-color: #3eaf7c
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #65bf96;
|
||||
border-color: #65bf96
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
box-shadow: 0 0 0 3px rgba(101, 191, 96, .5)
|
||||
}
|
||||
|
||||
.btn-primary.disabled, .btn-primary:disabled {
|
||||
background-color: #3eaf7c;
|
||||
border-color: #3eaf7c
|
||||
}
|
||||
|
||||
|
||||
.form-control:focus {
|
||||
color: #495057;
|
||||
background-color: #fff;
|
||||
border-color: #78c7a3;
|
||||
outline: 0
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<form class="form-signin" method="post" action="/login">
|
||||
<h2 class="form-signin-heading">Please sign in</h2>
|
||||
<h4 style="text-align: center" class="form-signin-heading">爬虫管理系统登录</h4>
|
||||
<p>
|
||||
<label for="username" class="sr-only">Username</label>
|
||||
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required
|
||||
<label for="username" class="sr-only">用户名</label>
|
||||
<input type="text" id="username" name="username" class="form-control" placeholder="用户名" required
|
||||
autofocus>
|
||||
</p>
|
||||
<p>
|
||||
<label for="password" class="sr-only">Password</label>
|
||||
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
|
||||
<label for="password" class="sr-only">密码</label>
|
||||
<input type="password" id="password" name="password" class="form-control" placeholder="密码" required>
|
||||
</p>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -1,6 +0,0 @@
|
||||
FROM java:8
|
||||
ADD novel-front-1.1.0.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -jar /root/novel-front-1.1.0.jar"]
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>novel</artifactId>
|
||||
<groupId>com.java2nb</groupId>
|
||||
<version>4.2.0</version>
|
||||
<version>4.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -98,6 +98,9 @@
|
||||
<zip destfile='${project.build.directory}/build/${project.artifactId}.zip'>
|
||||
<zipfileset filemode="755" dir='${project.build.directory}/build/'/>
|
||||
</zip>
|
||||
|
||||
<copy file="${basedir}/src/main/build/docker/Dockerfile"
|
||||
tofile="${project.build.directory}/build/Dockerfile"/>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
@ -34,7 +34,7 @@ pic:
|
||||
|
||||
#模版配置
|
||||
templates:
|
||||
name: orange
|
||||
name: green
|
||||
|
||||
#小说内容保存配置
|
||||
content:
|
||||
|
9
novel-front/src/main/build/docker/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM openjdk:8
|
||||
ADD novel-front.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENV redishost = ""
|
||||
ENV redisport = ""
|
||||
ENV redispwd = ""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -Dspring.redis.host=${redishost} -Dspring.redis.port=${redisport} -Dspring.redis.password=${redispwd} -jar /root/novel-front.jar"]
|
@ -6,6 +6,7 @@ import com.alipay.api.DefaultAlipayClient;
|
||||
import com.alipay.api.internal.util.AlipaySignature;
|
||||
import com.alipay.api.request.AlipayTradePagePayRequest;
|
||||
import com.alipay.api.request.AlipayTradeWapPayRequest;
|
||||
import com.alipay.api.response.AlipayTradePagePayResponse;
|
||||
import com.alipay.api.response.AlipayTradeWapPayResponse;
|
||||
import com.java2nb.novel.core.bean.UserDetails;
|
||||
import com.java2nb.novel.core.config.AlipayProperties;
|
||||
@ -50,7 +51,7 @@ public class PayController extends BaseController {
|
||||
UserDetails userDetails = getUserDetails(request);
|
||||
if (userDetails == null) {
|
||||
//未登录,跳转到登陆页面
|
||||
httpResponse.sendRedirect("/user/login.html?originUrl=/pay/aliPay?payAmount=" + payAmount);
|
||||
httpResponse.sendRedirect("/user/login.html?originUrl=/pay/index.html");
|
||||
} else {
|
||||
//创建充值订单
|
||||
Long outTradeNo = orderService.createPayOrder((byte) 1, payAmount, userDetails.getId());
|
||||
@ -79,8 +80,8 @@ public class PayController extends BaseController {
|
||||
bizContent.put("product_code", "QUICK_WAP_WAY");
|
||||
|
||||
alipayRequest.setBizContent(bizContent.toString());
|
||||
AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest);
|
||||
form = alipayClient.pageExecute(alipayRequest).getBody();
|
||||
AlipayTradeWapPayResponse payResponse = alipayClient.pageExecute(alipayRequest);
|
||||
form = payResponse.getBody();
|
||||
} else {
|
||||
// 电脑站
|
||||
//创建API对应的request
|
||||
@ -96,7 +97,8 @@ public class PayController extends BaseController {
|
||||
" \"subject\":\"小说精品屋-plus\"" +
|
||||
" }");
|
||||
//调用SDK生成表单
|
||||
form = alipayClient.pageExecute(alipayRequest).getBody();
|
||||
AlipayTradePagePayResponse payResponse = alipayClient.pageExecute(alipayRequest);
|
||||
form = payResponse.getBody();
|
||||
|
||||
}
|
||||
|
||||
@ -119,7 +121,7 @@ public class PayController extends BaseController {
|
||||
|
||||
PrintWriter out = httpResponse.getWriter();
|
||||
|
||||
//获取支付宝POST过来反馈信息
|
||||
//获取支付宝POST过来的信息
|
||||
Map<String, String> params = new HashMap<>();
|
||||
Map<String, String[]> requestParams = request.getParameterMap();
|
||||
for (String name : requestParams.keySet()) {
|
||||
@ -132,18 +134,10 @@ public class PayController extends BaseController {
|
||||
params.put(name, valueStr);
|
||||
}
|
||||
|
||||
//调用SDK验证签名
|
||||
//验证签名
|
||||
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getPublicKey(),
|
||||
alipayConfig.getCharset(), alipayConfig.getSignType());
|
||||
|
||||
//——请在这里编写您的程序(以下代码仅作参考)——
|
||||
|
||||
/* 实际验证过程建议商户务必添加以下校验:
|
||||
1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
|
||||
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
|
||||
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
|
||||
4、验证app_id是否为该商户本身。
|
||||
*/
|
||||
if (signVerified) {
|
||||
//验证成功
|
||||
//商户订单号
|
||||
@ -158,21 +152,18 @@ public class PayController extends BaseController {
|
||||
String tradeStatus = new String(request.getParameter("trade_status").getBytes(StandardCharsets.ISO_8859_1),
|
||||
StandardCharsets.UTF_8);
|
||||
|
||||
//更新订单状态
|
||||
orderService.updatePayOrder(Long.parseLong(outTradeNo), tradeNo, tradeStatus);
|
||||
if ("TRADE_SUCCESS".equals(tradeStatus)) {
|
||||
//支付成功
|
||||
orderService.updatePayOrder(Long.parseLong(outTradeNo), tradeNo, 1);
|
||||
}
|
||||
|
||||
out.println("success");
|
||||
|
||||
} else {//验证失败
|
||||
out.println("fail");
|
||||
|
||||
//调试用,写文本函数记录程序运行情况是否正常
|
||||
//String sWord = AlipaySignature.getSignCheckContentV1(params);
|
||||
//AlipayConfig.logResult(sWord);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.java2nb.novel.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public interface FrontUserMapper extends UserMapper {
|
||||
|
||||
|
||||
|
||||
void addUserBalance(@Param("userId") Long userId, @Param("amount") Integer amount);
|
||||
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package com.java2nb.novel.service;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author 11797
|
||||
*/
|
||||
@ -12,18 +11,19 @@ public interface OrderService {
|
||||
* 创建充值订单
|
||||
*
|
||||
* @param payChannel 支付渠道
|
||||
* @param payAmount 支付金额
|
||||
* @param userId 用户ID
|
||||
* @param payAmount 支付金额
|
||||
* @param userId 用户ID
|
||||
* @return 商户订单号
|
||||
* */
|
||||
*/
|
||||
Long createPayOrder(Byte payChannel, Integer payAmount, Long userId);
|
||||
|
||||
|
||||
/**
|
||||
* 更新订单状态
|
||||
*
|
||||
* @param outTradeNo 商户订单号
|
||||
* @param tradeNo 支付宝/微信 订单号
|
||||
* @param tradeStatus 支付状态
|
||||
* */
|
||||
void updatePayOrder(Long outTradeNo, String tradeNo, String tradeStatus);
|
||||
* @param tradeNo 支付宝/微信 订单号
|
||||
* @param payStatus 支付状态
|
||||
*/
|
||||
void updatePayOrder(Long outTradeNo, String tradeNo, int payStatus);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.mybatis.dynamic.sql.render.RenderingStrategies;
|
||||
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
|
||||
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -17,6 +18,7 @@ import java.util.Date;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
|
||||
import static org.mybatis.dynamic.sql.SqlBuilder.update;
|
||||
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
|
||||
|
||||
/**
|
||||
@ -35,7 +37,8 @@ public class OrderServiceImpl implements OrderService {
|
||||
@Override
|
||||
public Long createPayOrder(Byte payChannel, Integer payAmount, Long userId) {
|
||||
Date currentDate = new Date();
|
||||
Long outTradeNo = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(currentDate)+new Random().nextInt(10));
|
||||
Long outTradeNo = Long.parseLong(
|
||||
new SimpleDateFormat("yyyyMMddHHmmssSSS").format(currentDate) + new Random().nextInt(10));
|
||||
OrderPay orderPay = new OrderPay();
|
||||
orderPay.setOutTradeNo(outTradeNo);
|
||||
orderPay.setPayChannel(payChannel);
|
||||
@ -49,37 +52,39 @@ public class OrderServiceImpl implements OrderService {
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updatePayOrder(Long outTradeNo, String tradeNo, String tradeStatus) {
|
||||
SelectStatementProvider selectStatement = select(OrderPayDynamicSqlSupport.id,OrderPayDynamicSqlSupport.payStatus,OrderPayDynamicSqlSupport.totalAmount,OrderPayDynamicSqlSupport.userId)
|
||||
.from(OrderPayDynamicSqlSupport.orderPay)
|
||||
.where(OrderPayDynamicSqlSupport.outTradeNo, isEqualTo(outTradeNo))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
public void updatePayOrder(Long outTradeNo, String tradeNo, int payStatus) {
|
||||
SelectStatementProvider selectStatement = select(OrderPayDynamicSqlSupport.id,
|
||||
OrderPayDynamicSqlSupport.payStatus, OrderPayDynamicSqlSupport.totalAmount,
|
||||
OrderPayDynamicSqlSupport.userId)
|
||||
.from(OrderPayDynamicSqlSupport.orderPay)
|
||||
.where(OrderPayDynamicSqlSupport.outTradeNo, isEqualTo(outTradeNo))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
|
||||
OrderPay orderPay = orderPayMapper.selectMany(selectStatement).get(0);
|
||||
OrderPay orderPay = orderPayMapper.selectOne(selectStatement).orElse(null);
|
||||
|
||||
if(orderPay.getPayStatus()!=1) {
|
||||
//此订单还未处理过
|
||||
|
||||
if (tradeStatus.equals("TRADE_SUCCESS") || tradeStatus.equals("TRADE_FINISHED")) {
|
||||
if (orderPay.getPayStatus().intValue() == 2) {
|
||||
//待支付订单处理
|
||||
if (payStatus == 1) {
|
||||
//支付成功
|
||||
//1.更新订单状态为成功
|
||||
orderPay.setPayStatus((byte) 1);
|
||||
orderPay.setUpdateTime(new Date());
|
||||
orderPayMapper.updateByPrimaryKeySelective(orderPay);
|
||||
|
||||
//2.增加用户余额
|
||||
userService.addAmount(orderPay.getUserId(),orderPay.getTotalAmount()*100);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UpdateStatementProvider updateStatement = update(OrderPayDynamicSqlSupport.orderPay)
|
||||
.set(OrderPayDynamicSqlSupport.tradeNo).equalTo(tradeNo)
|
||||
.set(OrderPayDynamicSqlSupport.payStatus).equalTo((byte) 1)
|
||||
.set(OrderPayDynamicSqlSupport.updateTime).equalTo(new Date())
|
||||
.where(OrderPayDynamicSqlSupport.id, isEqualTo(orderPay.getId()))
|
||||
.and(OrderPayDynamicSqlSupport.payStatus, isEqualTo((byte) 2))
|
||||
.build()
|
||||
.render(RenderingStrategies.MYBATIS3);
|
||||
int updateRow = orderPayMapper.update(updateStatement);
|
||||
if (updateRow > 0) {
|
||||
//更新成功
|
||||
//2.增加用户余额
|
||||
userService.addAmount(orderPay.getUserId(), orderPay.getTotalAmount() * 100);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|