├── .env.development ├── .env.production ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── jsconfig.json ├── package.json ├── public ├── default.gif ├── favicon.ico └── index.html ├── src ├── App.vue ├── api │ ├── author.js │ ├── book.js │ ├── home.js │ ├── news.js │ ├── resource.js │ └── user.js ├── assets │ ├── images │ │ ├── 404.jpeg │ │ ├── author_head.png │ │ ├── default.gif │ │ ├── icon_dt.png │ │ ├── icon_readpage.png │ │ ├── icon_reply.png │ │ ├── icon_sj.png │ │ ├── icon_user.png │ │ ├── login_qq.png │ │ ├── login_weibo.png │ │ ├── login_weixin.png │ │ ├── logo.png │ │ ├── logo_white.png │ │ ├── man.png │ │ ├── no_comment.png │ │ ├── pay_wx.png │ │ ├── pay_zfb.png │ │ ├── pic_upload.png │ │ ├── search.png │ │ └── smlcover.png │ ├── logo.png │ └── styles │ │ ├── about.css │ │ ├── base.css │ │ ├── book.css │ │ ├── easyui.css │ │ ├── layer.css │ │ ├── main.css │ │ ├── read.css │ │ └── user.css ├── components │ ├── author │ │ └── Header.vue │ ├── common │ │ ├── Footer.vue │ │ ├── Header.vue │ │ ├── Navbar.vue │ │ └── Top.vue │ ├── home │ │ ├── BookNewestRank.vue │ │ ├── BookUpdateRank.vue │ │ ├── BookVisitRank.vue │ │ ├── FriendLink.vue │ │ └── LatestNews.vue │ └── user │ │ └── Menu.vue ├── main.js ├── router │ └── index.js ├── utils │ ├── auth.js │ ├── index.js │ └── request.js └── views │ ├── Book.vue │ ├── BookClass.vue │ ├── BookContent.vue │ ├── BookRank.vue │ ├── ChapterList.vue │ ├── FeadBack.vue │ ├── Home.vue │ ├── Login.vue │ ├── News.vue │ ├── Register.vue │ ├── UserComment.vue │ ├── UserSetup.vue │ └── author │ ├── BookAdd.vue │ ├── BookList.vue │ ├── ChapterAdd.vue │ ├── ChapterList.vue │ ├── ChapterUpdate.vue │ └── Register.vue ├── vue.config.js └── yarn.lock /.env.development: -------------------------------------------------------------------------------- 1 | # 开发环境配置 2 | 3 | ENV = 'development' 4 | VUE_APP_BASE_API_URL = 'http://127.0.0.1:8888/api' 5 | VUE_APP_BASE_IMG_URL = 'http://127.0.0.1:8888' 6 | 7 | 8 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | # 生产环境配置 2 | 3 | ENV = 'production' 4 | VUE_APP_BASE_API_URL = 'http://api.test.baidu.com/api' 5 | VUE_APP_BASE_IMG_URL = 'http://api.test.baidu.com' 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=Vue 2 | *.css linguist-language=Vue 3 | *.html linguist-language=Vue 4 | *.vue linguist-language=Vue 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![index]( https://youdoc.github.io/img/tencent.jpg )]( https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console ) 2 | 3 |

4 | Github stars 5 | Github forks 6 | Gitee stars 7 | Gitee forks 8 |

