├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── api ├── article-label.js ├── article.js ├── comment.js ├── link.js ├── sys.js └── user.js ├── components ├── AboutMe.vue ├── ArtSidebar.vue ├── ArticleTag.vue ├── ArticleType.vue ├── AsideNewComments.vue ├── AuthorWidget.vue ├── BackTop.vue ├── BlogGrid3.vue ├── Comment.vue ├── Detail.vue ├── FooterLine.vue ├── FrendLinks.vue ├── HeaderBar.vue ├── HomePage.vue ├── ListSidebar.vue ├── MarkDown.vue ├── MySidebar.vue ├── PageTitle.vue ├── TabWidget.vue ├── Tag.vue ├── TagCloud.vue ├── categories.vue └── paging.vue ├── config └── sitemap.js ├── layouts ├── error.vue └── index.vue ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages ├── about.vue ├── article │ ├── detail │ │ └── _id.vue │ ├── tag │ │ ├── _id.vue │ │ └── index.vue │ └── type │ │ ├── _id.vue │ │ └── index.vue ├── index.vue ├── links.vue └── login.vue ├── plugins ├── animate │ └── animate.min.css ├── font-awesome.js ├── js │ ├── background.js │ ├── scripts.js │ ├── slider │ │ └── main.js │ └── utils.js ├── magnific-popup │ ├── jquery.magnific-popup.min.js │ └── magnific-popup.css ├── vue-append.js └── vue-markdown.js ├── static ├── css │ ├── custom.css │ ├── list-item.css │ ├── main.css │ ├── particle │ │ └── style.css │ ├── slider │ │ ├── menu_sideslide.css │ │ └── normalize.css │ ├── style.css │ ├── type-tag │ │ └── style.css │ └── util.css ├── favicon.ico ├── images │ ├── close.svg │ ├── favicon.ico │ ├── gongan.png │ ├── login.png │ ├── menu-toggler.svg │ └── search-icon.svg ├── js │ └── jquery-3.6.0.min.js └── logo │ ├── long-logo.png │ └── square-logo.png └── utils ├── auth.js └── request.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | parser: 'babel-eslint', 5 | sourceType: 'module' 6 | }, 7 | env: { 8 | browser: true, 9 | node: true, 10 | es6: true, 11 | }, 12 | extends: [ 13 | '@nuxtjs/eslint-config-typescript', 14 | 'plugin:nuxt/recommended' 15 | ], 16 | 17 | // add your custom rules here 18 | //it is base on https://github.com/vuejs/eslint-config-vue 19 | rules: { 20 | "vue/comment-directive": 'off', 21 | "vue/max-attributes-per-line": [2, { 22 | "singleline": 10, 23 | "multiline": { 24 | "max": 1, 25 | "allowFirstLine": false 26 | } 27 | }], 28 | "vue/singleline-html-element-content-newline": "off", 29 | "vue/multiline-html-element-content-newline": "off", 30 | "vue/name-property-casing": ["error", "PascalCase"], 31 | "vue/no-v-html": "off", 32 | 'accessor-pairs': 2, 33 | 'arrow-spacing': [2, { 34 | 'before': true, 35 | 'after': true 36 | }], 37 | 'block-spacing': [2, 'always'], 38 | 'brace-style': [2, '1tbs', { 39 | 'allowSingleLine': true 40 | }], 41 | 'camelcase': [0, { 42 | 'properties': 'always' 43 | }], 44 | 'comma-dangle': [2, 'never'], 45 | 'comma-spacing': [2, { 46 | 'before': false, 47 | 'after': true 48 | }], 49 | 'comma-style': [2, 'last'], 50 | 'constructor-super': 2, 51 | 'curly': [2, 'multi-line'], 52 | 'dot-location': [2, 'property'], 53 | 'eol-last': 2, 54 | 'eqeqeq': ["error", "always", {"null": "ignore"}], 55 | 'generator-star-spacing': [2, { 56 | 'before': true, 57 | 'after': true 58 | }], 59 | 'handle-callback-err': [2, '^(err|error)$'], 60 | 'indent': [2, 2, { 61 | 'SwitchCase': 1 62 | }], 63 | 'jsx-quotes': [2, 'prefer-single'], 64 | 'key-spacing': [2, { 65 | 'beforeColon': false, 66 | 'afterColon': true 67 | }], 68 | 'keyword-spacing': [2, { 69 | 'before': true, 70 | 'after': true 71 | }], 72 | 'new-cap': [2, { 73 | 'newIsCap': true, 74 | 'capIsNew': false 75 | }], 76 | 'new-parens': 2, 77 | 'no-array-constructor': 2, 78 | 'no-caller': 2, 79 | 'no-console': 'off', 80 | 'no-class-assign': 2, 81 | 'no-cond-assign': 2, 82 | 'no-const-assign': 2, 83 | 'no-control-regex': 0, 84 | 'no-delete-var': 2, 85 | 'no-dupe-args': 2, 86 | 'no-dupe-class-members': 2, 87 | 'no-dupe-keys': 2, 88 | 'no-duplicate-case': 2, 89 | 'no-empty-character-class': 2, 90 | 'no-empty-pattern': 2, 91 | 'no-eval': 2, 92 | 'no-ex-assign': 2, 93 | 'no-extend-native': 2, 94 | 'no-extra-bind': 2, 95 | 'no-extra-boolean-cast': 2, 96 | 'no-extra-parens': [2, 'functions'], 97 | 'no-fallthrough': 2, 98 | 'no-floating-decimal': 2, 99 | 'no-func-assign': 2, 100 | 'no-implied-eval': 2, 101 | 'no-inner-declarations': [2, 'functions'], 102 | 'no-invalid-regexp': 2, 103 | 'no-irregular-whitespace': 2, 104 | 'no-iterator': 2, 105 | 'no-label-var': 2, 106 | 'no-labels': [2, { 107 | 'allowLoop': false, 108 | 'allowSwitch': false 109 | }], 110 | 'no-lone-blocks': 2, 111 | 'no-mixed-spaces-and-tabs': 2, 112 | 'no-multi-spaces': 2, 113 | 'no-multi-str': 2, 114 | 'no-multiple-empty-lines': [2, { 115 | 'max': 1 116 | }], 117 | 'no-native-reassign': 2, 118 | 'no-negated-in-lhs': 2, 119 | 'no-new-object': 2, 120 | 'no-new-require': 2, 121 | 'no-new-symbol': 2, 122 | 'no-new-wrappers': 2, 123 | 'no-obj-calls': 2, 124 | 'no-octal': 2, 125 | 'no-octal-escape': 2, 126 | 'no-path-concat': 2, 127 | 'no-proto': 2, 128 | 'no-redeclare': 2, 129 | 'no-regex-spaces': 2, 130 | 'no-return-assign': [2, 'except-parens'], 131 | 'no-self-assign': 2, 132 | 'no-self-compare': 2, 133 | 'no-sequences': 2, 134 | 'no-shadow-restricted-names': 2, 135 | 'no-spaced-func': 2, 136 | 'no-sparse-arrays': 2, 137 | 'no-this-before-super': 2, 138 | 'no-throw-literal': 2, 139 | 'no-trailing-spaces': 2, 140 | 'no-undef': 2, 141 | 'no-undef-init': 2, 142 | 'no-unexpected-multiline': 2, 143 | 'no-unmodified-loop-condition': 2, 144 | 'no-unneeded-ternary': [2, { 145 | 'defaultAssignment': false 146 | }], 147 | 'no-unreachable': 2, 148 | 'no-unsafe-finally': 2, 149 | 'no-unused-vars': [2, { 150 | 'vars': 'all', 151 | 'args': 'none' 152 | }], 153 | 'no-useless-call': 2, 154 | 'no-useless-computed-key': 2, 155 | 'no-useless-constructor': 2, 156 | 'no-useless-escape': 0, 157 | 'no-whitespace-before-property': 2, 158 | 'no-with': 2, 159 | 'one-var': [2, { 160 | 'initialized': 'never' 161 | }], 162 | 'operator-linebreak': [2, 'after', { 163 | 'overrides': { 164 | '?': 'before', 165 | ':': 'before' 166 | } 167 | }], 168 | 'padded-blocks': [2, 'never'], 169 | 'quotes': [2, 'single', { 170 | 'avoidEscape': true, 171 | 'allowTemplateLiterals': true 172 | }], 173 | 'semi': [2, 'never'], 174 | 'semi-spacing': [2, { 175 | 'before': false, 176 | 'after': true 177 | }], 178 | 'space-before-blocks': [2, 'always'], 179 | 'space-before-function-paren': [2, 'never'], 180 | 'space-in-parens': [2, 'never'], 181 | 'space-infix-ops': 2, 182 | 'space-unary-ops': [2, { 183 | 'words': true, 184 | 'nonwords': false 185 | }], 186 | 'spaced-comment': [2, 'always', { 187 | 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] 188 | }], 189 | 'template-curly-spacing': [2, 'never'], 190 | 'use-isnan': 2, 191 | 'valid-typeof': 2, 192 | 'wrap-iife': [2, 'any'], 193 | 'yield-star-spacing': [2, 'both'], 194 | 'yoda': [2, 'never'], 195 | 'prefer-const': 2, 196 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 197 | 'object-curly-spacing': [2, 'always', { 198 | objectsInObjects: false 199 | }], 200 | 'array-bracket-spacing': [2, 'never'] 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | .vscode 83 | .vs 84 | 85 | # Service worker 86 | sw.* 87 | 88 | # macOS 89 | .DS_Store 90 | 91 | # Vim swap files 92 | *.swp 93 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | 3 | LABEL "author"="WindSnowLi" 4 | LABEL "version"="1.0.1" 5 | LABEL "email"="windsnowli@163.com" 6 | # 配置环境变量支持中文 7 | ENV LANG="en_US.UTF-8" 8 | ENV NODE_OPTIONS=--openssl-legacy-provider 9 | RUN mkdir -p /vue-ssr-blog 10 | WORKDIR /vue-ssr-blog 11 | COPY . /vue-ssr-blog 12 | 13 | RUN npm install -g cnpm --registry=https://registry.npm.taobao.org 14 | RUN cnpm install 15 | RUN npm run build 16 | 17 | # 前台端口,为前台项目监听的端口,可在项目中修改 18 | EXPOSE 3000 19 | 20 | ENTRYPOINT ["sh", "-c", "npm run start"] 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 WindSnowLi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # w-blog 2 | 3 | ## 描述 4 | 5 | 一个后端使用Spring Boot 2.x、前台使用nuxtJs、后台使用vue的个人博客 6 | 7 | ## 简介 8 | 9 | 1. 链接 10 | * Gitee链接: 11 | * [api](https://gitee.com/windsnowli/w-blog-api): `https://gitee.com/windsnowli/w-blog-api` 12 | 13 | * [前台](https://gitee.com/windsnowli/vue-ssr-blog): `https://gitee.com/windsnowli/vue-ssr-blog` 14 | 15 | * [后台](https://gitee.com/windsnowli/vue-admin-blog): `https://gitee.com/windsnowli/vue-admin-blog` 16 | 17 | * GitHub链接: 18 | * [api](https://github.com/WindSnowLi/w-blog-api): `https://github.com/WindSnowLi/w-blog-api` 19 | 20 | * [前台](https://github.com/WindSnowLi/vue-ssr-blog): `https://github.com/WindSnowLi/vue-ssr-blog` 21 | 22 | * [后台](https://github.com/WindSnowLi/vue-admin-blog): `https://github.com/WindSnowLi/vue-admin-blog` 23 | 24 | 2. 一个简单的的个人博客项目,共分为了 `前台`、 `后台`、 `api`三个部分。 25 | 26 | 3. api 27 | 后端基于 `SpringBoot` 。主要依赖 `mybatis` 、 `fastjson` 、 `DruidDataSource` 、 `Lombok` 、 `java-jwt` 、 `aliyun-sdk-oss` 、 `knife4j` 等,数据库使用的是 `MySQL8.0+` 28 | 29 | 4. 前台 30 | 前台的主要样式是来源于网络上了一个 `BizBlog` 模板,最初来源于哪我不得而知,在原本的基础上改写成了 `nuxtJs` 项目。 31 | 5. 后台 32 | 后台UI套用的[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin),基本是直接拿来用了,想自己定制着实实力不允许。 33 | 6. 示例:[绿色食品——菜狗](https://www.blog.hiyj.cn/) 34 | 35 | ## 本地启动 36 | 37 | ### api:前台后台请求的api使用的是同一个项目 38 | 39 | 1. `git clone https://gitee.com/WindSnowLi/w-blog-api.git`或`git clone https://github.com/WindSnowLi/w-blog-api.git` 克隆项目到本地 40 | 2. `mvn clean install dependency:tree` 安装依赖 41 | 3. 修改开发环境 `application-dev.yml` 和生产环境 `application-prod.yml` 中的数据库配置信息; `knife4j` 只在开发环境中激活。 42 | 4. 创建数据库配置中指定名称的空数据库,`UTF8`编码 43 | 5. `mvn clean package -Dmaven.test.skip=true` 跳过测试并生成 `jar` 包 44 | 6. `java -jar 生成的包名.jar` 运行开发配置环境,初次运行会自动初始化数据库 45 | 7. 访问 `http://127.0.0.1:8888/doc.html` 查看 `api` 文档 46 | 8. *推荐使用IDEA打开项目文件夹自动处理依赖、方便运行* 47 | 48 | ### 前台 49 | 50 | 1. `git clone https://gitee.com/WindSnowLi/vue-ssr-blog.git`或`git clone https://github.com/WindSnowLi/vue-ssr-blog.git` 克隆项目到本地 51 | 2. `npm install` 安装依赖 52 | 3. 可修改 `config/sitemap.xml` 文件中的 `host` 地址,用于生成访问地图 53 | 4. 可修改 `nuxt.config.js` 中的端口号 54 | 5. 可修改 `package.json` 文件中的 `script` 中的 `BASE_URL` 来指定后端 `api` 地址 55 | 6. `npm run build` 编译 56 | 7. `npm start` 本地运行 57 | 58 | ### 后台 59 | 60 | 1. `git clone https://gitee.com/WindSnowLi/vue-admin-blog.git`或`git clone https://github.com/WindSnowLi/vue-admin-blog.git` 克隆项目到本地 61 | 2. `npm install` 安装依赖 62 | 3. `npm run dev` 使用模拟数据预览界面 63 | 4. 修改 `.env.production` 文件中的 `VUE_APP_BASE_API` 地址为后端 `api` 的地址 64 | 5. `npm run build:prod` 编译 65 | 6. `dist` 文件夹下的为编译好的文件,可放到 `http` 服务器下(可以使用 `npm` 安装 `http-server` )进行访问 66 | 7. 默认账号:`admin@163.com`,密码:`123456` 67 | 68 | ## 界面展示 69 | 70 | ### 前台 71 | 72 | ![首页](https://pic.hiyj.cn/images/2021/08/30/8be350dc4ad9f76c10f7daa8f0ec2f83.png) 73 | 74 |
75 | 76 | ![文章详情](https://pic.hiyj.cn/images/2021/08/30/d921a4e9d688c8e42e4cb491e81ea29f.png) 77 | 78 |
79 | 80 | ![友链](https://pic.hiyj.cn/images/2021/08/30/1e6a95dba9dffe2c518fb1114d27f9ef.png) 81 | 82 |
83 | 84 | ![关于信息](https://pic.hiyj.cn/images/2021/08/30/2a71cb94b94aed68d5628ee41beb0359.png) 85 | 86 | ### 后台 87 | 88 | ![首页](https://pic.hiyj.cn/images/2021/08/30/c058c6879cad0dc8db994a7dc57f1de6.png) 89 | 90 |
91 | 92 | ![创建文章](https://pic.hiyj.cn/images/2021/08/30/5a9b1e429a934801704cc9ef9526ff60.png) 93 | 94 |
95 | 96 | ![管理文章](https://pic.hiyj.cn/images/2021/08/30/b9a4cc395e4e02ff996c198f39c10895.png) 97 | 98 | ![文章列表](https://pic.hiyj.cn/images/2021/08/30/7e69e00b415213d37034dd49d236d18e.png) 99 | 100 |
101 | 102 | ![友链管理](https://pic.hiyj.cn/images/2021/08/30/2cd2f03ab3eab5ea0e14a7ced2695d09.png) 103 | 104 |
105 | 106 | ![关于信息](https://pic.hiyj.cn/images/2021/08/30/5582f506f1a93b114baef9d9977841ea.png) 107 | 108 | ## License 109 | 110 | [MIT](https://github.com/WindSnowLi/w-blog-api/blob/master/LICENSE) 111 | 112 | Copyright (c) 2021 WindSnowLi 113 | -------------------------------------------------------------------------------- /api/article-label.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | /** 4 | * 通过分类ID获取分类 5 | */ 6 | export function getAllType() { 7 | return request({ 8 | url: '/articleLabel/getAllType', 9 | method: 'post' 10 | }) 11 | } 12 | 13 | /** 14 | * 获取所有标签 15 | */ 16 | export function getAllLabel() { 17 | return request({ 18 | url: '/articleLabel/getAllLabel', 19 | method: 'post' 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /api/article.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request.js' 2 | 3 | /** 4 | * 获取所有文章 5 | */ 6 | export function getArticlesByPage(page, limit) { 7 | return request({ 8 | url: '/article/getArticlesByPage', 9 | method: 'post', 10 | data: { 11 | page, 12 | limit, 13 | sort: '-id', 14 | status: 'PUBLISHED' 15 | } 16 | }) 17 | } 18 | 19 | /** 20 | * 获取最近文章 21 | */ 22 | export function getRecentArticles() { 23 | return getArticlesByPage(1, 3) 24 | } 25 | 26 | /** 27 | * 分页获取文章 28 | * @param {*} page 页 29 | * @param {*} limit 每页大小 30 | */ 31 | export function getHistoryArticles(page, limit) { 32 | return getArticlesByPage(page, limit) 33 | } 34 | 35 | /** 36 | * 获取访问最多的文章 37 | */ 38 | export function getMostPV() { 39 | return request({ 40 | url: '/article/getMostPV', 41 | method: 'post', 42 | data: { 43 | limit: 5 44 | } 45 | }) 46 | } 47 | 48 | /** 49 | * 获取单篇文章详情信息 50 | * @param {*} id 文章ID 51 | */ 52 | export function getArticleById(id) { 53 | return request({ 54 | url: '/article/getArticleById', 55 | method: 'post', 56 | data: { 57 | id 58 | } 59 | }) 60 | } 61 | 62 | /** 63 | * 获取所属分类文章 64 | * @param {*} id 分类ID 65 | * @param {*} page 页 66 | * @param {*} limit 每页大小 67 | */ 68 | export function getArticlesByType(id, page, limit) { 69 | return request({ 70 | url: '/article/getArticlesByType', 71 | method: 'post', 72 | data: { 73 | id, 74 | content: { 75 | limit, 76 | page, 77 | sort: '-id', 78 | status: 'PUBLISHED' 79 | } 80 | } 81 | }) 82 | } 83 | 84 | /** 85 | * 通过分类ID获取分类 86 | * @param {*} id 分类ID 87 | */ 88 | export function getTypeById(id) { 89 | return request({ 90 | url: '/articleLabel/getTypeById', 91 | method: 'post', 92 | data: { 93 | id 94 | } 95 | }) 96 | } 97 | 98 | /** 99 | * 通过标签ID获取标签 100 | * @param {*} id 标签ID 101 | */ 102 | export function getLabelById(id) { 103 | return request({ 104 | url: '/articleLabel/getLabelById', 105 | method: 'post', 106 | data: { 107 | id 108 | } 109 | }) 110 | } 111 | 112 | /** 113 | * 通过标签ID获取标签所属文章 114 | * @param {*} id 标签ID 115 | * @param {*} page 页 116 | * @param {*} limit 每页大小 117 | */ 118 | export function getArticlesByLabel(id, page, limit) { 119 | return request({ 120 | url: '/article/getArticlesByLabel', 121 | method: 'post', 122 | data: { 123 | id, 124 | content: { 125 | limit, 126 | page, 127 | sort: '-id', 128 | status: 'PUBLISHED' 129 | } 130 | } 131 | }) 132 | } 133 | 134 | /** 135 | * 分页获取文章ID列表 136 | * @param {*} page 页 137 | * @param {*} limit 每页大小 138 | */ 139 | export function getArticleIdByPage(page, limit) { 140 | return request({ 141 | url: '/article/getArticleIdByPage', 142 | method: 'post', 143 | data: { 144 | limit, 145 | page, 146 | status: 'PUBLISHED' 147 | } 148 | }) 149 | } 150 | -------------------------------------------------------------------------------- /api/comment.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request' 2 | 3 | /** 4 | * 获取评论表 5 | * @param {Number} targetId 评论目标ID 6 | * @param {String} sessionType 会话类型 7 | * @param status 评论状态 8 | */ 9 | export function getTargetComments(sessionType, status, targetId = null) { 10 | return request({ 11 | url: '/comment/getTargetComments', 12 | method: 'post', 13 | data: { 14 | targetId, 15 | sessionType, 16 | status 17 | } 18 | }) 19 | } 20 | 21 | /** 22 | * 发表评论 23 | * @param {string} token 验证信息 24 | * @param {Number} targetId 评论目标ID 25 | * @param {String} sessionType 会话类型 26 | * @param {String} content 评论内容 27 | * @param {Number} parentId 父评论ID 28 | * @param {Number} toUser 回复给谁 29 | */ 30 | export function addComment(token, sessionType, content, targetId = null, parentId = null, toUser = null) { 31 | return request({ 32 | url: '/comment/addComment', 33 | method: 'post', 34 | data: { 35 | token, 36 | content: { 37 | targetId, 38 | sessionType, 39 | content, 40 | parentId, 41 | toUser 42 | } 43 | } 44 | }) 45 | } 46 | 47 | /** 48 | * 获取所有文章最新的评论 49 | * @param limit 条数限制 50 | */ 51 | export function getRecentComment(limit) { 52 | return request({ 53 | url: '/comment/getRecentComment', 54 | method: 'post', 55 | data: { 56 | content: limit 57 | } 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /api/link.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request.js' 2 | 3 | /** 4 | * 获取友链列表 5 | */ 6 | export function getFriendLinks() { 7 | return request({ 8 | url: '/links/getFriendLinks', 9 | method: 'post', 10 | data: { 11 | status: 'PASS' 12 | } 13 | }) 14 | } 15 | 16 | /** 17 | * 申请友链 18 | */ 19 | export function applyFriendLink(friendLinks) { 20 | return request({ 21 | url: '/links/applyFriendLink', 22 | method: 'post', 23 | data: { 24 | coverPic: friendLinks.coverPic, 25 | email: friendLinks.email, 26 | describe: friendLinks.describe, 27 | title: friendLinks.title, 28 | link: friendLinks.link 29 | } 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /api/sys.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request.js' 2 | 3 | /** 4 | * 获取用户UI配置 5 | * @param _id 6 | */ 7 | export function getUiConfig(_id) { 8 | return request({ 9 | url: '/sys/getUiConfig', 10 | method: 'post', 11 | data: { 12 | id: 1 13 | } 14 | }) 15 | } 16 | 17 | /** 18 | * 获取Gitee的应用程序ID 19 | */ 20 | export function getGiteeClientId() { 21 | return request({ 22 | url: '/sys/getGiteeClientId', 23 | method: 'post' 24 | }) 25 | } 26 | 27 | /** 28 | * 获取系统基础配置,包含表单描述信息 29 | */ 30 | export function getFixedConfig() { 31 | return request({ 32 | url: '/sys/getFixedConfig', 33 | method: 'post' 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /api/user.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request.js' 2 | 3 | /** 4 | * 获取用户关于信息 5 | * @param _id 6 | */ 7 | export function getAboutByUserId(_id) { 8 | return request({ 9 | url: '/user/getAboutByUserId', 10 | method: 'post', 11 | data: { 12 | id: 1 13 | } 14 | }) 15 | } 16 | 17 | /** 18 | * 19 | * 根据Gitee授权码获取对象 20 | * @param {String} code Gitee授权码 21 | * @param {String} redirect 重定向Url 22 | */ 23 | export function giteeLogin(code, redirect) { 24 | return request({ 25 | url: '/user/giteeLogin', 26 | method: 'post', 27 | data: { 28 | code, 29 | redirect 30 | } 31 | }) 32 | } 33 | 34 | /** 35 | * 登录,返回验证信息 36 | * @param {Object} data 行号密码 37 | */ 38 | export function login(data) { 39 | return request({ 40 | url: '/user/login', 41 | method: 'post', 42 | data 43 | }) 44 | } 45 | 46 | /** 47 | * 通过用户ID获取信息 48 | */ 49 | export function getVisitorInfo() { 50 | return request({ 51 | url: '/user/getVisitorInfo', 52 | method: 'post', 53 | data: { 54 | id: 1 55 | } 56 | }) 57 | } 58 | -------------------------------------------------------------------------------- /components/AboutMe.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 55 | -------------------------------------------------------------------------------- /components/ArtSidebar.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 38 | 39 | 42 | -------------------------------------------------------------------------------- /components/ArticleTag.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 53 | -------------------------------------------------------------------------------- /components/ArticleType.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 55 | -------------------------------------------------------------------------------- /components/AsideNewComments.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 44 | 45 | 62 | -------------------------------------------------------------------------------- /components/AuthorWidget.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 37 | -------------------------------------------------------------------------------- /components/BackTop.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /components/BlogGrid3.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 59 | -------------------------------------------------------------------------------- /components/Comment.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 197 | 198 | 236 | -------------------------------------------------------------------------------- /components/Detail.vue: -------------------------------------------------------------------------------- 1 | 134 | 135 | 194 | -------------------------------------------------------------------------------- /components/FooterLine.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 45 | 46 | 48 | -------------------------------------------------------------------------------- /components/FrendLinks.vue: -------------------------------------------------------------------------------- 1 | 73 | 74 | 154 | 155 | 236 | -------------------------------------------------------------------------------- /components/HeaderBar.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 83 | 84 | 93 | -------------------------------------------------------------------------------- /components/HomePage.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 68 | 71 | -------------------------------------------------------------------------------- /components/ListSidebar.vue: -------------------------------------------------------------------------------- 1 | 83 | 84 | 131 | 134 | -------------------------------------------------------------------------------- /components/MarkDown.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | 30 | 66 | -------------------------------------------------------------------------------- /components/MySidebar.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 52 | -------------------------------------------------------------------------------- /components/PageTitle.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | -------------------------------------------------------------------------------- /components/TabWidget.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 46 | 51 | -------------------------------------------------------------------------------- /components/Tag.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 55 | 58 | -------------------------------------------------------------------------------- /components/TagCloud.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 116 | 121 | -------------------------------------------------------------------------------- /components/categories.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 56 | 59 | -------------------------------------------------------------------------------- /components/paging.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 34 | 70 | -------------------------------------------------------------------------------- /config/sitemap.js: -------------------------------------------------------------------------------- 1 | import { 2 | getArticleIdByPage 3 | } from '../api/article.js' 4 | 5 | const sitemap = { 6 | path: '/sitemap.xml', // 生成的文件路径 7 | hostname: 'http://127.0.0.1:3000/', // 网址 8 | cacheTime: 1000 * 60 * 60 * 24, // 1天 更新频率,只在 generate: false有用 9 | gzip: true, // 生成 .xml.gz 压缩的 sitemap 10 | generate: false, // 允许使用 nuxt generate 生成 11 | // 排除不要页面 12 | exclude: [ 13 | '/404', // 这里的路径相对 hostname 14 | '/about' 15 | ], 16 | // xml默认的配置 17 | defaults: { 18 | changefreq: 'always', 19 | lastmod: new Date() 20 | }, 21 | // 需要生成的xml数据, return 返回需要给出的xml数据 22 | routes: async() => { 23 | let rs = [] 24 | // 从后台获取数据,拼接url生成更多的xml数据 25 | const data = await getArticleIdByPage(1, 100) 26 | const routes = [ 27 | { 28 | url: '/', // 这里的路径相对 hostname 29 | changefreq: 'always', 30 | lastmod: new Date() 31 | } 32 | ] 33 | if (data) { 34 | const arr = [] 35 | data.forEach(item => arr.push({ 36 | url: '/article/detail/' + item.id, 37 | lastmod: new Date(item.updateTime), 38 | changefreq: 'yearly' 39 | })) 40 | rs = routes.concat(arr) 41 | } 42 | return rs 43 | } 44 | } 45 | 46 | export default sitemap 47 | -------------------------------------------------------------------------------- /layouts/index.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 79 | 80 | 83 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | import cheerio from 'cheerio' 2 | import sitemap from './config/sitemap' 3 | 4 | export default { 5 | server: { 6 | port: 3000, // default: 3000 7 | host: '0.0.0.0' // default: localhost 8 | }, 9 | // Global page headers: https://go.nuxtjs.dev/config-head 10 | head: { 11 | title: 'vue-ssr-blog', 12 | htmlAttrs: { 13 | lang: 'en' 14 | }, 15 | meta: [{ 16 | charset: 'utf-8' 17 | }, 18 | { 19 | name: 'viewport', 20 | content: 'width=device-width, initial-scale=1' 21 | }, 22 | { 23 | name: 'format-detection', 24 | content: 'telephone=no' 25 | } 26 | ], 27 | link: [{ 28 | rel: 'icon', 29 | type: 'image/x-icon', 30 | href: '/favicon.ico' 31 | }], 32 | script: [{ 33 | src: '/js/jquery-3.6.0.min.js', 34 | ssr: false 35 | }] 36 | }, 37 | 38 | // Global CSS: https://go.nuxtjs.dev/config-css 39 | css: [ 40 | 'mavon-editor/dist/css/index.css', 41 | 'animate.css/animate.css' 42 | ], 43 | 44 | // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins 45 | plugins: [{ 46 | src: '~/plugins/font-awesome.js', 47 | ssr: false 48 | }, 49 | { 50 | src: '~/plugins/magnific-popup/jquery.magnific-popup.min.js', 51 | ssr: false 52 | }, 53 | { 54 | src: '~/plugins/js/scripts.js', 55 | ssr: false 56 | }, 57 | { 58 | src: '~/plugins/js/background.js', 59 | ssr: false 60 | }, 61 | { 62 | src: '~plugins/vue-markdown.js', 63 | ssr: false 64 | }, 65 | { 66 | src: '~plugins/vue-append.js', 67 | ssr: false 68 | }, 69 | { 70 | src: '~plugins/js/utils.js', 71 | ssr: false 72 | }, 73 | { 74 | src: '~plugins/js/slider/main.js', 75 | ssr: false 76 | } 77 | ], 78 | 79 | // Auto import components: https://go.nuxtjs.dev/config-components 80 | components: true, 81 | 82 | // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules 83 | buildModules: [], 84 | 85 | // Modules: https://go.nuxtjs.dev/config-modules 86 | modules: [ 87 | // https://go.nuxtjs.dev/bootstrap 88 | 'bootstrap-vue/nuxt', 89 | 'nuxt-fontawesome', 90 | '@nuxtjs/sitemap' 91 | ], 92 | // Build Configuration: https://go.nuxtjs.dev/config-build 93 | build: { 94 | // 解决引用文件过大会报错的问题 95 | babel: { 96 | compact: false 97 | }, 98 | // 抽离CSS 99 | extractCSS: true 100 | }, 101 | env: { 102 | BASE_URL: process.env.BASE_URL, 103 | NODE_ENV: process.env.NODE_ENV 104 | }, 105 | hooks: { 106 | // 删除meta信息的无关标签(为了百度验证) 107 | 'render:route': (url, result) => { 108 | const $ = cheerio.load(result.html, { 109 | decodeEntities: false 110 | }) 111 | $(`meta`).removeAttr('data-n-head') 112 | result.html = $.html() 113 | } 114 | }, 115 | // target: 'static', // default is 'server' 116 | sitemap 117 | } 118 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-ssr-blog", 3 | "version": "1.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "cross-env BASE_URL=http://127.0.0.1:9000/api NODE_ENV=dev nuxt", 7 | "start": "cross-env BASE_URL=http://127.0.0.1:9000/api NODE_ENV=production nuxt start", 8 | "build": "cross-env BASE_URL=http://127.0.0.1:9000/api NODE_ENV=production nuxt build", 9 | "test": "cross-env BASE_URL=http://127.0.0.1:9000/api NODE_ENV=test nuxt generate", 10 | "generate": "cross-env BASE_URL=http://127.0.0.1:9000/api NODE_ENV=generate nuxt generate" 11 | }, 12 | "dependencies": { 13 | "@fortawesome/fontawesome-svg-core": "^1.2.36", 14 | "@fortawesome/free-brands-svg-icons": "^6.2.0", 15 | "@fortawesome/free-regular-svg-icons": "^6.2.0", 16 | "@fortawesome/free-solid-svg-icons": "^6.2.1", 17 | "@fortawesome/vue-fontawesome": "^2.0.9", 18 | "animate.css": "^4.1.1", 19 | "axios": "^0.27.2", 20 | "bootstrap": "^5.2.1", 21 | "bootstrap-vue": "^2.22.0", 22 | "cheerio": "^1.0.0-rc.12", 23 | "core-js": "^3.25.2", 24 | "cross-env": "^7.0.3", 25 | "github-markdown-css": "^5.1.0", 26 | "highlight": "^0.2.4", 27 | "highlightjs-line-numbers.js": "^2.8.0", 28 | "jquery": "^3.6.1", 29 | "js-cookie": "^3.0.1", 30 | "mavon-editor": "^2.10.4", 31 | "nuxt": "^2.15.8", 32 | "nuxt-fontawesome": "^0.4.0", 33 | "tilt.js": "^1.2.1", 34 | "vue-append": "^2.2.0", 35 | "wowjs": "^1.1.3" 36 | }, 37 | "devDependencies": { 38 | "@nuxtjs/eslint-config-typescript": "^11.0.0", 39 | "@nuxtjs/eslint-module": "^3.1.0", 40 | "@nuxtjs/sitemap": "^2.4.0", 41 | "babel-eslint": "^10.1.0", 42 | "cross-env": "^7.0.3", 43 | "eslint": "^8.23.1", 44 | "eslint-plugin-nuxt": ">=4.0.0", 45 | "install": "^0.13.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pages/about.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 46 | 50 | -------------------------------------------------------------------------------- /pages/article/detail/_id.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 51 | -------------------------------------------------------------------------------- /pages/article/tag/_id.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 62 | -------------------------------------------------------------------------------- /pages/article/tag/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 46 | -------------------------------------------------------------------------------- /pages/article/type/_id.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 62 | -------------------------------------------------------------------------------- /pages/article/type/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 44 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 58 | 62 | -------------------------------------------------------------------------------- /pages/links.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 34 | -------------------------------------------------------------------------------- /pages/login.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 144 | -------------------------------------------------------------------------------- /plugins/font-awesome.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | // 导入所有fontawesome,组件名fa 3 | import { library } from '@fortawesome/fontawesome-svg-core' 4 | import { fas } from '@fortawesome/free-solid-svg-icons' 5 | import { far } from '@fortawesome/free-regular-svg-icons' 6 | import { fab } from '@fortawesome/free-brands-svg-icons' 7 | import { FontAwesomeIcon, FontAwesomeLayers, FontAwesomeLayersText } 8 | from '@fortawesome/vue-fontawesome' 9 | library.add(fas, far, fab) 10 | Vue.component('fa', FontAwesomeIcon) 11 | Vue.component('font-awesome-layers', FontAwesomeLayers) 12 | Vue.component('font-awesome-layers-text', FontAwesomeLayersText) 13 | Vue.config.productionTip = false 14 | -------------------------------------------------------------------------------- /plugins/js/background.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 设置动态壁纸 3 | * @param {Object} imgList 图片列表 4 | * @param {Object} id 控件ID 5 | */ 6 | export function background(imgList, id) { 7 | const duration = imgList.length * 6 8 | let rs = '' 9 | for (const i in imgList) { 10 | rs = rs + "
  • " 13 | } 14 | if (process.client) { 15 | document.getElementById(id).innerHTML = rs 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /plugins/js/scripts.js: -------------------------------------------------------------------------------- 1 | /* --------------------------------------------- 2 | Template name: BizBlog 3 | Version: 1.0 4 | Author: ThemeLooks 5 | Author url: http://themelooks.com 6 | 7 | NOTE: 8 | ------ 9 | Please DO NOT EDIT THIS JS, you may need to use "custom.js" file for writing your custom js. 10 | We may release future updates so it will overwrite this file. it's better and safer to use "custom.js". 11 | 12 | [Table of Content] 13 | 14 | 01: Background Image 15 | 02: Image To SVG 16 | 03: Searh Box 17 | 04: Navbar 18 | 05: Banner 19 | 06: Post Video Thumbnail 20 | 07: Owl Carousel Defaults 21 | 08: Preloader 22 | 09: Back To Top 23 | 10: Ajex Contact Form 24 | ----------------------------------------------*/ 25 | 26 | (function($) { 27 | 'use strict' 28 | 29 | /* 01: Background Image 30 | ==============================================*/ 31 | const $bgImg = $('[data-bg-img]') 32 | $bgImg.css('background-image', function() { 33 | return 'url("' + $(this).data('bg-img') + '")' 34 | }).removeAttr('data-bg-img').addClass('bg-img') 35 | 36 | /* 02: Image To SVG 37 | ==============================================*/ 38 | 39 | jQuery('img.svg').each(function() { 40 | const $img = jQuery(this) 41 | const imgID = $img.attr('id') 42 | const imgClass = $img.attr('class') 43 | const imgURL = $img.attr('src') 44 | jQuery.get(imgURL, function(data) { 45 | // Get the SVG tag, ignore the rest 46 | let $svg = jQuery(data).find('svg') // Add replaced image's ID to the new SVG 47 | 48 | if (typeof imgID !== 'undefined') { 49 | $svg = $svg.attr('id', imgID) 50 | } // Add replaced image's classes to the new SVG 51 | 52 | if (typeof imgClass !== 'undefined') { 53 | $svg = $svg.attr('class', imgClass + ' replaced-svg') 54 | } // Remove any invalid XML tags as per http://validator.w3.org 55 | 56 | $svg = $svg.removeAttr('xmlns:a') // Check if the viewport is set, if the viewport is not set the SVG wont't scale. 57 | 58 | if (!$svg.attr('viewBox') && $svg.attr('height') && $svg.attr('width')) { 59 | $svg.attr('viewBox', '0 0 ' + $svg.attr('height') + ' ' + $svg.attr('width')) 60 | } // Replace image with new SVG 61 | 62 | $img.replaceWith($svg) 63 | }, 'xml') 64 | }) 65 | 66 | /* 03: Searh Box 67 | ==============================================*/ 68 | const searchOpen = $('.mobile-nav-menu .search-toggle-open') 69 | const searchClose = $('.mobile-nav-menu .search-toggle-close') 70 | const searchBox = $('.nav-search-box') 71 | 72 | searchOpen.on('click', function() { 73 | searchBox.addClass('show') 74 | $(this).addClass('hide') 75 | searchClose.removeClass('hide') 76 | }) 77 | searchClose.on('click', function() { 78 | searchBox.removeClass('show') 79 | $(this).addClass('hide') 80 | searchOpen.removeClass('hide') 81 | }) 82 | 83 | /* 04: Navbar 84 | ==============================================*/ 85 | $(window).on('scroll', function() { 86 | navOnScroll() 87 | }) 88 | 89 | function navOnScroll() { 90 | if ($(window).scrollTop() > 0) { 91 | $('.header-fixed').addClass('is-sticky fadeInDown animated') 92 | } else { 93 | $('.header-fixed').removeClass('is-sticky fadeInDown animated') 94 | } 95 | } 96 | 97 | navOnScroll() 98 | $('.mobile-nav-menu .nav-menu-toggle').on('click', function() { 99 | $('.nav-menu').toggleClass('show') 100 | }) 101 | $('.nav-menu .menu-item-has-children a').on('click', function(e) { 102 | if ($(window).width() <= 991) { 103 | $(this).siblings('.sub-menu').addClass('show') 104 | } 105 | }) 106 | 107 | const subToggle = function subToggle() { 108 | $('.nav-menu .menu-item-has-children a').each(function() { 109 | $(this).siblings('.sub-menu').prepend('') 110 | }) 111 | } 112 | 113 | subToggle() 114 | $('.nav-menu .menu-item-has-children .sub-menu .sub-menu-close').on('click', function() { 115 | $(this).parent('.sub-menu').removeClass('show') 116 | }) 117 | 118 | function subMenu() { 119 | $('.nav-menu .menu-item-has-children .sub-menu').each(function() { 120 | if ($(window).width() > 991) { 121 | if ($(this).offset().left + $(this).width() > $(window).width()) { 122 | $(this).css({ 123 | left: 'auto', 124 | right: '100%' 125 | }) 126 | } 127 | } 128 | }) 129 | } 130 | 131 | subMenu() 132 | $(window).resize(subMenu) 133 | 134 | /* 08: Preloader 135 | ==============================================*/ 136 | $(window).on('load', function() { 137 | $('.preloader').fadeOut(2000) 138 | }) 139 | 140 | /* 09: Back to Top 141 | ==============================================*/ 142 | const $backToTopBtn = $('.back-to-top') 143 | 144 | if ($backToTopBtn.length) { 145 | const scrollTrigger = 400 146 | // px 147 | const backToTop = function backToTop() { 148 | const scrollTop = $(window).scrollTop() 149 | 150 | if (scrollTop > scrollTrigger) { 151 | $backToTopBtn.addClass('show') 152 | } else { 153 | $backToTopBtn.removeClass('show') 154 | } 155 | } 156 | 157 | backToTop() 158 | $(window).on('scroll', function() { 159 | backToTop() 160 | }) 161 | $backToTopBtn.on('click', function(e) { 162 | e.preventDefault() 163 | $('html,body').animate({ 164 | scrollTop: 0 165 | }, 700) 166 | }) 167 | } 168 | 169 | /* 10: Ajax Contact Form 170 | ==============================================*/ 171 | $('.my-contact-form-cover').on('submit', 'form', function(e) { 172 | e.preventDefault() 173 | 174 | const $el = $(this) 175 | 176 | $.post($el.attr('action'), $el.serialize(), function(res) { 177 | res = $.parseJSON(res) 178 | $el.parent('.my-contact-form-cover').find('.form-response').html('' + res[1] + '') 179 | }) 180 | }) 181 | })(jQuery) 182 | -------------------------------------------------------------------------------- /plugins/js/slider/main.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * classie - class helper functions 4 | * from bonzo https://github.com/ded/bonzo 5 | * 6 | * classie.has( elem, 'my-class' ) -> true/false 7 | * classie.add( elem, 'my-new-class' ) 8 | * classie.remove( elem, 'my-unwanted-class' ) 9 | * classie.toggle( elem, 'my-class' ) 10 | */ 11 | 12 | /* jshint browser: true, strict: true, undef: true */ 13 | /*global define: false */ 14 | 15 | export function classIe(window) { 16 | 'use strict' 17 | 18 | // class helper functions from bonzo https://github.com/ded/bonzo 19 | 20 | function classReg(className) { 21 | return new RegExp('(^|\\s+)' + className + '(\\s+|$)') 22 | } 23 | 24 | // classList support for class management 25 | // altho to be fair, the api sucks because it won't accept multiple classes at once 26 | let hasClass, addClass, removeClass 27 | 28 | if ('classList' in document.documentElement) { 29 | hasClass = function(elem, c) { 30 | return elem.classList.contains(c) 31 | } 32 | addClass = function(elem, c) { 33 | elem.classList.add(c) 34 | } 35 | removeClass = function(elem, c) { 36 | elem.classList.remove(c) 37 | } 38 | } else { 39 | hasClass = function(elem, c) { 40 | return classReg(c).test(elem.className) 41 | } 42 | addClass = function(elem, c) { 43 | if (!hasClass(elem, c)) { 44 | elem.className = elem.className + ' ' + c 45 | } 46 | } 47 | removeClass = function(elem, c) { 48 | elem.className = elem.className.replace(classReg(c), ' ') 49 | } 50 | } 51 | 52 | function toggleClass(elem, c) { 53 | const fn = hasClass(elem, c) ? removeClass : addClass 54 | fn(elem, c) 55 | } 56 | 57 | const classie = { 58 | // full names 59 | hasClass, 60 | addClass, 61 | removeClass, 62 | toggleClass, 63 | // short names 64 | has: hasClass, 65 | add: addClass, 66 | remove: removeClass, 67 | toggle: toggleClass 68 | } 69 | 70 | // transport 71 | if (typeof define === 'function' && define.amd) { 72 | // AMD 73 | define(classie) 74 | } else { 75 | // browser global 76 | window.classie = classie 77 | } 78 | } 79 | 80 | /** 81 | * main.js 82 | * http://www.codrops.com 83 | * 84 | * Licensed under the MIT license. 85 | * http://www.opensource.org/licenses/mit-license.php 86 | * 87 | * Copyright 2014, Codrops 88 | * http://www.codrops.com 89 | */ 90 | let bodyEl = null 91 | let headerOpenBtn = null 92 | let headerCloseBtn = null 93 | let headerIsOpen = false 94 | function toggleMenu() { 95 | if (headerIsOpen) { 96 | window.classie.remove(bodyEl, 'show-menu') 97 | } else { 98 | window.classie.add(bodyEl, 'show-menu') 99 | } 100 | headerIsOpen = !headerIsOpen 101 | } 102 | function initEvents() { 103 | headerOpenBtn.addEventListener('click', toggleMenu) 104 | if (headerCloseBtn) { 105 | headerCloseBtn.addEventListener('click', toggleMenu) 106 | } 107 | } 108 | export function headerIni() { 109 | if (process.client) { 110 | bodyEl = document.body 111 | headerOpenBtn = document.getElementById('open-button') 112 | headerCloseBtn = document.getElementById('close-button') 113 | console.log(bodyEl) 114 | console.log(headerOpenBtn) 115 | console.log(headerCloseBtn) 116 | classIe(window) 117 | initEvents() 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /plugins/js/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 设置动态壁纸 3 | */ 4 | export function getPageUrl() { 5 | if (process.client) { 6 | return window.location.protocol + '//' + window.location.host + window.location.pathname 7 | } else { 8 | return '#' 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/magnific-popup/jquery.magnific-popup.min.js: -------------------------------------------------------------------------------- 1 | /*! Magnific Popup - v1.1.0 - 2016-02-20 2 | * http://dimsemenov.com/plugins/magnific-popup/ 3 | * Copyright (c) 2016 Dmitry Semenov; */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):window.jQuery||window.Zepto)}(function(a){var b,c,d,e,f,g,h="Close",i="BeforeClose",j="AfterClose",k="BeforeAppend",l="MarkupParse",m="Open",n="Change",o="mfp",p="."+o,q="mfp-ready",r="mfp-removing",s="mfp-prevent-close",t=function(){},u=!!window.jQuery,v=a(window),w=function(a,c){b.ev.on(o+a+p,c)},x=function(b,c,d,e){var f=document.createElement("div");return f.className="mfp-"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},y=function(c,d){b.ev.triggerHandler(o+c,d),b.st.callbacks&&(c=c.charAt(0).toLowerCase()+c.slice(1),b.st.callbacks[c]&&b.st.callbacks[c].apply(b,a.isArray(d)?d:[d]))},z=function(c){return c===g&&b.currTemplate.closeBtn||(b.currTemplate.closeBtn=a(b.st.closeMarkup.replace("%title%",b.st.tClose)),g=c),b.currTemplate.closeBtn},A=function(){a.magnificPopup.instance||(b=new t,b.init(),a.magnificPopup.instance=b)},B=function(){var a=document.createElement("p").style,b=["ms","O","Moz","Webkit"];if(void 0!==a.transition)return!0;for(;b.length;)if(b.pop()+"Transition"in a)return!0;return!1};t.prototype={constructor:t,init:function(){var c=navigator.appVersion;b.isLowIE=b.isIE8=document.all&&!document.addEventListener,b.isAndroid=/android/gi.test(c),b.isIOS=/iphone|ipad|ipod/gi.test(c),b.supportsTransition=B(),b.probablyMobile=b.isAndroid||b.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),d=a(document),b.popupsCache={}},open:function(c){var e;if(c.isObj===!1){b.items=c.items.toArray(),b.index=0;var g,h=c.items;for(e=0;e(a||v.height())},_setFocus:function(){(b.st.focus?b.content.find(b.st.focus).eq(0):b.wrap).focus()},_onFocusIn:function(c){return c.target===b.wrap[0]||a.contains(b.wrap[0],c.target)?void 0:(b._setFocus(),!1)},_parseMarkup:function(b,c,d){var e;d.data&&(c=a.extend(d.data,c)),y(l,[b,c,d]),a.each(c,function(c,d){if(void 0===d||d===!1)return!0;if(e=c.split("_"),e.length>1){var f=b.find(p+"-"+e[0]);if(f.length>0){var g=e[1];"replaceWith"===g?f[0]!==d[0]&&f.replaceWith(d):"img"===g?f.is("img")?f.attr("src",d):f.replaceWith(a("").attr("src",d).attr("class",f.attr("class"))):f.attr(e[1],d)}}else b.find(p+"-"+c).html(d)})},_getScrollbarSize:function(){if(void 0===b.scrollbarSize){var a=document.createElement("div");a.style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(a),b.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return b.scrollbarSize}},a.magnificPopup={instance:null,proto:t.prototype,modules:[],open:function(b,c){return A(),b=b?a.extend(!0,{},b):{},b.isObj=!0,b.index=c||0,this.instance.open(b)},close:function(){return a.magnificPopup.instance&&a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'',tClose:"Close (Esc)",tLoading:"Loading...",autoFocusLast:!0}},a.fn.magnificPopup=function(c){A();var d=a(this);if("string"==typeof c)if("open"===c){var e,f=u?d.data("magnificPopup"):d[0].magnificPopup,g=parseInt(arguments[1],10)||0;f.items?e=f.items[g]:(e=d,f.delegate&&(e=e.find(f.delegate)),e=e.eq(g)),b._openClick({mfpEl:e},d,f)}else b.isOpen&&b[c].apply(b,Array.prototype.slice.call(arguments,1));else c=a.extend(!0,{},c),u?d.data("magnificPopup",c):d[0].magnificPopup=c,b.addGroup(d,c);return d};var C,D,E,F="inline",G=function(){E&&(D.after(E.addClass(C)).detach(),E=null)};a.magnificPopup.registerModule(F,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content not found"},proto:{initInline:function(){b.types.push(F),w(h+"."+F,function(){G()})},getInline:function(c,d){if(G(),c.src){var e=b.st.inline,f=a(c.src);if(f.length){var g=f[0].parentNode;g&&g.tagName&&(D||(C=e.hiddenClass,D=x(C),C="mfp-"+C),E=f.after(D).detach().removeClass(C)),b.updateStatus("ready")}else b.updateStatus("error",e.tNotFound),f=a("
    ");return c.inlineElement=f,f}return b.updateStatus("ready"),b._parseMarkup(d,{},c),d}}});var H,I="ajax",J=function(){H&&a(document.body).removeClass(H)},K=function(){J(),b.req&&b.req.abort()};a.magnificPopup.registerModule(I,{options:{settings:null,cursor:"mfp-ajax-cur",tError:'The content could not be loaded.'},proto:{initAjax:function(){b.types.push(I),H=b.st.ajax.cursor,w(h+"."+I,K),w("BeforeChange."+I,K)},getAjax:function(c){H&&a(document.body).addClass(H),b.updateStatus("loading");var d=a.extend({url:c.src,success:function(d,e,f){var g={data:d,xhr:f};y("ParseAjax",g),b.appendContent(a(g.data),I),c.finished=!0,J(),b._setFocus(),setTimeout(function(){b.wrap.addClass(q)},16),b.updateStatus("ready"),y("AjaxContentAdded")},error:function(){J(),c.finished=c.loadError=!0,b.updateStatus("error",b.st.ajax.tError.replace("%url%",c.src))}},b.st.ajax.settings);return b.req=a.ajax(d),""}}});var L,M=function(c){if(c.data&&void 0!==c.data.title)return c.data.title;var d=b.st.image.titleSrc;if(d){if(a.isFunction(d))return d.call(b,c);if(c.el)return c.el.attr(d)||""}return""};a.magnificPopup.registerModule("image",{options:{markup:'
    ',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'The image could not be loaded.'},proto:{initImage:function(){var c=b.st.image,d=".image";b.types.push("image"),w(m+d,function(){"image"===b.currItem.type&&c.cursor&&a(document.body).addClass(c.cursor)}),w(h+d,function(){c.cursor&&a(document.body).removeClass(c.cursor),v.off("resize"+p)}),w("Resize"+d,b.resizeImage),b.isLowIE&&w("AfterChange",b.resizeImage)},resizeImage:function(){var a=b.currItem;if(a&&a.img&&b.st.image.verticalFit){var c=0;b.isLowIE&&(c=parseInt(a.img.css("padding-top"),10)+parseInt(a.img.css("padding-bottom"),10)),a.img.css("max-height",b.wH-c)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,L&&clearInterval(L),a.isCheckingImgSize=!1,y("ImageHasSize",a),a.imgHidden&&(b.content&&b.content.removeClass("mfp-loading"),a.imgHidden=!1))},findImageSize:function(a){var c=0,d=a.img[0],e=function(f){L&&clearInterval(L),L=setInterval(function(){return d.naturalWidth>0?void b._onImageHasSize(a):(c>200&&clearInterval(L),c++,void(3===c?e(10):40===c?e(50):100===c&&e(500)))},f)};e(1)},getImage:function(c,d){var e=0,f=function(){c&&(c.img[0].complete?(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("ready")),c.hasSize=!0,c.loaded=!0,y("ImageLoadComplete")):(e++,200>e?setTimeout(f,100):g()))},g=function(){c&&(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("error",h.tError.replace("%url%",c.src))),c.hasSize=!0,c.loaded=!0,c.loadError=!0)},h=b.st.image,i=d.find(".mfp-img");if(i.length){var j=document.createElement("img");j.className="mfp-img",c.el&&c.el.find("img").length&&(j.alt=c.el.find("img").attr("alt")),c.img=a(j).on("load.mfploader",f).on("error.mfploader",g),j.src=c.src,i.is("img")&&(c.img=c.img.clone()),j=c.img[0],j.naturalWidth>0?c.hasSize=!0:j.width||(c.hasSize=!1)}return b._parseMarkup(d,{title:M(c),img_replaceWith:c.img},c),b.resizeImage(),c.hasSize?(L&&clearInterval(L),c.loadError?(d.addClass("mfp-loading"),b.updateStatus("error",h.tError.replace("%url%",c.src))):(d.removeClass("mfp-loading"),b.updateStatus("ready")),d):(b.updateStatus("loading"),c.loading=!0,c.hasSize||(c.imgHidden=!0,d.addClass("mfp-loading"),b.findImageSize(c)),d)}}});var N,O=function(){return void 0===N&&(N=void 0!==document.createElement("p").style.MozTransform),N};a.magnificPopup.registerModule("zoom",{options:{enabled:!1,easing:"ease-in-out",duration:300,opener:function(a){return a.is("img")?a:a.find("img")}},proto:{initZoom:function(){var a,c=b.st.zoom,d=".zoom";if(c.enabled&&b.supportsTransition){var e,f,g=c.duration,j=function(a){var b=a.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),d="all "+c.duration/1e3+"s "+c.easing,e={position:"fixed",zIndex:9999,left:0,top:0,"-webkit-backface-visibility":"hidden"},f="transition";return e["-webkit-"+f]=e["-moz-"+f]=e["-o-"+f]=e[f]=d,b.css(e),b},k=function(){b.content.css("visibility","visible")};w("BuildControls"+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.content.css("visibility","hidden"),a=b._getItemToZoom(),!a)return void k();f=j(a),f.css(b._getOffset()),b.wrap.append(f),e=setTimeout(function(){f.css(b._getOffset(!0)),e=setTimeout(function(){k(),setTimeout(function(){f.remove(),a=f=null,y("ZoomAnimationEnded")},16)},g)},16)}}),w(i+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.st.removalDelay=g,!a){if(a=b._getItemToZoom(),!a)return;f=j(a)}f.css(b._getOffset(!0)),b.wrap.append(f),b.content.css("visibility","hidden"),setTimeout(function(){f.css(b._getOffset())},16)}}),w(h+d,function(){b._allowZoom()&&(k(),f&&f.remove(),a=null)})}},_allowZoom:function(){return"image"===b.currItem.type},_getItemToZoom:function(){return b.currItem.hasSize?b.currItem.img:!1},_getOffset:function(c){var d;d=c?b.currItem.img:b.st.zoom.opener(b.currItem.el||b.currItem);var e=d.offset(),f=parseInt(d.css("padding-top"),10),g=parseInt(d.css("padding-bottom"),10);e.top-=a(window).scrollTop()-f;var h={width:d.width(),height:(u?d.innerHeight():d[0].offsetHeight)-g-f};return O()?h["-moz-transform"]=h.transform="translate("+e.left+"px,"+e.top+"px)":(h.left=e.left,h.top=e.top),h}}});var P="iframe",Q="//about:blank",R=function(a){if(b.currTemplate[P]){var c=b.currTemplate[P].find("iframe");c.length&&(a||(c[0].src=Q),b.isIE8&&c.css("display",a?"block":"none"))}};a.magnificPopup.registerModule(P,{options:{markup:'
    ',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){b.types.push(P),w("BeforeChange",function(a,b,c){b!==c&&(b===P?R():c===P&&R(!0))}),w(h+"."+P,function(){R()})},getIframe:function(c,d){var e=c.src,f=b.st.iframe;a.each(f.patterns,function(){return e.indexOf(this.index)>-1?(this.id&&(e="string"==typeof this.id?e.substr(e.lastIndexOf(this.id)+this.id.length,e.length):this.id.call(this,e)),e=this.src.replace("%id%",e),!1):void 0});var g={};return f.srcAction&&(g[f.srcAction]=e),b._parseMarkup(d,g,c),b.updateStatus("ready"),d}}});var S=function(a){var c=b.items.length;return a>c-1?a-c:0>a?c+a:a},T=function(a,b,c){return a.replace(/%curr%/gi,b+1).replace(/%total%/gi,c)};a.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%"},proto:{initGallery:function(){var c=b.st.gallery,e=".mfp-gallery";return b.direction=!0,c&&c.enabled?(f+=" mfp-gallery",w(m+e,function(){c.navigateByImgClick&&b.wrap.on("click"+e,".mfp-img",function(){return b.items.length>1?(b.next(),!1):void 0}),d.on("keydown"+e,function(a){37===a.keyCode?b.prev():39===a.keyCode&&b.next()})}),w("UpdateStatus"+e,function(a,c){c.text&&(c.text=T(c.text,b.currItem.index,b.items.length))}),w(l+e,function(a,d,e,f){var g=b.items.length;e.counter=g>1?T(c.tCounter,f.index,g):""}),w("BuildControls"+e,function(){if(b.items.length>1&&c.arrows&&!b.arrowLeft){var d=c.arrowMarkup,e=b.arrowLeft=a(d.replace(/%title%/gi,c.tPrev).replace(/%dir%/gi,"left")).addClass(s),f=b.arrowRight=a(d.replace(/%title%/gi,c.tNext).replace(/%dir%/gi,"right")).addClass(s);e.click(function(){b.prev()}),f.click(function(){b.next()}),b.container.append(e.add(f))}}),w(n+e,function(){b._preloadTimeout&&clearTimeout(b._preloadTimeout),b._preloadTimeout=setTimeout(function(){b.preloadNearbyImages(),b._preloadTimeout=null},16)}),void w(h+e,function(){d.off(e),b.wrap.off("click"+e),b.arrowRight=b.arrowLeft=null})):!1},next:function(){b.direction=!0,b.index=S(b.index+1),b.updateItemHTML()},prev:function(){b.direction=!1,b.index=S(b.index-1),b.updateItemHTML()},goTo:function(a){b.direction=a>=b.index,b.index=a,b.updateItemHTML()},preloadNearbyImages:function(){var a,c=b.st.gallery.preload,d=Math.min(c[0],b.items.length),e=Math.min(c[1],b.items.length);for(a=1;a<=(b.direction?e:d);a++)b._preloadItem(b.index+a);for(a=1;a<=(b.direction?d:e);a++)b._preloadItem(b.index-a)},_preloadItem:function(c){if(c=S(c),!b.items[c].preloaded){var d=b.items[c];d.parsed||(d=b.parseEl(c)),y("LazyLoad",d),"image"===d.type&&(d.img=a('').on("load.mfploader",function(){d.hasSize=!0}).on("error.mfploader",function(){d.hasSize=!0,d.loadError=!0,y("LazyLoadError",d)}).attr("src",d.src)),d.preloaded=!0}}}});var U="retina";a.magnificPopup.registerModule(U,{options:{replaceSrc:function(a){return a.src.replace(/\.\w+$/,function(a){return"@2x"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var a=b.st.retina,c=a.ratio;c=isNaN(c)?c():c,c>1&&(w("ImageHasSize."+U,function(a,b){b.img.css({"max-width":b.img[0].naturalWidth/c,width:"100%"})}),w("ElementParse."+U,function(b,d){d.src=a.replaceSrc(d,c)}))}}}}),A()}); -------------------------------------------------------------------------------- /plugins/magnific-popup/magnific-popup.css: -------------------------------------------------------------------------------- 1 | /* Magnific Popup CSS */ 2 | .mfp-bg { 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | height: 100%; 7 | z-index: 1042; 8 | overflow: hidden; 9 | position: fixed; 10 | background: #0b0b0b; 11 | opacity: 0.8; } 12 | 13 | .mfp-wrap { 14 | top: 0; 15 | left: 0; 16 | width: 100%; 17 | height: 100%; 18 | z-index: 1043; 19 | position: fixed; 20 | outline: none !important; 21 | -webkit-backface-visibility: hidden; } 22 | 23 | .mfp-container { 24 | text-align: center; 25 | position: absolute; 26 | width: 100%; 27 | height: 100%; 28 | left: 0; 29 | top: 0; 30 | padding: 0 8px; 31 | box-sizing: border-box; } 32 | 33 | .mfp-container:before { 34 | content: ''; 35 | display: inline-block; 36 | height: 100%; 37 | vertical-align: middle; } 38 | 39 | .mfp-align-top .mfp-container:before { 40 | display: none; } 41 | 42 | .mfp-content { 43 | position: relative; 44 | display: inline-block; 45 | vertical-align: middle; 46 | margin: 0 auto; 47 | text-align: left; 48 | z-index: 1045; } 49 | 50 | .mfp-inline-holder .mfp-content, 51 | .mfp-ajax-holder .mfp-content { 52 | width: 100%; 53 | cursor: auto; } 54 | 55 | .mfp-ajax-cur { 56 | cursor: progress; } 57 | 58 | .mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { 59 | cursor: -moz-zoom-out; 60 | cursor: -webkit-zoom-out; 61 | cursor: zoom-out; } 62 | 63 | .mfp-zoom { 64 | cursor: pointer; 65 | cursor: -webkit-zoom-in; 66 | cursor: -moz-zoom-in; 67 | cursor: zoom-in; } 68 | 69 | .mfp-auto-cursor .mfp-content { 70 | cursor: auto; } 71 | 72 | .mfp-close, 73 | .mfp-arrow, 74 | .mfp-preloader, 75 | .mfp-counter { 76 | -webkit-user-select: none; 77 | -moz-user-select: none; 78 | user-select: none; } 79 | 80 | .mfp-loading.mfp-figure { 81 | display: none; } 82 | 83 | .mfp-hide { 84 | display: none !important; } 85 | 86 | .mfp-preloader { 87 | color: #CCC; 88 | position: absolute; 89 | top: 50%; 90 | width: auto; 91 | text-align: center; 92 | margin-top: -0.8em; 93 | left: 8px; 94 | right: 8px; 95 | z-index: 1044; } 96 | .mfp-preloader a { 97 | color: #CCC; } 98 | .mfp-preloader a:hover { 99 | color: #FFF; } 100 | 101 | .mfp-s-ready .mfp-preloader { 102 | display: none; } 103 | 104 | .mfp-s-error .mfp-content { 105 | display: none; } 106 | 107 | button.mfp-close, 108 | button.mfp-arrow { 109 | overflow: visible; 110 | cursor: pointer; 111 | background: transparent; 112 | border: 0; 113 | -webkit-appearance: none; 114 | display: block; 115 | outline: none; 116 | padding: 0; 117 | z-index: 1046; 118 | box-shadow: none; 119 | touch-action: manipulation; } 120 | 121 | button::-moz-focus-inner { 122 | padding: 0; 123 | border: 0; } 124 | 125 | .mfp-close { 126 | width: 44px; 127 | height: 44px; 128 | line-height: 44px; 129 | position: absolute; 130 | right: 0; 131 | top: 0; 132 | text-decoration: none; 133 | text-align: center; 134 | opacity: 0.65; 135 | padding: 0 0 18px 10px; 136 | color: #FFF; 137 | font-style: normal; 138 | font-size: 28px; 139 | font-family: Arial, Baskerville, monospace; } 140 | .mfp-close:hover, 141 | .mfp-close:focus { 142 | opacity: 1; } 143 | .mfp-close:active { 144 | top: 1px; } 145 | 146 | .mfp-close-btn-in .mfp-close { 147 | color: #333; } 148 | 149 | .mfp-image-holder .mfp-close, 150 | .mfp-iframe-holder .mfp-close { 151 | color: #FFF; 152 | right: -6px; 153 | text-align: right; 154 | padding-right: 6px; 155 | width: 100%; } 156 | 157 | .mfp-counter { 158 | position: absolute; 159 | top: 0; 160 | right: 0; 161 | color: #CCC; 162 | font-size: 12px; 163 | line-height: 18px; 164 | white-space: nowrap; } 165 | 166 | .mfp-arrow { 167 | position: absolute; 168 | opacity: 0.65; 169 | margin: 0; 170 | top: 50%; 171 | margin-top: -55px; 172 | padding: 0; 173 | width: 90px; 174 | height: 110px; 175 | -webkit-tap-highlight-color: transparent; } 176 | .mfp-arrow:active { 177 | margin-top: -54px; } 178 | .mfp-arrow:hover, 179 | .mfp-arrow:focus { 180 | opacity: 1; } 181 | .mfp-arrow:before, 182 | .mfp-arrow:after { 183 | content: ''; 184 | display: block; 185 | width: 0; 186 | height: 0; 187 | position: absolute; 188 | left: 0; 189 | top: 0; 190 | margin-top: 35px; 191 | margin-left: 35px; 192 | border: medium inset transparent; } 193 | .mfp-arrow:after { 194 | border-top-width: 13px; 195 | border-bottom-width: 13px; 196 | top: 8px; } 197 | .mfp-arrow:before { 198 | border-top-width: 21px; 199 | border-bottom-width: 21px; 200 | opacity: 0.7; } 201 | 202 | .mfp-arrow-left { 203 | left: 0; } 204 | .mfp-arrow-left:after { 205 | border-right: 17px solid #FFF; 206 | margin-left: 31px; } 207 | .mfp-arrow-left:before { 208 | margin-left: 25px; 209 | border-right: 27px solid #3F3F3F; } 210 | 211 | .mfp-arrow-right { 212 | right: 0; } 213 | .mfp-arrow-right:after { 214 | border-left: 17px solid #FFF; 215 | margin-left: 39px; } 216 | .mfp-arrow-right:before { 217 | border-left: 27px solid #3F3F3F; } 218 | 219 | .mfp-iframe-holder { 220 | padding-top: 40px; 221 | padding-bottom: 40px; } 222 | .mfp-iframe-holder .mfp-content { 223 | line-height: 0; 224 | width: 100%; 225 | max-width: 900px; } 226 | .mfp-iframe-holder .mfp-close { 227 | top: -40px; } 228 | 229 | .mfp-iframe-scaler { 230 | width: 100%; 231 | height: 0; 232 | overflow: hidden; 233 | padding-top: 56.25%; } 234 | .mfp-iframe-scaler iframe { 235 | position: absolute; 236 | display: block; 237 | top: 0; 238 | left: 0; 239 | width: 100%; 240 | height: 100%; 241 | box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); 242 | background: #000; } 243 | 244 | /* Main image in popup */ 245 | img.mfp-img { 246 | width: auto; 247 | max-width: 100%; 248 | height: auto; 249 | display: block; 250 | line-height: 0; 251 | box-sizing: border-box; 252 | padding: 40px 0 40px; 253 | margin: 0 auto; } 254 | 255 | /* The shadow behind the image */ 256 | .mfp-figure { 257 | line-height: 0; } 258 | .mfp-figure:after { 259 | content: ''; 260 | position: absolute; 261 | left: 0; 262 | top: 40px; 263 | bottom: 40px; 264 | display: block; 265 | right: 0; 266 | width: auto; 267 | height: auto; 268 | z-index: -1; 269 | box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); 270 | background: #444; } 271 | .mfp-figure small { 272 | color: #BDBDBD; 273 | display: block; 274 | font-size: 12px; 275 | line-height: 14px; } 276 | .mfp-figure figure { 277 | margin: 0; } 278 | 279 | .mfp-bottom-bar { 280 | margin-top: -36px; 281 | position: absolute; 282 | top: 100%; 283 | left: 0; 284 | width: 100%; 285 | cursor: auto; } 286 | 287 | .mfp-title { 288 | text-align: left; 289 | line-height: 18px; 290 | color: #F3F3F3; 291 | word-wrap: break-word; 292 | padding-right: 36px; } 293 | 294 | .mfp-image-holder .mfp-content { 295 | max-width: 100%; } 296 | 297 | .mfp-gallery .mfp-image-holder .mfp-figure { 298 | cursor: pointer; } 299 | 300 | @media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { 301 | /** 302 | * Remove all paddings around the image on small screen 303 | */ 304 | .mfp-img-mobile .mfp-image-holder { 305 | padding-left: 0; 306 | padding-right: 0; } 307 | .mfp-img-mobile img.mfp-img { 308 | padding: 0; } 309 | .mfp-img-mobile .mfp-figure:after { 310 | top: 0; 311 | bottom: 0; } 312 | .mfp-img-mobile .mfp-figure small { 313 | display: inline; 314 | margin-left: 5px; } 315 | .mfp-img-mobile .mfp-bottom-bar { 316 | background: rgba(0, 0, 0, 0.6); 317 | bottom: 0; 318 | margin: 0; 319 | top: auto; 320 | padding: 3px 5px; 321 | position: fixed; 322 | box-sizing: border-box; } 323 | .mfp-img-mobile .mfp-bottom-bar:empty { 324 | padding: 0; } 325 | .mfp-img-mobile .mfp-counter { 326 | right: 5px; 327 | top: 3px; } 328 | .mfp-img-mobile .mfp-close { 329 | top: 0; 330 | right: 0; 331 | width: 35px; 332 | height: 35px; 333 | line-height: 35px; 334 | background: rgba(0, 0, 0, 0.6); 335 | position: fixed; 336 | text-align: center; 337 | padding: 0; } } 338 | 339 | @media all and (max-width: 900px) { 340 | .mfp-arrow { 341 | -webkit-transform: scale(0.75); 342 | transform: scale(0.75); } 343 | .mfp-arrow-left { 344 | -webkit-transform-origin: 0; 345 | transform-origin: 0; } 346 | .mfp-arrow-right { 347 | -webkit-transform-origin: 100%; 348 | transform-origin: 100%; } 349 | .mfp-container { 350 | padding-left: 6px; 351 | padding-right: 6px; } } 352 | -------------------------------------------------------------------------------- /plugins/vue-append.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueAppend from 'vue-append' 3 | Vue.use(VueAppend) 4 | -------------------------------------------------------------------------------- /plugins/vue-markdown.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import mavonEditor from 'mavon-editor' 3 | Vue.use(mavonEditor) 4 | -------------------------------------------------------------------------------- /static/css/custom.css: -------------------------------------------------------------------------------- 1 | /*================================================================================== 2 | Custom Stylesheet (Any custom styling you want to apply should be defined here). 3 | ====================================================================================*/ 4 | 5 | /* 霓虹灯标题 */ 6 | 7 | .navbar-brand { 8 | height: 54px; 9 | line-height: 24px; 10 | font-size: 28px; 11 | opacity: 1; 12 | background-color: rgba(0, 0, 0, 0); 13 | text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #228DFF, 0 0 35px #228DFF, 0 0 40px #228DFF, 0 0 50px #228DFF, 0 0 75px #228DFF; 14 | } 15 | 16 | /* 动态背景图 */ 17 | 18 | @-webkit-keyframes imageAnimation { 19 | 0% { 20 | opacity: 0; 21 | -webkit-animation-timing-function: ease-in 22 | } 23 | 8% { 24 | opacity: 1; 25 | -webkit-transform: scale(1.05); 26 | -webkit-animation-timing-function: ease-out 27 | } 28 | 17% { 29 | opacity: 1; 30 | -webkit-transform: scale(1.1) rotate(0deg) 31 | } 32 | 25% { 33 | opacity: 0; 34 | -webkit-transform: scale(1.1) rotate(0deg) 35 | } 36 | 100% { 37 | opacity: 0 38 | } 39 | } 40 | 41 | @-moz-keyframes imageAnimation { 42 | 0% { 43 | opacity: 0; 44 | -moz-animation-timing-function: ease-in 45 | } 46 | 8% { 47 | opacity: 1; 48 | -moz-transform: scale(1.05); 49 | -moz-animation-timing-function: ease-out 50 | } 51 | 17% { 52 | opacity: 1; 53 | -moz-transform: scale(1.1) rotate(0deg) 54 | } 55 | 25% { 56 | opacity: 0; 57 | -moz-transform: scale(1.1) rotate(0deg) 58 | } 59 | 100% { 60 | opacity: 0 61 | } 62 | } 63 | 64 | @-o-keyframes imageAnimation { 65 | 0% { 66 | opacity: 0; 67 | -o-animation-timing-function: ease-in 68 | } 69 | 8% { 70 | opacity: 1; 71 | -o-transform: scale(1.05); 72 | -o-animation-timing-function: ease-out 73 | } 74 | 17% { 75 | opacity: 1; 76 | -o-transform: scale(1.1) rotate(0deg) 77 | } 78 | 25% { 79 | opacity: 0; 80 | -o-transform: scale(1.1) rotate(0deg) 81 | } 82 | 100% { 83 | opacity: 0 84 | } 85 | } 86 | 87 | @-ms-keyframes imageAnimation { 88 | 0% { 89 | opacity: 0; 90 | -ms-animation-timing-function: ease-in 91 | } 92 | 8% { 93 | opacity: 1; 94 | -ms-transform: scale(1.05); 95 | -ms-animation-timing-function: ease-out 96 | } 97 | 17% { 98 | opacity: 1; 99 | -ms-transform: scale(1.1) rotate(0deg) 100 | } 101 | 25% { 102 | opacity: 0; 103 | -ms-transform: scale(1.1) rotate(0deg) 104 | } 105 | 100% { 106 | opacity: 0 107 | } 108 | } 109 | 110 | @keyframes imageAnimation { 111 | 0% { 112 | opacity: 0; 113 | animation-timing-function: ease-in 114 | } 115 | 8% { 116 | opacity: 1; 117 | transform: scale(1.05); 118 | animation-timing-function: ease-out 119 | } 120 | 17% { 121 | opacity: 1; 122 | transform: scale(1.1) rotate(0deg) 123 | } 124 | 25% { 125 | opacity: 0; 126 | transform: scale(1.1) rotate(0deg) 127 | } 128 | 100% { 129 | opacity: 0 130 | } 131 | } 132 | 133 | .cb-slideshow, .cb-slideshow:after { 134 | position: fixed; 135 | width: 100%; 136 | height: 100%; 137 | top: 0; 138 | left: 0; 139 | z-index: -2 140 | } 141 | 142 | .cb-slideshow:after { 143 | content: '' 144 | } 145 | 146 | .cb-slideshow li span { 147 | width: 100%; 148 | height: 100%; 149 | position: absolute; 150 | top: 0; 151 | left: 0; 152 | color: transparent; 153 | background-size: cover; 154 | background-position: 50% 50%; 155 | opacity: 0; 156 | z-index: -2; 157 | } 158 | 159 | /* 动态背景图结束 */ 160 | 161 | /*圆润*/ 162 | 163 | .panel { 164 | border-radius: 4px; 165 | background-color: #ffffff; 166 | box-shadow: 0 0 5px #ffffff; 167 | -webkit-box-shadow: 0 0 5px #ffffff; 168 | -moz-box-shadow: 0 0 5px #ffffff; 169 | -o-box-shadow: 0 0 5px #ffffff; 170 | border: none; 171 | } 172 | 173 | .empty-padding { 174 | background-clip: content-box; 175 | padding-bottom: 15px; 176 | padding-top: 15px; 177 | } 178 | 179 | .panel:hover { 180 | box-shadow: 0 0 50px black; 181 | -webkit-box-shadow: 0 0 50px black; 182 | -moz-box-shadow: 0 0 50px black; 183 | -o-box-shadow: 0 0 50px black 184 | } 185 | 186 | /*圆润结束*/ 187 | 188 | /* 半透明 */ 189 | .transparent-part { 190 | background-color: rgba(255, 255, 255, 0.41) !important; 191 | } 192 | .transparent-part:hover { 193 | background-color: rgba(255, 255, 255, 0.6) !important; 194 | } 195 | /* 半透明结束 */ 196 | 197 | /* 文章作者赘述 */ 198 | 199 | .author-box { 200 | width: 100%; 201 | } 202 | 203 | .author-box ul { 204 | display: flex; 205 | flex-direction: row; 206 | justify-content: center; 207 | } 208 | 209 | /* 文章作者赘述结束 */ 210 | 211 | 212 | /*文章版权声明*/ 213 | .declare { 214 | background-color: #eaeaea; 215 | margin-top: 2em; 216 | border-left: 3px solid rgb(0, 191, 255);; 217 | padding: 0.5em 1em; 218 | border-radius: 10px; 219 | } 220 | 221 | .declare a { 222 | display: inline-block; 223 | position: relative; 224 | color: #0087ca; 225 | font-family: lucida console, serif; 226 | } 227 | 228 | /*文章版权声明结束*/ 229 | 230 | /*上下文章导航*/ 231 | .previous-next-links { 232 | line-height: 24px; 233 | overflow: hidden; 234 | padding: 10px 20px; 235 | font-size: 15px; 236 | background-color: rgba(217, 237, 247, 0.8); 237 | box-sizing: border-box; 238 | border-radius: 5px; 239 | } 240 | 241 | .previous-next-links a { 242 | color: #3f51b5; 243 | } 244 | 245 | .previous-design-link { 246 | float: left; 247 | } 248 | 249 | .next-design-link { 250 | float: right; 251 | } 252 | 253 | /*上下文章导航结束*/ 254 | -------------------------------------------------------------------------------- /static/css/list-item.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | outline: none; 6 | -webkit-tap-highlight-color: transparent; 7 | } 8 | 9 | .meta .items div { 10 | display: block; 11 | } 12 | 13 | .header h1 { 14 | font-size: 50px; 15 | } 16 | 17 | @media screen and (min-width: 1200px) { 18 | .list-item .thumbnail { 19 | width: 185px; 20 | height: 125px; 21 | } 22 | } 23 | 24 | .content-list li { 25 | list-style: none; 26 | } 27 | 28 | .meta .items .a { 29 | text-decoration: none; 30 | } 31 | 32 | .content-list ul ul { 33 | list-style-type: circle; 34 | margin-block-start: 0; 35 | margin-block-end: 0; 36 | } 37 | 38 | .content-list ul { 39 | display: block; 40 | list-style-type: disc; 41 | margin-block-start: 1em; 42 | margin-block-end: 1em; 43 | margin-inline-start: 0; 44 | margin-inline-end: 0; 45 | padding-inline-start: 1px; 46 | } 47 | 48 | .list-item { 49 | display: flex; 50 | position: relative; 51 | width: 100%; 52 | border-bottom: 1px solid #4bb6ff14; 53 | padding: 17px 17px 17px 17px; 54 | border-radius: 8px; 55 | box-shadow: 0 0 20px -5px rgb(248 255 186); 56 | margin-top: 15px; 57 | background-color: #fff; 58 | } 59 | 60 | .list-item .thumbnail { 61 | flex-shrink: 0; 62 | position: relative; 63 | margin-right: 15px; 64 | overflow: hidden; 65 | } 66 | 67 | .list-item .thumbnail img { 68 | width: 210px; 69 | height: 140px; 70 | -o-object-fit: cover; 71 | object-fit: cover; 72 | border-radius: 4px; 73 | transition: opacity 0.35s; 74 | } 75 | 76 | .list-item .thumbnail .flash-bar { 77 | position: absolute; 78 | left:-100px; 79 | width: 20px; 80 | height: 100%; 81 | background: #fff; 82 | opacity: 0.5; 83 | transform: skewX(-30deg); 84 | transform-origin: 0 100%; 85 | } 86 | 87 | .list-item:hover .flash-bar { 88 | left: 100%; 89 | transition: left ease-in-out 1s; 90 | } 91 | 92 | .list-item .thumbnail svg { 93 | position: absolute; 94 | z-index: 1; 95 | top: 5px; 96 | left: 5px; 97 | width: 20px; 98 | height: 20px; 99 | fill: #fff; 100 | } 101 | 102 | .list-item .information .title .badge { 103 | height: 20px; 104 | line-height: 20px; 105 | font-size: 12px; 106 | margin-right: 5px; 107 | border-radius: 2px; 108 | padding: 0 8px; 109 | white-space: nowrap; 110 | vertical-align: 2px; 111 | } 112 | 113 | .information { 114 | display: flex; 115 | flex-direction: column; 116 | flex: 1; 117 | min-width: 0; 118 | } 119 | 120 | .information .abstract { 121 | margin-bottom: 10px; 122 | display: -webkit-box; 123 | -webkit-line-clamp: 2; 124 | -webkit-box-orient: vertical; 125 | overflow: hidden; 126 | text-overflow: ellipsis; 127 | word-break: break-word; 128 | color: #000; 129 | line-height: 24px; 130 | max-height: 48px; 131 | transition: color 0.35s; 132 | text-decoration: none; 133 | font-size: 14px; 134 | } 135 | 136 | .list-item .information .title { 137 | margin-bottom: 10px; 138 | display: -webkit-box; 139 | -webkit-line-clamp: 2; 140 | -webkit-box-orient: vertical; 141 | overflow: hidden; 142 | text-overflow: ellipsis; 143 | word-break: break-word; 144 | color: #000; 145 | font-size: 18px; 146 | line-height: 24px; 147 | max-height: 48px; 148 | transition: color 0.35s; 149 | } 150 | 151 | .list-item .thumbnail time { 152 | position: absolute; 153 | z-index: 1; 154 | top: 5px; 155 | right: 5px; 156 | background: #3faeff; 157 | height: 20px; 158 | line-height: 20px; 159 | padding: 0 8px; 160 | color: #fff; 161 | font-size: 12px; 162 | border-radius: 10px; 163 | transition: -webkit-transform 0.35s; 164 | transition: transform 0.35s, -webkit-transform 0.35s; 165 | -webkit-transform: translate3d(120%, 0, 0); 166 | transform: translate3d(120%, 0, 0); 167 | } 168 | 169 | .meta { 170 | display: flex; 171 | align-items: center; 172 | margin-top: auto; 173 | color: #000; 174 | font-size: 13px; 175 | } 176 | 177 | .meta .items { 178 | display: flex; 179 | align-items: center; 180 | } 181 | 182 | .meta .items li::after { 183 | content: '/'; 184 | color: #000; 185 | padding: 0 5px; 186 | } 187 | 188 | .meta .items li:last-child::after { 189 | content: "" 190 | } 191 | 192 | .meta .last { 193 | margin-left: auto; 194 | display: flex; 195 | align-items: center; 196 | } 197 | 198 | .meta .last .icon { 199 | margin-right: 3px; 200 | } 201 | 202 | .meta .last .link { 203 | color: #000; 204 | } 205 | 206 | @media screen and (max-width: 768px) { 207 | .meta .items { 208 | width: 100%; 209 | } 210 | .meta .items li { 211 | display: none; 212 | } 213 | .meta .items li:nth-child(1) { 214 | display: block; 215 | } 216 | .meta .items li:nth-child(1)::after { 217 | content: "" 218 | } 219 | .abstract { 220 | display: none; 221 | } 222 | .list-item .thumbnail svg { 223 | display: none; 224 | } 225 | .list-item .information .abstract { 226 | display: none; 227 | } 228 | .list-item .meta .items li:nth-child(2) { 229 | display: block; 230 | margin-left: auto; 231 | } 232 | .list-item .meta .items li:nth-child(2)::after { 233 | content: "" 234 | } 235 | .list-item .meta .last { 236 | display: none !important; 237 | } 238 | .list-item .thumbnail img { 239 | width: 120px; 240 | height: 80px; 241 | -o-object-fit: cover; 242 | object-fit: cover; 243 | border-radius: 4px; 244 | transition: opacity 0.35s; 245 | } 246 | } 247 | 248 | img { 249 | border: 0; 250 | vertical-align: middle; 251 | } 252 | -------------------------------------------------------------------------------- /static/css/main.css: -------------------------------------------------------------------------------- 1 | /*//////////////////////////////////////////////////////////////////[ RESTYLE TAG ]*/ 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body, html { 10 | height: 100%; 11 | font-family: Poppins-Regular, sans-serif; 12 | } 13 | 14 | /*---------------------------------------------*/ 15 | 16 | a { 17 | font-family: Poppins-Regular; 18 | font-size: 14px; 19 | line-height: 1.7; 20 | color: #666666; 21 | margin: 0; 22 | transition: all 0.4s; 23 | -webkit-transition: all 0.4s; 24 | -o-transition: all 0.4s; 25 | -moz-transition: all 0.4s; 26 | } 27 | 28 | a:focus { 29 | outline: none !important; 30 | } 31 | 32 | a:hover { 33 | text-decoration: none; 34 | color: #57b846; 35 | } 36 | 37 | /*---------------------------------------------*/ 38 | 39 | h1, h2, h3, h4, h5, h6 { 40 | margin: 0; 41 | } 42 | 43 | p { 44 | font-family: Poppins-Regular; 45 | font-size: 14px; 46 | line-height: 1.7; 47 | color: #666666; 48 | margin: 0; 49 | } 50 | 51 | ul, li { 52 | margin: 0; 53 | list-style-type: none; 54 | } 55 | 56 | /*---------------------------------------------*/ 57 | 58 | input { 59 | outline: none; 60 | border: none; 61 | } 62 | 63 | textarea { 64 | outline: none; 65 | border: none; 66 | } 67 | 68 | textarea:focus, input:focus { 69 | border-color: transparent !important; 70 | } 71 | 72 | input:focus::-webkit-input-placeholder { 73 | color: transparent; 74 | } 75 | 76 | input:focus:-moz-placeholder { 77 | color: transparent; 78 | } 79 | 80 | input:focus::-moz-placeholder { 81 | color: transparent; 82 | } 83 | 84 | input:focus:-ms-input-placeholder { 85 | color: transparent; 86 | } 87 | 88 | textarea:focus::-webkit-input-placeholder { 89 | color: transparent; 90 | } 91 | 92 | textarea:focus:-moz-placeholder { 93 | color: transparent; 94 | } 95 | 96 | textarea:focus::-moz-placeholder { 97 | color: transparent; 98 | } 99 | 100 | textarea:focus:-ms-input-placeholder { 101 | color: transparent; 102 | } 103 | 104 | input::-webkit-input-placeholder { 105 | color: #999999; 106 | } 107 | 108 | input:-moz-placeholder { 109 | color: #999999; 110 | } 111 | 112 | input::-moz-placeholder { 113 | color: #999999; 114 | } 115 | 116 | input:-ms-input-placeholder { 117 | color: #999999; 118 | } 119 | 120 | textarea::-webkit-input-placeholder { 121 | color: #999999; 122 | } 123 | 124 | textarea:-moz-placeholder { 125 | color: #999999; 126 | } 127 | 128 | textarea::-moz-placeholder { 129 | color: #999999; 130 | } 131 | 132 | textarea:-ms-input-placeholder { 133 | color: #999999; 134 | } 135 | 136 | /*---------------------------------------------*/ 137 | 138 | button { 139 | outline: none !important; 140 | border: none; 141 | background: transparent; 142 | } 143 | 144 | button:hover { 145 | cursor: pointer; 146 | } 147 | 148 | iframe { 149 | border: none !important; 150 | } 151 | 152 | /*//////////////////////////////////////////////////////////////////[ Utility ]*/ 153 | 154 | .txt1 { 155 | font-family: Poppins-Regular; 156 | font-size: 13px; 157 | line-height: 1.5; 158 | color: #999999; 159 | } 160 | 161 | .txt2 { 162 | font-family: Poppins-Regular; 163 | font-size: 13px; 164 | line-height: 1.5; 165 | color: #666666; 166 | } 167 | 168 | /*//////////////////////////////////////////////////////////////////[ login ]*/ 169 | 170 | .limiter { 171 | width: 100%; 172 | margin: 0 auto; 173 | } 174 | 175 | .container-login100 { 176 | width: 100%; 177 | min-height: 100vh; 178 | display: -webkit-box; 179 | display: -webkit-flex; 180 | display: -moz-box; 181 | display: -ms-flexbox; 182 | display: flex; 183 | flex-wrap: wrap; 184 | justify-content: center; 185 | align-items: center; 186 | padding: 15px; 187 | background: #9053c7; 188 | background: -webkit-linear-gradient(-135deg, #c850c0, #4158d0); 189 | background: -o-linear-gradient(-135deg, #c850c0, #4158d0); 190 | background: -moz-linear-gradient(-135deg, #c850c0, #4158d0); 191 | background: linear-gradient(-135deg, #c850c0, #4158d0); 192 | } 193 | 194 | .wrap-login100 { 195 | width: 960px; 196 | background: #fff; 197 | border-radius: 10px; 198 | overflow: hidden; 199 | display: -webkit-box; 200 | display: -webkit-flex; 201 | display: -moz-box; 202 | display: -ms-flexbox; 203 | display: flex; 204 | flex-wrap: wrap; 205 | justify-content: space-between; 206 | padding: 147px 130px 33px 95px; 207 | } 208 | 209 | /*------------------------------------------------------------------[ ]*/ 210 | 211 | .login100-pic { 212 | width: 316px; 213 | } 214 | 215 | .login100-pic img { 216 | max-width: 100%; 217 | } 218 | 219 | /*------------------------------------------------------------------[ ]*/ 220 | 221 | .login100-form { 222 | width: 290px; 223 | } 224 | 225 | .login100-form-title { 226 | font-family: Poppins-Bold; 227 | font-size: 24px; 228 | color: #333333; 229 | line-height: 1.2; 230 | text-align: center; 231 | width: 100%; 232 | display: block; 233 | padding-bottom: 54px; 234 | } 235 | 236 | /*---------------------------------------------*/ 237 | 238 | .wrap-input100 { 239 | position: relative; 240 | width: 100%; 241 | z-index: 1; 242 | margin-bottom: 10px; 243 | } 244 | 245 | .input100 { 246 | font-family: Poppins-Medium; 247 | font-size: 15px; 248 | line-height: 1.5; 249 | color: #666666; 250 | display: block; 251 | width: 100%; 252 | background: #e6e6e6; 253 | height: 50px; 254 | border-radius: 25px; 255 | padding: 0 30px 0 68px; 256 | } 257 | 258 | /*------------------------------------------------------------------[ Focus ]*/ 259 | 260 | .focus-input100 { 261 | display: block; 262 | position: absolute; 263 | border-radius: 25px; 264 | bottom: 0; 265 | left: 0; 266 | z-index: -1; 267 | width: 100%; 268 | height: 100%; 269 | box-shadow: 0 0 0 0; 270 | color: rgba(87, 184, 70, 0.8); 271 | } 272 | 273 | .input100:focus + .focus-input100 { 274 | -webkit-animation: anim-shadow 0.5s ease-in-out forwards; 275 | animation: anim-shadow 0.5s ease-in-out forwards; 276 | } 277 | 278 | @-webkit-keyframes anim-shadow { 279 | to { 280 | box-shadow: 0 0 70px 25px; 281 | opacity: 0; 282 | } 283 | } 284 | 285 | @keyframes anim-shadow { 286 | to { 287 | box-shadow: 0 0 70px 25px; 288 | opacity: 0; 289 | } 290 | } 291 | 292 | .symbol-input100 { 293 | font-size: 15px; 294 | display: -webkit-box; 295 | display: -webkit-flex; 296 | display: -moz-box; 297 | display: -ms-flexbox; 298 | display: flex; 299 | align-items: center; 300 | position: absolute; 301 | border-radius: 25px; 302 | bottom: 0; 303 | left: 0; 304 | width: 100%; 305 | height: 100%; 306 | padding-left: 35px; 307 | pointer-events: none; 308 | color: #666666; 309 | -webkit-transition: all 0.4s; 310 | -o-transition: all 0.4s; 311 | -moz-transition: all 0.4s; 312 | transition: all 0.4s; 313 | } 314 | 315 | .input100:focus + .focus-input100 + .symbol-input100 { 316 | color: #57b846; 317 | padding-left: 28px; 318 | } 319 | 320 | /*------------------------------------------------------------------[ Button ]*/ 321 | 322 | .container-login100-form-btn { 323 | width: 100%; 324 | display: -webkit-box; 325 | display: -webkit-flex; 326 | display: -moz-box; 327 | display: -ms-flexbox; 328 | display: flex; 329 | flex-wrap: wrap; 330 | justify-content: center; 331 | padding-top: 20px; 332 | } 333 | 334 | .login100-form-btn { 335 | font-family: Montserrat-Bold, serif; 336 | font-size: 15px; 337 | line-height: 1.5; 338 | color: #fff; 339 | text-transform: uppercase; 340 | width: 100%; 341 | height: 50px; 342 | border-radius: 25px; 343 | background: #57b846; 344 | display: -webkit-box; 345 | display: -webkit-flex; 346 | display: -moz-box; 347 | display: -ms-flexbox; 348 | display: flex; 349 | justify-content: center; 350 | align-items: center; 351 | padding: 0 25px; 352 | -webkit-transition: all 0.4s; 353 | -o-transition: all 0.4s; 354 | -moz-transition: all 0.4s; 355 | transition: all 0.4s; 356 | } 357 | 358 | .login100-form-btn:hover { 359 | background: #333333; 360 | } 361 | 362 | /*------------------------------------------------------------------[ Responsive ]*/ 363 | 364 | @media (max-width: 992px) { 365 | .wrap-login100 { 366 | padding: 177px 90px 33px 85px; 367 | } 368 | 369 | .login100-pic { 370 | width: 35%; 371 | } 372 | 373 | .login100-form { 374 | width: 50%; 375 | } 376 | } 377 | 378 | @media (max-width: 768px) { 379 | .wrap-login100 { 380 | padding: 100px 80px 33px 80px; 381 | } 382 | 383 | .login100-pic { 384 | display: none; 385 | } 386 | 387 | .login100-form { 388 | width: 100%; 389 | } 390 | } 391 | 392 | @media (max-width: 576px) { 393 | .wrap-login100 { 394 | padding: 100px 15px 33px 15px; 395 | } 396 | } 397 | 398 | /*------------------------------------------------------------------[ Alert validate ]*/ 399 | 400 | .validate-input { 401 | position: relative; 402 | } 403 | -------------------------------------------------------------------------------- /static/css/slider/menu_sideslide.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | .menu-wrap a { 4 | color: #b8b7ad; 5 | } 6 | 7 | .menu-wrap a:hover, 8 | .menu-wrap a:focus { 9 | color: #c94e50; 10 | } 11 | 12 | .content { 13 | position: relative; 14 | background: #b4bad2; 15 | } 16 | 17 | .content::before { 18 | position: absolute; 19 | top: 0; 20 | left: 0; 21 | z-index: 10; 22 | width: 100%; 23 | height: 100%; 24 | background: rgba(0, 0, 0, 0.3); 25 | content: ''; 26 | opacity: 0; 27 | -webkit-transform: translate3d(100%, 0, 0); 28 | transform: translate3d(100%, 0, 0); 29 | -webkit-transition: opacity 0.4s, -webkit-transform 0s 0.4s; 30 | transition: opacity 0.4s, transform 0s 0.4s; 31 | -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 32 | transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 33 | } 34 | 35 | /* Menu Button */ 36 | .menu-button { 37 | position: fixed; 38 | margin: 1em; 39 | padding: 0; 40 | border: none; 41 | text-indent: 2.5em; 42 | font-size: 1.5em; 43 | color: transparent; 44 | width: 50px; 45 | height: 50px; 46 | line-height: 50px; 47 | cursor: pointer; 48 | background-color: #000; 49 | border-radius: 5px; 50 | text-align: center; 51 | -webkit-tap-highlight-color: transparent; 52 | z-index: 1000; 53 | top: 20px; 54 | left: 20px; 55 | } 56 | 57 | .menu-button::before { 58 | 59 | position: absolute; 60 | top: 0.5em; 61 | right: 0.5em; 62 | bottom: 0.5em; 63 | left: 0.5em; 64 | background: linear-gradient(#ffffff 20%, transparent 20%, transparent 40%, #ffffff 40%, #ffffff 60%, transparent 60%, transparent 80%, #ffffff 80%); 65 | content: ''; 66 | } 67 | 68 | .menu-button:hover { 69 | opacity: 0.6; 70 | } 71 | 72 | /* Close Button */ 73 | .close-button { 74 | width: 1em; 75 | height: 1em; 76 | position: absolute; 77 | right: 1em; 78 | top: 1em; 79 | overflow: hidden; 80 | text-indent: 1em; 81 | font-size: 0.75em; 82 | border: none; 83 | background: transparent; 84 | color: transparent; 85 | } 86 | 87 | .close-button::before, 88 | .close-button::after { 89 | content: ''; 90 | position: absolute; 91 | width: 3px; 92 | height: 100%; 93 | top: 0; 94 | left: 50%; 95 | background: #bdc3c7; 96 | } 97 | 98 | .close-button::before { 99 | -webkit-transform: rotate(45deg); 100 | transform: rotate(45deg); 101 | } 102 | 103 | .close-button::after { 104 | -webkit-transform: rotate(-45deg); 105 | transform: rotate(-45deg); 106 | } 107 | 108 | /* Menu */ 109 | .menu-wrap { 110 | position: fixed; 111 | z-index: 1001; 112 | width: 300px; 113 | height: 100%; 114 | background: #fff; 115 | padding: 2.5em 1.5em 0; 116 | font-size: 1.15em; 117 | -webkit-transform: translate3d(-320px, 0, 0); 118 | transform: translate3d(-320px, 0, 0); 119 | -webkit-transition: -webkit-transform 0.4s; 120 | transition: transform 0.4s; 121 | -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 122 | transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 123 | } 124 | 125 | .menu, 126 | .icon-list { 127 | height: 100%; 128 | } 129 | 130 | .icon-list { 131 | -webkit-transform: translate3d(0, 100%, 0); 132 | transform: translate3d(0, 100%, 0); 133 | } 134 | 135 | .icon-list a { 136 | display: block; 137 | padding: 0.8em; 138 | -webkit-transform: translate3d(0, 500px, 0); 139 | transform: translate3d(0, 500px, 0); 140 | text-align: center; 141 | } 142 | 143 | .icon-list a:hover { 144 | padding: 1em; 145 | font-size: 1.5em; 146 | width: 110%; 147 | } 148 | 149 | .icon-list, 150 | .icon-list a { 151 | -webkit-transition: -webkit-transform 0s 0.4s; 152 | transition: transform 0s 0.4s; 153 | -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 154 | transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 155 | font-size: 15px; 156 | } 157 | 158 | .icon-list a:nth-child(2) { 159 | -webkit-transform: translate3d(0, 1000px, 0); 160 | transform: translate3d(0, 1000px, 0); 161 | } 162 | 163 | .icon-list a:nth-child(3) { 164 | -webkit-transform: translate3d(0, 1500px, 0); 165 | transform: translate3d(0, 1500px, 0); 166 | } 167 | 168 | .icon-list a:nth-child(4) { 169 | -webkit-transform: translate3d(0, 2000px, 0); 170 | transform: translate3d(0, 2000px, 0); 171 | } 172 | 173 | .icon-list a:nth-child(5) { 174 | -webkit-transform: translate3d(0, 2500px, 0); 175 | transform: translate3d(0, 2500px, 0); 176 | } 177 | 178 | .icon-list a:nth-child(6) { 179 | -webkit-transform: translate3d(0, 3000px, 0); 180 | transform: translate3d(0, 3000px, 0); 181 | } 182 | 183 | .icon-list a span { 184 | margin-left: 10px; 185 | font-weight: 700; 186 | } 187 | 188 | /* Shown menu */ 189 | .show-menu .menu-wrap { 190 | -webkit-transform: translate3d(0, 0, 0); 191 | transform: translate3d(0, 0, 0); 192 | -webkit-transition: -webkit-transform 0.8s; 193 | transition: transform 0.8s; 194 | -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 195 | transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 196 | } 197 | 198 | .show-menu .icon-list, 199 | .show-menu .icon-list a { 200 | -webkit-transform: translate3d(0, 0, 0); 201 | transform: translate3d(0, 0, 0); 202 | -webkit-transition: -webkit-transform 0.8s; 203 | transition: transform 0.8s; 204 | -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 205 | transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 206 | } 207 | 208 | .show-menu .icon-list a { 209 | -webkit-transition-duration: 0.9s; 210 | transition-duration: 0.9s; 211 | } 212 | 213 | .show-menu .content::before { 214 | opacity: 1; 215 | -webkit-transition: opacity 0.8s; 216 | transition: opacity 0.8s; 217 | -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 218 | transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); 219 | -webkit-transform: translate3d(0, 0, 0); 220 | transform: translate3d(0, 0, 0); 221 | } 222 | 223 | .menu-wrap .menu .icon-list a { 224 | margin-top: 5px; 225 | background: none; 226 | border-radius: 30px; 227 | border: 1px solid #9194a7; 228 | color: #5111e7; 229 | text-indent: 10px; 230 | line-height: 26px; 231 | font-size: 12px; 232 | } 233 | 234 | .h-opulent-color-animate { 235 | animation: opulent-color-animate 3s steps(100) infinite; 236 | color: #151515; 237 | font-size: 1.2em; 238 | text-align: center; 239 | text-transform: uppercase; 240 | } 241 | 242 | @keyframes opulent-color-animate { 243 | 0% { 244 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 245 | filter: blur(0); 246 | } 247 | 248 | 1% { 249 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 250 | filter: blur(0); 251 | } 252 | 2% { 253 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 254 | filter: blur(0); 255 | } 256 | 3% { 257 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 258 | filter: blur(0); 259 | } 260 | 4% { 261 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 262 | filter: blur(0); 263 | } 264 | 5% { 265 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 266 | filter: blur(0); 267 | } 268 | 6% { 269 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 270 | filter: blur(0); 271 | } 272 | 7% { 273 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 274 | filter: blur(0); 275 | } 276 | 8% { 277 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 278 | filter: blur(0); 279 | } 280 | 9% { 281 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 282 | filter: blur(0); 283 | } 284 | 10% { 285 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 286 | filter: blur(0); 287 | } 288 | 11% { 289 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 290 | filter: blur(0.5px 291 | ); 292 | } 293 | 12% { 294 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 295 | filter: blur(0.5px 296 | ); 297 | } 298 | 13% { 299 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 300 | filter: blur(0.5px 301 | ); 302 | } 303 | 14% { 304 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 305 | filter: blur(0); 306 | } 307 | 15% { 308 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 309 | filter: blur(0); 310 | } 311 | 16% { 312 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 313 | filter: blur(0); 314 | } 315 | 17% { 316 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 317 | filter: blur(0); 318 | } 319 | 18% { 320 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 321 | filter: blur(0); 322 | } 323 | 19% { 324 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 325 | filter: blur(0); 326 | } 327 | 20% { 328 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 329 | filter: blur(0); 330 | } 331 | 21% { 332 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 333 | filter: blur(0); 334 | } 335 | 22% { 336 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 337 | filter: blur(0); 338 | } 339 | 23% { 340 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 341 | filter: blur(0); 342 | } 343 | 24% { 344 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 345 | filter: blur(0); 346 | } 347 | 25% { 348 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 349 | filter: blur(0); 350 | } 351 | 26% { 352 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 353 | filter: blur(0.5px 354 | ); 355 | } 356 | 27% { 357 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 358 | filter: blur(0.5px 359 | ); 360 | } 361 | 28% { 362 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 363 | filter: blur(0); 364 | } 365 | 29% { 366 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 367 | filter: blur(0); 368 | } 369 | 30% { 370 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 371 | filter: blur(0); 372 | } 373 | 31% { 374 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 375 | filter: blur(0); 376 | } 377 | 32% { 378 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 379 | filter: blur(0); 380 | } 381 | 33% { 382 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 383 | filter: blur(0); 384 | } 385 | 34% { 386 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 387 | filter: blur(0); 388 | } 389 | 35% { 390 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 391 | filter: blur(0.5px 392 | ); 393 | } 394 | 36% { 395 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 396 | filter: blur(0.5px 397 | ); 398 | } 399 | 37% { 400 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 401 | filter: blur(0.5px 402 | ); 403 | } 404 | 38% { 405 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 406 | filter: blur(0); 407 | } 408 | 39% { 409 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 410 | filter: blur(0); 411 | } 412 | 40% { 413 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 414 | filter: blur(0); 415 | } 416 | 41% { 417 | text-shadow: 45px 0 0 #0c33f5, -45px 0 0 lime; 418 | filter: blur(0); 419 | } 420 | 42% { 421 | text-shadow: 0 0 0 #0c33f5, 0 0 0 lime; 422 | filter: blur(0); 423 | } 424 | 43% { 425 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 426 | filter: blur(0); 427 | } 428 | 44% { 429 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 430 | filter: blur(0); 431 | } 432 | 45% { 433 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 434 | filter: blur(0); 435 | } 436 | 46% { 437 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 438 | filter: blur(0.5px 439 | ); 440 | } 441 | 47% { 442 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 443 | filter: blur(0.5px 444 | ); 445 | } 446 | 48% { 447 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 448 | filter: blur(0); 449 | } 450 | 49% { 451 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 452 | filter: blur(0); 453 | } 454 | 50% { 455 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 456 | filter: blur(0); 457 | } 458 | 51% { 459 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 460 | filter: blur(0); 461 | } 462 | 52% { 463 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 464 | filter: blur(0); 465 | } 466 | 53% { 467 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 468 | filter: blur(0); 469 | } 470 | 54% { 471 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 472 | filter: blur(0); 473 | } 474 | 55% { 475 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 476 | filter: blur(0.5px 477 | ); 478 | } 479 | 56% { 480 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 481 | filter: blur(0.5px 482 | ); 483 | } 484 | 57% { 485 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 486 | filter: blur(0.5px 487 | ); 488 | } 489 | 58% { 490 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 491 | filter: blur(0); 492 | } 493 | 59% { 494 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 495 | filter: blur(0); 496 | } 497 | 60% { 498 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 499 | filter: blur(0); 500 | } 501 | 61% { 502 | text-shadow: 30px 0 0 red, -30px 0 0 lime; 503 | filter: blur(0); 504 | } 505 | 62% { 506 | text-shadow: 0 0 0 red, 0 0 0 lime; 507 | filter: blur(0); 508 | } 509 | 63% { 510 | text-shadow: 1px 0 0 red, -1px 0 0 #0c33f5; 511 | filter: blur(0); 512 | } 513 | 64% { 514 | text-shadow: 1px 0 0 red, -1px 0 0 #0c33f5; 515 | filter: blur(0); 516 | } 517 | 65% { 518 | text-shadow: 1px 0 0 red, -1px 0 0 #0c33f5; 519 | filter: blur(0); 520 | } 521 | 66% { 522 | text-shadow: 1px 0 0 red, -1px 0 0 #0c33f5; 523 | filter: blur(0.5px 524 | ); 525 | } 526 | 67% { 527 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 528 | filter: blur(0.5px 529 | ); 530 | } 531 | 68% { 532 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 533 | filter: blur(0); 534 | } 535 | 69% { 536 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 537 | filter: blur(0); 538 | } 539 | 70% { 540 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 541 | filter: blur(0); 542 | } 543 | 71% { 544 | text-shadow: 50px 0 0 red, -50px 0 0 #0c33f5; 545 | filter: blur(0); 546 | } 547 | 72% { 548 | text-shadow: 0 0 0 red, 0 0 0 #0c33f5; 549 | filter: blur(0); 550 | } 551 | 73% { 552 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 553 | filter: blur(0); 554 | } 555 | 74% { 556 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 557 | filter: blur(0); 558 | } 559 | 75% { 560 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 561 | filter: blur(0); 562 | } 563 | 76% { 564 | text-shadow: 3px 0 0 red, -3px 0 0 #0c33f5; 565 | filter: blur(0); 566 | } 567 | 77% { 568 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 569 | filter: blur(0); 570 | } 571 | 78% { 572 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 573 | filter: blur(0); 574 | } 575 | 79% { 576 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 577 | filter: blur(0); 578 | } 579 | 80% { 580 | text-shadow: -3px 0 0 red, 3px 0 0 #0c33f5; 581 | filter: blur(0); 582 | } 583 | 81% { 584 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 585 | filter: blur(0); 586 | } 587 | 82% { 588 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 589 | filter: blur(0); 590 | } 591 | 83% { 592 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 593 | filter: blur(0.5px 594 | ); 595 | } 596 | 84% { 597 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 598 | filter: blur(0.5px 599 | ); 600 | } 601 | 85% { 602 | text-shadow: 1px 0 0 red, -1px 0 0 lime; 603 | filter: blur(0.5px 604 | ); 605 | } 606 | 86% { 607 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 608 | filter: blur(0.5px 609 | ); 610 | } 611 | 87% { 612 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 613 | filter: blur(0.5px 614 | ); 615 | } 616 | 88% { 617 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 618 | filter: blur(0); 619 | } 620 | 89% { 621 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 622 | filter: blur(0); 623 | } 624 | 90% { 625 | text-shadow: -3px 0 0 red, 3px 0 0 lime; 626 | filter: blur(0); 627 | } 628 | 91% { 629 | text-shadow: 60px 0 0 lime, -60px 0 0 #0c33f5; 630 | filter: blur(0); 631 | } 632 | 92% { 633 | text-shadow: 0 0 0 lime, 0 0 0 #0c33f5; 634 | filter: blur(0); 635 | } 636 | 92% { 637 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 638 | filter: blur(0); 639 | } 640 | 93% { 641 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 642 | filter: blur(0); 643 | } 644 | 94% { 645 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 646 | filter: blur(0); 647 | } 648 | 95% { 649 | text-shadow: 0.8px 0 0 #0c33f5, -0.8px 0 0 lime; 650 | filter: blur(0); 651 | } 652 | 96% { 653 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 654 | filter: blur(0); 655 | } 656 | 97% { 657 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 658 | filter: blur(0); 659 | } 660 | 98% { 661 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 662 | filter: blur(0); 663 | } 664 | 99% { 665 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 666 | filter: blur(0); 667 | } 668 | 100% { 669 | text-shadow: -3px 0 0 #0c33f5, 3px 0 0 lime; 670 | filter: blur(0); 671 | } 672 | } 673 | -------------------------------------------------------------------------------- /static/css/slider/normalize.css: -------------------------------------------------------------------------------- 1 | article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} -------------------------------------------------------------------------------- /static/css/type-tag/style.css: -------------------------------------------------------------------------------- 1 | .type-tag-list { 2 | list-style: none; 3 | } 4 | .type-tag-list .clearfix { 5 | position: relative; 6 | } 7 | .type-tag-list li { 8 | width: 100%; 9 | max-width: 768px; 10 | margin: 0 auto 40px; 11 | padding: 0 20px; 12 | -webkit-box-sizing: border-box; 13 | box-sizing: border-box; 14 | display: block; 15 | } 16 | .type-tag-list li a { 17 | background: #fff; 18 | } 19 | .type-tag-list li a { 20 | width: 100%; 21 | height: 100%; 22 | padding-left: 20px; 23 | border-radius: 5px; 24 | text-decoration: none; 25 | -webkit-transition: .2s; 26 | transition: .2s; 27 | display: block; 28 | position: relative; 29 | } 30 | .type-tag-list .eo-bg { 31 | background: #fff; 32 | } 33 | .type-tag-list li a .description { 34 | color: #212121; 35 | } 36 | .type-tag-list li a .description { 37 | font-size: 14px; 38 | } 39 | .type-tag-list li a .description { 40 | min-height: 70px; 41 | padding: 20px 0 0; 42 | color: #333; 43 | } 44 | .type-tag-list li a .type-tag-row { 45 | padding: 40px 0; 46 | position: relative; 47 | } 48 | .type-tag-list li a .type-tag-row .name { 49 | color: #212121; 50 | } 51 | .type-tag-list li a .type-tag-row .name { 52 | font-size: 28px; 53 | } 54 | .type-tag-list li a .type-tag-row .name { 55 | color: #333; 56 | font-weight: 700; 57 | position: relative; 58 | } 59 | .type-tag-list li a .type-tag-row .articles { 60 | color: #bdbdbd; 61 | } 62 | .type-tag-list li a .type-tag-row .articles { 63 | height: 80px; 64 | line-height: 80px; 65 | font-size: 80px; 66 | position: absolute; 67 | right: 20px; 68 | bottom: 10px; 69 | font-family: WeChatNumber-151125,sans-serif; 70 | color: #939898; 71 | } 72 | 73 | @media screen and (min-width: 1150px) 74 | { 75 | .type-tag-list li { 76 | width: 50%; 77 | float: left; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WindSnowLi/vue-ssr-blog/1aefe4fe107a0c6ccaee4e7fb7475c26a0d6875c/static/favicon.ico -------------------------------------------------------------------------------- /static/images/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WindSnowLi/vue-ssr-blog/1aefe4fe107a0c6ccaee4e7fb7475c26a0d6875c/static/images/favicon.ico -------------------------------------------------------------------------------- /static/images/gongan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WindSnowLi/vue-ssr-blog/1aefe4fe107a0c6ccaee4e7fb7475c26a0d6875c/static/images/gongan.png -------------------------------------------------------------------------------- /static/images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WindSnowLi/vue-ssr-blog/1aefe4fe107a0c6ccaee4e7fb7475c26a0d6875c/static/images/login.png -------------------------------------------------------------------------------- /static/images/menu-toggler.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /static/images/search-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /static/logo/long-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WindSnowLi/vue-ssr-blog/1aefe4fe107a0c6ccaee4e7fb7475c26a0d6875c/static/logo/long-logo.png -------------------------------------------------------------------------------- /static/logo/square-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WindSnowLi/vue-ssr-blog/1aefe4fe107a0c6ccaee4e7fb7475c26a0d6875c/static/logo/square-logo.png -------------------------------------------------------------------------------- /utils/auth.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const TokenKey = 'Token-Cookies' 4 | 5 | export function getToken() { 6 | return Cookies.get(TokenKey) 7 | } 8 | 9 | export function setToken(token) { 10 | return Cookies.set(TokenKey, token) 11 | } 12 | 13 | export function removeToken() { 14 | return Cookies.remove(TokenKey) 15 | } 16 | -------------------------------------------------------------------------------- /utils/request.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 原源码详情链接:https://github.com/PanJiaChen/vue-element-admin/blob/master/src/utils/request.js 3 | */ 4 | import axios from 'axios' 5 | import {getToken} from "./auth"; 6 | 7 | // create an axios instance 8 | const service = axios.create({ 9 | baseURL: process.env.BASE_URL, // url = base url + request url 10 | // withCredentials: true, // send cookies when cross-domain requests 11 | timeout: 5000 // request timeout 12 | }) 13 | 14 | // request interceptor 15 | service.interceptors.request.use( 16 | config => { 17 | // do something before request is sent 18 | if (getToken()) { 19 | config.headers['token'] = getToken() 20 | } 21 | return config 22 | }, 23 | error => { 24 | // do something with request error 25 | console.log(error) // for debug 26 | return Promise.reject(error) 27 | } 28 | ) 29 | 30 | // response interceptor 31 | service.interceptors.response.use( 32 | response => { 33 | const res = response.data 34 | if (res.code !== 20000) { 35 | return Promise.reject(new Error(res.message || 'Error')) 36 | } else { 37 | return res.data 38 | } 39 | }, 40 | error => { 41 | console.log('err' + error) // for debug 42 | return Promise.reject(error) 43 | } 44 | ) 45 | 46 | export default service 47 | --------------------------------------------------------------------------------