├── .gitignore ├── .vscode └── settings.json ├── README.md ├── backstage ├── .browserslistrc ├── .env.development ├── .env.production ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── api │ │ ├── article.js │ │ ├── user.js │ │ └── word.js │ ├── assets │ │ └── font │ │ │ ├── iconfont.css │ │ │ ├── iconfont.eot │ │ │ ├── iconfont.svg │ │ │ ├── iconfont.ttf │ │ │ ├── iconfont.woff │ │ │ └── iconfont.woff2 │ ├── components │ │ └── markdown.vue │ ├── main.js │ ├── router │ │ ├── index.js │ │ └── power.js │ ├── store │ │ └── index.js │ ├── styles │ │ └── main.scss │ ├── utils │ │ ├── request.js │ │ └── uploadFile.js │ └── views │ │ ├── AboutMe │ │ └── index.vue │ │ ├── AddArt │ │ └── index.vue │ │ ├── Comment │ │ └── index.vue │ │ ├── Layout │ │ ├── components │ │ │ ├── main.vue │ │ │ └── nav.vue │ │ └── index.vue │ │ ├── Login │ │ └── index.vue │ │ ├── Setting │ │ └── index.vue │ │ └── Work │ │ └── index.vue ├── vue.config.js └── yarn.lock ├── client ├── .browserslistrc ├── .env.development ├── .env.production ├── .gitignore ├── .postcssrx.js ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── api │ │ ├── article.js │ │ ├── articleWord.js │ │ ├── myWord.js │ │ └── user.js │ ├── assets │ │ ├── font │ │ │ ├── iconfont.css │ │ │ ├── iconfont.eot │ │ │ ├── iconfont.svg │ │ │ ├── iconfont.ttf │ │ │ ├── iconfont.woff │ │ │ └── iconfont.woff2 │ │ ├── img │ │ │ ├── blacklogo.png │ │ │ ├── dzh.png │ │ │ ├── dzq.png │ │ │ ├── logo1.png │ │ │ ├── logo2.png │ │ │ ├── night.gif │ │ │ ├── pl.png │ │ │ ├── rain │ │ │ │ ├── loudThunder.mp3 │ │ │ │ ├── rain.mp3 │ │ │ │ ├── rain2_off.png │ │ │ │ ├── rain2_on.png │ │ │ │ ├── rain3_off.png │ │ │ │ ├── rain3_on.png │ │ │ │ ├── rain4_off.png │ │ │ │ ├── rain4_on.png │ │ │ │ ├── rain_off.png │ │ │ │ ├── rain_on.png │ │ │ │ ├── thunder.mp3 │ │ │ │ └── words.png │ │ │ ├── rs.png │ │ │ ├── sc.png │ │ │ ├── textlogo.png │ │ │ ├── white.png │ │ │ ├── whitelogo.png │ │ │ └── wxImg.jpg │ │ └── js │ │ │ └── flexible.js │ ├── components │ │ ├── Article │ │ │ └── index.vue │ │ ├── BackTop │ │ │ └── index.vue │ │ ├── Button │ │ │ └── index.vue │ │ ├── Contact │ │ │ └── index.vue │ │ ├── GiantScreen │ │ │ └── index.vue │ │ ├── Header │ │ │ └── index.vue │ │ ├── Index │ │ │ └── center.vue │ │ ├── Loading │ │ │ └── index.vue │ │ ├── loginRegistration │ │ │ ├── index.vue │ │ │ └── loginBg.vue │ │ └── pageLoadScrollBar │ │ │ └── index.vue │ ├── main.js │ ├── router │ │ ├── handler.js │ │ ├── index.js │ │ └── routes.js │ ├── store │ │ └── index.js │ ├── style │ │ ├── animate.min.css │ │ └── normalize.less │ ├── utils │ │ ├── index.js │ │ └── request.js │ └── views │ │ ├── ArticleList │ │ ├── components │ │ │ ├── messageInput.vue │ │ │ ├── messageList.vue │ │ │ └── scrollBar.vue │ │ ├── detail.vue │ │ └── index.vue │ │ ├── Demo │ │ ├── components │ │ │ └── Piano │ │ │ │ ├── audio.js │ │ │ │ └── index.vue │ │ └── index.vue │ │ ├── Exhibit │ │ └── index.vue │ │ ├── Home │ │ └── index.vue │ │ ├── Login │ │ └── index.vue │ │ ├── MessageBoard │ │ ├── components │ │ │ └── messageList.vue │ │ └── index.vue │ │ ├── Rainy │ │ └── index.vue │ │ ├── SelfInfo │ │ └── index.vue │ │ └── backbone.vue ├── vue.config.js └── yarn.lock ├── index.js ├── logger.js ├── models ├── init.js ├── relation.js ├── sync.js └── tables │ ├── article.js │ ├── articleWord.js │ ├── classify.js │ ├── db.js │ ├── myWord.js │ └── user.js ├── nodemon.json ├── package-lock.json ├── package.json ├── routes ├── api │ ├── article.js │ ├── articleWord.js │ ├── myWord.js │ ├── ossUpload.js │ ├── sync.js │ ├── upload.js │ └── user.js ├── apiLoggerMiddleware.js ├── captchaMiddleware.js ├── errorMiddleware.js ├── getSendMessage.js ├── init.js ├── jwt.js ├── sessionConfig.js └── tokenMiddleware.js └── services ├── articleServ.js ├── commentServ.js ├── myCommServ.js ├── userServ.js └── utils.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | encrypt 4 | 5 | dist 6 | 7 | dist.zip 8 | 9 | public 10 | 11 | logs -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /backstage/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /backstage/.env.development: -------------------------------------------------------------------------------- 1 | VUE_APP_URL = http://localhost:5008 -------------------------------------------------------------------------------- /backstage/.env.production: -------------------------------------------------------------------------------- 1 | VUE_APP_URL = https://www.llongjie.top:5008 -------------------------------------------------------------------------------- /backstage/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | -------------------------------------------------------------------------------- /backstage/README.md: -------------------------------------------------------------------------------- 1 | # backstage 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | yarn lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /backstage/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"] 3 | }; 4 | -------------------------------------------------------------------------------- /backstage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backstage", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.2", 12 | "core-js": "^3.6.5", 13 | "element-ui": "^2.13.2", 14 | "mavon-editor": "^2.9.0", 15 | "vue": "^2.6.11", 16 | "vue-router": "^3.2.0", 17 | "vuex": "^3.4.0" 18 | }, 19 | "devDependencies": { 20 | "@vue/cli-plugin-babel": "^4.4.0", 21 | "@vue/cli-plugin-eslint": "^4.4.0", 22 | "@vue/cli-plugin-router": "^4.4.0", 23 | "@vue/cli-plugin-vuex": "^4.4.0", 24 | "@vue/cli-service": "^4.4.0", 25 | "@vue/eslint-config-prettier": "^6.0.0", 26 | "babel-eslint": "^10.1.0", 27 | "compression-webpack-plugin": "^5.0.1", 28 | "eslint": "^6.7.2", 29 | "eslint-plugin-prettier": "^3.1.3", 30 | "eslint-plugin-vue": "^6.2.2", 31 | "node-sass": "^4.14.1", 32 | "prettier": "^1.19.1", 33 | "sass-loader": "^8.0.2", 34 | "vue-template-compiler": "^2.6.11" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backstage/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/backstage/public/favicon.ico -------------------------------------------------------------------------------- /backstage/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 后台系统 12 | 13 | 14 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /backstage/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 32 | -------------------------------------------------------------------------------- /backstage/src/api/article.js: -------------------------------------------------------------------------------- 1 | import axios from '../utils/request.js' 2 | 3 | // 新增一篇文章 4 | export const add = data => axios.post('/api/article/addArticle', data) 5 | -------------------------------------------------------------------------------- /backstage/src/api/user.js: -------------------------------------------------------------------------------- 1 | import axios from '../utils/request.js' 2 | import uploadFile from '../utils/uploadFile' 3 | 4 | // 登录 5 | export const login = (account, password) => axios.post('/api/user/login',{account, password}) 6 | 7 | // 获取我的个人信息 8 | export const whoami = () => axios.get('/api/user/whoami') 9 | 10 | // 修改用户信息 11 | export const updateUserInfo = data => axios.post('/api/user/updateUserInfo', data) 12 | 13 | // 获取首页信息 14 | export const getHomeInfo = () => axios.get('/api/user/getHomeInfo') 15 | 16 | // 上传图片 17 | export const uploadImg = data => uploadFile.post('/ossUpload', data) -------------------------------------------------------------------------------- /backstage/src/api/word.js: -------------------------------------------------------------------------------- 1 | import axios from '../utils/request.js' 2 | 3 | export const list = data => axios.post('/api/myWord/getMyComList', data) 4 | 5 | export const deleteWord = data => axios.post('/api/myWord/deleteCom', data) 6 | -------------------------------------------------------------------------------- /backstage/src/assets/font/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1599581849729'); /* IE9 */ 3 | src: url('iconfont.eot?t=1599581849729#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), 5 | url('iconfont.woff?t=1599581849729') format('woff'), 6 | url('iconfont.ttf?t=1599581849729') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1599581849729#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-Music1:before { 19 | content: "\e794"; 20 | } 21 | 22 | .icon-yinle:before { 23 | content: "\e60a"; 24 | } 25 | 26 | .icon-jurassic_image:before { 27 | content: "\e69c"; 28 | } 29 | 30 | .icon-zhengli:before { 31 | content: "\e613"; 32 | } 33 | 34 | .icon-dili:before { 35 | content: "\e60c"; 36 | } 37 | 38 | .icon-tiyu:before { 39 | content: "\e60d"; 40 | } 41 | 42 | .icon-shuxue:before { 43 | content: "\e60e"; 44 | } 45 | 46 | .icon-jiaoliu:before { 47 | content: "\e60f"; 48 | } 49 | 50 | .icon-tianwen:before { 51 | content: "\e610"; 52 | } 53 | 54 | .icon-xiaoche:before { 55 | content: "\e611"; 56 | } 57 | 58 | .icon-xiaoyuanka:before { 59 | content: "\e612"; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /backstage/src/assets/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/backstage/src/assets/font/iconfont.eot -------------------------------------------------------------------------------- /backstage/src/assets/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/backstage/src/assets/font/iconfont.ttf -------------------------------------------------------------------------------- /backstage/src/assets/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/backstage/src/assets/font/iconfont.woff -------------------------------------------------------------------------------- /backstage/src/assets/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/backstage/src/assets/font/iconfont.woff2 -------------------------------------------------------------------------------- /backstage/src/components/markdown.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 59 | 60 | -------------------------------------------------------------------------------- /backstage/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import router from "./router/power"; 4 | import store from "./store"; 5 | 6 | import ElementUI from 'element-ui'; 7 | import 'element-ui/lib/theme-chalk/index.css'; 8 | 9 | // 引入 iconfont 10 | import '@/assets/font/iconfont.css'; 11 | // 引入 iconfont 12 | 13 | // 引入markDown 编辑器 14 | import mavonEditor from 'mavon-editor' 15 | import 'mavon-editor/dist/css/index.css' 16 | Vue.use(mavonEditor) 17 | 18 | Vue.use(ElementUI) 19 | 20 | Vue.prototype.mainUrl = process.env.VUE_APP_URL 21 | 22 | Vue.config.productionTip = false; 23 | 24 | new Vue({ 25 | router, 26 | store, 27 | render: h => h(App) 28 | }).$mount("#app"); 29 | 30 | if (process.env.NODE_ENV == 'development') { 31 | Vue.config.devtools = true 32 | } else { 33 | Vue.config.devtools = false 34 | Vue.config.productionTip = false 35 | } -------------------------------------------------------------------------------- /backstage/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import VueRouter from "vue-router"; 3 | import Layout from '@/views/Layout' 4 | Vue.use(VueRouter); 5 | 6 | const routes = [ 7 | { 8 | path: "/", 9 | redirect: 'login', 10 | hidden: true, 11 | meta: { 12 | name: '主页', 13 | icon: 'icon-zhengli' 14 | } 15 | }, 16 | { 17 | path: "/login", 18 | name: "Login", 19 | hidden: true, 20 | meta: { 21 | name: "登陆", 22 | icon: 'icon-dili' 23 | }, 24 | component: () => import(/* webpackChunkName: "login" */ "../views/Login/index.vue") 25 | }, 26 | { 27 | path: "/home", 28 | name: "Home", 29 | redirect: 'index', 30 | meta: { 31 | name: '主页', 32 | icon: 'el-icon-s-home' 33 | }, 34 | component: Layout, 35 | children: [ 36 | { 37 | path: "/index", 38 | name: "index", 39 | component: () => import(/* webpackChunkName: "home" */ "../views/Work") 40 | } 41 | ] 42 | }, 43 | { 44 | path: "/article", 45 | name: "Article", 46 | redirect: 'addArt', 47 | meta: { 48 | name: '发布文章', 49 | icon: 'el-icon-position' 50 | }, 51 | component: Layout, 52 | children: [ 53 | { 54 | path: "/addArt", 55 | name: "AddArt", 56 | component: () => import( /* webpackChunkName: "article" */"../views/AddArt") 57 | } 58 | ] 59 | }, 60 | { 61 | path: "/about", 62 | name: "About", 63 | redirect: 'aboutMe', 64 | meta: { 65 | name: '关于我', 66 | icon: 'el-icon-watermelon' 67 | }, 68 | component: Layout, 69 | children: [ 70 | { 71 | path: "/aboutMe", 72 | name: "aboutMe", 73 | component: () => import(/* webpackChunkName: "about" */"../views/AboutMe") 74 | } 75 | ] 76 | }, 77 | { 78 | path: "/comment", 79 | name: "Comment", 80 | redirect: 'commentList', 81 | meta: { 82 | name: '评论列表', 83 | icon: 'el-icon-chat-dot-square' 84 | }, 85 | component: Layout, 86 | children: [ 87 | { 88 | path: "/commentList", 89 | name: "CommentList", 90 | component: () => import(/* webpackChunkName: "comment" */ "../views/Comment") 91 | } 92 | ] 93 | }, 94 | { 95 | path: "/set", 96 | name: "Set", 97 | redirect: 'setting', 98 | meta: { 99 | name: '设置', 100 | icon: 'el-icon-setting' 101 | }, 102 | component: Layout, 103 | children: [ 104 | { 105 | path: "/setting", 106 | name: "Setting", 107 | component: () => import(/* webpackChunkName: "set" */"../views/Setting") 108 | } 109 | ] 110 | }, 111 | ]; 112 | 113 | let base = '' 114 | process.env.NODE_ENV === 'production' ? base = '/back/' : base = '' 115 | 116 | const router = new VueRouter({ 117 | mode: 'hash', 118 | base, 119 | routes 120 | }); 121 | 122 | 123 | export default router; 124 | -------------------------------------------------------------------------------- /backstage/src/router/power.js: -------------------------------------------------------------------------------- 1 | import router from './index' 2 | 3 | const whiteRouter = ['/login'] 4 | 5 | router.beforeEach((to, from, next) => { 6 | const isToken = !!localStorage.getItem('token') 7 | if (isToken) { 8 | next() 9 | } else { // 没有token 10 | whiteRouter.includes(to.path) ? next() : next('/login') 11 | } 12 | }) 13 | 14 | export default router -------------------------------------------------------------------------------- /backstage/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | 4 | Vue.use(Vuex); 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | userInfo: {} 9 | }, 10 | mutations: { 11 | setUserInfo (state, data) { 12 | state.userInfo = data 13 | } 14 | }, 15 | actions: {}, 16 | modules: {} 17 | }); 18 | -------------------------------------------------------------------------------- /backstage/src/utils/request.js: -------------------------------------------------------------------------------- 1 | // 发送请求的时候,如果有token,需要附带在请求头中 2 | // 响应的时候,如果响应的消息码是403( 没有token,token失效),在本地删除token 3 | import axios from 'axios' 4 | import { Message } from "element-ui" 5 | 6 | let baseURL = process.env.VUE_APP_URL 7 | 8 | const ins = axios.create({ 9 | baseURL, 10 | timeout: 15000, 11 | withCredentials: true 12 | }) 13 | 14 | ins.interceptors.request.use(req => { 15 | const token = localStorage.getItem("token") 16 | if (token) { 17 | req.headers['authorization'] = "bearer " + token 18 | } 19 | return req 20 | },err => { 21 | return Promise.reject(err) 22 | }) 23 | 24 | ins.interceptors.response.use(resp => { 25 | // if (resp.headers.authorization) { 26 | // localStorage.setItem("token", resp.headers.authorization) 27 | // } 28 | const data = resp.data 29 | if (data.code !== 200 ) { 30 | Message.error(data.msg) 31 | return Promise.reject(data) 32 | } 33 | return resp 34 | }, err => { 35 | if (err.response.status === 403) { 36 | localStorage.removeItem("token") 37 | Message.error('登陆已过期,请重新登陆') 38 | } 39 | return Promise.reject(err) 40 | }) 41 | 42 | export default ins -------------------------------------------------------------------------------- /backstage/src/utils/uploadFile.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { Message } from "element-ui" 3 | 4 | let baseURL = '' 5 | process.env.NODE_ENV === 'production' ? baseURL = 'http://www.llongjie.top:5008' : baseURL = 'http://localhost:5008' 6 | 7 | const ins = axios.create({ 8 | baseURL, 9 | withCredentials: true 10 | }) 11 | 12 | ins.interceptors.request.use(req => { 13 | const token = localStorage.getItem("token") 14 | if (token) { 15 | req.headers['authorization'] = "bearer " + token 16 | req.headers['Content-Type'] = 'multipart/form-data' 17 | } 18 | return req 19 | },err => { 20 | return Promise.reject(err) 21 | }) 22 | 23 | 24 | ins.interceptors.response.use(resp => { 25 | const data = resp.data 26 | if (data.code !== 200 ) { 27 | Message.error(data.msg) 28 | return Promise.reject(data) 29 | } 30 | return resp 31 | }, err => { 32 | if (err.response.status === 403) { 33 | localStorage.removeItem("token") 34 | Message.error('登陆已过期,请重新登陆') 35 | } 36 | return Promise.reject(err) 37 | }) 38 | 39 | export default ins -------------------------------------------------------------------------------- /backstage/src/views/AboutMe/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 51 | 52 | -------------------------------------------------------------------------------- /backstage/src/views/AddArt/index.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 137 | 138 | -------------------------------------------------------------------------------- /backstage/src/views/Comment/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 68 | 69 | -------------------------------------------------------------------------------- /backstage/src/views/Layout/components/main.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /backstage/src/views/Layout/components/nav.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 51 | 52 | -------------------------------------------------------------------------------- /backstage/src/views/Layout/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | -------------------------------------------------------------------------------- /backstage/src/views/Login/index.vue: -------------------------------------------------------------------------------- 1 | 32 | 64 | 129 | -------------------------------------------------------------------------------- /backstage/src/views/Setting/index.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 101 | 102 | -------------------------------------------------------------------------------- /backstage/src/views/Work/index.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 52 | 53 | -------------------------------------------------------------------------------- /backstage/vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CompressionPlugin = require("compression-webpack-plugin"); // gzip压缩 3 | 4 | 5 | module.exports = { 6 | // 基本路径 7 | publicPath: process.env.NODE_ENV === 'production' ? '/back/' : '/', 8 | // 输出文件目录 9 | outputDir: process.env.NODE_ENV === 'production' ? path.resolve(__dirname, '../public/back') : 'devdist', 10 | // eslint-loader 是否在保存的时候检查 11 | lintOnSave: false, 12 | /** 13 | * webpack配置,see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md 14 | **/ 15 | configureWebpack: (config) => { 16 | config.resolve = { // 配置解析别名 17 | extensions: ['.js', '.json', '.vue'], 18 | alias: { 19 | 'vue': 'vue/dist/vue.js', 20 | '@': path.resolve(__dirname, './src'), 21 | '@img': path.resolve(__dirname, './src/assets/img'), 22 | '@c': path.resolve(__dirname, './src/components'), 23 | } 24 | }, 25 | // config.externals = { // 不打包elementUi和Vue 使用cdn的方式引入 26 | // "element-ui": "ELEMENT", 27 | // 'vue': 'Vue' 28 | // }, 29 | process.env.NODE_ENV === 'production' ? config.mode = 'production' : config.mode = 'development' 30 | // config.optimization.minimizer[0].options.terserOptions.compress = { drop_console: process.env.NODE_ENV === 'production', drop_debugger: false, pure_funcs: ['console.log'] } // 移除console 31 | config.plugins.push(new CompressionPlugin({ 32 | filename: '[path].gz[query]', 33 | //压缩算法 34 | algorithm: 'gzip', 35 | //匹配文件 36 | test: /\.js$|\.css$|\.html$|/, 37 | //压缩超过此大小的文件,以字节为单位 38 | threshold: 1024, 39 | minRatio: 0.8, 40 | //删除原始文件只保留压缩后的文件 41 | // deleteOriginalAssets: process.env.NODE_ENV === 'production' 42 | })) 43 | }, 44 | // 生产环境是否生成 sourceMap 文件 45 | productionSourceMap: false, 46 | // css相关配置 47 | css: { 48 | // 是否使用css分离插件 ExtractTextPlugin 49 | extract: true, 50 | // 开启 CSS source maps? 51 | sourceMap: false, 52 | // css预设器配置项 53 | loaderOptions: { 54 | scss: { 55 | prependData: `@import "./src/styles/main.scss";` 56 | } 57 | } 58 | }, 59 | // use thread-loader for babel & TS in production build 60 | // enabled by default if the machine has more than 1 cores 61 | parallel: require('os').cpus().length > 1, 62 | /** 63 | * PWA 插件相关配置,see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa 64 | */ 65 | pwa: {}, 66 | // webpack-dev-server 相关配置 67 | // devServer: { 68 | // hot: true, // 开启热加载 69 | // hotOnly: false, 70 | // proxy: { // 设置代理 71 | // '/api': { 72 | // target: 'http://localhost:5008', //API服务器的地址 73 | // changeOrigin: true 74 | // } 75 | // }, 76 | // overlay: { // 全屏模式下是否显示脚本错误 77 | // warnings: true, 78 | // errors: true 79 | // }, 80 | // before: app => {} 81 | // }, 82 | /** 83 | * 第三方插件配置 84 | */ 85 | pluginOptions: { 86 | 'style-resources-loader': { 87 | preProcessor: 'less', 88 | // 需要通过less-loader自动引入的资源,集合类型 89 | patterns: [path.resolve(__dirname, 'src/style/normalize.less')] 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /client/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /client/.env.development: -------------------------------------------------------------------------------- 1 | VUE_APP_URL = http://localhost:5008 -------------------------------------------------------------------------------- /client/.env.production: -------------------------------------------------------------------------------- 1 | VUE_APP_URL = https://www.llongjie.top:5008 -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | -------------------------------------------------------------------------------- /client/.postcssrx.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | // 'postcss-px2rem': { 4 | // remUnit: 35 5 | // }, 6 | 'autoprefixer':{} 7 | } 8 | } -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # blog 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | yarn lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /client/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"] 3 | }; 4 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "autoprefixer": "^9.8.4", 12 | "axios": "^0.19.2", 13 | "core-js": "^3.6.5", 14 | "css-loader": "^3.6.0", 15 | "element-ui": "^2.13.2", 16 | "github-markdown-css": "^4.0.0", 17 | "highlight.js": "^10.1.2", 18 | "marked": "^1.1.1", 19 | "parallax-js": "^3.1.0", 20 | "postcss-px2rem": "^0.3.0", 21 | "vue": "^2.6.11", 22 | "vue-router": "^3.2.0", 23 | "vuex": "^3.4.0", 24 | "webpack-bundle-analyzer": "^3.8.0", 25 | "wowjs": "^1.1.3" 26 | }, 27 | "devDependencies": { 28 | "@vue/cli-plugin-babel": "^4.4.0", 29 | "@vue/cli-plugin-eslint": "^4.4.0", 30 | "@vue/cli-plugin-router": "^4.4.0", 31 | "@vue/cli-plugin-vuex": "^4.4.0", 32 | "@vue/cli-service": "^4.4.0", 33 | "@vue/eslint-config-prettier": "^6.0.0", 34 | "babel-eslint": "^10.1.0", 35 | "compression-webpack-plugin": "^5.0.1", 36 | "eslint": "^6.7.2", 37 | "eslint-plugin-prettier": "^3.1.3", 38 | "eslint-plugin-vue": "^6.2.2", 39 | "less": "^3.0.4", 40 | "less-loader": "^5.0.0", 41 | "mini-css-extract-plugin": "^1.2.1", 42 | "prettier": "^1.19.1", 43 | "style-resources-loader": "^1.3.3", 44 | "vue-cli-plugin-style-resources-loader": "^0.1.4", 45 | "vue-template-compiler": "^2.6.11" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | <% for (var i in htmlWebpackPlugin.options.cdn && 14 | htmlWebpackPlugin.options.cdn.css) { %> 15 | 19 | <% } %> 20 | 漆黑之牙 21 | 22 | 23 | 26 |
27 | 28 | 29 | 30 | <% for (var i in htmlWebpackPlugin.options.cdn && 31 | htmlWebpackPlugin.options.cdn.js) { %> 32 | 33 | <% } %> 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /client/src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 24 | 45 | -------------------------------------------------------------------------------- /client/src/api/article.js: -------------------------------------------------------------------------------- 1 | import axios from '../utils/request.js' 2 | 3 | // 新增一篇文章 4 | export const add = data => axios.post('/api/article/addArticle', data) 5 | 6 | // 获取文章列表 7 | export const list = data => axios.post('/api/article/getArtList', data) 8 | 9 | // 获取文章详情 10 | export const detail = (id, userId) => axios.get('/api/article/getArtDetail', { params: { id, userId } }) 11 | 12 | // 喜欢这篇文章 13 | export const setLike = data => axios.post('/api/article/likeArt', data) -------------------------------------------------------------------------------- /client/src/api/articleWord.js: -------------------------------------------------------------------------------- 1 | import axios from '../utils/request.js' 2 | 3 | // 新增评论 4 | export const add = data => axios.post('/api/articleWord/addComment', data) 5 | 6 | // 获取评论列表 7 | export const list = data => axios.post('/api/articleWord/getArtComList',data) -------------------------------------------------------------------------------- /client/src/api/myWord.js: -------------------------------------------------------------------------------- 1 | import axios from '../utils/request.js' 2 | 3 | // 新增评论 4 | export const add = data => axios.post('/api/myWord/addmyCom', data) 5 | 6 | // 获取评论列表 7 | export const list = data => axios.post('/api/myWord/getMyComList', data) -------------------------------------------------------------------------------- /client/src/api/user.js: -------------------------------------------------------------------------------- 1 | import axios from '../utils/request' 2 | 3 | // 登陆 4 | export const login = (account, password) => axios.post('/api/user/login',{account, password}) 5 | 6 | // 增加用户 7 | export const addUser = (data) => axios.post('/api/user/addUser', data) 8 | 9 | // 注册 按我的博客逻辑是需要验证码的修改用户信息。。。 10 | export const registry = (data) => axios.post('/api/user/registry', data) 11 | 12 | // 修改用户信息 13 | export const updateUserInfo = data => axios.post('/api/user/updateUserInfo', data) 14 | 15 | // 获取个人信息 16 | export const whoami = () => axios.get('/api/user/whoami') 17 | 18 | // 获取管理员的个人信息,必须在数据库里面id为 **1** 19 | export const getAboutMe = () => axios.get('/api/user/getAboutMe') -------------------------------------------------------------------------------- /client/src/assets/font/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1599576878291'); /* IE9 */ 3 | src: url('iconfont.eot?t=1599576878291#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), 5 | url('iconfont.woff?t=1599576878291') format('woff'), 6 | url('iconfont.ttf?t=1599576878291') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1599576878291#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-wei-:before { 19 | content: "\e606"; 20 | } 21 | 22 | .icon-user:before { 23 | content: "\e611"; 24 | } 25 | 26 | .icon-zhedie2:before { 27 | content: "\e620"; 28 | } 29 | 30 | .icon-xinheart118:before { 31 | content: "\e755"; 32 | } 33 | 34 | .icon-xin:before { 35 | content: "\e6c2"; 36 | } 37 | 38 | .icon-zanting:before { 39 | content: "\e626"; 40 | } 41 | 42 | .icon-bofang:before { 43 | content: "\e66e"; 44 | } 45 | 46 | .icon-view:before { 47 | content: "\e63f"; 48 | } 49 | 50 | .icon-dianzan:before { 51 | content: "\e644"; 52 | } 53 | 54 | .icon-pinglun:before { 55 | content: "\e614"; 56 | } 57 | 58 | .icon-shijian:before { 59 | content: "\e661"; 60 | } 61 | 62 | .icon-zhucehuise:before { 63 | content: "\e61c"; 64 | } 65 | 66 | .icon-ico-:before { 67 | content: "\e80f"; 68 | } 69 | 70 | .icon-weixin1:before { 71 | content: "\e619"; 72 | } 73 | 74 | .icon-yonghu:before { 75 | content: "\e60a"; 76 | } 77 | 78 | .icon-GitHub:before { 79 | content: "\ea0a"; 80 | } 81 | 82 | .icon-xiangce:before { 83 | content: "\e607"; 84 | } 85 | 86 | .icon-ziyuan:before { 87 | content: "\e623"; 88 | } 89 | 90 | .icon-QQ:before { 91 | content: "\e667"; 92 | } 93 | 94 | .icon-liuyanban:before { 95 | content: "\e610"; 96 | } 97 | 98 | .icon-weixin:before { 99 | content: "\e66c"; 100 | } 101 | 102 | .icon-wenzhangguanli:before { 103 | content: "\e652"; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /client/src/assets/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/font/iconfont.eot -------------------------------------------------------------------------------- /client/src/assets/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/font/iconfont.ttf -------------------------------------------------------------------------------- /client/src/assets/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/font/iconfont.woff -------------------------------------------------------------------------------- /client/src/assets/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/font/iconfont.woff2 -------------------------------------------------------------------------------- /client/src/assets/img/blacklogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/blacklogo.png -------------------------------------------------------------------------------- /client/src/assets/img/dzh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/dzh.png -------------------------------------------------------------------------------- /client/src/assets/img/dzq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/dzq.png -------------------------------------------------------------------------------- /client/src/assets/img/logo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/logo1.png -------------------------------------------------------------------------------- /client/src/assets/img/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/logo2.png -------------------------------------------------------------------------------- /client/src/assets/img/night.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/night.gif -------------------------------------------------------------------------------- /client/src/assets/img/pl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/pl.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/loudThunder.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/loudThunder.mp3 -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain.mp3 -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain2_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain2_off.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain2_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain2_on.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain3_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain3_off.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain3_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain3_on.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain4_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain4_off.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain4_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain4_on.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain_off.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/rain_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/rain_on.png -------------------------------------------------------------------------------- /client/src/assets/img/rain/thunder.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/thunder.mp3 -------------------------------------------------------------------------------- /client/src/assets/img/rain/words.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rain/words.png -------------------------------------------------------------------------------- /client/src/assets/img/rs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/rs.png -------------------------------------------------------------------------------- /client/src/assets/img/sc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/sc.png -------------------------------------------------------------------------------- /client/src/assets/img/textlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/textlogo.png -------------------------------------------------------------------------------- /client/src/assets/img/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/white.png -------------------------------------------------------------------------------- /client/src/assets/img/whitelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/whitelogo.png -------------------------------------------------------------------------------- /client/src/assets/img/wxImg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiheizhiya/myBlog/fe8b0237f6838fbb222902f6a6ddc5d20c898d51/client/src/assets/img/wxImg.jpg -------------------------------------------------------------------------------- /client/src/assets/js/flexible.js: -------------------------------------------------------------------------------- 1 | !function(){var a="@charset \"utf-8\";html{color:#000;background:#fff;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}html *{outline:0;-webkit-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}html,body{font-family:sans-serif}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{margin:0;padding:0}input,select,textarea{font-size:100%}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}abbr,acronym{border:0;font-variant:normal}del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:500}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:500}q:before,q:after{content:''}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}a:hover{text-decoration:underline}ins,a{text-decoration:none}",b=document.createElement("style");if(document.getElementsByTagName("head")[0].appendChild(b),b.styleSheet)b.styleSheet.disabled||(b.styleSheet.cssText=a);else try{b.innerHTML=a}catch(c){b.innerText=a}}();!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){ 2 | // console.warn("灏嗘牴鎹凡鏈夌殑meta鏍囩鏉ヨ缃缉鏀炬瘮渚�"); 3 | var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={})); -------------------------------------------------------------------------------- /client/src/components/BackTop/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 37 | 38 | -------------------------------------------------------------------------------- /client/src/components/Button/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 23 | -------------------------------------------------------------------------------- /client/src/components/Contact/index.vue: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /client/src/components/GiantScreen/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 69 | -------------------------------------------------------------------------------- /client/src/components/Header/index.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 134 | 135 | -------------------------------------------------------------------------------- /client/src/components/Loading/index.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /client/src/components/loginRegistration/index.vue: -------------------------------------------------------------------------------- 1 | 44 | 130 | -------------------------------------------------------------------------------- /client/src/components/loginRegistration/loginBg.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 36 | 37 | -------------------------------------------------------------------------------- /client/src/components/pageLoadScrollBar/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | -------------------------------------------------------------------------------- /client/src/main.js: -------------------------------------------------------------------------------- 1 | 2 | import Vue from "vue"; 3 | if (process.env.NODE_ENV !== 'production') { 4 | 5 | import('element-ui').then(ele => { 6 | Vue.use(ele) 7 | }) 8 | import('element-ui/lib/theme-chalk/index.css') 9 | 10 | } 11 | 12 | import App from "./App.vue"; 13 | 14 | import router from "./router/handler"; 15 | 16 | import store from "./store"; 17 | 18 | 19 | // 引入全局组件Header 20 | import Header from "@c/Header" 21 | Vue.component('Header', Header) 22 | // 引入全局组件Header 23 | 24 | // 引入 iconfont 25 | import '@/assets/font/iconfont.css'; 26 | // 引入 iconfont 27 | 28 | // 高亮富文本 29 | import hljs from 'highlight.js/lib/core'; 30 | import javascript from 'highlight.js/lib/languages/javascript'; 31 | hljs.registerLanguage('javascript', javascript); 32 | Vue.directive('highlight',function (el) { 33 | let blocks = el.querySelectorAll('pre code'); 34 | blocks.forEach((block)=>{ 35 | hljs.highlightBlock(block) 36 | }) 37 | }) 38 | // 高亮富文本 39 | 40 | // 引入markdown-css 41 | import 'github-markdown-css/github-markdown.css' 42 | // 引入markdown-css 43 | 44 | Vue.config.productionTip = false; 45 | 46 | // 设置请求域名 47 | let mainUrl = process.env.VUE_APP_URL 48 | Vue.prototype.mainUrl = mainUrl 49 | 50 | // 添加百度统计 51 | var _hmt = _hmt || []; 52 | window._hmt = _hmt; // 必须把_hmt挂载到window下,否则找不到 53 | (function () { 54 | var hm = document.createElement("script"); 55 | hm.src = "https://hm.baidu.com/hm.js?47c4ba855b7925913cdf701208a1dc0f"; 56 | var s = document.getElementsByTagName("script")[0]; 57 | s.parentNode.insertBefore(hm, s); 58 | })(); 59 | 60 | new Vue({ 61 | router, 62 | store, 63 | render: h => h(App) 64 | }).$mount("#app"); 65 | 66 | 67 | if (process.env.NODE_ENV == 'development') { 68 | Vue.config.devtools = true 69 | Vue.config.productionTip = false 70 | } else { 71 | Vue.config.devtools = false 72 | Vue.config.productionTip = false 73 | } -------------------------------------------------------------------------------- /client/src/router/handler.js: -------------------------------------------------------------------------------- 1 | import router from './index' 2 | import store from "../store" 3 | import Vue from 'vue' 4 | import { Loading } from 'element-ui'; 5 | let load = '' 6 | 7 | router.beforeEach((to, from, next) => { 8 | store.commit('setShowPageLoadScrollBar', true) 9 | if (to.name === 'Exhibit') { 10 | load = Loading.service({ 11 | lock: true, 12 | background: 'rgba(255,255,255,.8)' 13 | }); 14 | } 15 | if (_hmt) { 16 | if (to.path) { 17 | _hmt.push(['_trackPageview', to.fullPath]); 18 | } 19 | } 20 | const { meta } = to 21 | for (let name in meta) { 22 | document[name] = meta[name] 23 | } 24 | next() 25 | }) 26 | router.afterEach((to, from) => { 27 | setTimeout(() => { 28 | if (to.name === 'Exhibit') { 29 | load.close() 30 | } 31 | store.commit('setShowPageLoadScrollBar', false) 32 | }, 1200) 33 | }) 34 | 35 | export default router -------------------------------------------------------------------------------- /client/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import VueRouter from "vue-router"; 3 | import routeArr from "./routes" 4 | Vue.use(VueRouter); 5 | 6 | const routes = routeArr 7 | 8 | const router = new VueRouter({ 9 | mode: "history", 10 | routes, 11 | scrollBehavior () { // 页面刷新后回到顶部 12 | return { x: 0, y: 0} 13 | } 14 | }); 15 | 16 | export default router; 17 | -------------------------------------------------------------------------------- /client/src/router/routes.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | path: "/", 4 | name: "Home", 5 | component: () => import(/* webpackChunkName: "main" */ "../views/Home"), 6 | meta: { 7 | title: '漆黑之牙' 8 | } 9 | }, 10 | { 11 | path: "/exhibit", 12 | name: "Exhibit", 13 | component: () => import(/* webpackChunkName: "exhibit" */ "../views/Exhibit"), 14 | meta: { 15 | title: '展览 | 漆黑之牙' 16 | } 17 | }, 18 | { 19 | path: "/articleList", 20 | name: "ArticleList", 21 | component: () => import(/* webpackChunkName: "article" */ "../views/ArticleList"), 22 | meta: { 23 | title: 'Article | 漆黑之牙' 24 | } 25 | }, 26 | { 27 | path: '/detail/:id', 28 | name: 'Detail', 29 | component: () => import(/* webpackChunkName: "article" */ "../views/ArticleList/detail"), 30 | }, 31 | { 32 | path: "/demo", 33 | name: "Demo", 34 | component: () => import(/* webpackChunkName: "other" */ "../views/Demo"), 35 | meta: { 36 | title: 'Demo | 漆黑之牙' 37 | } 38 | }, 39 | { 40 | path: "/self", 41 | name: "Self", 42 | component: () => import(/* webpackChunkName: "other" */ "../views/SelfInfo") 43 | }, 44 | { 45 | path: "/message", 46 | name: "Message", 47 | component: () => import(/* webpackChunkName: "article" */ "../views/MessageBoard") 48 | }, 49 | { 50 | path: "/rainy", 51 | name: "Rainy", 52 | component: () => import(/* webpackChunkName: "rainy" */ "../views/Rainy") 53 | }, 54 | { 55 | path: "/login", 56 | name: "Login", 57 | component: () => import(/* webpackChunkName: "other" */ "../views/Login") 58 | }, 59 | ] -------------------------------------------------------------------------------- /client/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | import { list } from "@/api/article" 4 | Vue.use(Vuex); 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | isToken: !!localStorage.getItem('token'), // 有没有token 9 | showPageLoadScrollBar: false 10 | }, 11 | mutations: { 12 | setIsToken (state, data) { 13 | state.isToken = data 14 | }, 15 | setShowPageLoadScrollBar (state, data) { 16 | state.showPageLoadScrollBar = !!data 17 | } 18 | }, 19 | actions: { 20 | // 清除token 21 | clearToken ({ commit }) { 22 | localStorage.removeItem('token') 23 | commit('setIsToken', false) 24 | }, 25 | // 获取文章列表 26 | async getArtList (state, page) { 27 | return await list(page) 28 | }, 29 | /** 30 | * 把日期变成 月份 哪一天 年份 31 | */ 32 | async dataHandle(state, result) { 33 | const arr = ['', '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'] 34 | let [y, m, other] = result.createdAt.split("-") 35 | const d = other.split(" ")[0] 36 | m = arr[parseInt(m)] 37 | const resultDate = [y, m, d] 38 | const keys = ['year', 'month', 'day'] 39 | resultDate.forEach((item, index) => result[keys[index]] = resultDate[index]) 40 | return result 41 | } 42 | }, 43 | modules: {} 44 | }); 45 | -------------------------------------------------------------------------------- /client/src/utils/index.js: -------------------------------------------------------------------------------- 1 | import { Message } from 'element-ui' 2 | export function debounce(fn, delay) { 3 | var delay = delay || 200; 4 | var timer; 5 | return function () { 6 | var th = this; 7 | var args = arguments; 8 | if (timer) { 9 | clearTimeout(timer); 10 | } 11 | timer = setTimeout(function () { 12 | timer = null; 13 | fn.apply(th, args); 14 | }, delay); 15 | }; 16 | } 17 | 18 | export function throttle(fn, delay) { 19 | var last; 20 | var timer; 21 | var interval = interval || 200; 22 | return function () { 23 | var th = this; 24 | var args = arguments; 25 | var now = +new Date(); 26 | if (last && now - last < interval) { 27 | clearTimeout(timer); 28 | timer = setTimeout(function () { 29 | last = now; 30 | fn.apply(th, args); 31 | }, interval); 32 | } else { 33 | last = now; 34 | fn.apply(th, args); 35 | } 36 | } 37 | } 38 | export async function valiFunc(arr) { 39 | let res = true 40 | for (let item of arr) { 41 | if (!item.data || item.data.length === 0) { 42 | res = false 43 | Message({ 44 | message: item.msg, 45 | type: 'error', 46 | offset: 60 47 | }) 48 | break 49 | } 50 | } 51 | return res 52 | } 53 | 54 | export function bottomHandle (isScroll, callback) { 55 | // window.onscroll = throttle(scrollChange.bind(null, isScroll, callback), 200) 56 | window.addEventListener('scroll', throttleScroll(isScroll, callback), 200) 57 | } 58 | 59 | export function clearBottomHandle () { 60 | window.removeEventListener('scroll', throttleScroll) 61 | } 62 | 63 | 64 | function scrollChange (isScroll, callback) { 65 | if (!isScroll()) return 66 | const scrollTop = Math.ceil(document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset) 67 | const windowHeight = document.documentElement.clientHeight || document.body.clientHeight 68 | const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight || window.scrollHeight 69 | if (scrollTop + windowHeight >= scrollHeight) { 70 | console.log(scrollTop, windowHeight, scrollHeight) 71 | callback() 72 | } 73 | } 74 | 75 | // 节流滚动方法 76 | const throttleScroll = (isScroll, callback) => throttle(scrollChange.bind(null, isScroll, callback), 200) 77 | 78 | -------------------------------------------------------------------------------- /client/src/utils/request.js: -------------------------------------------------------------------------------- 1 | // 发送请求的时候,如果有token,需要附带在请求头中 2 | // 响应的时候,如果有token,保存到本地 3 | // 响应的时候,如果响应的消息码是403( 没有token,token失效),在本地删除token 4 | import axios from 'axios' 5 | import { Message } from "element-ui" 6 | 7 | const baseURL = process.env.VUE_APP_URL 8 | 9 | const ins = axios.create({ 10 | baseURL, 11 | timeout: 15000, 12 | withCredentials: true 13 | }) 14 | 15 | ins.interceptors.request.use(req => { 16 | const token = localStorage.getItem("token") 17 | if (token) { 18 | req.headers['authorization'] = "bearer " + token 19 | } 20 | return req 21 | },err => { 22 | return Promise.reject(err) 23 | }) 24 | 25 | ins.interceptors.response.use(resp => { 26 | // if (resp.headers.authorization) { 27 | // localStorage.setItem("token", resp.headers.authorization) 28 | // } 29 | const data = resp.data 30 | if (data.code !== 200 ) { 31 | Message({ 32 | type: 'error', 33 | message: data.msg, 34 | offset: 60 35 | }) 36 | return Promise.reject(data) 37 | } 38 | return resp 39 | }, err => { 40 | if (err.response.status === 403) { 41 | localStorage.removeItem("token") 42 | localStorage.removeItem('userInfo') 43 | Message({ 44 | type: 'error', 45 | message: '登陆已过期,请重新登陆', 46 | offset: 60 47 | }) 48 | } 49 | return Promise.reject(err) 50 | }) 51 | 52 | export default ins -------------------------------------------------------------------------------- /client/src/views/ArticleList/components/messageInput.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 90 | 91 | -------------------------------------------------------------------------------- /client/src/views/ArticleList/components/messageList.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 79 | 80 | -------------------------------------------------------------------------------- /client/src/views/ArticleList/components/scrollBar.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 30 | 31 | -------------------------------------------------------------------------------- /client/src/views/ArticleList/detail.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 155 | 156 | 214 | -------------------------------------------------------------------------------- /client/src/views/ArticleList/index.vue: -------------------------------------------------------------------------------- 1 | 27 | 86 | 87 | -------------------------------------------------------------------------------- /client/src/views/Demo/components/Piano/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 125 | 126 | -------------------------------------------------------------------------------- /client/src/views/Demo/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 60 | 61 | -------------------------------------------------------------------------------- /client/src/views/Exhibit/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 58 | -------------------------------------------------------------------------------- /client/src/views/Home/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 24 | -------------------------------------------------------------------------------- /client/src/views/Login/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 62 | 63 | -------------------------------------------------------------------------------- /client/src/views/MessageBoard/components/messageList.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 65 | 66 | -------------------------------------------------------------------------------- /client/src/views/MessageBoard/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 83 | 84 | -------------------------------------------------------------------------------- /client/src/views/Rainy/index.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 97 | 98 | 218 | -------------------------------------------------------------------------------- /client/src/views/SelfInfo/index.vue: -------------------------------------------------------------------------------- 1 | 31 | 67 | 68 | -------------------------------------------------------------------------------- /client/src/views/backbone.vue: -------------------------------------------------------------------------------- 1 | 7 | 15 | -------------------------------------------------------------------------------- /client/vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const isProduction = process.env.NODE_ENV === 'production'; 3 | const CompressionPlugin = require("compression-webpack-plugin"); 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 5 | 6 | const cdn = { 7 | externals: { 8 | 'vue': 'Vue', 9 | 'vuex': 'Vuex', 10 | 'vue-router': 'VueRouter', 11 | 'axios': 'axios', 12 | "element-ui": "ELEMENT", 13 | }, 14 | css: [ 15 | 'https://lib.baomitu.com/element-ui/2.13.2/theme-chalk/index.css' 16 | ], 17 | js: [ 18 | 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js', 19 | 'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js', 20 | 'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js', 21 | 'https://lib.baomitu.com/element-ui/2.13.2/index.js', 22 | 'https://cdn.bootcss.com/axios/0.19.2/axios.min.js' 23 | ] 24 | } 25 | 26 | module.exports = { 27 | // 基本路径 28 | publicPath: '/', 29 | assetsDir: './', 30 | // 输出文件目录 31 | outputDir: isProduction ? path.resolve(__dirname, '../public/pc') : 'devdist', 32 | // eslint-loader 是否在保存的时候检查 33 | lintOnSave: false, 34 | // 默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存。 35 | filenameHashing: true, 36 | // 设置生成的 HTML 中