9 | 10 | ## 项目简介 11 | 12 | novel 是一套基于时下**最新** Java 技术栈 Spring Boot 3 + Vue 3 开发的前后端分离**学习型** 13 | 小说项目,配备[保姆级教程](https://docs.xxyopen.com/course/novel)手把手教你**从零开始**开发上线一套生产级别的 Java 14 | 系统,由小说门户系统、作家后台管理系统、平台后台管理系统等多个子系统构成。包括小说推荐、作品检索、小说排行榜、小说阅读、小说评论、会员中心、作家专区、充值订阅、新闻发布等功能。 15 | 16 | ## 项目地址 17 | 18 | - 后端项目(更新中):[GitHub](https://github.com/201206030/novel) | [码云](https://gitee.com/novel_dev_team/novel) 19 | - 前端项目(更新中):[GitHub](https://github.com/201206030/novel-front-web) 20 | | [码云](https://gitee.com/novel_dev_team/novel-front-web) 21 | - 线上应用版:[GitHub](https://github.com/201206030/novel-plus) | [码云](https://gitee.com/novel_dev_team/novel-plus) 22 | - 微服务版:[GitHub](https://github.com/201206030/novel-cloud) | [码云](https://gitee.com/novel_dev_team/novel-cloud) 23 | 24 | ## 开发环境 25 | 26 | - MySQL 8.0 27 | - Redis 7.0 28 | - Elasticsearch 8.2.0(可选) 29 | - RabbitMQ 3.10.2(可选) 30 | - XXL-JOB 2.3.1(可选) 31 | - JDK 21 32 | - Maven 3.8 33 | - IntelliJ IDEA(可选) 34 | - Node 16.14 35 | 36 | **注:Elasticsearch、RabbitMQ 和 XXL-JOB 默认关闭,可通过 application.yml 配置文件中相应的`enable`配置属性开启。** 37 | 38 | ## 后端技术选型 39 | 40 | | 技术 | 版本 | 说明 | 官网 | 学习 | 41 | |---------------------|:------------:|-------------------------| ------------------------------------ |:------------------------------------------------------------------------------------------------------------------------:| 42 | | Spring Boot | 3.3.0 | 容器 + MVC 框架 | [进入](https://spring.io/projects/spring-boot) | [进入](https://docs.spring.io/spring-boot/docs/3.0.0/reference/html) | 43 | | Spring AI | 1.0.0-SNAPSHOT | Spring 官方 AI 框架 | [进入](https://spring.io/projects/spring-ai) | [进入](https://docs.spring.io/spring-ai/reference/) | 44 | | MyBatis | 3.5.9 | ORM 框架 | [进入](http://www.mybatis.org) | [进入](https://mybatis.org/mybatis-3/zh/index.html) | 45 | | MyBatis-Plus | 3.5.3 | MyBatis 增强工具 | [进入](https://baomidou.com/) | [进入](https://baomidou.com/pages/24112f/) | 46 | | JJWT | 0.11.5 | JWT 登录支持 | [进入](https://github.com/jwtk/jjwt) | - | 47 | | Lombok | 1.18.24 | 简化对象封装工具 | [进入](https://github.com/projectlombok/lombok) | [进入](https://projectlombok.org/features/all) | 48 | | Caffeine | 3.1.0 | 本地缓存支持 | [进入](https://github.com/ben-manes/caffeine) | [进入](https://github.com/ben-manes/caffeine/wiki/Home-zh-CN) | 49 | | Redis | 7.0 | 分布式缓存支持 | [进入](https://redis.io) | [进入](https://redis.io/docs) | 50 | | Redisson | 3.17.4 | 分布式锁实现 | [进入](https://github.com/redisson/redisson) | [进入](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 51 | | MySQL | 8.0 | 数据库服务 | [进入](https://www.mysql.com) | [进入](https://docs.oracle.com/en-us/iaas/mysql-database/doc/getting-started.html) | 52 | | ShardingSphere-JDBC | 5.5.1 | 数据库分库分表支持 | [进入](https://shardingsphere.apache.org) | [进入](https://shardingsphere.apache.org/document/5.1.1/cn/overview) | 53 | | Elasticsearch | 8.2.0 | 搜索引擎服务 | [进入](https://www.elastic.co) | [进入](https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html) | 54 | | RabbitMQ | 3.10.2 | 开源消息中间件 | [进入](https://www.rabbitmq.com) | [进入](https://www.rabbitmq.com/tutorials/tutorial-one-java.html) | 55 | | XXL-JOB | 2.3.1 | 分布式任务调度平台 | [进入](https://www.xuxueli.com/xxl-job) | [进入](https://www.xuxueli.com/xxl-job) | 56 | | Sentinel | 1.8.4 | 流量控制组件 | [进入](https://github.com/alibaba/Sentinel) | [进入](https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5) | 57 | | Springdoc-openapi | 2.0.0 | Swagger 3 接口文档自动生成 | [进入](https://github.com/springdoc/springdoc-openapi) | [进入](https://springdoc.org/) | 58 | | Spring Boot Admin | 3.0.0-M1 | 应用管理和监控 | [进入](https://github.com/codecentric/spring-boot-admin) | [进入](https://codecentric.github.io/spring-boot-admin/3.0.0-M1) | 59 | | Tomcat | 10.1.24 | Spring Boot 默认内嵌 Web 容器 | [进入](https://tomcat.apache.org) | [进入](https://tomcat.apache.org/tomcat-10.1-doc/index.html) | 60 | | Docker | - | 应用容器引擎 | [进入](https://www.docker.com/) | - | 61 | | Jenkins | - | 自动化部署工具 | [进入](https://github.com/jenkinsci/jenkins) | - | 62 | | Sonarqube | - | 代码质量控制 | [进入](https://www.sonarqube.org/) | - | 63 | 64 | **注:更多热门新技术待集成。** 65 | 66 | ## 前端技术选型 67 | 68 | | 技术 | 版本 | 说明 | 官网 | 学习 | 69 | | :----------------- | :-----: | -------------------------- | --------------------------------------- | :-------------------------------------------------: | 70 | | Vue.js | 3.2.13 | 渐进式 JavaScript 框架 | [进入](https://vuejs.org) | [进入](https://staging-cn.vuejs.org/guide/introduction.html) | 71 | | Vue Router | 4.0.15 | Vue.js 的官方路由 | [进入](https://router.vuejs.org) | [进入](https://router.vuejs.org/zh/guide/) | 72 | | axios | 0.27.2 | 基于 promise 的网络请求库 | [进入](https://axios-http.com) | [进入](https://axios-http.com/zh/docs/intro) | 73 | | element-plus | 2.2.0 | 基于 Vue 3,面向设计师和开发者的组件库 | [进入](https://element-plus.org) | [进入](https://element-plus.org/zh-CN/guide/design.html) | 74 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "baseUrl": "./", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": [ 9 | "src/*" 10 | ] 11 | }, 12 | "lib": [ 13 | "esnext", 14 | "dom", 15 | "dom.iterable", 16 | "scripthost" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "novel-front-web", 3 | "version": "3.4.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.27.2", 12 | "core-js": "^3.8.3", 13 | "element-plus": "^2.2.0", 14 | "jquery": "^3.6.0", 15 | "vue": "^3.2.13", 16 | "vue-router": "^4.0.15" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.12.16", 20 | "@babel/eslint-parser": "^7.12.16", 21 | "@vue/cli-plugin-babel": "~5.0.0", 22 | "@vue/cli-plugin-eslint": "~5.0.0", 23 | "@vue/cli-service": "~5.0.0", 24 | "eslint": "^7.32.0", 25 | "eslint-plugin-vue": "^8.0.3" 26 | }, 27 | "eslintConfig": { 28 | "root": true, 29 | "env": { 30 | "node": true 31 | }, 32 | "extends": [ 33 | "plugin:vue/vue3-essential", 34 | "eslint:recommended" 35 | ], 36 | "parserOptions": { 37 | "parser": "@babel/eslint-parser" 38 | }, 39 | "rules": {} 40 | }, 41 | "browserslist": [ 42 | "> 1%", 43 | "last 2 versions", 44 | "not dead", 45 | "not ie 11" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /public/default.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/public/default.gif -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/api/author.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | export function getAuthorStatus() { 4 | return request.get('/author/status'); 5 | } 6 | 7 | export function register(params) { 8 | return request.post('/author/register', params); 9 | } 10 | 11 | export function listBooks(params) { 12 | return request.get('/author/books', { params }); 13 | } 14 | 15 | export function publishBook(params) { 16 | return request.post('/author/book', params); 17 | } 18 | 19 | export function listChapters(bookId, params) { 20 | return request.get(`/author/book/chapters/${bookId}`, { params }); 21 | } 22 | 23 | export function publishChapter(bookId,params) { 24 | return request.post(`/author/book/chapter/${bookId}`, params); 25 | } 26 | 27 | export function aiGenerate(action,params) { 28 | const formData = new FormData(); 29 | Object.keys(params).forEach(key => { 30 | formData.append(key, params[key]); 31 | }); 32 | return request.post(`/author/ai/${action}`, formData, { 33 | headers: { 34 | 'Content-Type': 'application/x-www-form-urlencoded' 35 | }, 36 | timeout: 60000 37 | }); 38 | } 39 | 40 | export function deleteChapter(id) { 41 | return request.delete(`/author/book/chapter/${id}`); 42 | } 43 | 44 | export function getChapter(id) { 45 | return request.get(`/author/book/chapter/${id}`); 46 | } 47 | 48 | export function updateChapter(id,params) { 49 | return request.put(`/author/book/chapter/${id}`,params); 50 | } -------------------------------------------------------------------------------- /src/api/book.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | export function listCategorys(params) { 4 | return request.get('/front/book/category/list', { params }); 5 | } 6 | 7 | export function searchBooks(params) { 8 | return request.get('/front/search/books', { params }); 9 | } 10 | 11 | export function getBookById(bookId) { 12 | return request.get(`/front/book/${bookId}`); 13 | } 14 | 15 | export function addVisitCount(params) { 16 | return request.post('/front/book/visit', params); 17 | } 18 | 19 | export function getLastChapterAbout(params) { 20 | return request.get('/front/book/last_chapter/about', { params }); 21 | } 22 | 23 | export function listRecBooks(params) { 24 | return request.get('/front/book/rec_list', { params }); 25 | } 26 | 27 | export function listChapters(params) { 28 | return request.get('/front/book/chapter/list', { params }); 29 | } 30 | 31 | export function getBookContent(chapterId) { 32 | return request.get(`/front/book/content/${chapterId}`); 33 | } 34 | 35 | export function getPreChapterId(chapterId) { 36 | return request.get(`/front/book/pre_chapter_id/${chapterId}`); 37 | } 38 | 39 | export function getNextChapterId(chapterId) { 40 | return request.get(`/front/book/next_chapter_id/${chapterId}`); 41 | } 42 | 43 | export function listVisitRankBooks() { 44 | return request.get('/front/book/visit_rank'); 45 | } 46 | 47 | export function listNewestRankBooks() { 48 | return request.get('/front/book/newest_rank'); 49 | } 50 | 51 | export function listUpdateRankBooks() { 52 | return request.get('/front/book/update_rank'); 53 | } 54 | 55 | export function listNewestComments(params) { 56 | return request.get('/front/book/comment/newest_list',{ params }); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/api/home.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | export function listHomeBooks() { 4 | return request.get('/front/home/books'); 5 | } 6 | 7 | 8 | export function listHomeFriendLinks() { 9 | return request.get('/front/home/friend_Link/list'); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/api/news.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | export function listLatestNews() { 4 | return request.get('/front/news/latest_list'); 5 | } 6 | 7 | export function getNewsById(newsId) { 8 | return request.get(`/front/news/${newsId}`); 9 | } -------------------------------------------------------------------------------- /src/api/resource.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | export function getImgVerifyCode() { 4 | return request.get('/front/resource/img_verify_code'); 5 | } 6 | -------------------------------------------------------------------------------- /src/api/user.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | export function register(params) { 4 | return request.post('/front/user/register', params); 5 | } 6 | 7 | export function login(params) { 8 | return request.post('/front/user/login', params); 9 | } 10 | 11 | export function submitFeedBack(params) { 12 | return request.post('/front/user/feedback', params); 13 | } 14 | 15 | export function comment(params) { 16 | return request.post('/front/user/comment',params); 17 | } 18 | 19 | export function deleteComment(id) { 20 | return request.delete(`/front/user/comment/${id}`); 21 | } 22 | 23 | export function updateComment(id,content) { 24 | return request.putForm(`/front/user/comment/${id}`,content); 25 | } 26 | 27 | export function getUserinfo() { 28 | return request.get('/front/user'); 29 | } 30 | 31 | export function updateUserInfo(userInfo) { 32 | return request.put('/front/user',userInfo); 33 | } 34 | 35 | export function listComments(params) { 36 | return request.get('/front/user/comments', { params }); 37 | } -------------------------------------------------------------------------------- /src/assets/images/404.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/404.jpeg -------------------------------------------------------------------------------- /src/assets/images/author_head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/author_head.png -------------------------------------------------------------------------------- /src/assets/images/default.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/default.gif -------------------------------------------------------------------------------- /src/assets/images/icon_dt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/icon_dt.png -------------------------------------------------------------------------------- /src/assets/images/icon_readpage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/icon_readpage.png -------------------------------------------------------------------------------- /src/assets/images/icon_reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/icon_reply.png -------------------------------------------------------------------------------- /src/assets/images/icon_sj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/icon_sj.png -------------------------------------------------------------------------------- /src/assets/images/icon_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/icon_user.png -------------------------------------------------------------------------------- /src/assets/images/login_qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/login_qq.png -------------------------------------------------------------------------------- /src/assets/images/login_weibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/login_weibo.png -------------------------------------------------------------------------------- /src/assets/images/login_weixin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/login_weixin.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/logo_white.png -------------------------------------------------------------------------------- /src/assets/images/man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/man.png -------------------------------------------------------------------------------- /src/assets/images/no_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/no_comment.png -------------------------------------------------------------------------------- /src/assets/images/pay_wx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/pay_wx.png -------------------------------------------------------------------------------- /src/assets/images/pay_zfb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/pay_zfb.png -------------------------------------------------------------------------------- /src/assets/images/pic_upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/pic_upload.png -------------------------------------------------------------------------------- /src/assets/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/search.png -------------------------------------------------------------------------------- /src/assets/images/smlcover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/images/smlcover.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/201206030/novel-front-web/7004f55fc92d3ca4e5f53bbaef4197edccaa42da/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/styles/about.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | .userBox { width: 998px; border: 1px solid #eaeaea; margin: 0 auto 50px; background: #fff } 3 | .my_l { width: 198px; float: left; font-size: 13px; 4 | padding-top: 20px; } 5 | .my_l li a { display: block; height: 48px; line-height: 48px; padding-left: 40px; border-left: 2px solid transparent; font-size: 14px; margin: 0 0 2px; } 6 | .my_l li .on { border-left: 2px solid #f80; background: #f8f8f8 } 7 | .my_r { width: 739px; padding: 30px; float: right; border-left: 1px solid #ededed; min-height: 470px; background: #fff } 8 | .my_r .title { padding: 15px 0 } 9 | .my_r h4 { font-size: 15px; color: #666; font-weight: bold } 10 | .newsBox { } 11 | .news_list .dot { width: 4px; height: 4px; border-radius: 50%; background-color: #999; display: inline-block; margin: 0 10px 3px 0; } 12 | .news_list li { padding: 0 0 20px; margin-bottom: 20px; border-bottom: 1px solid #f5f5f5 } 13 | .news_list li h5 { font-size: 14px } 14 | .news_list li p { color: #999; padding-top: 15px } 15 | .news_nav { color: #999; padding: 0px 0; line-height: 2.5; } 16 | .news_nav a { font: 12px/1 "Microsoft YaHei"; margin: 0 5px; } 17 | .news_title { text-align: center; border-bottom: 1px solid #eee; margin: 30px auto 40px; } 18 | .news_title h2 { font-size: 20px; } 19 | .news_title .from { color: #999; display: block; margin: 20px 0; } 20 | .news_title .time { margin-left: 20px } 21 | .news_title .click { margin-left: 40px } 22 | .news_info { padding: 0 60px; line-height: 28px; font-size: 14px; min-height:400px } 23 | .news_info p { margin-bottom: 30px } 24 | .aboutBox h2 { font-size:16px; margin-bottom:15px } 25 | .about_info { line-height: 28px; font-size: 14px; min-height:400px } 26 | .about_info p, .about_info h4 { margin-bottom: 10px } 27 | .news_info img { max-width: 100% } -------------------------------------------------------------------------------- /src/assets/styles/base.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, p, a, blockquote, th { margin: 0; padding: 0 } 3 | h1, h2, h3, h4, h5, h6 { font-size: 14px } 4 | ol, ul, li { list-style: none outside none } 5 | table { border-collapse: collapsse; border-spacing: 0 } 6 | fieldset, img { border: 0 none } 7 | /*html { background: ##f5f5f5 }*/ 8 | body { background: #f5f5f5; color: #333; font: 12px/1.5 PingFangSC-Regular,HelveticaNeue-Light,'Helvetica Neue Light','Microsoft YaHei',sans-serif,"宋体"; text-align: left } 9 | input::-moz-focus-inner { 10 | border:none; 11 | padding:0 12 | } 13 | a img { border: none } 14 | a { outline: none; color: #333; text-decoration: none } 15 | a:hover, .topBar a:hover, .red, .record_list li:hover .read_link a { color: #f70 } 16 | .red1 { color: #ff4040 } 17 | .unlink { text-decoration: underline } 18 | .blue { color: #5fc3f3 } 19 | .green { color: #360 } 20 | .black { color: #000 } 21 | .black3 { color: #333 } 22 | .black6 { color: #666 } 23 | .black9 { color: #999 } 24 | .ccc { color: #ccc } 25 | .orange { color: #f60 } 26 | .font12 { font-size: 12px!important } 27 | .font14 { font-size: 14px!important } 28 | .font16 { font-size: 16px!important } 29 | .font18 { font-size: 18px!important } 30 | .font20 { font-size: 20px!important } 31 | .font26 { font-size: 26px!important } 32 | .ellipsis {overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: keep-all } 33 | textarea { resize: none; outline: none; border: 1px solid #CCC; font: 12px/1.8 "microsoft yahei", Arial; padding-left: 5px } 34 | input { outline: none; border: none; /* padding-left: 5px; font-size: 13px;*/ font-family: "microsoft yahei", Arial; *background:none 35 | } 36 | i, em, cite { font-style: normal } 37 | .layui-inline, input, label { vertical-align: middle } 38 | button, input, optgroup, select, textarea { color: inherit; font: inherit; margin: 0; outline: 0 } 39 | button, select { text-transform: none } 40 | /*select { -webkit-appearance: none; border: none }*/ 41 | input { line-height: normal } 42 | input[type=checkbox], input[type=radio] { box-sizing: border-box; padding: 0 } 43 | input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { height:auto } 44 | input[type=search] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box } 45 | input[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration { -webkit-appearance:none } 46 | input[type="submit"], input[type="reset"], input[type="button"], button { -webkit-appearance: none } 47 | :-moz-placeholder { color: #999 } 48 | ::-moz-placeholder { color: #999 } 49 | input:-ms-input-placeholder, textarea:-ms-input-placeholder { color: #999 } 50 | input::-webkit-input-placeholder, textarea::-webkit-input-placeholder { color: #999 } 51 | .cf { zoom: 1 } 52 | .cf:before, .cf:after { content: ""; display: table; display: block; font-size: 0; height: 0; line-height: 0; clear: both; visibility: hidden } 53 | .cf:after { clear: both } 54 | .clear { clear: both } 55 | .tl { text-align: left } 56 | .tc { text-align: center } 57 | .tr { text-align: right } 58 | .fl { float: left } 59 | .fr { float: right } 60 | .block { display: block } 61 | .none, .hidden { display: none } 62 | /*base end*/ 63 | .channelWrap { background: #fff; border-radius: 6px; padding: 20px; margin-bottom: 20px } 64 | .channelWrap.channelBanner { padding-bottom: 14px } 65 | .wrap_left { width: 750px } 66 | .wrap_right { width: 250px } 67 | .wrap_inner { padding: 20px; border-radius: 6px; background: #fff; } 68 | .wrap_bg { border-radius: 6px; background: #fff; } 69 | .pad20 { padding: 20px } 70 | .pad20_nobt { padding: 20px 20px 0 } 71 | .topBar { width: 100%; background: #fbfaf8; border-bottom: 1px solid #eae6e2; height: 35px; line-height: 35px } 72 | .box_center { width: 1020px; margin: 0 auto } 73 | .top_l { float: left } 74 | .top_r { float: right } 75 | .topBar .line { display: inline-block; padding: 0 12px; color: #e5d9da } 76 | .topBar a { display: inline-block; color: #8C8C8C } 77 | .topBar a.on { color: #333 } 78 | .topMain { height: 92px; background: #fff; overflow: hidden } 79 | .logo { width: 198px; float: left; padding: 23px 130px 0 0; display: block } 80 | .logo img { width: auto; height: 48px } 81 | .searchBar { width: 342px; margin-top: 27px; overflow: hidden } 82 | .searchBar .search/*, .searchBar .hotword*/ { width: 342px; overflow: hidden } 83 | .searchBar .s_int { width: 250px; padding: 0 14px 0 18px; height: 36px; line-height: 36px\9; vertical-align: middle; border: 1px solid #f80; border-right: none; color: #333; float: left; border-radius: 20px 0 0 20px; font-size: 14px; /*background: #fff;*/ background: 0 0 } 84 | /*.searchBar .s_btn { width: 78px; height: 38px; line-height: 38px; background: #f65167; color: #fff; font-size: 16px; text-align: center; float: left; cursor: pointer; padding: 0 } 85 | .searchBar .s_btn:hover { background:#E23249 }*/ 86 | .searchBar .search_btn { float: left; 87 | width: 58px; 88 | height: 38px; 89 | text-align: center; 90 | border-radius: 0 20px 20px 0; 91 | background-color: #f80; cursor: pointer; } 92 | .searchBar .search_btn .icon { width: 18px; height: 18px; display: block; margin: 9px auto 0; background: url(../images/search.png) no-repeat; background-size:cover; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/search.png', sizingMethod='scale'); } 93 | 94 | /*.hotword { padding-top: 3px } 95 | .hotword a, .hotword span { color: #999; margin: 0 6px 0 5px } 96 | .hotword a:hover { color: #666 }*/ 97 | .bookShelf { margin-top: 27px; padding-left: 20px; overflow: hidden } 98 | .bookShelf .sj_link { height: 38px; line-height: 38px; padding-left: 30px; font-size: 15px; color: #404040; background: url(../images/icon_sj.png) no-repeat 6px 50%; float: left } 99 | .bookShelf .user_link { height: 38px; line-height: 38px; padding-left: 20px; font-size: 15px; color: #404040; float: right } 100 | .bookShelf .user_head { width: 26px; height: 26px; border-radius: 50%; float: left; margin: 6px 5px 0 0 } 101 | .bookShelf .user_name { max-width: 100px; display: inline-block } 102 | .bookShelf .line { float: left; color: #ccc } 103 | /*.bookShelf img { position: absolute; top: 17px; left: 17px; z-index: 10 }*/ 104 | .mainNav { width: 100%; height: 48px; background: #f80; margin-bottom: 20px } 105 | .mainNav .nav li { float: left } 106 | .mainNav .nav li a { float: left; height: 44px; line-height: 48px; color: #fff; font-size: 16px; margin: 0 34px; border-bottom: 2px solid #f80; transition: color .3s,background-color .3s,border .3s } 107 | .mainNav .nav li.on a, .mainNav .nav li a:hover { border-bottom: 2px solid rgba(255,255,255,.8) } 108 | .footer { padding: 0 0 20px; /*margin-top: 20px; background: #fbfaf8; border-top: 1px solid #e0e0e0; */text-align: center; font-size: 12px } 109 | .copyright ul li { color: #999; line-height: 26px } 110 | .copyright .menu { padding: 2px 0 6px; font-size: 12px } 111 | .copyright .line { display: inline-block; padding: 0 12px; color: #e5d9da } 112 | .copyright p { margin-top: 10px; color: #999 } 113 | .code_bar img { margin-left: 66px } 114 | .rBar { float: right; width: 268px } 115 | .btn_gray, .btn_red, .btn_ora, .btn_ora_white, .btn_red1 { border-radius: 20px; font-size: 15px; display: inline-block; text-align: center; cursor: pointer; /*padding: 0 34px; height: 34px; line-height: 34px;*/ padding: 11px 36px; line-height: 1; } 116 | .btn_gray { border: 1px solid #dedede; background: #fafafa; } 117 | .btn_red, .btn_ora { border: 1px solid #f80; background: #f80; color: #fff } 118 | .btn_red1 { border: 1px solid #ff4040; background: #ff4040; color: #fff } 119 | .btn_ora_white { border: 1px solid #f80; color: #f80 } 120 | .btn_ora_white:hover { background: #fefaf6 } 121 | .btn_link { padding: 2px 6px; background: #f80; color: #fff; border-radius: 2px } 122 | .btn_gray:hover { background: #f0f0f0; color: #333 } 123 | .btn_ora:hover, .btn_red:hover, .btn_link:hover { background: #f70; color: #fff } 124 | .btn_red1:hover { background: #fc2525; color: #fff } 125 | .pay_Checkout .btn_red, .btn_big { 126 | font-size: 16px; 127 | padding: 15px 0; 128 | border-radius: 4px; 129 | width: 196px; } 130 | i.vip { width: 26px; height: 14px; text-align: center; line-height: 14px; font-size: 11px; color: #fff; background: #fe8034; border-radius: 2px; margin: 13px 0 0 3px; display: inline-block; transform: scale(0.88); } 131 | i.vip_b { width: 36px; height: 22px; text-align: center; line-height: 22px; font-size: 15px; color: #fff; background: #f70; border-radius: 4px; margin-left: 5px; display: inline-block; vertical-align: 3px } 132 | .pageBox { text-align: center; padding: 20px 0 } 133 | .pageBox a, .pageBox span { display: inline-block; color: #999; padding: 6px 10px; margin: 0 5px; border-radius: 4px; font-size: 14px; line-height: 1 } 134 | .pageBox .current, .pageBox a:hover { background: #f80; color: #fff } 135 | .top_nearread { display: inline-block; position: relative; margin-right: 10px; float:left } 136 | .top_nearread .nearread { padding: 0 9px } 137 | .top_nearread .nearread.on { border-left: 1px solid #d9d9d9; border-right: 1px solid #d9d9d9; background: #FFF; padding: 0 8px; height: 36px; position: relative; z-index: 8 } 138 | .icon_down { display: inline-block; vertical-align: middle; margin: 2px 0 0 5px; width: 0px; height: 0px; overflow: hidden; border-width: 4px; border-style: solid dashed dashed; border-color: #7f7f7f transparent transparent; } 139 | .book_record { width: 382px; position: absolute; top: 0; right: 0; z-index: 9 } 140 | .record_box { width: 380px; background: #fff; margin-top:35px; border: 1px solid #d9d9d9 } 141 | .book_record .sp { width:77px; height:6px; background:#fff; position:absolute; top:32px; right:1px } 142 | .record_title { padding: 14px 10px } 143 | .record_title a { border: 1px solid #dedede; background: #fafafa; border-radius: 2px; font-size: 12px; padding: 6px 12px; line-height: 1; margin-right: 14px } 144 | .record_title a.on { border: 1px solid #f65167; background: #f65167; color: #fff } 145 | .record_box .all { display: block; height: 28px; line-height: 28px; text-align: center; background: #f6f6f6 } 146 | .record_list ul { margin-bottom: 10px } 147 | .record_list li { clear: both; padding: 10px; line-height: 1; overflow: hidden } 148 | .record_list li:hover { background: #f6f6f6 } 149 | .record_list li .cover { width: 50px; height: 63px; background: #f6f6f6 } 150 | .record_list li .cover img { width: 100%; height: 100%; } 151 | .record_list a { display: inline; color: #333 } 152 | .record_list .book_intro { width: 300px; height: 65px; padding-left: 10px; position: relative; } 153 | .record_list .book_intro p { height: 20px; line-height: 20px; overflow: hidden; color: #999; } 154 | .record_list .book_intro .p1 { font-size: 14px; } 155 | .record_list .book_intro .p2 { margin: 2px 0; white-space: nowrap; text-overflow: ellipsis } 156 | .record_list .book_intro .p3 { } 157 | .record_list .book_intro i.vip { margin:0 0 0 3px } 158 | .record_list .read_link a { color: #fff } 159 | .manBody {} 160 | .manBody .mainNav { background:#3e3d43 } 161 | .manBody .searchBar .s_int { border: 1px solid #878689; border-right:none; background-position:8px -22px } 162 | .manBody .mainNav .nav li.on a, .manBody .mainNav .nav li a:hover { background:#313035 } 163 | .nav_sub { margin-bottom: 16px } 164 | .nav_sub a { padding: 0 6px } 165 | 166 | .copyright .menu a { color: #666; font-size: 12px } 167 | .copyright .menu a:hover, .bookShelf .sj_link:hover { color: #f70 } 168 | 169 | .rightList .more, .more_bar { margin: 1px 0; height: 34px; line-height: 34px; border-radius: 1px; background-color: #f7f7f7; text-align: center } 170 | .rightList .more a, .more_bar a { display: block; color: #666 } 171 | .header, .footer { min-width: 1020px } 172 | 173 | /*base*/ 174 | .noborder { border: 0!important } 175 | .nomargin { margin: 0!important } 176 | .ml { margin-left: 12px } 177 | .mr { margin-right: 12px } 178 | .ml5 { margin-left: 5px } 179 | .ml10 { margin-left: 10px } 180 | .ml15 { margin-left: 15px } 181 | .ml20 { margin-left: 20px } 182 | .mr5 { margin-right: 5px } 183 | .mr10 { margin-right: 10px } 184 | .mr15 { margin-right: 15px } 185 | .mr20 { margin-right: 20px } 186 | .mt5 { margin-top: 5px } 187 | .mt10 { margin-top: 10px } 188 | .mt15 { margin-top: 15px } 189 | .mt20 { margin-top: 20px } 190 | .mb5 { margin-bottom: 5px } 191 | .mb10 { margin-bottom: 10px } 192 | .mb15 { margin-bottom: 15px } 193 | .mb20 { margin-bottom: 20px } 194 | .mb50 { margin-bottom: 50px } 195 | .pointer { cursor: pointer } 196 | .notindent { text-indent: inherit!important } 197 | .vm { vertical-align: middle!important } 198 | .border_t { border-top: 1px solid #eee } 199 | .border_b { border-bottom: 1px solid #eee } 200 | .border_l { border-left: 1px solid #eee } 201 | .border_r { border-right: 1px solid #eee } 202 | .layui-laypage-curr{ 203 | background: #f80; 204 | } 205 | .layui-laypage-curr em { 206 | color: #fff; 207 | } 208 | .layui-disabled, .layui-disabled:hover { 209 | color: #d2d2d2 !important; 210 | cursor: not-allowed !important 211 | } 212 | 213 | #noFeedbackNote { 214 | line-height: 400px; 215 | text-align: center; 216 | border-top: 1px solid #eee; 217 | } 218 | 219 | #txtDescription { 220 | /*width: 900px;*/ 221 | height: 288px; 222 | margin: 20px auto 20px; 223 | padding: 10px; 224 | 225 | 226 | /*新增样式*/ 227 | width: 100%; 228 | box-sizing: border-box; 229 | border: 1px solid #eee; 230 | font-size: 14px; 231 | } 232 | 233 | .userBox { 234 | margin: 0 auto 235 | } -------------------------------------------------------------------------------- /src/assets/styles/book.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | .InteractionBox { padding: 15px 14px 11px } 3 | .Interaction_tab a { width: 339px; height: 60px; line-height: 60px; font-size: 14px; color: #000 } 4 | /*.Interaction_tab a:hover, .Interaction_tab a.on { background-position: 0 -60px; color: #000 }*/ 5 | .Interaction_tab a .icon { width: 38px; height: 60px; float: left; margin: 0 10px 0 64px; background-position: -348px 0 } 6 | .Interaction_tab a.fr .icon { background-position: -348px -60px } 7 | .Interaction_tab h4 { font-size: 17px; margin-right: 8px; display: inline } 8 | .InteractionBox .l_bar, .InteractionBox .r_bar { width: 335px; margin: 0 2px; float: left } 9 | .InteractionBox .r_bar .time { padding-right: 1px } 10 | .InteractionBox .l_bar .tit { padding: 22px 14px 0 4px } 11 | .InteractionBox .l_bar .tit .red, .InteractionBox .r_bar .tit .red { padding: 0 5px } 12 | .InteractionBox .l_bar .tit .fl { font-size: 17px } 13 | .InteractionBox .l_bar .tit .fr { padding-top: 7px } 14 | .dashang_bar .l_bar .list { padding-top: 20px } 15 | .dashang_bar .l_bar .list li { width: 90px; height: 134px; line-height: 1; float: left; margin: 0 20px 0 6px; text-align: center; background-position: 0 -130px } 16 | .dashang_bar .l_bar .list li img { width: 60px; height: 60px; background: #fff; margin: 35px 15px 10px; border-radius: 50%; box-shadow: 0 1px 0 rgba(0,0,0,.3) } 17 | .dashang_bar .l_bar .list li .user_name { line-height: 1!important; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; display: block; padding: 0 10px } 18 | .dashang_bar .l_bar .list .li_2 { background-position: -100px -130px } 19 | .dashang_bar .l_bar .list .li_3 { background-position: -200px -130px; margin-right: 0 } 20 | .InteractionBox .r_bar .tit { padding: 14px 1px 12px 1px } 21 | .InteractionBox .r_bar .tit strong { display: block; font-size: 13px } 22 | .InteractionBox .r_bar .list, .InteractionBox .r_bar .sum { margin: 0 1px } 23 | .InteractionBox .r_bar .list li { height: 27px; line-height: 27px; overflow: hidden; border-top: 1px dotted #ccc; color: #999 } 24 | .InteractionBox .r_bar .list li .user_name { margin-right: 8px } 25 | .InteractionBox .r_bar .sum { border-top: 1px dotted #ccc; line-height: 34px } 26 | .btn_pc, .btn_flw { width: 140px; height: 44px; display: inline-block; background-position: 0 -270px } 27 | .btn_flw { width: 122px; background-position: -150px -270px } 28 | .flower_bar .l_bar .list { padding: 0 14px 0 4px } 29 | .flower_bar .l_bar li { padding: 15px 0 6px; overflow: hidden; clear: both } 30 | .flower_bar .l_bar .book_intro { width: 265px } 31 | .flower_bar .l_bar .cover img { width: 45px; height: 56px; background: #f6f6f6; margin: 2px 16px 0 0 } 32 | .flower_bar .l_bar .book_intro .txt { height: 38px; line-height: 18px; padding-top: 2px; color: #999; overflow: hidden; display: block } 33 | .r_fansBrank .book_intro { float: inherit!important } 34 | .user_level1, .user_level2, .user_level3, .user_level4, .user_level5, .user_level6, .user_level7, .user_level8, .user_level9, .user_level10, .user_level11 { width: 30px; height: 16px; line-height: 16px; text-align: center; border-radius: 2px; margin: 11px 0 0; color: #fff } 35 | .user_level1 { background: #d0d0d0 } 36 | .user_level2 { background: #c0c0c0 } 37 | .user_level3 { background: #b4b3b3 } 38 | .user_level4 { background: #a0dfe6 } 39 | .user_level5 { background: #77d2db } 40 | .user_level6 { background: #b4d894 } 41 | .user_level7 { background: #94c766 } 42 | .user_level8 { background: #ffc24c } 43 | .user_level9 { background: #ffa800 } 44 | .user_level10 { background: #ff6e26 } 45 | .user_level11 { background: #ff0000 } 46 | /*固定悬浮图层*/ 47 | .readPopup { border: 1px solid #D9D9D9; border-radius: 3px; background: #FFF; box-shadow: 0 1px 2px #999; overflow: hidden; padding-bottom: 20px; z-index: 9999; position: fixed; left: 50%; top: 50% } 48 | .icon_check { position: absolute; width: 29px; height: 25px; right: -1px; top: -1px; z-index: 2; background: url(../images/icon_readpage.png) no-repeat 0 -142px } 49 | .on .icon_check { display: block } 50 | .closePopup { position: absolute; top: 20px; right: 20px; width: 16px; height: 15px; background: url(../images/icon_readpage.png) no-repeat -43px -126px } 51 | .chapterBox { width: 600px; margin-left: -300px; margin-top: -260px } 52 | .chapterBox .scrollWrap { height: 540px } 53 | /*弹窗内容*/ 54 | .popupTit h2 { text-align: center; letter-spacing: 15px; color: #333; font: 700 20px/30px "Microsoft Yahei"; margin: 30px 0 } 55 | .popupTit h3 { font-size: 16px; margin: 15px 20px } 56 | .scrollWrap { overflow-y: scroll; position: relative } 57 | .dirWrap { padding: 0 40px } 58 | .scrollWrap h3 { padding-left: 26px; font-size: 14px; background: #e6e6e6; height: 30px; line-height: 30px; font-weight: normal; position: relative; cursor: pointer; margin: 0 0 15px; border-radius: 3px } 59 | .readPopup .tc .btn_gray { margin-left: 30px } 60 | /*捧场、送鲜花*/ 61 | .pcBox, .flowerBox { width: 500px; margin-left: -251px; margin-top: -215px } 62 | .propsList { padding: 15px 0 10px 20px } 63 | .propsList li { float: left; cursor: pointer; margin: 0 8px 16px; text-align: center } 64 | .propWrap { width: 134px; height: 54px; line-height: 54px; text-align: center; font-size: 15px; color: #000; display: block; border: 1px solid #e6e6e6; background: #fafafa; position: relative } 65 | .on .propWrap, .propWrap:hover { width: 132px; height: 52px; line-height: 52px; color: #f70; border: 2px solid #f80; background: #fff } 66 | .propsList li i { display: none; line-height: 1 } 67 | .propsList li .propsBox { padding-top: 20px } 68 | .have_num { padding: 0 30px 10px; font-size: 14px; color: #999 } 69 | .have_num .red { margin: 0 4px } 70 | .popup_text { width: 418px; height: 62px; padding: 8px 10px; margin: 8px 30px 20px; color: #555; border: 1px solid #e6e6e6; } 71 | /*消息提示*/ 72 | .newsTipBox { width: 400px; padding-bottom: 30px; margin-left: -200px; margin-top: -105px } 73 | .tipWrap { padding: 30px; font-size: 14px } 74 | /*遮罩层*/ 75 | .maskBox { position: fixed; left: 0; top: 0; z-index: 995; width: 100%; height: 100%; background: black; filter: alpha(opacity=30); opacity: 0.3; animation: mask 2s ease-out 0s 1 normal } 76 | @keyframes mask { 0% { 77 | filter:alpha(opacity=0); 78 | opacity:0 79 | } 80 | 100% { 81 | filter:alpha(opacity=30); 82 | opacity:0.3 83 | } 84 | } 85 | .fansBox { width: 998px; border: 1px solid #eaeaea } 86 | .fansHead { height: 54px; line-height: 54px; margin: 0 14px; border-bottom: 1px solid #eaeaea; font-weight: normal } 87 | .fansHead h2 { font-size: 20px; font-weight: normal } 88 | .fansCon { padding: 20px } 89 | .fansCon .r_bar { width: 204px } 90 | .fansCon .cover { width: 200px; height: 250px; background: #f6f6f6; border: 1px solid #ebebeb; padding: 1px; } 91 | .fansCon .btn_red { width: 202px; margin: 2px 0 14px; padding: 10px 0 } 92 | .fansCon .l_bar { width: 750px } 93 | .fansCon .l_bar .list1 { padding-top: 4px } 94 | .fansCon .list1 li { width: 33%; line-height: 1; float: left } 95 | .fansCon .list1 .fans_bg { width: 90px; height: 112px; background-position: 0 -320px; position: relative; margin-right: 18px } 96 | .fansCon .list1 .fans_bg img { width: 60px; height: 60px; background: #fff; margin: 39px 15px 0; border-radius: 50%; box-shadow: 0 1px 0 rgba(0,0,0,.3) } 97 | .fansCon .list1 h5 { font-size: 16px; padding: 9px 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } 98 | .fansCon .list1 li .user_name { line-height: 1!important } 99 | .fansCon .list1 .li_2 .fans_bg { background-position: -100px -320px } 100 | .fansCon .list1 .li_3 .fans_bg { background-position: -200px -320px } 101 | .fansCon .fans_info { width: 136px; font-size: 14px } 102 | .fansCon .fans_info .fans_pointer { padding: 14px 0 22px } 103 | .fans_level span { padding: 1px 10px 2px } 104 | .icon_hg { width: 30px; height: 30px; display: inline-block; background-position: -300px -320px; position: absolute; top: -13px; right: -13px } 105 | .fansCon .list2 { padding: 0 } 106 | .fansCon .list2 li { width: 250px; float: left; height: 59px; padding: 0 0 19px; display: inline } 107 | .fansCon .list2 .num { font: 16px/59px "microsoft yahei", Arial, "宋体"; width: 32px; color: #666; font-weight: bold } 108 | .fansCon .list2 .img { width: 40px; height: 40px; margin-top: 10px; position: relative } 109 | .fansCon .list2 .img img { width: 100%; height: 100%; border-radius: 50% } 110 | .fansCon .list2 .img span { display: block; margin: 0; position: absolute; left: 5px; bottom: 0 } 111 | .fansCon .list2 .msg { display: inline; width: 164px; padding: 8px 0 0 12px; } 112 | .fansCon .list2 .msg h4 { line-height: 24px; font-weight: normal; font-size: 16px; overflow: hidden; height: 24px; white-space: nowrap; text-overflow: ellipsis; } 113 | .fansCon .list2 .msg p { font-size: 12px; line-height: 16px; color: #999; } 114 | .fansTop { margin-bottom: 8px; border-bottom: 1px solid #eaeaea } 115 | .fans_tab { width: 1005px; overflow: hidden; } 116 | .fans_tab ul { float: left; width: 280px; margin-right: 55px; } 117 | .fans_tab li { line-height: 39px; overflow: hidden; font-size: 14px; height: 39px; border-bottom: 1px solid #ebebeb; } 118 | .fans_tab li .num { float: left; width: 40px; color: #666; } 119 | .fans_tab li a { float: left; overflow: hidden; width: 200px; white-space: nowrap; text-overflow: ellipsis; } 120 | .fans_tab li .fans_level { float: left; font-size: 12px; width: 40px; text-align: right; color: #999; } 121 | .fansRule dl { padding: 20px 20px 30px } 122 | .fansRule dt { line-height: 24px; margin-bottom: 6px; font-size: 16px; } 123 | .fansRule dd { font-size: 12px; line-height: 20px; margin-bottom: 16px; color: #777; } 124 | .fansRule table { width: 100%; border-collapse: collapse; } 125 | .fansRule table th, .fansRule table td { font-weight: 400; min-width: 40px; padding: 12px 0; text-align: left; border-top: 1px solid #ebebeb; border-bottom: 1px solid #ebebeb; } 126 | .fansRule ol li { list-style-type: decimal; list-style-position: inside; } 127 | .InteractionBox .l_bar, .flower_bar .l_bar { display: none } 128 | .dashang_bar { float: left } 129 | .flower_bar { float: right } 130 | .author_head { text-align: center } 131 | .author_head .head img { width:64px; height:64px; border-radius: 50%; background:#f6f6f6; display: block; margin: 0 auto } 132 | .author_head .msg { margin-top: -4px } 133 | .author_head .msg h4 { font-size:14px; line-height:2.4 } 134 | .icon_qyzz { padding: 5px; line-height:1; background:#f70; color:#fff; border-radius:3px; display:inline-block } 135 | .author_intro, .author_book { border-top:1px dotted #e0e0e0 } 136 | .author_intro h4,.author_book h4 { font-weight: normal; font-size: 12px; padding:10px 0 5px } 137 | .author_intro .intro_txt, .author_book .book_txt { line-height:1.8; padding-bottom:10px } 138 | .author_book .rightList ul { padding:0 } 139 | 140 | 141 | .tj_bar .cover { float: left; display: block; margin-right: 10px } 142 | .tj_bar .cover img { width: 64px; height: auto; background: #f6f6f6 } 143 | .tj_bar .book_intro { padding: 15px 0; clear: both; word-break: break-all; zoom: 1; overflow: hidden } 144 | .tj_bar .dec { width: 136px; float: right } 145 | .tj_bar .book_intro .book_name { display: block; font-size: 14px; line-height: 1; white-space: nowrap; text-overflow: ellipsis; overflow: hidden } 146 | .tj_bar .book_intro .txt { height: 54px; line-height: 1.5; color: #808080; overflow: hidden; display: block; margin-top: 10px; } 147 | .tj_bar li { border-bottom: 1px solid #eee } 148 | .tj_bar li:last-child { border: none } 149 | .tj_bar li:last-child .book_intro { padding: 15px 0 2px } 150 | 151 | .friend_link { display: none } 152 | .footer { background: #fff; padding: 16px 0 20px } 153 | 154 | -------------------------------------------------------------------------------- /src/assets/styles/layer.css: -------------------------------------------------------------------------------- 1 | .layermbox{position:absolute;left:0;top:0;width:100%;z-index:19891014}.layermmain,.laymshade{position:fixed;left:0;top:0;width:100%;height:100%}.layermbtn span,.layermchild{display:inline-block;position:relative}.laymshade{background-color:rgba(0,0,0,.5);pointer-events:auto}.layermmain{display:table;font-family:Helvetica,arial,sans-serif;pointer-events:none}.layermmain .section{display:table-cell;vertical-align:middle;text-align:center}.layermchild{text-align:left;background-color:#fff;font-size:14px;border-radius:6px;box-shadow:0 0 8px rgba(0,0,0,.1);pointer-events:auto;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.18s;animation-duration:.18s}.layermborder{border:1px solid #999}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.layermanim{animation-name:bounceIn;-webkit-animation-name:bounceIn}.layermbox0 .layermchild{max-width:260px;min-width:150px}.layermbox1 .layermchild{border:none;border-radius:0}.layermbox2 .layermchild{width:auto;max-width:260px;min-width:40px;border:none;background-color:rgba(0,0,0,.6);color:#fff}.layermchild h3{padding:0 45px 0 10px;height:50px;line-height:50px;font-size:16px;font-weight:400;border-radius:5px 5px 0 0;border-bottom:1px solid #EBEBEB}.layermbtn span,.layermchild h3{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layermcont{padding:20px 15px;line-height:22px;border-radius:5px}.layermbox1 .layermcont{padding:0}.layermbox2 .layermcont{text-align:center;padding:30px 30px 0;line-height:0}.layermbox2 .layermcont i{width:1.5rem;height:1.5rem;margin-left:8px;display:inline-block;background-color:#fff;border-radius:100%;-webkit-animation:bouncedelay 1.4s infinite ease-in-out;animation:bouncedelay 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}@-webkit-keyframes bouncedelay{0%,100%,80%{-webkit-transform:scale(0)}40%{-webkit-transform:scale(1)}}@keyframes bouncedelay{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.layermbox2 .layermcont i:first-child{margin-left:0;-webkit-animation-delay:-.32s;animation-delay:-.32s}.layermbox2 .layermcont i.laymloadtwo{-webkit-animation-delay:-.16s;animation-delay:-.16s}.layermbox2 .layermcont>div{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layermbtn{position:relative;height:40px;line-height:40px;font-size:0;text-align:center;border-top:1px solid #EBEBEB}.layermbtn span{width:50%;text-align:center;font-size:14px;cursor:pointer;border-radius:0 5px 0 0}.layermbtn span:first-child{height:39px;background-color:#fff;border-radius:0 0 0 5px}.layermbtn:before{content:'\20';position:absolute;width:1px;height:39px;left:50%;top:0;background-color:#EBEBEB}.layermend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layermend::after,.layermend::before{position:absolute;left:5px;top:13px;content:'';width:20px;height:2px;background-color:rgba(0,0,0,.3);transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layermend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)} -------------------------------------------------------------------------------- /src/assets/styles/main.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | .items_txt .author a, .updateTable .author a { cursor: text } 3 | .friend_link { padding: 12px 0 0; line-height: 2.4; text-align: center } 4 | .friend_link a { margin: 0 10px; display: inline-block } 5 | /*.leftBox, .rightBox, .rightBox2 { margin-bottom: 14px } 6 | .channelBanner .leftBox, .channelBanner .rightBox { height: 334px; overflow: hidden }*/ 7 | .channelPic .leftBox, .channelPic .rightBox { /*height: 515px; */overflow: hidden } 8 | .channelTable .leftBox { /*height: 1046px;*/ overflow: hidden } 9 | .scBigImg img, .rightList li.on .cover img, .itemsList .items_img img { box-shadow: 0 0 1px rgba(0,0,0,.05) } 10 | .scBigImg:hover img, .rightList li.on .cover a:hover img, .itemsList .items_img:hover img { box-shadow: 0 0 1px rgb(0,0,0,.25) } 11 | .leftBox { width: 720px; float: left; /*border: 1px solid #EAEAEA*/ } 12 | .sliderContent { width: 306px; float: left; /*margin: 16px 0 16px 14px;*/ position: relative } 13 | .scSmallImg { position: absolute; top: 0px; right: 0px; /*height: 335px*/ } 14 | .scSmallImg li { height: 65px; margin-bottom: 8px; border: 2px solid #fff } 15 | .scSmallImg li.on { border: 2px solid #FF7800 } 16 | .scSmallImg img { width: auto; height: 65px; cursor: pointer; filter: alpha(opacity=60); -moz-opacity: 0.6; opacity: 0.6 } 17 | .scSmallImg li.on img { filter: alpha(opacity=100); -moz-opacity: 1; opacity: 1 } 18 | .scBigImg dd { display: none } 19 | .scBigImg dd.on { display: block } 20 | .scBigImg img { width: 240px; height: 300px; background: #f6f6f6 } 21 | .hot_articles { width: 396px; float: right; padding: 0 2px } 22 | .hot_articles dl { padding: 0 4px 8px; border-bottom: 1px dotted #eae6e2 } 23 | .hot_articles .hot_recommend { margin-bottom: 12px; } 24 | .hot_articles dt { /*height: 40px; line-height: 40px;*/ padding-bottom: 7px; text-align: center; font-size: 16px; font-weight: 600; line-height: 1.8 } 25 | .hot_articles dt a { color: #F70 } 26 | .hot_articles dd { line-height: 30px; font-size: 14px; overflow: hidden } 27 | .hot_articles dd a { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } 28 | .hot_articles .hot_recommend dd a { width: 49%; padding-right: 1%; float: left; } 29 | .hot_articles .hot_notice dd a { padding-right: 1%; } 30 | .hot_articles span.tit { color: #f70; margin-right: 6px } 31 | .hot_articles .hot_notice { border: none } 32 | .hot_articles .line { padding: 0 14px; color: #eee } 33 | .rightBox { width: 240px; float: right; /*border: 1px solid #EAEAEA;*/ position: relative } 34 | .rightBox .title, .wrap_right_cont .title { /*height: 48px; margin: 0 14px;*/ border-bottom: 1px solid #e0e0e0 } 35 | .rightBox .title h3, .wrap_right_cont .title h3 { line-height: 1; padding-bottom: 14px; display: inline-block; font-size: 20px; font-weight: 600; /*border-bottom: 4px solid transparent*/ } 36 | /*.rightBox .title h3.on { border-color: #f80 }*/ 37 | .rightList ul { padding: 0 } 38 | .rightList li { /*border-bottom: 1px dotted #e0e0e0; height: 37px; line-height: 37px;*/ overflow: hidden; position: relative; vertical-align: middle } 39 | .rightList li:last-child { border: none } 40 | .rightList .book_name { font-size: 14px; height: 34px; line-height: 34px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden } 41 | .rightList .book_intro { background: #f7f7f7; border: 1px solid #eee; clear: both; padding: 8px; word-break: break-all; zoom: 1; overflow: hidden; display: none } 42 | .rightList .cover, .rightList .book_intro .txt { display: none } 43 | .rightList li.on { height: auto; padding: 4px 0; border: none } 44 | .rightList li.on .book_intro { display: block } 45 | .rightList li.on .cover { float: left; display: block } 46 | .rightList li.on .cover img { width: 60px; height: auto; background: #f6f6f6; margin-right: 9px } 47 | .rightList li.on .book_intro .name { line-height: 26px; height: 26px; display: block; overflow: hidden } 48 | .rightList_nobor ul { padding: 4px 14px 10px } 49 | .rightList_nobor li { height: auto; padding: 10px 0!important; border: none } 50 | .book_intro .author { color: #999; display: block; line-height: 30px } 51 | .book_intro .class { color: #999; display: block; line-height: 1 } 52 | .rightList .on .book_intro .txt { height: 72px; line-height: 1.5; color: #808080; overflow: hidden; display: block } 53 | 54 | .rightList li i, .rankTable .rank i { width: 17px; height: 17px; line-height: 17px; text-align: center; background-color: #999; color: #fff; vertical-align: middle; display: inline-block; font-size: 12px; } 55 | .rightList li i { float: left; margin: 8px 7px 0 0; } 56 | .rankTable .rank i { margin: 1px 1px 0 } 57 | /*.rightList li.on i { position: absolute; top: 12px; left: 0; margin: 0; display:none }*/ 58 | .rightList li.num1 i, .rankTable .rank .num1 { background-color: #fc7403 } 59 | .rightList li.num2 i, .rankTable .rank .num2 { background-color: #f79415 } 60 | .rightList li.num3 i, .rankTable .rank .num3 { background-color: #ffa95e } 61 | .rightList li.num1 i,.rightList li.num2 i,.rightList li.num3 i { display:block } 62 | /*.rightList .more{ margin: 1px 0; height: 34px; line-height: 34px; border-radius: 1px; background-color: #f7f7f7; text-align: center } 63 | .rightList .more a{ display: block; color: #666 }*/ 64 | .leftBox .title { border-bottom: 1px solid #e9e9e9 } 65 | .leftBox .title h2 { line-height: 1; padding-bottom: 14px; display: inline-block; font-size: 20px; font-weight: 600; /*border-bottom: 4px solid transparent*/ } 66 | .picRecommend { width: 720px; padding: 12px 0 0 } 67 | .itemsList { width: 50%; float: left; padding: 17px 0 } 68 | .itemsList .items_img { float: left; margin-right: 14px } 69 | .itemsList .items_img img { width: 96px; height: 120px; background: #f6f6f6 } 70 | .items_txt { width: 230px; float: left; /*padding-right: 20px;*/ } 71 | .items_txt h4 { height: 20px; line-height: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: keep-all; margin-bottom: 8px; font-size: 16px; font-weight: normal } 72 | .items_txt .author { margin: 8px 0 } 73 | .items_txt .author a { color: #a6a6a6 } 74 | .items_txt .intro { margin-top: 8px; line-height: 1.5; height: 54px; overflow: hidden } 75 | .searchTipBar { color: #333; font-size: 14px; padding: 1px 7px 16px 7px } 76 | .leftBox .updateTable { width: 718px; } 77 | .updateTable { color: #999 } 78 | .updateTable table { width: 100%; margin-bottom: 14px; } 79 | .updateTable th, .updateTable td { height: 41px; line-height: 41px; vertical-align: middle; padding-left: 1px; text-align: left } 80 | .updateTable th { font-weight: normal; font-size: 14px; } 81 | .updateTable td { border-top: 1px solid #eee } 82 | .updateTable .style { width: 74px; font-size: 14px; } 83 | .updateTable .name { width: 192px; padding-right: 10px; font-size: 14px; } 84 | .updateTable td.name { padding-top: 15px; } 85 | .updateTable .name a, .updateTable .chapter a { max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: keep-all } 86 | .updateTable .chapter { padding-right: 5px } 87 | .updateTable .chapter a { max-width: 200px; float: left; color: #666 } 88 | .updateTable .author { width: 82px; text-align: left } 89 | .updateTable td.author { padding-top: 15px; } 90 | .updateTable .time { width: 82px; text-align: center } 91 | .updateTable .word { width: 60px; padding-right: 10px; text-align: right } 92 | .updateTable .rank { width: 2.5em; padding-right: 10px; text-align: center } 93 | .updateTable .name a, .updateTable .chapter a, .updateTable .author a { height: 41px; line-height: 41px; display: inline-block; overflow: hidden } 94 | .rankBox { padding-bottom: 14px; height: auto!important } 95 | .rankTable th { background: #f9f9f9; color: #333 } 96 | .rankTable td { border: none; height: 40px; line-height: 40px } 97 | .rankTable tr:nth-child(2n) td { background: #fafafa } 98 | .rankTable .chapter a { max-width: 176px } 99 | .classTable { font-size: 14px } 100 | .classTable .rank { width: 60px; } 101 | .classTable .rank i { float: inherit; margin: 0; color: #fff } 102 | .classTable .style { width: 100px; } 103 | .classTable .name { width: 250px; } 104 | .classTable .name a, .classTable .chapter a { max-width: 90% } 105 | .classTable .author { width: 120px } 106 | .classTable .word { width: 80px; padding-right: 15px } 107 | .rightBox2 { width: 266px; float: right; border: 1px solid #EAEAEA; position: relative; overflow: hidden } 108 | .rightBox2 .title h3 { height: 45px; line-height: 48px; padding: 0 30px; font-size: 18px; font-weight: normal; color: #ff758f; border-bottom: 4px solid #ff758f } 109 | .rightList2 li { vertical-align: middle } 110 | .rightList2 li a { display: block; /*padding: 0 30px;*/ height: 47px; line-height: 47px; font-size: 16px; overflow: hidden; border-top: 1px dotted #eee; } 111 | .rightList2 li:first-child a { border: none } 112 | .rightList2 li a.on, .rightList2 li a:hover { color: #f70 } 113 | .so_tag { /*padding: 4px 14px 0;*/ font-size: 14px; padding: 5px 0 } 114 | .so_tag li { padding: 0 0 24px; /*border-bottom: 1px solid #eee*/ } 115 | .so_tag li:last-child { padding: 0 0 4px } 116 | .so_tag li .tit, .so_tag li a { line-height: 1; padding: 3px 7px; margin-right: 12px } 117 | .so_tag li .tit { color: #999 } 118 | .so_tag li a.on, .so_tag li a:hover { color: #f70 } 119 | .so_tag li .so_girl { display: inline-block } 120 | .so_tag li .so_boy { display: inline-block/*; margin: 8px 0 0 140px;*/ } 121 | 122 | /*.payBox { width: 998px; border: 1px solid #eaeaea }*/ 123 | .payHead { height: 36px; line-height: 36px; padding: 20px 0 30px; margin: 0 24px; font-size: 16px; border-bottom: 1px solid #eaeaea } 124 | .payHead .user_name { margin-right: 25px } 125 | .payHead .btn_gray { font-size: 14px; padding: 10px 20px; margin-left: 20px } 126 | .payFoot { line-height: 2.4; padding: 30px 0 40px; margin: 0 24px; font-size: 13px; color: #999; border-top: 1px solid #eee; } 127 | .payCon { margin: 0 24px } 128 | .payCon h5 { font-size: 16px; font-weight: normal; padding: 28px 0 2px } 129 | .pay_way { padding-bottom: 5px } 130 | .pay_way li { width: 196px; text-align: center; border: 2px solid #eee; border-radius: 4px; margin: 20px 26px 3px 0; float: left; cursor: pointer; line-height: 1 } 131 | .pay_way li.on { border-color: #f80 } 132 | .pay_way li .pay_pic { width: 180px; margin: 12px auto; } 133 | .pay_way li strong { font-size: 24px; display: block; line-height: 1; padding: 20px 0 5px } 134 | .pay_way li .pay_mn { display: table-cell; width: 196px; height: 40px; vertical-align: middle; line-height: 1.2; padding-bottom: 12px; font-size: 14px; text-align: center } 135 | .pay_way li .pay_mn em.red { display: block } 136 | .pay_Checkout { padding: 20px 0; font-size: 14px; line-height: 1.8; } 137 | .pay_Checkout .btn_red { margin: 20px 0; } 138 | 139 | .payResultBox { padding: 90px 40px 160px; text-align: center } 140 | .payResultBox h3 { font-size: 38px; line-height: 1; padding-bottom: 30px; } 141 | .payResultBox .list { display: inline-block; padding-bottom: 15px;} 142 | .payResultBox .list li { font-size: 16px; line-height: 36px } 143 | .payResultImg { width: 60px; 144 | margin-right: 12px; 145 | vertical-align: middle; } 146 | /*.bookCover, .reply_bar { padding: 14px }*/ 147 | .bookCover .book_cover { width: 200px; display: block; height: auto; margin-right: 25px; float: left; position: relative; overflow: hidden; box-shadow: 0 1px 6px rgba(0,0,0,.3), 0 0 5px #f9f2e9 inset; transition: color .3s,background-color .3s,border .3s; 148 | } 149 | .bookCover .cover { width: 100%; height: 100%; background: #f6f6f6; 150 | -webkit-transition: -webkit-transform .3s ease-out; 151 | -moz-transition: -moz-transform .3s ease-out; 152 | -ms-transition: -ms-transform .3s ease-out; 153 | transition: transform .3s ease-out; 154 | } 155 | .bookCover .cover:hover { 156 | -webkit-transform: scale(1.05); 157 | -moz-transform: scale(1.05); 158 | -o-transform: scale(1.05); 159 | transform: scale(1.05) } 160 | .book_info { width: 755px; float: left } 161 | .book_info h1 { font-size: 25px; display: inline-block; line-height: 1; } 162 | .book_info .author { font-size: 14px; margin-left: 20px; color: #444 } 163 | .book_info .list { padding: 15px 0 20px } 164 | .book_info .list li { line-height: 26px; color: #666 } 165 | .book_info .list li .item { width: 20%; display: inline-block } 166 | /*目录页*/ 167 | .book_info1 { text-align: center; padding: 10px 0 15px } 168 | .book_info1 .tit { padding: 10px 0 20px } 169 | .book_info1 h1 { font-size: 28px; display: inline-block } 170 | .book_info1 .list { padding: 5px 0; font-size: 14px } 171 | .book_info1 .list li { line-height: 26px; color: #999 } 172 | .book_info1 .list li span { display: inline-block; margin: 0 15px } 173 | .dirWrap { padding-bottom: 30px } 174 | .dirWrap h3 { padding-left: 6px; font-size: 14px; background: #f9f9f9; height: 40px; line-height: 40px; font-weight: normal; position: relative; cursor: pointer; margin: 0 0 5px; border-radius: 3px } 175 | .dirList { overflow: hidden; padding-bottom: 20px } 176 | .dirList li { float: left; width: 265px; padding-left: 5px; padding-right: 30px; height: 40px; line-height: 40px; overflow: hidden; border-bottom: 1px dotted #ddd; *zoom:1; font-size: 14px 177 | } 178 | .dirList li a { float: left; text-overflow: ellipsis; overflow: hidden; white-space: nowrap } 179 | .dirList li i.red { padding-left: 5px } 180 | .book_info .intro_txt { height: 96px; min-height: 96px; line-height: 24px; font-size: 14px; position: relative; margin-bottom: 26px; overflow: hidden } 181 | .book_info .intro_txt em.black9 { font-weight: bold; color: #333; display: block; } 182 | /*.book_info .intro_txt p { text-indent:2em }*/ 183 | .icon_show, .icon_hide { display:inline-block; color:#2972cc; height: 24px; padding:0 2px 0 10px; text-indent: 0; text-align: center; font-size: 12px; position: absolute; right: 0; bottom: 0; background: #fff } 184 | .icon_show i, .icon_hide i { display:inline-block; width:12px; height:12px; background:url(../images/icon_dt.png) no-repeat 0 2px; margin-right: 4px; *vertical-align:middle } 185 | .icon_hide i { background-position:-12px 2px } 186 | .icon_hide { display: none } 187 | .btns .btn_red, .btns .btn_ora, .btns .btn_addsj { margin-right: 24px } 188 | .book_tit { /*height: 48px; line-height: 48px; margin: 0 14px;*/ border-bottom: 1px solid #eee; overflow: hidden; padding-bottom: 14px; line-height: 1.2 } 189 | .book_tit .fl { font-size: 14px; color: #666 } 190 | .book_tit .fl h3 { font-size: 20px; color: #333; margin-right: 5px; display: inline } 191 | .book_tit .fr { font-size: 13px } 192 | .bookChapter .list { padding: 8px 0 } 193 | .bookChapter .list li { line-height: 36px; overflow: hidden } 194 | .zj_yl { color: #999; font-size: 13px } 195 | /*.bookChapter .list li .zj { width: 50%; float: left } 196 | .bookChapter .list li .zj_1 a { color: #f60 }*/ 197 | 198 | 199 | 200 | /*.commentBar { padding: 0 14px }*/ 201 | .comment_list { padding: 20px 0; border-bottom: 1px solid #eee } 202 | .comment_list:last-child { border: none } 203 | .comment_list .user_heads { /*width: 54px; height: 54px; float: left;*/ position:relative; margin-right: 20px } 204 | .comment_list .user_head { width: 50px; height: 50px; border-radius: 50%; background: #f6f6f6 } 205 | .comment_list .user_heads span { display: block; margin: 0; position: absolute; left: 12px; bottom: 0 } 206 | .comment_list ul { width: 640px } 207 | .comment_list .li_0 { font-family: "宋体" } 208 | .comment_list .li_0 strong { font-size: 14px; color: #f00 } 209 | .comment_list .li_1 { overflow: hidden } 210 | .comment_list .user_name { color: #ed4259 } 211 | .comment_list .li_2 { padding: 6px 0 } 212 | .comment_list .li_3 { color: #999 } 213 | .comment_list .reply { padding-left: 12px } 214 | .comment_list .num { color: #ed4259; margin: 0 3px } 215 | .comment_list .li_4 { line-height: 34px; padding-top: 8px; margin-top: 15px; border-top: 1px solid #eaeaea } 216 | .no_comment { padding: 70px 14px 115px; color: #CCCCCC; text-align: center; font-size: 14px; } 217 | .pl_bar li { display: block } 218 | .pl_bar .name { color: #666; padding-top: 2px; font-size: 14px } 219 | .pl_bar .dec { font-size: 14px; line-height: 1.8; padding: 12px 0 } 220 | .pl_bar .other { line-height: 24px; color: #999; font-size: 13px } 221 | .pl_bar .other a { display: inline-block; color: #999 } 222 | .pl_bar .reply { padding-left: 22px; background: url(../images/icon_reply.png) no-repeat 0 2px } 223 | .reply_bar .tit { line-height: 52px; font-size: 13px } 224 | .replay_text { width: 100%; height: 110px; border: 1px solid #eaeaea; border-radius: 5px; padding: 10px; box-sizing: border-box; font-size: 14px; box-shadow: 0 0 4px 2px hsla(0,0%,92%,.35); } 225 | .replay_text:hover { background: #fff } 226 | .reply_btn { padding: 17px 0 19px; overflow: hidden } 227 | .reply_bar .reply_btn { padding-bottom: 4px } 228 | .reply_btn .btn_red { padding: 10px 20px; font-size: 14px } 229 | .reply_btn .fr { margin-top: 8px } 230 | .write_bar { padding: 1rem 0; margin: 0 1rem } 231 | .write_comment { padding: 1rem; background: #f6f6f6; min-height: 16rem } 232 | .write_comment .text { width: 100%; min-height: 10rem; border: 1px solid #ddd; font-size: 0.875rem; line-height: 1.8; margin-bottom: 1rem } 233 | .book_comment_tit { font-size: 24px; padding: 20px 15px 10px 15px } 234 | .page_bar { padding: 1rem 0; margin: 0 1rem; border-top: 1px solid #eee } 235 | .page_bar li { width: 33.3%; float: left; text-align: center } 236 | .page_bar li a, .page_bar li .select_page { display: block; height: 2rem; line-height: 2rem; font-size: 0.875rem; border: 1px solid #eee; background: #fff; box-sizing: border-box } 237 | .page_bar .previous a { margin-right: 1rem } 238 | .page_bar .next a { margin-left: 1rem } 239 | .page_bar li .select_page { width: 100% } 240 | .icon_jh, .icon_zd { text-align: center; margin: 2px 5px 0 0; color: #fff; font-size: 12px; padding: 3px 3px; line-height: 1; display: inline-block; background: #ed4259; border-radius: 2px } 241 | .icon_zd { background: #4a90e2 } 242 | 243 | 244 | .hot_notice span, .items_txt .intro a, .updateTable .author a, .updateTable .style a, .updateTable .time a, .updateTable th { color: #888 } 245 | .items_txt .intro a:hover, .rightList .more a:hover, .updateTable .style a:hover, .rightList .on .book_intro .txt:hover { color: #f70 } 246 | .icon_show:hover, .icon_hide:hover { color: #2972cc } 247 | .channelChapterlist { min-height: 600px } 248 | -------------------------------------------------------------------------------- /src/assets/styles/read.css: -------------------------------------------------------------------------------- 1 | .read_menu li a, .closePopup, .menu_left li a span, .menu_right li a span, .icon_check, .icon_yb { background: url(../images/icon_readpage.png) no-repeat } 2 | -------------------------------------------------------------------------------- /src/assets/styles/user.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | .icon_name, .icon_key, .icon_code { width:312px; padding-left:36px; background:url(../images/icon_user.png) no-repeat 13px 13px } 3 | .my_l li a { display:block; height:42px; line-height:42px; padding-left:62px; border-left:4px solid #fff; background:url(../images/icon_user.png) no-repeat; margin-bottom:5px; color: #666 } 4 | .no_comment { background:url(../images/no_comment.png) no-repeat center 80px } 5 | .pl_bar .reply { padding-left: 22px; background: url(../images/icon_reply.png) no-repeat 0 2px } 6 | -------------------------------------------------------------------------------- /src/components/author/Header.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /src/components/common/Footer.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | -------------------------------------------------------------------------------- /src/components/common/Header.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /src/components/common/Navbar.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | -------------------------------------------------------------------------------- /src/components/common/Top.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | -------------------------------------------------------------------------------- /src/components/home/BookNewestRank.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | -------------------------------------------------------------------------------- /src/components/home/BookUpdateRank.vue: -------------------------------------------------------------------------------- 1 | 84 | 85 | -------------------------------------------------------------------------------- /src/components/home/BookVisitRank.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/home/FriendLink.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | -------------------------------------------------------------------------------- /src/components/home/LatestNews.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /src/components/user/Menu.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import ElementPlus from 'element-plus' 3 | import 'element-plus/dist/index.css' 4 | import App from './App.vue' 5 | import router from '@/router' 6 | import '@/assets/styles/base.css' 7 | import '@/assets/styles/main.css' 8 | import { Loading } from '@element-plus/icons-vue' 9 | 10 | const app = createApp(App) 11 | 12 | app.use(ElementPlus) 13 | 14 | app.use(router) 15 | 16 | app.mount('#app') 17 | 18 | app.component('Loading', Loading) 19 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from 'vue-router' 2 | 3 | const router = createRouter({ 4 | // createWebHistory 路由模式路径不带#号(生产环境下不能直接访问项目,需要 nginx 转发) 5 | // createWebHashHistory 路由模式路径带#号 6 | history: createWebHashHistory(), 7 | routes: [ 8 | { 9 | path: '/', 10 | redirect: '/home' 11 | }, 12 | { 13 | path: '/home', 14 | name: 'home', 15 | component: () => import('@/views/Home') 16 | }, 17 | { 18 | path: '/register', 19 | name: 'register', 20 | component: () => import('@/views/Register') 21 | }, 22 | { 23 | path: '/login', 24 | name: 'login', 25 | component: () => import('@/views/Login') 26 | }, 27 | { 28 | path: '/feadback', 29 | name: 'feadback', 30 | component: () => import('@/views/FeadBack') 31 | }, 32 | { 33 | path: '/news/:id', 34 | name: 'news', 35 | component: () => import('@/views/News') 36 | }, 37 | { 38 | path: '/bookclass', 39 | name: 'bookclass', 40 | component: () => import('@/views/BookClass') 41 | }, 42 | { 43 | path: '/book_rank', 44 | name: 'bookRank', 45 | component: () => import('@/views/BookRank') 46 | }, 47 | { 48 | path: '/book/:id', 49 | name: 'book', 50 | component: () => import('@/views/Book') 51 | 52 | }, 53 | { 54 | path: '/chapter_list/:bookId', 55 | name: 'chapterList', 56 | component: () => import('@/views/ChapterList') 57 | 58 | }, 59 | { 60 | path: '/book/:id/:chapterId', 61 | name: 'bookContent', 62 | component: () => import('@/views/BookContent') 63 | 64 | }, 65 | { 66 | path: '/user/setup', 67 | name: 'userSetup', 68 | component: () => import('@/views/UserSetup') 69 | }, 70 | { 71 | path: '/user/comment', 72 | name: 'userComment', 73 | component: () => import('@/views/UserComment') 74 | 75 | }, 76 | { 77 | path: '/author/register', 78 | name: 'authorRegister', 79 | component: () => import('@/views/author/Register') 80 | }, 81 | { 82 | path: '/author/book_list', 83 | name: 'authorBookList', 84 | component: () => import('@/views/author/BookList') 85 | }, 86 | { 87 | path: '/author/book_add', 88 | name: 'authorBookAdd', 89 | component: () => import('@/views/author/BookAdd') 90 | }, 91 | { 92 | path: '/author/chapter_list', 93 | name: 'authorChapterList', 94 | component: () => import('@/views/author/ChapterList') 95 | }, 96 | { 97 | path: '/author/chapter_add', 98 | name: 'authorChapterAdd', 99 | component: () => import('@/views/author/ChapterAdd') 100 | }, 101 | { 102 | path: '/author/chapter_update', 103 | name: 'authorChapterUpdate', 104 | component: () => import('@/views/author/ChapterUpdate') 105 | } 106 | ] 107 | }) 108 | 109 | // 解决 vue 中路由跳转时,总是从新页面中间开始显示 110 | router.afterEach((to,from,next) => { 111 | window.scrollTo(0,0) 112 | }) 113 | 114 | export default router -------------------------------------------------------------------------------- /src/utils/auth.js: -------------------------------------------------------------------------------- 1 | 2 | const TokenKey = 'Authorization' 3 | 4 | const nickNameKey = 'nickName' 5 | 6 | const uidKey = 'uid' 7 | 8 | 9 | export const getToken = () => { 10 | return localStorage.getItem(TokenKey); 11 | } 12 | 13 | export const setToken = (token) => { 14 | return localStorage.setItem(TokenKey, token) 15 | } 16 | 17 | export const removeToken = () => { 18 | return localStorage.removeItem(TokenKey) 19 | } 20 | 21 | export const removeNickName = () => { 22 | return localStorage.removeItem(nickNameKey) 23 | } 24 | 25 | export const setNickName = (nickName) => { 26 | return localStorage.setItem(nickNameKey, nickName) 27 | } 28 | 29 | export const getNickName = () => { 30 | return localStorage.getItem(nickNameKey); 31 | } 32 | 33 | export const setUid = (uid) => { 34 | return localStorage.setItem(uidKey, uid) 35 | } 36 | 37 | export const getUid = () => { 38 | return localStorage.getItem(uidKey); 39 | } 40 | 41 | export const removeUid = () => { 42 | return localStorage.removeItem(uidKey) 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | 2 | export const goToAnchor = (id) => { 3 | var anchor = document.getElementById(id); 4 | // chrome 5 | document.body.scrollTop = anchor.offsetTop; 6 | // firefox 7 | document.documentElement.scrollTop = anchor.offsetTop; 8 | // safari 9 | window.pageYOffset = anchor.offsetTop; 10 | } 11 | 12 | export const getQueryObject = (url) => { 13 | url = url == null ? window.location.href : url 14 | const search = url.substring(url.lastIndexOf('?') + 1) 15 | const obj = {} 16 | const reg = /([^?&=]+)=([^?&=]*)/g 17 | search.replace(reg, (rs, $1, $2) => { 18 | const name = decodeURIComponent($1) 19 | let val = decodeURIComponent($2) 20 | val = String(val) 21 | obj[name] = val 22 | return rs 23 | }) 24 | return obj 25 | } 26 | 27 | export const getQueryString = (name) => { 28 | return getQueryObject(window.location.href)[name]; 29 | } 30 | 31 | export const getLocal = (name) => { 32 | return localStorage.getItem(name) 33 | } 34 | 35 | export const setLocal = (name, value) => { 36 | localStorage.setItem(name, value) 37 | } 38 | 39 | export const addDay = (days) => { 40 | //创建date 41 | let nowDate = new Date(); 42 | //添加天数 43 | nowDate.setDate(nowDate.getDate() + days); 44 | //返回 45 | return nowDate 46 | } 47 | 48 | export const addMonth= (months) => { 49 | //创建date 50 | let nowDate = new Date(); 51 | //添加周数 52 | nowDate.setMonth(nowDate.getMonth() + months); 53 | //返回 54 | return nowDate 55 | } 56 | 57 | export const addYear= (years) => { 58 | //创建date 59 | let nowDate = new Date(); 60 | //添加年数 61 | nowDate.setMonth(nowDate.getYear() + years); 62 | //返回 63 | return nowDate 64 | } 65 | 66 | export const dateFormat = (fmt, date) => { 67 | let ret; 68 | const opt = { 69 | "Y+": date.getFullYear().toString(), // 年 70 | "m+": (date.getMonth() + 1).toString(), // 月 71 | "d+": date.getDate().toString(), // 日 72 | "H+": date.getHours().toString(), // 时 73 | "M+": date.getMinutes().toString(), // 分 74 | "S+": date.getSeconds().toString() // 秒 75 | // 有其他格式化字符需求可以继续添加,必须转化成字符串 76 | }; 77 | for (let k in opt) { 78 | ret = new RegExp("(" + k + ")").exec(fmt); 79 | if (ret) { 80 | fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) 81 | }; 82 | }; 83 | return fmt; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/utils/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import router from '@/router' 3 | import { ElMessage } from 'element-plus' 4 | import {getToken,removeToken,removeNickName, setToken} from '@/utils/auth' 5 | 6 | 7 | 8 | axios.defaults.baseURL = process.env.VUE_APP_BASE_API_URL 9 | axios.defaults.timeout = 10000 10 | axios.defaults.withCredentials = true 11 | axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest' 12 | axios.defaults.headers.post['Content-Type'] = 'application/json' 13 | 14 | axios.interceptors.request.use(config => { 15 | config.headers['Authorization'] = getToken() 16 | return config 17 | }, error => { 18 | console.log(error) 19 | Promise.reject(error) 20 | }) 21 | 22 | axios.interceptors.response.use(res => { 23 | if (typeof res.data !== 'object') { 24 | ElMessage.error('服务端异常!') 25 | return Promise.reject(res) 26 | } 27 | if (res.data.code != "00000") { 28 | if (res.data.message) { 29 | ElMessage.error(res.data.message) 30 | } 31 | // 登录已过期 32 | if (res.data.code == 'A0230') { 33 | // 移除 token 34 | removeToken(); 35 | removeNickName(); 36 | router.push({ path: '/login' }) 37 | } 38 | 39 | return Promise.reject(res.data) 40 | } 41 | 42 | return res.data 43 | }, error => { 44 | ElMessage.error('网络异常!') 45 | console.log(error) 46 | Promise.reject(error) 47 | }) 48 | 49 | export default axios -------------------------------------------------------------------------------- /src/views/BookClass.vue: -------------------------------------------------------------------------------- 1 | 229 | 230 | 375 | 376 | 387 | -------------------------------------------------------------------------------- /src/views/BookRank.vue: -------------------------------------------------------------------------------- 1 | 93 | 94 | 172 | 173 | 184 | -------------------------------------------------------------------------------- /src/views/ChapterList.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 104 | -------------------------------------------------------------------------------- /src/views/FeadBack.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 97 | 98 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 208 | 209 | 338 | -------------------------------------------------------------------------------- /src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 97 | 98 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /src/views/News.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 61 | 62 | -------------------------------------------------------------------------------- /src/views/UserComment.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 96 | 97 | -------------------------------------------------------------------------------- /src/views/UserSetup.vue: -------------------------------------------------------------------------------- 1 | 75 | 76 | 138 | 139 | -------------------------------------------------------------------------------- /src/views/author/Register.vue: -------------------------------------------------------------------------------- 1 | 165 | 166 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('@vue/cli-service') 2 | const webpack = require("webpack"); 3 | module.exports = defineConfig({ 4 | devServer:{ 5 | // 端口号的配置 6 | port:1024 7 | }, 8 | transpileDependencies: true, 9 | lintOnSave: false, 10 | configureWebpack: { 11 | plugins: [ 12 | new webpack.ProvidePlugin({ 13 | $:"jquery", 14 | jQuery:"jquery", 15 | "windows.jQuery":"jquery" 16 | }) 17 | ] 18 | } 19 | }) 20 | 21 | --------------------------------------------------------------------------------