mirror of
https://gitee.com/doramart/DoraCMS.git
synced 2024-11-29 18:58:47 +08:00
⏰ v2.0.4 版本更新
This commit is contained in:
parent
c6742748b9
commit
34c40969e6
31
README.md
31
README.md
@ -1,35 +1,38 @@
|
||||
# DoraCMS 2.0.3
|
||||
# DoraCMS 2.0.4
|
||||
|
||||
![DoraCMS](http://7xkrk4.com1.z0.glb.clouddn.com/doracms2.jpg "DoraCMS")
|
||||
|
||||
## 2.0.3版本更新
|
||||
## 2.0.4版本更新
|
||||
|
||||
1、上传缩略图支持七牛云存储
|
||||
1、添加系统支持redis缓存,通过开关控制,并添加通过redis缓存数据中间件。要知道redis在存储性能方面MongoDB要好很多(主要存储session数据)
|
||||
|
||||
2、取消在后台首页显示用户敏感信息,提高安全性
|
||||
2、重新整理了样式,组件样式全部单独提取,提高可维护性。
|
||||
|
||||
3、管理员登录md5加密 ![#87](https://github.com/doramart/DoraCMS/pull/87 "#87")
|
||||
3、文档详情页添加了“喜欢”功能。
|
||||
|
||||
4、修复描述信息不是必填项,但是也验证了 ![#91](https://github.com/doramart/DoraCMS/issues/91 "#91")
|
||||
4、修复了某些场景下批量删除留言异常的bug。
|
||||
|
||||
5、站点地图域名可配置
|
||||
5、添加了二维码分享功能。
|
||||
|
||||
6、统一端口号配置
|
||||
6、添加了回到顶部按钮。
|
||||
|
||||
7、修复管理员在留言管理中 对某个会员 回复信息, 然后再给自己(doramart)回复信息后,进入系统主页浏览器报错的问题![#93](https://github.com/doramart/DoraCMS/issues/93 "#93")
|
||||
7、优化了包括 最新文档、近期文档、推荐文档等模块的代码结构。
|
||||
|
||||
8、修复修改管理员信息没有改手机号却提示手机号格式不正确的问题 ![#92](https://github.com/doramart/DoraCMS/pull/92 "#92")
|
||||
8、优化了用户中心的界面和交互。
|
||||
|
||||
9、前台后台添加404页面
|
||||
9、修复页面跳转后滚动条不置顶的问题。
|
||||
|
||||
10、后台没有权限的菜单不显示
|
||||
10、修复了某些场景下通过标签查询,分页异常的问题。
|
||||
|
||||
11、优化了cms在移动端的显示。
|
||||
|
||||
12、修复了一些明显bug
|
||||
|
||||
11、修复了一些样式问题
|
||||
|
||||
|
||||
## 更新方法:
|
||||
|
||||
1、checkout 最新 2.0.3 代码
|
||||
1、checkout 最新 2.0.4 代码
|
||||
|
||||
2、删除 node_modules,重新安装依赖包
|
||||
|
||||
|
@ -26,6 +26,7 @@ const config = {
|
||||
],
|
||||
alias: {
|
||||
'@': path.join(__dirname, '..', 'src'),
|
||||
'front_public': '@/index/assets/css/public.scss',
|
||||
'scss_vars': '@/manage/assets/styles/vars.scss',
|
||||
'~src': path.resolve(__dirname, '../src'),
|
||||
'~api': path.resolve(__dirname, '../src/api/index-client'),
|
||||
|
@ -32,6 +32,8 @@ var config = merge(base, {
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.join(__dirname, '..', 'src'),
|
||||
'front_public': '@/index/assets/css/public.scss',
|
||||
'~api': path.resolve(__dirname, '../src/api/index-server'),
|
||||
'~server': path.resolve(__dirname, '../server'),
|
||||
'api-config': path.resolve(__dirname, '../src/api/config-server'),
|
||||
|
12334
package-lock.json
generated
Normal file
12334
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "doracms",
|
||||
"version": "2.0.3",
|
||||
"version": "2.0.4",
|
||||
"description": "基于nodejs,express,vue2 内容管理系统.",
|
||||
"keywords": [
|
||||
"vue",
|
||||
@ -28,6 +28,7 @@
|
||||
"body-parser": "^1.18.2",
|
||||
"compression": "^1.7.1",
|
||||
"connect-mongo": "^1.3.2",
|
||||
"connect-redis": "^3.3.2",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"cross-env": "^5.1.1",
|
||||
"crypto": "0.0.3",
|
||||
@ -51,6 +52,7 @@
|
||||
"nodemailer": "^4.4.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"qiniu": "^7.1.1",
|
||||
"qr-image": "^3.2.0",
|
||||
"serve-favicon": "^2.4.5",
|
||||
"shelljs": "^0.7.8",
|
||||
"shortid": "^2.2.8",
|
||||
@ -114,4 +116,4 @@
|
||||
"engines": {
|
||||
"node": "8.x"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
46
server.js
46
server.js
@ -9,6 +9,7 @@ const favicon = require('serve-favicon')
|
||||
const express = require('express')
|
||||
const session = require('express-session');
|
||||
const MongoStore = require('connect-mongo')(session);
|
||||
const RedisStore = require('connect-redis')(session);
|
||||
const compression = require('compression')
|
||||
const lurCache = require('lru-cache')
|
||||
const ueditor = require("ueditor")
|
||||
@ -96,21 +97,36 @@ app.use(bodyParser.urlencoded({ extended: true }))
|
||||
// cookie 解析中间件
|
||||
app.use(cookieParser(settings.session_secret));
|
||||
// session配置
|
||||
app.use(session({ //session持久化配置
|
||||
secret: settings.encrypt_key,
|
||||
// key: "kvkenskey",
|
||||
cookie: {
|
||||
maxAge: 1000 * 60 * 60 * 24 * 1
|
||||
},
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
store: new MongoStore({
|
||||
db: "session",
|
||||
host: "localhost",
|
||||
port: 27017,
|
||||
url: !isProd ? settings.URL : 'mongodb://' + settings.USERNAME + ':' + settings.PASSWORD + '@' + settings.HOST + ':' + settings.PORT + '/' + settings.DB + ''
|
||||
})
|
||||
}));
|
||||
let sessionConfig = {};
|
||||
if (settings.openRedis) {
|
||||
sessionConfig = {
|
||||
secret: settings.session_secret,
|
||||
store: new RedisStore({
|
||||
port: settings.redis_port,
|
||||
host: settings.redis_host,
|
||||
pass: settings.redis_psd,
|
||||
ttl: 1800 // 过期时间
|
||||
}),
|
||||
resave: true,
|
||||
saveUninitialized: true
|
||||
}
|
||||
} else {
|
||||
sessionConfig = {
|
||||
secret: settings.encrypt_key,
|
||||
cookie: {
|
||||
maxAge: 1000 * 60 * 10
|
||||
},
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
store: new MongoStore({
|
||||
db: "session",
|
||||
host: "localhost",
|
||||
port: 27017,
|
||||
url: !isProd ? settings.URL : 'mongodb://' + settings.USERNAME + ':' + settings.PASSWORD + '@' + settings.HOST + ':' + settings.PORT + '/' + settings.DB + ''
|
||||
})
|
||||
}
|
||||
}
|
||||
app.use(session(sessionConfig));
|
||||
// 鉴权用户
|
||||
app.use(authUser.auth);
|
||||
// 初始化日志目录
|
||||
|
@ -6,7 +6,7 @@ const formidable = require('formidable');
|
||||
const { service, settings, validatorUtil, logUtil, siteFunc } = require('../../../utils');
|
||||
const shortid = require('shortid');
|
||||
const validator = require('validator')
|
||||
|
||||
const _ = require('lodash')
|
||||
function checkFormData(req, res, fields) {
|
||||
let errMsg = '';
|
||||
if (fields._id && !siteFunc.checkCurrentId(fields._id)) {
|
||||
@ -63,9 +63,12 @@ class Content {
|
||||
}
|
||||
|
||||
if (sortby) {
|
||||
for (const item of sortby) {
|
||||
sortObj[item] = -1
|
||||
}
|
||||
// for (const item of sortby) {
|
||||
// sortObj[item] = -1
|
||||
// }
|
||||
delete sortObj.date;
|
||||
sortObj[sortby] = -1;
|
||||
|
||||
}
|
||||
|
||||
if (state) {
|
||||
@ -169,7 +172,7 @@ class Content {
|
||||
content && (content.commentNum = commentNum);
|
||||
// 推荐文章查询
|
||||
const totalContents = await ContentModel.count({});
|
||||
const randomArticles = await ContentModel.find({}, 'stitle sImg').skip(Math.floor(totalContents * Math.random())).limit(4);
|
||||
const randomArticles = await ContentModel.find({}, 'stitle sImg').skip(Math.floor(totalContents * Math.random())).limit(6);
|
||||
res.send({
|
||||
state: 'success',
|
||||
doc: content || {},
|
||||
@ -187,6 +190,33 @@ class Content {
|
||||
}
|
||||
}
|
||||
|
||||
async updateLikeNum(req, res, next) {
|
||||
let targetId = req.query.contentId;
|
||||
let userId = req.session.user._id;
|
||||
try {
|
||||
let oldContent = await ContentModel.findOne({ _id: targetId });
|
||||
if (!_.isEmpty(oldContent) && (oldContent.likeUserIds).indexOf(userId) > -1) {
|
||||
res.send({
|
||||
state: 'error',
|
||||
type: 'ERROR_IN_UPDATE_DATA',
|
||||
message: '不可重复提交',
|
||||
})
|
||||
} else {
|
||||
let newContent = await ContentModel.findOneAndUpdate({ _id: targetId }, { '$inc': { 'likeNum': 1 }, '$push': { 'likeUserIds': userId } });
|
||||
res.send({
|
||||
state: 'success',
|
||||
likeNum: newContent.likeNum + 1
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.send({
|
||||
state: 'error',
|
||||
type: 'ERROR_IN_SAVE_DATA',
|
||||
message: '更新数据失败:' + error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async addContent(req, res, next) {
|
||||
const form = new formidable.IncomingForm();
|
||||
form.parse(req, async (err, fields, files) => {
|
||||
@ -216,7 +246,8 @@ class Content {
|
||||
isTop: fields.isTop,
|
||||
from: fields.from,
|
||||
discription: fields.discription,
|
||||
comments: fields.comments
|
||||
comments: fields.comments,
|
||||
likeUserIds: []
|
||||
}
|
||||
|
||||
const newContent = new ContentModel(groupObj);
|
||||
|
@ -183,12 +183,10 @@ class Message {
|
||||
message: errMsg,
|
||||
})
|
||||
}
|
||||
let contentIdArr = [];
|
||||
|
||||
for (let i = 0; i < targetIds.length; i++) {
|
||||
let msgObj = await MessageModel.findOne({ _id: targetIds[i] });
|
||||
if (msgObj && contentIdArr.indexOf(msgObj.contentId) == -1) {
|
||||
// 避免重复删除
|
||||
contentIdArr.push(msgObj.contentId);
|
||||
if (msgObj) {
|
||||
await ContentModel.findOneAndUpdate({ _id: msgObj.contentId }, { '$inc': { 'commentNum': -1 } })
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class User {
|
||||
queryObj.userName = { $regex: reKey }
|
||||
}
|
||||
|
||||
const Users = await UserModel.find(queryObj, { password: 0}).sort({ date: -1 }).skip(Number(pageSize) * (Number(current) - 1)).limit(Number(pageSize));
|
||||
const Users = await UserModel.find(queryObj, { password: 0 }).sort({ date: -1 }).skip(Number(pageSize) * (Number(current) - 1)).limit(Number(pageSize));
|
||||
const totalItems = await UserModel.count(queryObj);
|
||||
res.send({
|
||||
state: 'success',
|
||||
@ -113,10 +113,12 @@ class User {
|
||||
email: fields.email,
|
||||
logo: fields.logo,
|
||||
phoneNum: fields.phoneNum || '',
|
||||
password: service.encrypt(fields.password, settings.encrypt_key),
|
||||
confirm: fields.confirm,
|
||||
group: fields.group
|
||||
}
|
||||
if (fields.password) {
|
||||
userObj.password = service.encrypt(fields.password, settings.encrypt_key);
|
||||
}
|
||||
const item_id = fields._id;
|
||||
|
||||
try {
|
||||
|
@ -14,7 +14,7 @@ var AdminUser = require('./AdminUser');
|
||||
var ContentSchema = new Schema({
|
||||
_id: {
|
||||
type: String,
|
||||
|
||||
|
||||
'default': shortid.generate
|
||||
},
|
||||
title: String,
|
||||
@ -35,7 +35,7 @@ var ContentSchema = new Schema({
|
||||
comments: String,
|
||||
commentNum: { type: Number, default: 0 }, // 评论数
|
||||
likeNum: { type: Number, default: 0 }, // 喜欢数
|
||||
likeUserIds: String, // 喜欢该文章的用户ID集合
|
||||
likeUserIds: [{ type: String, default: [] }], // 喜欢该文章的用户ID集合
|
||||
from: { type: String, default: '1' } // 来源 1为原创 2为转载
|
||||
|
||||
});
|
||||
@ -48,7 +48,7 @@ ContentSchema.path('date').get(function (v) {
|
||||
return moment(v).startOf('hour').fromNow();
|
||||
});
|
||||
ContentSchema.path('updateDate').get(function (v) {
|
||||
return moment(v).format("YYYY-MM-DD HH:mm");
|
||||
return moment(v).format("YYYY-MM-DD");
|
||||
});
|
||||
|
||||
var Content = mongoose.model("Content", ContentSchema);
|
||||
|
@ -15,6 +15,7 @@ const authUser = require('../../utils/middleware/authUser');
|
||||
|
||||
const { AdminUser, ContentCategory, Content, ContentTag, User, Message, SystemConfig, UserNotify, Ads } = require('../lib/controller');
|
||||
const _ = require('lodash');
|
||||
const qr = require('qr-image')
|
||||
|
||||
function checkUserSession(req, res, next) {
|
||||
if (!_.isEmpty(req.session.user)) {
|
||||
@ -55,6 +56,22 @@ router.get('/content/getSimpleListByParams', (req, res, next) => { req.query.sta
|
||||
// 查询文档详情
|
||||
router.get('/content/getContent', Content.getOneContent)
|
||||
|
||||
// 更新喜欢文档
|
||||
router.get('/content/updateLikeNum', checkUserSession, Content.updateLikeNum)
|
||||
|
||||
//文章二维码生成
|
||||
router.get('/qrImg', (req, res, next) => {
|
||||
let detailLink = req.query.detailLink;
|
||||
try {
|
||||
let img = qr.image(detailLink, { size: 10 });
|
||||
res.writeHead(200, { 'Content-Type': 'image/png' });
|
||||
img.pipe(res);
|
||||
} catch (e) {
|
||||
res.writeHead(414, { 'Content-Type': 'text/html' });
|
||||
res.end('<h1>414 Request-URI Too Large</h1>');
|
||||
}
|
||||
});
|
||||
|
||||
// 用户登录
|
||||
router.post('/users/doLogin', User.loginAction);
|
||||
|
||||
|
@ -2,7 +2,6 @@ import Vue from 'vue'
|
||||
import { createApp } from './app'
|
||||
import ProgressBar from './index/components/ProgressBar.vue'
|
||||
|
||||
import "./index/assets/base.css"
|
||||
import '../node_modules/element-ui/lib/theme-chalk/index.css'
|
||||
import '../node_modules/element-ui/lib/theme-chalk/display.css';
|
||||
import '../node_modules/font-awesome/css/font-awesome.min.css'
|
||||
@ -22,9 +21,6 @@ router.beforeResolve((to, from, next) => {
|
||||
const matched = router.getMatchedComponents(to)
|
||||
const prevMatched = router.getMatchedComponents(from)
|
||||
|
||||
// [a, b]
|
||||
// [a, b, c, d]
|
||||
// => [c, d]
|
||||
let diffed = false
|
||||
const activated = matched.filter((c, i) => diffed || (diffed = prevMatched[i] !== c))
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<style lang="scss">
|
||||
|
||||
@import "~front_public";
|
||||
</style>
|
||||
<template>
|
||||
<div id="app">
|
||||
|
@ -1,171 +0,0 @@
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: #ffffff;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
color: rgb(51, 51, 51);
|
||||
font-family: -apple-system, SF UI Text, Arial, PingFang SC, Hiragino Sans GB, Microsoft YaHei, WenQuanYi Micro Hei, sans-serif;
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
a:link,
|
||||
a:active,
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #409EFF
|
||||
}
|
||||
|
||||
.content-main a:link,
|
||||
.content-main a:active,
|
||||
.content-main a:visited {
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.h1,
|
||||
.h2,
|
||||
.h3,
|
||||
.h4,
|
||||
.h5,
|
||||
.h6,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
padding: 15px;
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
color: #657b83;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
overflow: auto;
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
}
|
||||
|
||||
.contentContainer {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.content-item:last-child {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.normaltitle,
|
||||
.catetitle {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.normaltitle span {
|
||||
background-color: #409EFF;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 2px 12px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.catetitle {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
margin: 0 auto;
|
||||
padding-top: 6%;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.login-form .submit-btn {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.login-form .login-container {
|
||||
background-clip: padding-box;
|
||||
padding: 25px 35px 10px 35px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, .1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.login-form .login-container .title {
|
||||
margin: 0px auto 40px auto;
|
||||
text-align: center;
|
||||
color: #505458;
|
||||
}
|
||||
|
||||
.login-form .login-container.remember {
|
||||
margin: 0px 0px 35px 0px;
|
||||
}
|
||||
|
||||
@media screen and (max-width:768px) {
|
||||
.header .header-main {
|
||||
padding: 5px 0 !important;
|
||||
}
|
||||
.header .header-main .header-logo {
|
||||
width: 150px !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.header .header-main .header-nav {
|
||||
border-left: none !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.footer .sitemap {
|
||||
display: none !important;
|
||||
}
|
||||
.content-item {
|
||||
padding-bottom: 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width:1200px) {
|
||||
.search-pannel {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
69
src/index/assets/css/_adminLogin.scss
Normal file
69
src/index/assets/css/_adminLogin.scss
Normal file
@ -0,0 +1,69 @@
|
||||
.admin-logo-title {
|
||||
h3 {
|
||||
color: #99a9bf;
|
||||
font-size: 35px;
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-login-form {
|
||||
margin: 0 auto;
|
||||
margin-top: 70px;
|
||||
margin-bottom: 100px;
|
||||
input {
|
||||
border-top-right-radius: 4px !important;
|
||||
border-bottom-right-radius: 4px !important;
|
||||
}
|
||||
.el-input-group__prepend {
|
||||
padding: 0 10px;
|
||||
}
|
||||
.submit-btn {
|
||||
text-align: center;
|
||||
.el-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.imageCode {
|
||||
width: 8rem;
|
||||
height: 2rem;
|
||||
float: right;
|
||||
}
|
||||
.login-container {
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
background-clip: padding-box;
|
||||
background: transparent;
|
||||
border: 1px solid #eaeaea;
|
||||
box-shadow: 0 0 20px #cac6c6;
|
||||
h3 {
|
||||
margin: 0;
|
||||
border-bottom: 1px solid #e9eaec;
|
||||
padding: 14px 16px;
|
||||
line-height: 1;
|
||||
font-weight: 500;
|
||||
i {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.loginForm {
|
||||
padding: 14px 16px;
|
||||
}
|
||||
.el-form-item {
|
||||
margin-bottom: 15px;
|
||||
.el-form-item__error {
|
||||
left: 2rem;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
margin: 0px auto 40px auto;
|
||||
text-align: center;
|
||||
color: #505458;
|
||||
}
|
||||
.remember {
|
||||
margin: 0px 0px 35px 0px;
|
||||
}
|
||||
}
|
||||
}
|
20
src/index/assets/css/_backToTop.scss
Normal file
20
src/index/assets/css/_backToTop.scss
Normal file
@ -0,0 +1,20 @@
|
||||
// 回到顶部组件
|
||||
.page-component-up {
|
||||
background-color: #fff;
|
||||
position: fixed;
|
||||
right: 50px;
|
||||
bottom: 150px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.12);
|
||||
i {
|
||||
color: $color-primary;
|
||||
display: block;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
23
src/index/assets/css/_catesMenu.scss
Normal file
23
src/index/assets/css/_catesMenu.scss
Normal file
@ -0,0 +1,23 @@
|
||||
// 右侧分类
|
||||
.catesMenu {
|
||||
font-size: 14px;
|
||||
.parent-name {
|
||||
font-weight: 700;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding-left: 30px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.cate-list {
|
||||
padding-left: 40px;
|
||||
.active a:link,
|
||||
.active a:visited {
|
||||
color: #3ca5f6;
|
||||
}
|
||||
}
|
||||
.cate-list li {
|
||||
font-weight: normal;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
32
src/index/assets/css/_contentAds.scss
Normal file
32
src/index/assets/css/_contentAds.scss
Normal file
@ -0,0 +1,32 @@
|
||||
// 轮播图
|
||||
.content-ads {
|
||||
.el-carousel__item h3 {
|
||||
color: #475669;
|
||||
font-size: 18px;
|
||||
opacity: 0.75;
|
||||
margin: 0;
|
||||
}
|
||||
.el-carousel__item:nth-child(2n) {
|
||||
background-color: #99a9bf;
|
||||
}
|
||||
.el-carousel__item:nth-child(2n + 1) {
|
||||
background-color: #d3dce6;
|
||||
}
|
||||
.img-pannel {
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.text-pannel ul li {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.case-title {
|
||||
color: #b4bccc;
|
||||
margin: 15px auto;
|
||||
font-size: 13px;
|
||||
}
|
||||
.case-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
17
src/index/assets/css/_footer.scss
Normal file
17
src/index/assets/css/_footer.scss
Normal file
@ -0,0 +1,17 @@
|
||||
.footer {
|
||||
font-size: 14px;
|
||||
padding: 35px 0;
|
||||
color: #5f676f;
|
||||
background: #2d3237;
|
||||
ul {
|
||||
li {
|
||||
text-align: center;
|
||||
line-height: 35px;
|
||||
padding: 0 10px;
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #76818c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
159
src/index/assets/css/_header.scss
Normal file
159
src/index/assets/css/_header.scss
Normal file
@ -0,0 +1,159 @@
|
||||
// header组件
|
||||
.drop-menu {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
background: #fff;
|
||||
-webkit-box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.1);
|
||||
.header-main {
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
.header-logo {
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #333333;
|
||||
height: 62px;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
img {
|
||||
max-height: 38px;
|
||||
width: auto;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
.header-nav {
|
||||
font-size: 15px;
|
||||
float: left;
|
||||
width: 100%;
|
||||
.el-dropdown {
|
||||
font-size: 15px;
|
||||
color: #333333;
|
||||
}
|
||||
ul {
|
||||
li {
|
||||
display: inline-block;
|
||||
a {
|
||||
padding: 0 20px;
|
||||
line-height: 62px;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
li.active {
|
||||
a:link,
|
||||
a:visited {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.right-pannel {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
.toggle-menu,
|
||||
.toggle-search {
|
||||
color: #aaaaaa;
|
||||
font-size: 18px;
|
||||
padding-left: 0.6rem;
|
||||
padding-right: 0.6rem;
|
||||
border: none;
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
.toggle-search {
|
||||
float: right;
|
||||
}
|
||||
} // loginPannle
|
||||
.login-pannel {
|
||||
float: right;
|
||||
text-align: right;
|
||||
ul {
|
||||
li {
|
||||
cursor: pointer;
|
||||
color: $color-primary;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
i {
|
||||
font-size: 12px;
|
||||
}
|
||||
.logo {
|
||||
width: 1.8rem;
|
||||
height: 1.8rem;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
img {
|
||||
width: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.login-txt {
|
||||
a:first-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // searchPannel
|
||||
.search-pannel {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin-top: 5px;
|
||||
text-align: right;
|
||||
.input-area {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
i {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
font-weight: 700px;
|
||||
color: #cccccc;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 14px;
|
||||
font-size: 20px;
|
||||
}
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
background: #fff;
|
||||
border-left: 1px solid #eee;
|
||||
border-right: 1px solid #eee;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
vertical-align: top;
|
||||
-webkit-transition: all 0.3s ease-out 0s;
|
||||
-o-transition: all 0.3s ease-out 0s;
|
||||
transition: all 0.3s ease-out 0s;
|
||||
input {
|
||||
border: none;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
.input-area.active {
|
||||
width: 184px;
|
||||
-webkit-transition: all 0.3s ease-out 0s;
|
||||
-o-transition: all 0.3s ease-out 0s;
|
||||
transition: all 0.3s ease-out 0s;
|
||||
input {
|
||||
width: 155px;
|
||||
padding: 0 10px;
|
||||
-webkit-transition: all 0.3s ease-out 0s;
|
||||
-o-transition: all 0.3s ease-out 0s;
|
||||
transition: all 0.3s ease-out 0s;
|
||||
}
|
||||
}
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
46
src/index/assets/css/_hotContent.scss
Normal file
46
src/index/assets/css/_hotContent.scss
Normal file
@ -0,0 +1,46 @@
|
||||
// 热门话题
|
||||
|
||||
// 近期文档
|
||||
.hot-content-list {
|
||||
.content-list {
|
||||
text-align: left;
|
||||
ul {
|
||||
li {
|
||||
font-size: 14px;
|
||||
padding: 0 0 0.75rem 1rem;
|
||||
position: relative;
|
||||
.triangle {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-color: #fff #fff #fff #cccccc;
|
||||
-webkit-transform-origin: 25% center;
|
||||
transform-origin: 25% center;
|
||||
border-width: 4px;
|
||||
}
|
||||
.con {
|
||||
-webkit-transition: opacity 0.5s ease-in;
|
||||
transition: opacity 0.5s ease-in;
|
||||
.title {
|
||||
display: block;
|
||||
}
|
||||
.time {
|
||||
padding-top: 3px;
|
||||
display: inline-block;
|
||||
color: #a4abb1;
|
||||
}
|
||||
}
|
||||
.con a:link,
|
||||
.con a:visited {
|
||||
color: #666666;
|
||||
}
|
||||
.con a:hover {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
121
src/index/assets/css/_messageBox.scss
Normal file
121
src/index/assets/css/_messageBox.scss
Normal file
@ -0,0 +1,121 @@
|
||||
// 留言组件
|
||||
.content-message,
|
||||
.content-message-list {
|
||||
padding: 0 !important;
|
||||
h3 {
|
||||
padding: 0;
|
||||
border: none;
|
||||
font-size: 18px;
|
||||
margin: 30px 0 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.content-message {
|
||||
.give-message {
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.el-form-item__content {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.el-textarea__inner {
|
||||
border-color: #efefef !important;
|
||||
border-bottom-color: #f5f5f5 !important;
|
||||
border-width: 1px !important;
|
||||
}
|
||||
.el-form-item__error {
|
||||
padding-top: 20px;
|
||||
text-align: right;
|
||||
right: 100px;
|
||||
}
|
||||
.user-notice {
|
||||
float: left;
|
||||
font-size: 13px;
|
||||
a:link,
|
||||
a:visited {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
.send-content {
|
||||
// margin-bottom: 10px;
|
||||
}
|
||||
.send-button {
|
||||
padding: 5px 15px;
|
||||
text-align: right;
|
||||
background: #fbfbfb;
|
||||
border: 1px solid #efefef;
|
||||
border-top: 0;
|
||||
-webkit-border-bottom-left-radius: 2px;
|
||||
border-bottom-left-radius: 2px;
|
||||
-webkit-border-bottom-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-message-list {
|
||||
ul {
|
||||
li {
|
||||
border-top: 1px solid #efefef;
|
||||
padding: 15px 0 24px;
|
||||
font-size: 14px;
|
||||
.user-logo {
|
||||
img {
|
||||
width: 82%;
|
||||
min-height: 2rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.user-content {
|
||||
position: relative;
|
||||
color: #666666;
|
||||
padding-left: 15px;
|
||||
word-break: break-all;
|
||||
.reply {
|
||||
position: absolute;
|
||||
display: none;
|
||||
bottom: -20px;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.reply-message {
|
||||
margin-top: 30px;
|
||||
padding-left: 25px;
|
||||
.el-form-item {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 5px;
|
||||
text-align: right;
|
||||
.el-form-item__error {
|
||||
right: 100px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-name {
|
||||
margin: 0px 0 0px 15px;
|
||||
color: $color-primary;
|
||||
.name {
|
||||
display: inline-block;
|
||||
}
|
||||
.time {
|
||||
font-size: 11px;
|
||||
display: inline-block;
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
}
|
||||
li:hover {
|
||||
margin: 0 -30px;
|
||||
padding: 15px 30px 24px;
|
||||
background: #fafafa;
|
||||
-webkit-transition: all 0.3s ease-out 0s;
|
||||
-o-transition: all 0.3s ease-out 0s;
|
||||
transition: all 0.3s ease-out 0s;
|
||||
.reply {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
src/index/assets/css/_mixin.scss
Normal file
27
src/index/assets/css/_mixin.scss
Normal file
@ -0,0 +1,27 @@
|
||||
$divide:10;
|
||||
$pswWidth:375;
|
||||
$ppr:375/$divide/1; //定义单位,以iphone6为标准
|
||||
@mixin font-dpr($font-size) {
|
||||
font-size: #{$font-size / $ppr}rem;
|
||||
}
|
||||
|
||||
@mixin renderRem($property, $values...) {
|
||||
$max: length($values);
|
||||
$remValues: '';
|
||||
@for $i from 1 through $max {
|
||||
$newValue: nth($values, $i);
|
||||
$value: '';
|
||||
@if $newValue==auto {
|
||||
$value: $newValue;
|
||||
$remValues: #{$remValues + $value};
|
||||
}
|
||||
@else {
|
||||
$value: $newValue * $divide / $pswWidth;
|
||||
$remValues: #{$remValues + $value}rem;
|
||||
}
|
||||
@if $i < $max {
|
||||
$remValues:#{$remValues + " "}
|
||||
}
|
||||
}
|
||||
#{$property}:$remValues;
|
||||
}
|
5
src/index/assets/css/_pagonation.scss
Normal file
5
src/index/assets/css/_pagonation.scss
Normal file
@ -0,0 +1,5 @@
|
||||
// 分页组件
|
||||
.content-pagination {
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
}
|
18
src/index/assets/css/_pannelbox.scss
Normal file
18
src/index/assets/css/_pannelbox.scss
Normal file
@ -0,0 +1,18 @@
|
||||
// 公共模块-pannelbox
|
||||
.pannel-box {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.pannel-title {
|
||||
margin: 0 0 10px;
|
||||
padding: 1px 0 1px 7px;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
border-left: 3px solid #3ca5f6;
|
||||
}
|
||||
|
||||
.pannel-footer {
|
||||
clear: both;
|
||||
}
|
13
src/index/assets/css/_progress.scss
Normal file
13
src/index/assets/css/_progress.scss
Normal file
@ -0,0 +1,13 @@
|
||||
// 进度条
|
||||
.progress {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 2px;
|
||||
width: 0%;
|
||||
transition: width 0.2s, opacity 0.4s;
|
||||
opacity: 1;
|
||||
background-color: #efc14e;
|
||||
z-index: 999999;
|
||||
}
|
18
src/index/assets/css/_randomArticls.scss
Normal file
18
src/index/assets/css/_randomArticls.scss
Normal file
@ -0,0 +1,18 @@
|
||||
// 随机文档
|
||||
.random-articls {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 25px;
|
||||
.contentImg {
|
||||
height: 8rem;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.title {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
text-align: left;
|
||||
padding: 0px;
|
||||
min-height: 52px;
|
||||
line-height: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
29
src/index/assets/css/_recContent.scss
Normal file
29
src/index/assets/css/_recContent.scss
Normal file
@ -0,0 +1,29 @@
|
||||
// 推荐文档
|
||||
.rec-content-list {
|
||||
margin-bottom: 30px;
|
||||
.content-list {
|
||||
text-align: left;
|
||||
padding-top: 5px;
|
||||
.hot-li {
|
||||
margin: 0 0 10px;
|
||||
display: inline-block;
|
||||
.contentImg {
|
||||
height: 4.7rem;
|
||||
display: block;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-size: 12px;
|
||||
word-break: break-all;
|
||||
line-height: 16px;
|
||||
display: inline-block;
|
||||
height: 45px;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
48
src/index/assets/css/_recentContent.scss
Normal file
48
src/index/assets/css/_recentContent.scss
Normal file
@ -0,0 +1,48 @@
|
||||
// 近期文档
|
||||
.recent-content-list {
|
||||
margin-bottom: 30px;
|
||||
.content-list {
|
||||
text-align: left;
|
||||
ul {
|
||||
.hot-li:last-child {
|
||||
border: none;
|
||||
}
|
||||
li {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 7px 0 8px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
img {
|
||||
width: 100%;
|
||||
vertical-align: top;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.right-text {
|
||||
position: relative;
|
||||
line-height: 1.4;
|
||||
.title {
|
||||
font-size: 13px;
|
||||
height: 2.3rem;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
word-break: break-all;
|
||||
}
|
||||
span {
|
||||
display: block;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
line-height: 14px; // margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.recent-content-list.fixed {
|
||||
position: fixed;
|
||||
top: 62px;
|
||||
}
|
56
src/index/assets/css/_ucLeftMenu.scss
Normal file
56
src/index/assets/css/_ucLeftMenu.scss
Normal file
@ -0,0 +1,56 @@
|
||||
.user-menu-options {
|
||||
margin-top: 2rem;
|
||||
text-align: left;
|
||||
li {
|
||||
position: relative;
|
||||
margin-bottom: 1px;
|
||||
background: #eee;
|
||||
cursor: pointer;
|
||||
a {
|
||||
color: #999;
|
||||
padding: 4px 0;
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
display: block;
|
||||
i {
|
||||
padding: 0 15px;
|
||||
font-size: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
span.label {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
padding-left: 15px;
|
||||
}
|
||||
span.fa {
|
||||
font-size: 20px;
|
||||
padding: 0 15px;
|
||||
line-height: 30px;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
span.fa-asterisk {
|
||||
font-size: 15px;
|
||||
}
|
||||
.fa-angle-right {
|
||||
right: 0;
|
||||
top: 6px;
|
||||
font-size: 26px;
|
||||
position: absolute;
|
||||
opacity: .6;
|
||||
}
|
||||
}
|
||||
a:hover {
|
||||
color: #444;
|
||||
background: #ddd;
|
||||
}
|
||||
}
|
||||
li.active {
|
||||
span.label {
|
||||
font-weight: 700;
|
||||
}
|
||||
span.fa {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
47
src/index/assets/css/_userBar.scss
Normal file
47
src/index/assets/css/_userBar.scss
Normal file
@ -0,0 +1,47 @@
|
||||
// 公共模块-userbar
|
||||
.user-bar {
|
||||
background-color: #444444;
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
padding: 10px 0;
|
||||
text-align: left; // box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .05);
|
||||
transition: all 0.2s;
|
||||
-webkit-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
.bar-items {
|
||||
ul {
|
||||
li {
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
padding: 6px 10px 6px 28px;
|
||||
margin-left: 10px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
i {
|
||||
position: absolute;
|
||||
left: 11px;
|
||||
top: 11px;
|
||||
}
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
li.active {
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #ffffff;
|
||||
}
|
||||
background-color: $color-primary;
|
||||
}
|
||||
li.active:hover {
|
||||
background-color: $color-primary;
|
||||
}
|
||||
li:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
613
src/index/assets/css/public.scss
Normal file
613
src/index/assets/css/public.scss
Normal file
@ -0,0 +1,613 @@
|
||||
@import "mixin.scss";
|
||||
$color-primary: #409EFF; //主色调
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
color: rgb(51, 51, 51);
|
||||
line-height: 1.8;
|
||||
background: #f5f5f5;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Ubuntu, Helvetica Neue, Helvetica, Arial, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Source Han Sans CN, sans-serif;
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
a:link,
|
||||
a:active,
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: $color-primary
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.h1,
|
||||
.h2,
|
||||
.h3,
|
||||
.h4,
|
||||
.h5,
|
||||
.h6,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
color: #657b83;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
overflow: auto;
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.el-dropdown-menu {
|
||||
li {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.prop-wechat {
|
||||
text-align: center;
|
||||
h5 {
|
||||
line-height: 25px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
img {
|
||||
width: 10rem;
|
||||
height: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
@import 'pannelbox.scss';
|
||||
@import 'header.scss';
|
||||
@import 'footer.scss';
|
||||
@import 'backToTop.scss';
|
||||
@import 'catesMenu.scss';
|
||||
@import 'contentAds.scss';
|
||||
@import 'hotContent.scss';
|
||||
@import 'recContent.scss';
|
||||
@import 'messageBox.scss';
|
||||
@import 'pagonation.scss';
|
||||
@import 'progress.scss';
|
||||
@import 'randomArticls.scss';
|
||||
@import 'userBar.scss';
|
||||
@import 'recentContent.scss';
|
||||
@import 'ucLeftMenu.scss';
|
||||
@import 'adminLogin.scss';
|
||||
.contentContainer {
|
||||
padding-top: 62px;
|
||||
.mainbody {
|
||||
padding: 20px 0px 20px;
|
||||
.login-form,
|
||||
.user-info,
|
||||
.login-main {
|
||||
.el-form-item {
|
||||
.el-input .el-input__inner,
|
||||
.el-textarea .el-textarea__inner {
|
||||
border: 2px solid #dddddd;
|
||||
}
|
||||
.el-form-item__label {
|
||||
line-height: 22px;
|
||||
padding-bottom: 8px !important;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
} // 文档列表
|
||||
.content-list {
|
||||
.main-list {
|
||||
padding-bottom: 10px;
|
||||
background-color: #fff;
|
||||
.column-wrap {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 20px;
|
||||
color: #303030;
|
||||
padding: 0 15px;
|
||||
margin-bottom: 15px;
|
||||
h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 18px;
|
||||
line-height: 48px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
}
|
||||
}
|
||||
.cate-pannle-menu {
|
||||
position: relative;
|
||||
padding: 0 15px;
|
||||
.el-menu--horizontal {
|
||||
border-bottom: solid 1px #efefef;
|
||||
.el-menu-item {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0;
|
||||
margin-right: 31px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.el-menu-item.is-active {
|
||||
color: #3ca5f6;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
.article-list {
|
||||
padding: 0 15px;
|
||||
margin: 0 0 20px;
|
||||
list-style: none;
|
||||
.post-b {
|
||||
border-bottom: 1px solid #efefef; // margin-bottom: 25px;
|
||||
padding: 20px 0px;
|
||||
.content-item {
|
||||
.post-angle {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
height: 21px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #f63756;
|
||||
line-height: 24px;
|
||||
padding: 0 10px;
|
||||
z-index: 101;
|
||||
top: 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.post-angle:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 21px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 6px solid #cd213d;
|
||||
border-left: 10px solid transparent;
|
||||
}
|
||||
.contentImg {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
img {
|
||||
width: 100%;
|
||||
min-height: 6rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
height: auto;
|
||||
display: block;
|
||||
position: relative;
|
||||
.content-cate {
|
||||
position: absolute;
|
||||
top: 0.4rem;
|
||||
left: 0.4rem;
|
||||
display: block;
|
||||
padding: 0 0.5rem;
|
||||
color: #fff;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
font-size: 0.6rem;
|
||||
text-align: center;
|
||||
border-radius: 1rem;
|
||||
z-index: 11;
|
||||
}
|
||||
}
|
||||
.discription {
|
||||
text-align: left; // min-height: 152px;
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
word-break: break-all;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.dis {
|
||||
margin: 10px 0;
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
}
|
||||
.post-meta {
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #3ca5f6;
|
||||
}
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
li {
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
color: #999999;
|
||||
margin: 0px 10px 0px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-item:last-child {
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
.post-b:last-child {
|
||||
border: none;
|
||||
}
|
||||
.post-b:hover {
|
||||
margin: 0 -15px;
|
||||
padding: 20px 15px;
|
||||
background: #fafafa;
|
||||
-webkit-transition: all 0.3s ease 0s;
|
||||
-o-transition: all 0.3s ease 0s;
|
||||
transition: all 0.3s ease 0s;
|
||||
}
|
||||
}
|
||||
}
|
||||
.main-right {}
|
||||
} // 缩略图效果
|
||||
.contentImg {
|
||||
overflow: hidden;
|
||||
-webkit-transition: -webkit-box-shadow .3s ease 0s;
|
||||
transition: -webkit-box-shadow .3s ease 0s;
|
||||
-o-transition: box-shadow .3s ease 0s;
|
||||
transition: box-shadow .3s ease 0s;
|
||||
transition: box-shadow .3s ease 0s, -webkit-box-shadow .3s ease 0s;
|
||||
img {
|
||||
-webkit-transition: all 0.3s ease-out 0s;
|
||||
-o-transition: all 0.3s ease-out 0s;
|
||||
transition: all 0.3s ease-out 0s;
|
||||
}
|
||||
img:hover {
|
||||
-webkit-transform: scale(1.03);
|
||||
-ms-transform: scale(1.03);
|
||||
transform: scale(1.03);
|
||||
-webkit-transition: all .3s ease-out 0s;
|
||||
-o-transition: all .3s ease-out 0s;
|
||||
transition: all .3s ease-out 0s;
|
||||
}
|
||||
}
|
||||
.contentImg:hover {
|
||||
-webkit-box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.3);
|
||||
-webkit-transition: -webkit-box-shadow .3s ease 0s;
|
||||
transition: -webkit-box-shadow .3s ease 0s;
|
||||
-o-transition: box-shadow .3s ease 0s;
|
||||
transition: box-shadow .3s ease 0s;
|
||||
transition: box-shadow .3s ease 0s, -webkit-box-shadow .3s ease 0s;
|
||||
}
|
||||
} // 文档详情
|
||||
.content-detail {
|
||||
color: #3f3f3f;
|
||||
.hentry {
|
||||
background: #fff;
|
||||
padding: 30px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.from {
|
||||
color: #fa5555;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
height: auto;
|
||||
}
|
||||
.content-title {
|
||||
margin-top: 0;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
}
|
||||
.content-author {
|
||||
color: #969696;
|
||||
ul {
|
||||
li.author-name {
|
||||
color: $color-primary;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-main {
|
||||
font-size: 15px;
|
||||
}
|
||||
.meta-bottom {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.share-group {
|
||||
text-align: right;
|
||||
ul {
|
||||
li {
|
||||
padding: 0 10px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
i {
|
||||
font-size: 18px;
|
||||
}
|
||||
.fa-qq {
|
||||
color: #4296d3;
|
||||
}
|
||||
.fa-wechat {
|
||||
color: #00bb29;
|
||||
}
|
||||
.fa-weibo {
|
||||
color: #e05244;
|
||||
}
|
||||
.fa-heart {
|
||||
color: #cccccc;
|
||||
}
|
||||
.fa-heart:hover {
|
||||
color: #e05244;
|
||||
}
|
||||
}
|
||||
li.like {
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
color: #cccccc;
|
||||
border-right: 1px solid #ccc;
|
||||
padding-right: 20px;
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
li.more {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // 案例展示
|
||||
.case-box {
|
||||
.case-list {
|
||||
background-color: #ffffff;
|
||||
padding: 20px;
|
||||
h3 {
|
||||
margin: 5px 10px 20px;
|
||||
font-size: 15px;
|
||||
color: #878d99;
|
||||
.el-button--mini {
|
||||
padding: 5px 8px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
min-height: 400px;
|
||||
} // 用户中心
|
||||
.user-center {
|
||||
.user-message {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.user-info {
|
||||
background-color: #ffffff;
|
||||
.basic-info {
|
||||
padding: 30px;
|
||||
.left-pannel {
|
||||
padding: 0 30px;
|
||||
.user-left-menu {
|
||||
.user-logo {
|
||||
margin: 0 auto;
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
margin-top: 4rem;
|
||||
.el-form-item {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
span {
|
||||
font-weight: 700;
|
||||
color: #555;
|
||||
text-decoration: none !important;
|
||||
font-size: 18px;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: $color-primary;
|
||||
}
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
.avatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.right-pannel {
|
||||
.top-bar {
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
font-weight: 700;
|
||||
color: #555;
|
||||
margin-bottom: 15px;
|
||||
i {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-button {
|
||||
padding: 12px 50px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
} // 登录注册
|
||||
.login-main {
|
||||
background-color: #fff;
|
||||
.login-box {
|
||||
width: 50%;
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
padding: 20px 0px 100px;
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
position: relative;
|
||||
}
|
||||
.title::after {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: -15px;
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
margin-left: -10px;
|
||||
background: #999;
|
||||
content: '';
|
||||
}
|
||||
.el-button {
|
||||
width: 100%;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width:768px) {
|
||||
.header {
|
||||
.header-main {
|
||||
padding: 5px 0 !important;
|
||||
.header-logo {
|
||||
/* width: 150px !important; */
|
||||
margin-top: .5rem;
|
||||
a {
|
||||
height: auto !important;
|
||||
img {
|
||||
width: 100% !important;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.header-nav {
|
||||
border-left: none !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-item {
|
||||
.row-list {
|
||||
margin: 0 !important;
|
||||
.el-col {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.contentImg {
|
||||
max-height: 6rem;
|
||||
}
|
||||
}
|
||||
.discription {
|
||||
margin-top: 10px !important;
|
||||
line-height: 1.5;
|
||||
h2 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.post-meta {
|
||||
position: relative !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.main-list {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.footer {
|
||||
display: none !important;
|
||||
}
|
||||
.page-component-up {
|
||||
display: none !important;
|
||||
}
|
||||
.contentContainer {
|
||||
.mainbody {
|
||||
padding: 10px 0px 10px;
|
||||
.main-list {
|
||||
.cate-pannle-menu {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-detail {
|
||||
.hentry {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.meta-bottom {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 25px;
|
||||
.meta-tags {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.share-group {
|
||||
text-align: center !important;
|
||||
}
|
||||
.random-articls {
|
||||
.contentImg {
|
||||
height: 5rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.login-main {
|
||||
.login-box {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
<div class="content-ads" v-if="ads.data">
|
||||
<div class="img-pannel" v-if="ads.data.type == '1'">
|
||||
<div v-if="ads.data.items.length == 1">
|
||||
<a :href="ads.data.items[0].link" target="_blank"><img style="border-radius:4px;border: 1px solid #f0f0f0;" :src="ads.data.items[0].sImg" :alt="ads.data.items[0].alt" /></a>
|
||||
<a :href="ads.data.items[0].link" target="_blank"><img :src="ads.data.items[0].sImg" :alt="ads.data.items[0].alt" /></a>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- 轮播展示 -->
|
||||
@ -17,7 +17,8 @@
|
||||
</div>
|
||||
<!-- 橱窗展示 -->
|
||||
<div v-else>
|
||||
<el-col class="case-item" :xs="12" :sm="8" :md="6" :lg="6" :xl="6" v-for="(item,index) in ads.data.items" :key="item._id">
|
||||
<el-row :gutter="20">
|
||||
<el-col class="case-item" :xs="12" :sm="8" :md="6" :lg="6" :xl="6" v-for="(item,index) in ads.data.items" :key="item._id">
|
||||
<el-card :body-style="{ padding: '0px' }">
|
||||
<div style="padding:14px 14px 5px;text-align:center;cursor:point">
|
||||
<a :href="item.link" target="_blank"><img :src="item.sImg" class="image" :alt="item.alt"></a>
|
||||
@ -25,6 +26,7 @@
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -69,38 +71,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.el-carousel__item h3 {
|
||||
color: #475669;
|
||||
font-size: 18px;
|
||||
opacity: 0.75;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n) {
|
||||
background-color: #99a9bf;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n + 1) {
|
||||
background-color: #d3dce6;
|
||||
}
|
||||
|
||||
.img-pannel {
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-pannel ul li {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.case-title {
|
||||
color: #b4bccc;
|
||||
margin: 15px auto;
|
||||
font-size: 13px;
|
||||
}
|
||||
.case-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
46
src/index/components/BackTop.vue
Normal file
46
src/index/components/BackTop.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="page-component-up" :style="{display:showScroll?'block':'none'}" @click="scrollToTop(300)"><i class="el-icon-caret-top"></i></div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "BackTop",
|
||||
data() {
|
||||
return {
|
||||
showScroll: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
scrollToTop(scrollDuration) {
|
||||
const scrollHeight = window.scrollY,
|
||||
scrollStep = Math.PI / (scrollDuration / 15),
|
||||
cosParameter = scrollHeight / 2;
|
||||
let scrollCount = 0,
|
||||
scrollMargin,
|
||||
scrollInterval = setInterval(function() {
|
||||
if (window.scrollY != 0) {
|
||||
scrollCount = scrollCount + 1;
|
||||
scrollMargin =
|
||||
cosParameter - cosParameter * Math.cos(scrollCount * scrollStep);
|
||||
window.scrollTo(0, scrollHeight - scrollMargin);
|
||||
} else {
|
||||
clearInterval(scrollInterval);
|
||||
}
|
||||
}, 15);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
window.onscroll = () => {
|
||||
let t = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
if (t >= 400) {
|
||||
this.showScroll = true;
|
||||
} else {
|
||||
this.showScroll = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
@ -52,25 +52,5 @@
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.catesMenu {
|
||||
font-size: 14px;
|
||||
.parent-name {
|
||||
font-weight: 700;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding-left: 30px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.cate-list {
|
||||
padding-left: 40px;
|
||||
.active a:link,.active a:visited{
|
||||
color: #3ca5f6;
|
||||
}
|
||||
}
|
||||
.cate-list li {
|
||||
font-weight: normal;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -19,51 +19,28 @@
|
||||
<script>
|
||||
let packageJson = require("../../../package.json");
|
||||
|
||||
import {
|
||||
mapGetters,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
export default {
|
||||
name: 'Footer',
|
||||
async asyncData({
|
||||
store,
|
||||
route
|
||||
}, config = {
|
||||
|
||||
}) {
|
||||
const {
|
||||
params: path
|
||||
} = route
|
||||
const base = {
|
||||
...config,
|
||||
path,
|
||||
}
|
||||
await store.dispatch('global/footerConfigs/getSystemConfig')
|
||||
},
|
||||
serverCacheKey: props => 'footer',
|
||||
computed: {
|
||||
...mapGetters({
|
||||
systemConfig: 'global/footerConfigs/getSystemConfig'
|
||||
}),
|
||||
codeVersion() {
|
||||
return "DoraCMS " + packageJson.version
|
||||
}
|
||||
name: "Footer",
|
||||
async asyncData({ store, route }, config = {}) {
|
||||
const { params: path } = route;
|
||||
const base = {
|
||||
...config,
|
||||
path
|
||||
};
|
||||
await store.dispatch("global/footerConfigs/getSystemConfig");
|
||||
},
|
||||
serverCacheKey: props => "footer",
|
||||
computed: {
|
||||
...mapGetters({
|
||||
systemConfig: "global/footerConfigs/getSystemConfig"
|
||||
}),
|
||||
codeVersion() {
|
||||
return "DoraCMS " + packageJson.version;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.footer {
|
||||
font-size: 14px;
|
||||
background: #ffffff;
|
||||
padding: 20px 0;
|
||||
|
||||
ul {
|
||||
li {
|
||||
text-align: center;
|
||||
line-height: 35px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,18 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<PannelBox title="推荐文章" className="hot-content-list">
|
||||
<PannelBox title="热门文章" className="hot-content-list">
|
||||
<div class="content-list">
|
||||
<ul>
|
||||
<li class="hot-li" v-for="(item,index) in hotItems" :key="item._id">
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading">
|
||||
<img :src="item.sImg" :alt="item.title" />
|
||||
</router-link>
|
||||
<div class="left-area">
|
||||
<router-link class="title" :to="'/details/'+item._id+'.html'">{{item.title}}</router-link>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul>
|
||||
<li :key='index' v-for="(item,index) in hotItems">
|
||||
<span class="triangle"></span>
|
||||
<div class="con">
|
||||
<router-link class="title" :to="'/details/'+item._id+'.html'">{{item.title}}</router-link>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</PannelBox>
|
||||
</div>
|
||||
</template>
|
||||
@ -36,33 +34,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.hot-content-list {
|
||||
margin-bottom: 30px;
|
||||
.content-list {
|
||||
text-align: left;
|
||||
ul {
|
||||
.hot-li:last-child {
|
||||
border: none;
|
||||
}
|
||||
li {
|
||||
position: relative;
|
||||
padding: 10px 0;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
height: 2rem;
|
||||
img {
|
||||
width: 3rem;
|
||||
height: 2rem;
|
||||
position: absolute;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
.left-area {
|
||||
padding-left: 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -1,275 +1,236 @@
|
||||
<template>
|
||||
<PannelBox title="评论" className="content-message">
|
||||
<div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24">
|
||||
<div class="give-message">
|
||||
<el-form :model="msgFormState.formData" :rules="rules" ref="ruleForm" label-width="0px" class="demo-ruleForm">
|
||||
<el-form-item class="send-content" prop="content">
|
||||
<el-input @focus="changeReplyState(false)" type="textarea" :autosize="{ minRows: 2, maxRows: 4}" placeholder="请输入内容" v-model="msgFormState.formData.content">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="send-button">
|
||||
<div class="user-notice">
|
||||
<div v-if="loginState.logined">
|
||||
你好,
|
||||
<span style="color: #409EFF">{{loginState.userInfo.userName}} !</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<router-link to="/users/login">登录</router-link> 后参与评论
|
||||
</div>
|
||||
</div>
|
||||
<el-button type="primary" round @click="submitForm('ruleForm')">提交评论</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="(item,index) in userMessageList" :key="index">
|
||||
<el-row>
|
||||
<el-col :xs="3" :sm="3" :md="2" :lg="1">
|
||||
<div class="user-logo">
|
||||
<div v-if="item.utype == '1'">
|
||||
<img :src="item.adminAuthor.logo" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<img :src="item.author.logo" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="21" :sm="21" :md="22" :lg="23">
|
||||
<div class="user-name">
|
||||
<div class="name" v-if="item.utype == '1'">
|
||||
{{item.adminAuthor.userName}}
|
||||
<span title="管理员" style="color: #409EFF;font-size: 12px;">[
|
||||
<i class="el-icon-star-on"></i> 管理员]</span>
|
||||
</div>
|
||||
<div class="name" v-else>{{item.author.userName}}</div>
|
||||
<span class="time">{{item.date}}</span>
|
||||
<i @click="replyMsg(item)" class="fa fa-reply"></i>
|
||||
</div>
|
||||
<div class="user-content">
|
||||
<div v-if="item.replyAuthor">
|
||||
<span style="color: #409EFF">{{'@'+item.replyAuthor.userName}}</span> {{item.content}}
|
||||
</div>
|
||||
<div v-else-if="item.adminReplyAuthor">
|
||||
<span style="color: #409EFF">{{'@'+item.adminReplyAuthor.userName}}</span> {{item.content}}
|
||||
</div>
|
||||
<div v-else>
|
||||
{{item.content}}
|
||||
</div>
|
||||
<el-collapse-transition>
|
||||
<div class="reply-message" v-if="msgFormState.reply && replyObj._id == item._id">
|
||||
<el-form :model="msgFormState.formData" :rules="replyRules" ref="replyRuleForm" label-width="0px" class="demo-ruleForm">
|
||||
<el-form-item class="send-content" prop="replyContent">
|
||||
<el-input @focus="changeReplyState(true)" :autofocus="true" type="textarea" :autosize="{ minRows: 2, maxRows: 4}" placeholder="请输入内容" v-model="msgFormState.formData.replyContent">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="send-button">
|
||||
<el-button type="primary" round @click="submitForm('replyRuleForm')" size="small">回复</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</li>
|
||||
</ul>
|
||||
</PannelBox>
|
||||
<div>
|
||||
<PannelBox title="发表评论" className="content-message">
|
||||
<div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24">
|
||||
<div class="give-message">
|
||||
<el-form :model="msgFormState.formData" :rules="rules" ref="ruleForm" label-width="0px" class="demo-ruleForm">
|
||||
<el-form-item class="send-content" prop="content">
|
||||
<el-input @focus="changeReplyState(false)" type="textarea" :autosize="{ minRows: 4, maxRows: 8}" placeholder="请输入内容" v-model="msgFormState.formData.content">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="send-button">
|
||||
<div class="user-notice">
|
||||
<div v-if="loginState.logined">
|
||||
你好,
|
||||
<span style="color: #409EFF">{{loginState.userInfo.userName}} !</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<router-link to="/users/login">登录</router-link> 后参与评论
|
||||
</div>
|
||||
</div>
|
||||
<el-button type="primary" size="small" @click="submitForm('ruleForm')">发表</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</PannelBox>
|
||||
<PannelBox :title="messagelistTitle" className="content-message-list" v-if="userMessageList.length > 0">
|
||||
<ul>
|
||||
<li v-for="(item,index) in userMessageList" :key="index">
|
||||
<el-row>
|
||||
<el-col :xs="3" :sm="3" :md="2" :lg="2" :xl="2">
|
||||
<div class="user-logo">
|
||||
<div v-if="item.utype == '1'">
|
||||
<img :src="item.adminAuthor.logo" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<img :src="item.author.logo" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="21" :sm="21" :md="22" :lg="22" :xl="22">
|
||||
<div class="user-name">
|
||||
<div class="name" v-if="item.utype == '1'">
|
||||
{{item.adminAuthor.userName}}
|
||||
<span title="管理员" style="color: #409EFF;font-size: 12px;">[
|
||||
<i class="el-icon-star-on"></i> 管理员]</span>
|
||||
</div>
|
||||
<div class="name" v-else>{{item.author.userName}}</div>
|
||||
<span class="time">{{item.date}}</span>
|
||||
</div>
|
||||
<div class="user-content">
|
||||
<div v-if="item.replyAuthor">
|
||||
<span style="color: #409EFF">{{'@'+item.replyAuthor.userName}}</span> {{item.content}}
|
||||
</div>
|
||||
<div v-else-if="item.adminReplyAuthor">
|
||||
<span style="color: #409EFF">{{'@'+item.adminReplyAuthor.userName}}</span> {{item.content}}
|
||||
</div>
|
||||
<div v-else>
|
||||
{{item.content}}
|
||||
</div>
|
||||
<el-button size="mini" class="reply" type="text" @click="replyMsg(item)">回复</el-button>
|
||||
</div>
|
||||
<el-collapse-transition>
|
||||
<div class="reply-message" v-if="msgFormState.reply && replyObj._id == item._id">
|
||||
<el-form :model="msgFormState.formData" :rules="replyRules" ref="replyRuleForm" label-width="0px" class="demo-ruleForm">
|
||||
<el-form-item class="send-content" prop="replyContent">
|
||||
<el-input @focus="changeReplyState(true)" :autofocus="true" type="textarea" :autosize="{ minRows: 4, maxRows: 8}" :placeholder="replyPlaceholder" v-model="msgFormState.formData.replyContent">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="send-button">
|
||||
<el-button type="primary" @click="submitForm('replyRuleForm')" size="small">回复</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</li>
|
||||
</ul>
|
||||
</PannelBox>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex'
|
||||
import api from '~api'
|
||||
import _ from 'lodash'
|
||||
import PannelBox from './PannelBox.vue'
|
||||
import { mapGetters } from "vuex";
|
||||
import api from "~api";
|
||||
import _ from "lodash";
|
||||
import PannelBox from "./PannelBox.vue";
|
||||
export default {
|
||||
name: 'Message',
|
||||
data() {
|
||||
return {
|
||||
replyObj: {},
|
||||
rules: {
|
||||
content: [{
|
||||
required: true,
|
||||
message: '请填写评论',
|
||||
trigger: 'blur'
|
||||
}, {
|
||||
min: 5,
|
||||
max: 200,
|
||||
message: '请输入5-200个字符',
|
||||
trigger: 'blur'
|
||||
}]
|
||||
},
|
||||
replyRules: {
|
||||
replyContent: [{
|
||||
required: true,
|
||||
message: '请填写回复',
|
||||
trigger: 'blur'
|
||||
}, {
|
||||
min: 5,
|
||||
max: 200,
|
||||
message: '请输入5-200个字符',
|
||||
trigger: 'blur'
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
userMessageList: Array,
|
||||
contentId: String
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
msgFormState: 'global/message/getMessageForm',
|
||||
loginState: 'frontend/user/getSessionState'
|
||||
})
|
||||
},
|
||||
components: {
|
||||
PannelBox
|
||||
},
|
||||
methods: {
|
||||
changeReplyState(state) {
|
||||
if (!state) this.replyObj = {};
|
||||
this.$store.dispatch('global/message/messageform', { reply: state })
|
||||
},
|
||||
replyMsg(item) {
|
||||
this.replyObj = item;
|
||||
let currentMsgAuthor = !_.isEmpty(item.author) ? item.author : item.adminAuthor;
|
||||
let formParams = { replyAuthor: '', adminReplyAuthor: '', relationMsgId: item._id, replyContent: "@" + currentMsgAuthor.userName + " " };
|
||||
if(!_.isEmpty(item.author)){
|
||||
formParams.replyAuthor = currentMsgAuthor._id;
|
||||
}else{
|
||||
formParams.adminReplyAuthor = currentMsgAuthor._id
|
||||
}
|
||||
this.$store.dispatch('global/message/messageform', { reply: true, formData: formParams})
|
||||
},
|
||||
submitForm(formName) {
|
||||
if (!this.loginState.logined) {
|
||||
this.$router.push('/users/login');
|
||||
} else {
|
||||
let targetForm = this.msgFormState.reply ? this.$refs[formName][0] : this.$refs[formName];
|
||||
targetForm.validate((valid) => {
|
||||
if (valid) {
|
||||
let params = this.msgFormState.formData;
|
||||
if (this.msgFormState.formData.replyContent) {
|
||||
let currentMsgAuthor = !_.isEmpty(this.replyObj.author) ? this.replyObj.author : this.replyObj.adminAuthor;
|
||||
let oldContent = this.msgFormState.formData.replyContent;
|
||||
params.content = oldContent.replace("@" + currentMsgAuthor.userName + " ", "");
|
||||
} else {
|
||||
params['replyAuthor'] = '';
|
||||
params['relationMsgId'] = '';
|
||||
params['replyContent'] = '';
|
||||
}
|
||||
params.contentId = this.contentId;
|
||||
api.post('message/post', params).then((result) => {
|
||||
if (result.data.state === 'success') {
|
||||
this.$store.dispatch('global/message/getUserMessageList', {
|
||||
contentId: this.contentId
|
||||
})
|
||||
this.$message({
|
||||
message: '发布成功',
|
||||
type: 'success'
|
||||
});
|
||||
this.$store.dispatch('global/message/messageform', {
|
||||
reply: false,
|
||||
formData: {
|
||||
content: '',
|
||||
replyContent: ''
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
this.$message({
|
||||
message: result.data.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$message.error(err.response.data.error)
|
||||
})
|
||||
} else {
|
||||
console.log('error submit!!');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
name: "Message",
|
||||
data() {
|
||||
return {
|
||||
replyObj: {},
|
||||
rules: {
|
||||
content: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写评论",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 5,
|
||||
max: 200,
|
||||
message: "请输入5-200个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
},
|
||||
replyRules: {
|
||||
replyContent: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写回复",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 5,
|
||||
max: 200,
|
||||
message: "请输入5-200个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
},
|
||||
replyPlaceholder: "请输入回复内容"
|
||||
};
|
||||
},
|
||||
props: {
|
||||
userMessageList: Array,
|
||||
contentId: String
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
msgFormState: "global/message/getMessageForm",
|
||||
loginState: "frontend/user/getSessionState"
|
||||
}),
|
||||
messagelistTitle() {
|
||||
return "评论列表 (" + this.userMessageList.length + "条)";
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
components: {
|
||||
PannelBox
|
||||
},
|
||||
methods: {
|
||||
changeReplyState(state) {
|
||||
if (!state) this.replyObj = {};
|
||||
this.$store.dispatch("global/message/messageform", { reply: state });
|
||||
},
|
||||
replyMsg(item) {
|
||||
this.replyObj = item;
|
||||
let currentMsgAuthor = !_.isEmpty(item.author)
|
||||
? item.author
|
||||
: item.adminAuthor;
|
||||
this.replyPlaceholder = "回复 " + currentMsgAuthor.userName;
|
||||
let formParams = {
|
||||
replyAuthor: "",
|
||||
adminReplyAuthor: "",
|
||||
relationMsgId: item._id
|
||||
// replyContent: "@" + currentMsgAuthor.userName + " "
|
||||
};
|
||||
if (!_.isEmpty(item.author)) {
|
||||
formParams.replyAuthor = currentMsgAuthor._id;
|
||||
} else {
|
||||
formParams.adminReplyAuthor = currentMsgAuthor._id;
|
||||
}
|
||||
this.$store.dispatch("global/message/messageform", {
|
||||
reply: true,
|
||||
formData: formParams
|
||||
});
|
||||
},
|
||||
submitForm(formName) {
|
||||
if (!this.loginState.logined) {
|
||||
this.$router.push("/users/login");
|
||||
} else {
|
||||
let targetForm = this.msgFormState.reply
|
||||
? this.$refs[formName][0]
|
||||
: this.$refs[formName];
|
||||
targetForm.validate(valid => {
|
||||
if (valid) {
|
||||
let params = this.msgFormState.formData;
|
||||
if (this.msgFormState.formData.replyContent) {
|
||||
// let currentMsgAuthor = !_.isEmpty(this.replyObj.author)
|
||||
// ? this.replyObj.author
|
||||
// : this.replyObj.adminAuthor;
|
||||
// let oldContent = this.msgFormState.formData.replyContent;
|
||||
params.content = this.msgFormState.formData.replyContent;
|
||||
} else {
|
||||
params["replyAuthor"] = "";
|
||||
params["relationMsgId"] = "";
|
||||
params["replyContent"] = "";
|
||||
}
|
||||
params.contentId = this.contentId;
|
||||
api
|
||||
.post("message/post", params)
|
||||
.then(result => {
|
||||
if (result.data.state === "success") {
|
||||
this.$store.dispatch("global/message/getUserMessageList", {
|
||||
contentId: this.contentId
|
||||
});
|
||||
this.$message({
|
||||
message: "发布成功",
|
||||
type: "success"
|
||||
});
|
||||
this.$store.dispatch("global/message/messageform", {
|
||||
reply: false,
|
||||
formData: {
|
||||
content: "",
|
||||
replyContent: ""
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message({
|
||||
message: result.data.message,
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error(err.response.data.error);
|
||||
});
|
||||
} else {
|
||||
console.log("error submit!!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content-message {
|
||||
|
||||
ul {
|
||||
li {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
padding: 24px 0;
|
||||
font-size: 15px;
|
||||
.user-logo {
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
border-radius: 50%
|
||||
}
|
||||
}
|
||||
.user-content {
|
||||
color: #666666;
|
||||
padding-left: 15px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.user-name {
|
||||
margin: 5px 0 15px 15px;
|
||||
color: #409EFF;
|
||||
|
||||
.name {
|
||||
display: inline-block;
|
||||
}
|
||||
.time {
|
||||
font-size: 11px;
|
||||
display: inline-block;
|
||||
color: #777;
|
||||
}
|
||||
.fa-reply {
|
||||
float: right;
|
||||
color: #D3DCE6;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.give-message {
|
||||
padding-top: 15px;
|
||||
.el-form-item__content {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.user-notice {
|
||||
float: left;
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #409EFF
|
||||
}
|
||||
}
|
||||
.send-content {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.send-button {
|
||||
margin-top: 5px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-message {
|
||||
margin-top: 15px;
|
||||
padding-left: 25px;
|
||||
.el-form-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -37,8 +37,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content-pagination {
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -6,24 +6,12 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'PannelBox',
|
||||
props: ['title', 'className']
|
||||
}
|
||||
export default {
|
||||
name: "PannelBox",
|
||||
props: ["title", "className"]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.pannel-box {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
.pannel-title {
|
||||
font-size: 14px;
|
||||
color: #969696;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.pannel-footer {
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
@ -88,16 +88,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.progress {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 2px;
|
||||
width: 0%;
|
||||
transition: width 0.2s, opacity 0.4s;
|
||||
opacity: 1;
|
||||
background-color: #efc14e;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,38 +1,33 @@
|
||||
<template>
|
||||
|
||||
<div class="random-articls" v-if="articles && articles.length > 0">
|
||||
<el-row class="grid-content bg-purple-light" :gutter="15">
|
||||
<el-col :xs="12" :sm="12" :md="6" :lg="6" v-for="(item,index) in articles" :key="index">
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading"><img :src="item.sImg" :alt="item.title" /></router-link>
|
||||
<span class="title">{{item.stitle}}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<PannelBox title="相关推荐" className="content-message">
|
||||
<div class="random-articls" v-if="articles && articles.length > 0">
|
||||
<el-row class="grid-content bg-purple-light" :gutter="15">
|
||||
<el-col :xs="12" :sm="12" :md="8" :lg="8" :xl="8" v-for="(item,index) in articles" :key="index">
|
||||
<div class="contentImg">
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading"><img :src="item.sImg" :alt="item.title" /></router-link>
|
||||
</div>
|
||||
<span class="title">
|
||||
<router-link class="title" :to="'/details/'+item._id+'.html'">{{item.stitle?item.stitle:item.title}}</router-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</PannelBox>
|
||||
</template>
|
||||
<script>
|
||||
let packageJson = require("../../../package.json");
|
||||
|
||||
import PannelBox from "./PannelBox.vue";
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
export default {
|
||||
props: {
|
||||
articles: Array
|
||||
},
|
||||
components: {
|
||||
PannelBox
|
||||
},
|
||||
computed: {}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.random-articls {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 25px;
|
||||
img {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
.title {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,70 +1,45 @@
|
||||
<template>
|
||||
<PannelBox title="近期文章" className="recent-content-list">
|
||||
<PannelBox title="最新文章" :className="recentClassName">
|
||||
<div class="content-list">
|
||||
<ul>
|
||||
<li :key='index' v-for="(item,index) in recentItems">
|
||||
<span class="triangle"></span>
|
||||
<div class="con">
|
||||
<router-link class="title" :to="'/details/'+item._id+'.html'">{{item.title}}</router-link>
|
||||
<span class="time">{{item.updateDate}}</span>
|
||||
</div>
|
||||
<li class="hot-li" v-for="item in recentItems" :key="item._id">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="9" :sm="9" :md="9" :lg="9" :xl="9">
|
||||
<div class="contentImg">
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading">
|
||||
<img :src="item.sImg" :alt="item.title" />
|
||||
</router-link>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="15" :sm="15" :md="15" :lg="15" :xl="15">
|
||||
<div class="right-text">
|
||||
<router-link class="title" :to="'/details/'+item._id+'.html'">{{item.title}}</router-link>
|
||||
<span>{{item.updateDate}}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</PannelBox>
|
||||
</template>
|
||||
<script>
|
||||
import PannelBox from './PannelBox.vue'
|
||||
export default {
|
||||
name: 'recentlyContents',
|
||||
data() {
|
||||
return {
|
||||
loadingState: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
PannelBox
|
||||
},
|
||||
props: ['recentItems']
|
||||
}
|
||||
import PannelBox from "./PannelBox.vue";
|
||||
export default {
|
||||
name: "recentlyContents",
|
||||
data() {
|
||||
return {
|
||||
loadingState: true,
|
||||
recentClassName: "recent-content-list"
|
||||
};
|
||||
},
|
||||
components: {
|
||||
PannelBox
|
||||
},
|
||||
props: ["recentItems"]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.recent-content-list {
|
||||
.content-list {
|
||||
text-align: left;
|
||||
ul {
|
||||
li {
|
||||
font-size: 14px;
|
||||
padding: 0 0 .75rem 1rem;
|
||||
position: relative;
|
||||
color: #333;
|
||||
.triangle {
|
||||
position: absolute;
|
||||
top: .3rem;
|
||||
left: .3rem;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-color: #fff #fff #fff #4285f4;
|
||||
-webkit-transform-origin: 25% center;
|
||||
transform-origin: 25% center;
|
||||
border-width: 4px;
|
||||
}
|
||||
.con {
|
||||
-webkit-transition: opacity .5s ease-in;
|
||||
transition: opacity .5s ease-in;
|
||||
.title{
|
||||
display: block;
|
||||
}
|
||||
.time {
|
||||
padding-top: 3px;
|
||||
display: inline-block;
|
||||
color: #a4abb1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
40
src/index/components/RecommendContents.vue
Normal file
40
src/index/components/RecommendContents.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div>
|
||||
<PannelBox title="推荐文章" className="rec-content-list">
|
||||
<div class="content-list">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12" class="hot-li" v-for="(item,index) in reclist" :key="item._id">
|
||||
<div class="contentImg">
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading">
|
||||
<img :src="item.sImg" :alt="item.title" />
|
||||
</router-link>
|
||||
</div>
|
||||
<router-link class="title" :to="'/details/'+item._id+'.html'">{{item.title | cutWords(25)}}</router-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</PannelBox>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import PannelBox from "./PannelBox.vue";
|
||||
export default {
|
||||
name: "recommendContents",
|
||||
data() {
|
||||
return {
|
||||
loadingState: true
|
||||
};
|
||||
},
|
||||
props: ["reclist", "typeId"],
|
||||
components: {
|
||||
PannelBox
|
||||
},
|
||||
serverCacheKey: props => {
|
||||
return `recItem-${props.typeId}`;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
@ -1,60 +1,27 @@
|
||||
<template>
|
||||
<div class="user-bar">
|
||||
<el-row :gutter="0" class="header-main">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12">
|
||||
<div class="bar-items">
|
||||
<ul>
|
||||
<li :class="{active : $route.fullPath == '/users/center'}">
|
||||
<router-link to="/users/center">个人资料</router-link>
|
||||
</li>
|
||||
<li :class="{active : $route.fullPath == '/users/messages'}">
|
||||
<router-link to="/users/messages">消息管理</router-link>
|
||||
</li>
|
||||
<li :class="{active : $route.fullPath == '/users/replies'}">
|
||||
<router-link to="/users/replies">参与话题</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<div class="grid-content bg-purple">
|
||||
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="bar-items">
|
||||
<ul>
|
||||
<!-- <li :class="{active : $route.fullPath == '/users/center'}">
|
||||
<router-link to="/users/center">个人资料</router-link>
|
||||
</li> -->
|
||||
<li :class="{active : $route.fullPath == '/users/messages'}">
|
||||
<router-link to="/users/messages"><i aria-hidden="true" class="fa fa-comment"></i> 消息管理</router-link>
|
||||
</li>
|
||||
<li :class="{active : $route.fullPath == '/users/replies'}">
|
||||
<router-link to="/users/replies"><i aria-hidden="true" class="fa fa-file-text"></i> 参与话题</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mapGetters } from "vuex";
|
||||
export default {
|
||||
name: 'UserBar'
|
||||
}
|
||||
|
||||
name: "UserBar"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.user-bar {
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .05);
|
||||
transition: all .2s;
|
||||
-webkit-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
.bar-items {
|
||||
ul {
|
||||
li {
|
||||
padding: 12px 20px 12px 0;
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
}
|
||||
li.active a {
|
||||
color: #409EFF
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
47
src/index/components/UserCenterLeftMenu.vue
Normal file
47
src/index/components/UserCenterLeftMenu.vue
Normal file
@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div class="user-left-menu">
|
||||
<div class="user-logo" v-if="userInfo">
|
||||
<el-upload class="avatar-uploader" action="/system/upload?type=images" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
|
||||
<img v-if="userInfo.logo" :src="userInfo.logo" class="avatar">
|
||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||
</el-upload>
|
||||
<span>{{userInfo.userName}}</span>
|
||||
</div>
|
||||
<ul class="user-menu-options">
|
||||
<li :class="{active : $route.fullPath == '/users/center'}" @click="getToUserPage('center')"><a><span class="fa fa-user"></span><span class="label">基本资料</span><i class="fa fa-angle-right"></i></a></li>
|
||||
<li :class="{active : $route.fullPath == '/users/password'}" @click="getToUserPage('password')"><a><span class="fa fa-asterisk"></span><span class="label">修改密码</span><i class="fa fa-angle-right"></i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "user-left-menu",
|
||||
props: ["userInfo"],
|
||||
methods: {
|
||||
handleAvatarSuccess(res, file) {
|
||||
this.$emit("setNewlogo", res);
|
||||
},
|
||||
beforeAvatarUpload(file) {
|
||||
const isJPG = file.type === "image/jpeg";
|
||||
const isPNG = file.type === "image/png";
|
||||
const isGIF = file.type === "image/gif";
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isJPG && !isPNG && !isGIF) {
|
||||
this.$message.error("上传头像图片只能是 JPG,PNG,GIF 格式!");
|
||||
}
|
||||
if (!isLt2M) {
|
||||
this.$message.error("上传头像图片大小不能超过 2MB!");
|
||||
}
|
||||
return (isJPG || isPNG || isGIF) && isLt2M;
|
||||
},
|
||||
getToUserPage(page) {
|
||||
this.$router.push("/users/" + page);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="danger" plain round icon="el-icon-delete" @click="deleteMessage(scope.$index, dataList)"></el-button>
|
||||
<el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteMessage(scope.$index, dataList)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -12,41 +12,39 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '~api'
|
||||
import api from "~api";
|
||||
export default {
|
||||
props: {
|
||||
dataList: Array,
|
||||
userInfo: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
multipleSelection: [],
|
||||
}
|
||||
},
|
||||
props: {
|
||||
dataList: Array,
|
||||
userInfo: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
multipleSelection: []
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.replyList {
|
||||
|
||||
li {
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
padding-left: 15px;
|
||||
border-bottom: 1px dashed #ededed;
|
||||
blockquote {
|
||||
color: #475669;
|
||||
}
|
||||
time {
|
||||
float: right;
|
||||
color: #8492A6;
|
||||
font-size: 12px;
|
||||
}
|
||||
li {
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
padding-left: 15px;
|
||||
border-bottom: 1px dashed #ededed;
|
||||
blockquote {
|
||||
color: #475669;
|
||||
}
|
||||
time {
|
||||
float: right;
|
||||
color: #8492a6;
|
||||
font-size: 12px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,40 +1,89 @@
|
||||
<template>
|
||||
<header class="header">
|
||||
<el-row :gutter="0" class="header-main">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12">
|
||||
<el-row :gutter="10" class="grid-content bg-purple-light">
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14">
|
||||
<el-row :gutter="15" class="grid-content bg-purple-light">
|
||||
<el-col :xs="24" :sm="4" :md="4" :lg="4">
|
||||
<div class="header-logo">
|
||||
<router-link :to="{path: '/'}">
|
||||
<img src="../../assets/logo.png" />
|
||||
</router-link>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :xs="7" :sm="0" :md="0" :lg="0" :xl="0">
|
||||
<el-dropdown trigger="click">
|
||||
<el-button class="toggle-menu" size="mini" plain><i class="fa fa-align-justify"></i></el-button>
|
||||
<el-dropdown-menu class="drop-menu" slot="dropdown">
|
||||
<el-dropdown-item v-for="(nav,index) in headerNav" :key="index" v-once>
|
||||
<router-link :to="{path: '/'+nav.defaultUrl+ '___'+nav._id}">{{nav.name}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided v-if="loginState.logined && loginState.userInfo">
|
||||
<div>{{loginState.userInfo.userName}}
|
||||
<el-button type="text" @click="logOut">退出</el-button>
|
||||
</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided v-else>
|
||||
<div>
|
||||
<el-button type="text" @click="login">登录</el-button>
|
||||
<el-button type="text" @click="regUser">注册</el-button>
|
||||
</div>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-col>
|
||||
<el-col :xs="10" :sm="24" :md="24" :lg="24" :xl="24">
|
||||
<div class="header-logo">
|
||||
<router-link :to="{path: '/'}">
|
||||
<img src="../../assets/logo.png" />
|
||||
</router-link>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="7" :sm="0" :md="0" :lg="0" :xl="0">
|
||||
<el-popover
|
||||
ref="popoverSearch"
|
||||
placement="bottom"
|
||||
width="100%"
|
||||
v-model="visibleSearchPannel">
|
||||
<div>
|
||||
<el-input size="small" placeholder="请输入关键字" v-model="searchkey" suffix-icon="el-icon-search" @keyup.enter.native="searchResult">
|
||||
</el-input>
|
||||
</div>
|
||||
</el-popover>
|
||||
<el-button v-popover:popoverSearch class="toggle-search" size="mini" plain><i class="fa fa-search"></i></el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="13" :md="13" :lg="13">
|
||||
<el-col :xs="0" :sm="12" :md="12" :lg="12">
|
||||
<nav class="header-nav">
|
||||
<el-row type="flex">
|
||||
<el-col v-for="(nav,index) in headerNav" :key="index" v-once>
|
||||
<router-link :to="{path: '/'+nav.defaultUrl+ '___'+nav._id}">{{nav.name}}</router-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ul>
|
||||
<li :class="{active : $route.fullPath == '/'}"><router-link :to="{path: '/'}">首页</router-link></li>
|
||||
<li>
|
||||
<el-dropdown size="medium">
|
||||
<span class="el-dropdown-link">
|
||||
文章分类<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-for="(nav,index) in headerNav" :key="index" v-once>
|
||||
<router-link :to="{path: '/'+nav.defaultUrl+ '___'+nav._id}">{{nav.name}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</li>
|
||||
<li :class="{active : $route.fullPath == '/cmscase___SkCL09aCb'}"><router-link :to="{path: '/cmscase___SkCL09aCb'}">应用案例</router-link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</el-col>
|
||||
<el-col :xs="0" :sm="7" :md="7" :lg="7">
|
||||
<el-col :xs="0" :sm="8" :md="8" :lg="8" class="right-pannel">
|
||||
<el-row>
|
||||
<el-col :xs="0" :sm="14" :md="14" :lg="14" hidden-xs-only>
|
||||
<SearchBox />
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="10">
|
||||
<LoginPannel/>
|
||||
<el-col :xs="24" :sm="10" :md="10" :lg="10">
|
||||
<LoginPannel ref="loginPannel"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple">
|
||||
|
||||
</div>
|
||||
@ -65,9 +114,15 @@ export default {
|
||||
navs: Array
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
return {
|
||||
visibleSearchPannel: false,
|
||||
searchkey: ""
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
loginState: "frontend/user/getSessionState"
|
||||
}),
|
||||
headerNav() {
|
||||
let fullNav = this.$store.getters["global/category/getHeaderNavList"];
|
||||
let navs = fullNav.data;
|
||||
@ -79,42 +134,25 @@ export default {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
searchResult() {
|
||||
this.visibleSearchPannel = false;
|
||||
this.$router.replace("/search/" + this.searchkey);
|
||||
this.searchkey = "";
|
||||
},
|
||||
login() {
|
||||
this.$router.push("/users/login");
|
||||
},
|
||||
regUser() {
|
||||
this.$router.push("/users/reg");
|
||||
},
|
||||
logOut() {
|
||||
this.$refs.loginPannel.logout();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.header {
|
||||
overflow: hidden;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
|
||||
.header-main {
|
||||
margin: 0 auto;
|
||||
padding: 5px 0px;
|
||||
overflow: hidden;
|
||||
.header-logo {
|
||||
img {
|
||||
max-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
float: left;
|
||||
width: 100%;
|
||||
.el-row {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
.el-col {
|
||||
list-style-type: none;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
a.router-link-active {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -2,20 +2,22 @@
|
||||
<div class="login-pannel">
|
||||
<ul>
|
||||
<li v-if="loginState.logined && loginState.userInfo">
|
||||
<div class="logo"><img :src="loginState.userInfo.logo" alt=""></div>
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
{{loginState.userInfo.userName}}
|
||||
<i class="el-icon-caret-bottom el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="userCenter">用户中心</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="userCenter('messages')">用户中心</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="userCenter('center')">帐号设置</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="logout">退出</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</li>
|
||||
<li class="login-txt" v-else>
|
||||
<el-button type="text" style="color:#878D99;fontSize:13px;" @click="login">登录</el-button>
|
||||
<el-button type="primary" plain round size="mini" @click="regUser">注册</el-button>
|
||||
<el-button type="text" style="color:#878D99;fontSize:15px;" @click="login">登录</el-button>
|
||||
<el-button type="primary" size="small" @click="regUser">注册</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -42,8 +44,8 @@ export default {
|
||||
regUser() {
|
||||
this.$router.push("/users/reg");
|
||||
},
|
||||
userCenter() {
|
||||
this.$router.push("/users/center");
|
||||
userCenter(page) {
|
||||
this.$router.push("/users/" + page);
|
||||
},
|
||||
logout() {
|
||||
api.get("users/logOut").then(result => {
|
||||
@ -68,31 +70,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.login-pannel {
|
||||
float: right;
|
||||
text-align: right;
|
||||
ul {
|
||||
li {
|
||||
color: #409eff;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
i {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.login-txt {
|
||||
a:first-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-dropdown-menu {
|
||||
li {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div class="search-pannel" v-once>
|
||||
<div class="input-area">
|
||||
<el-input @keyup.enter.native="handleIconClick" suffix-icon="el-icon-search" size="small" placeholder="请输入关键字" v-model="searchkey"></el-input>
|
||||
<div class="search-pannel">
|
||||
<div class="input-area" v-bind:class="{ active: activeSearch }">
|
||||
<el-input @keyup.enter.native="handleIconClick" size="small" placeholder="请输入关键字" v-model="searchkey"></el-input>
|
||||
<i class="fa fa-search" @click="showSearchInput"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -11,25 +12,21 @@ export default {
|
||||
name: "searchbox",
|
||||
data() {
|
||||
return {
|
||||
searchkey: ""
|
||||
// readySearch: false
|
||||
searchkey: "",
|
||||
activeSearch: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleIconClick(ev) {
|
||||
this.$router.replace("/search/" + this.searchkey);
|
||||
},
|
||||
showSearchInput() {
|
||||
this.activeSearch = !this.activeSearch;
|
||||
},
|
||||
search(e) {}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.search-pannel {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin-top: 5px;
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -6,6 +6,7 @@ export const AdminLogin = () => import('../views/AdminLogin.vue')
|
||||
export const UserLoginForm = () => import('../views/UserLoginForm.vue')
|
||||
export const UserRegForm = () => import('../views/UserRegForm.vue')
|
||||
export const UserCenter = () => import('../views/UserCenter.vue')
|
||||
export const UserPwd = () => import('../views/UserPwd.vue')
|
||||
export const UserMessage = () => import('../views/UserMessage.vue')
|
||||
export const UserReplies = () => import('../views/UserReplies.vue')
|
||||
export const SiteMap = () => import('../views/SiteMap.vue')
|
||||
|
@ -5,6 +5,7 @@ export const AdminLogin = require('../views/AdminLogin.vue')
|
||||
export const UserLoginForm = require('../views/UserLoginForm.vue')
|
||||
export const UserRegForm = require('../views/UserRegForm.vue')
|
||||
export const UserCenter = require('../views/UserCenter.vue')
|
||||
export const UserPwd = require('../views/UserPwd.vue')
|
||||
export const UserMessage = require('../views/UserMessage.vue')
|
||||
export const UserReplies = require('../views/UserReplies.vue')
|
||||
export const SiteMap = require('../views/SiteMap.vue')
|
||||
@ -16,6 +17,7 @@ AdminLogin.chunkName = 'AdminLogin';
|
||||
UserLoginForm.chunkName = 'UserLoginForm';
|
||||
UserRegForm.chunkName = 'UserRegForm';
|
||||
UserCenter.chunkName = 'UserCenter';
|
||||
UserPwd.chunkName = 'UserPwd';
|
||||
UserMessage.chunkName = 'UserMessage';
|
||||
UserReplies.chunkName = 'UserReplies';
|
||||
SiteMap.chunkName = 'SiteMap';
|
||||
|
@ -2,44 +2,56 @@ import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import Meta from 'vue-meta'
|
||||
|
||||
import { ArticleList, CmsCase, Article, AdminLogin, UserLoginForm, UserRegForm, UserCenter, UserMessage, UserReplies, SiteMap } from 'create-route'
|
||||
import { ArticleList, CmsCase, Article, AdminLogin, UserLoginForm, UserRegForm, UserCenter, UserPwd, UserMessage, UserReplies, SiteMap } from 'create-route'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
Vue.use(Meta)
|
||||
|
||||
const scrollBehavior = to => {
|
||||
const position = {}
|
||||
if (to.hash) {
|
||||
position.selector = to.hash
|
||||
const scrollBehavior = (to, from, savedPosition) => {
|
||||
if (savedPosition) {
|
||||
// savedPosition is only available for popstate navigations.
|
||||
return savedPosition
|
||||
} else {
|
||||
const position = {}
|
||||
// new navigation.
|
||||
// scroll to anchor by returning the selector
|
||||
if (to.hash) {
|
||||
position.selector = to.hash
|
||||
}
|
||||
// check if any matched route config has meta that requires scrolling to top
|
||||
if (to.matched.some(m => m.meta.scrollToTop)) {
|
||||
// cords will be used if no selector is provided,
|
||||
// or if the selector didn't match any element.
|
||||
position.x = 0
|
||||
position.y = 0
|
||||
}
|
||||
// if the returned position is falsy or an empty object,
|
||||
// will retain current scroll position.
|
||||
return position
|
||||
}
|
||||
if (to.matched.some(mm => mm.meta.scrollToTop)) {
|
||||
position.x = 0
|
||||
position.y = 0
|
||||
}
|
||||
return position
|
||||
}
|
||||
|
||||
export function createRouter() {
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
//base: __dirname,
|
||||
// scrollBehavior,
|
||||
scrollBehavior,
|
||||
routes: [
|
||||
{ name: 'index', path: '/', component: ArticleList, meta: { typeId: 'indexPage' } },
|
||||
{ name: 'index', path: '/page/:current(\\d+)?', component: ArticleList, meta: { typeId: 'indexPage' } },
|
||||
{ name: 'index', path: '/', component: ArticleList, meta: { typeId: 'indexPage', scrollToTop: true } },
|
||||
{ name: 'index', path: '/page/:current(\\d+)?', component: ArticleList, meta: { typeId: 'indexPage', scrollToTop: true } },
|
||||
{ name: 'cmscase', path: '/cmscase___:typeId?/:current(\\d+)?', component: CmsCase },
|
||||
{ name: 'category', path: '/:cate1?___:typeId?/:current(\\d+)?', component: ArticleList },
|
||||
{ name: 'category', path: '/:cate0/:cate1?___:typeId?/:current(\\d+)?', component: ArticleList },
|
||||
{ name: 'search', path: '/search/:searchkey/:current(\\d+)?', component: ArticleList, meta: { typeId: 'search' } },
|
||||
{ name: 'article', path: '/details/:id', component: Article, meta: { notKeepAlive: true } },
|
||||
{ name: 'category', path: '/:cate1?___:typeId?/:current(\\d+)?', component: ArticleList, meta: { scrollToTop: true } },
|
||||
{ name: 'category', path: '/:cate0/:cate1?___:typeId?/:current(\\d+)?', component: ArticleList, meta: { scrollToTop: true } },
|
||||
{ name: 'search', path: '/search/:searchkey/:current(\\d+)?', component: ArticleList, meta: { typeId: 'search', scrollToTop: true } },
|
||||
{ name: 'article', path: '/details/:id', component: Article, meta: { notKeepAlive: true, scrollToTop: true } },
|
||||
{ name: 'login', path: '/users/login', component: UserLoginForm },
|
||||
{ name: 'reg', path: '/users/reg', component: UserRegForm },
|
||||
{ name: 'ucenter', path: '/users/center', component: UserCenter },
|
||||
{ name: 'upassword', path: '/users/password', component: UserPwd },
|
||||
{ name: 'umessage', path: '/users/messages', component: UserMessage },
|
||||
{ name: 'uReplies', path: '/users/replies', component: UserReplies },
|
||||
{ name: 'adminlogin', path: '/dr-admin', component: AdminLogin, meta: { typeId: 'adminlogin' } },
|
||||
{ name: 'sitemap', path: '/sitemap.html', component: SiteMap },
|
||||
{ name: 'tagPage', path: '/tag/:tagName/:page(\\d+)?', component: ArticleList, meta: { typeId: 'tags' } }
|
||||
{ name: 'tagPage', path: '/tag/:tagName/:current(\\d+)?', component: ArticleList, meta: { typeId: 'tags', scrollToTop: true } }
|
||||
]
|
||||
})
|
||||
return router;
|
||||
|
@ -13,6 +13,7 @@ const state = () => ({
|
||||
isLoad: false
|
||||
},
|
||||
hotContentList: [],
|
||||
recContentList: [],
|
||||
recentContentList: []
|
||||
})
|
||||
|
||||
@ -65,7 +66,6 @@ const actions = {
|
||||
data
|
||||
} = await api.get('content/getSimpleListByParams', {
|
||||
...config,
|
||||
isTop: 1,
|
||||
sortby: 'clickNum',
|
||||
model: 'simple',
|
||||
cache: true
|
||||
@ -74,6 +74,23 @@ const actions = {
|
||||
commit('receiveHotList', data)
|
||||
}
|
||||
},
|
||||
async ['getRecContentList']({
|
||||
commit,
|
||||
state
|
||||
}, config) {
|
||||
if (state.recContentList.length && config.path === state.lists.path) return
|
||||
const {
|
||||
data
|
||||
} = await api.get('content/getSimpleListByParams', {
|
||||
...config,
|
||||
isTop: 1,
|
||||
model: 'simple',
|
||||
cache: true
|
||||
})
|
||||
if (data.docs && data.state === 'success') {
|
||||
commit('receiveRecList', data)
|
||||
}
|
||||
},
|
||||
async ['getRecentContentList']({
|
||||
commit,
|
||||
state
|
||||
@ -122,6 +139,9 @@ const mutations = {
|
||||
['receiveHotList'](state, data) {
|
||||
state.hotContentList = data.docs
|
||||
},
|
||||
['receiveRecList'](state, data) {
|
||||
state.recContentList = data.docs
|
||||
},
|
||||
['receiveRecentList'](state, data) {
|
||||
state.recentContentList = data.docs
|
||||
}
|
||||
@ -142,6 +162,9 @@ const getters = {
|
||||
['getHotContentList'](state) {
|
||||
return state.hotContentList
|
||||
},
|
||||
['getRecContentList'](state) {
|
||||
return state.recContentList
|
||||
},
|
||||
['getRecentContentList'](state) {
|
||||
return state.recentContentList
|
||||
}
|
||||
|
@ -2,35 +2,42 @@
|
||||
<div class="dr-admin-login">
|
||||
<div class="admin-login-form">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="2" :sm="6" :md="8" :lg="8" :xl="10">
|
||||
<el-col :xs="2" :sm="7" :md="8" :lg="8" :xl="9">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="20" :sm="12" :md="8" :lg="8" :xl="4">
|
||||
<el-col :xs="20" :sm="10" :md="8" :lg="8" :xl="6">
|
||||
<div class="admin-logo-title">
|
||||
<h3>
|
||||
<b style="color:#1D8CE0">Dora</b>CMS</h3>
|
||||
</div>
|
||||
<el-form :model="adminLoginFormData" :rules="rules" ref="ruleForm" label-width="80px" class="demo-ruleForm login-container">
|
||||
<h3 class="pannel-title">
|
||||
<span>管理员登录</span>
|
||||
<div class="login-container">
|
||||
<h3>
|
||||
<span><i class="fa fa-sign-in" aria-hidden="true"></i>欢迎登录</span>
|
||||
</h3>
|
||||
<el-form-item label="用户名" prop="userName">
|
||||
<el-input size="small" v-model="adminLoginFormData.userName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input size="small" type="password" v-model="adminLoginFormData.password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="验证码" prop="imageCode">
|
||||
<el-input size="small" style="width: 30%" type="imageCode" @keyup.enter.native="submitForm('ruleForm')" v-model="adminLoginFormData.imageCode"></el-input>
|
||||
<img :src="imgCodeUrl" class="imageCode" @click="reSetImgCode"/>
|
||||
</el-form-item>
|
||||
<el-form-item class="submit-btn">
|
||||
<el-button size="small" type="primary" @click="submitForm('ruleForm')">登录</el-button>
|
||||
<el-button size="small" @click="resetForm('ruleForm')">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form :model="adminLoginFormData" :rules="rules" ref="ruleForm" label-width="0px" class="loginForm">
|
||||
<el-form-item prop="userName">
|
||||
<el-input size="small" v-model="adminLoginFormData.userName" placeholder="请输入用户名">
|
||||
<template slot="prepend"><i class="fa fa-user"></i></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input size="small" type="password" v-model="adminLoginFormData.password" placeholder="请输入密码">
|
||||
<template slot="prepend"><i class="fa fa-lock"></i></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="imageCode">
|
||||
<el-input size="small" style="width: 40%" type="imageCode" placeholder="图形码" @keyup.enter.native="submitForm('ruleForm')" v-model="adminLoginFormData.imageCode">
|
||||
<template slot="prepend"><i class="fa fa-random"></i></template>
|
||||
</el-input>
|
||||
<img :src="imgCodeUrl" class="imageCode" @click="reSetImgCode"/>
|
||||
</el-form-item>
|
||||
<el-form-item class="submit-btn">
|
||||
<el-button size="small" type="primary" @click="submitForm('ruleForm')">登录</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="2" :sm="6" :md="8" :lg="8" :xl="10">
|
||||
<el-col :xs="2" :sm="7" :md="8" :lg="8" :xl="9">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -133,9 +140,6 @@ export default {
|
||||
this.$refs[formName].resetFields();
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// this.$store.dispatch('simplePage');
|
||||
},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
@ -146,50 +150,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.admin-logo-title {
|
||||
h3 {
|
||||
color: #99a9bf;
|
||||
font-size: 35px;
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-login-form {
|
||||
margin: 0 auto;
|
||||
margin-top: 70px;
|
||||
margin-bottom: 100px;
|
||||
|
||||
.submit-btn {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.imageCode {
|
||||
width: 10rem;
|
||||
height: 2rem;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
background-clip: padding-box; // margin: 180px auto;
|
||||
padding: 25px 35px 10px 35px;
|
||||
background: #fff;
|
||||
border: 1px solid #eaeaea;
|
||||
box-shadow: 0 0 25px #cac6c6;
|
||||
.el-form-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.title {
|
||||
margin: 0px auto 40px auto;
|
||||
text-align: center;
|
||||
color: #505458;
|
||||
}
|
||||
.remember {
|
||||
margin: 0px 0px 35px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,20 +1,19 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="content-detail">
|
||||
<div class="readme">
|
||||
<el-row :gutter="0" class="header-main">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<div class="contentContainer">
|
||||
<div class="mainbody content-detail">
|
||||
<el-row :gutter="0">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12">
|
||||
<el-row :gutter="24">
|
||||
<el-col :xs="24" :sm="17" :md="17" :lg="17">
|
||||
<div>
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14" class="main-details">
|
||||
<el-row :gutter="15">
|
||||
<el-col :xs="24" :sm="17" :md="17" :lg="17" >
|
||||
<div class="hentry">
|
||||
<h2 class="content-title">{{article.doc.title}} <span v-show="article.doc.from == '2'" class="from">[转]</span></h2>
|
||||
<div class="content-author">
|
||||
<ul>
|
||||
<li class="author-name">
|
||||
<el-tag size="mini">{{article.doc.author ? article.doc.author.name:''}}</el-tag>
|
||||
{{article.doc.author ? article.doc.author.name:''}}
|
||||
</li>
|
||||
<li>
|
||||
<span class="dot"> • </span>{{cateName}}
|
||||
@ -29,6 +28,53 @@
|
||||
</div>
|
||||
<div v-html="article.doc.comments" class="content-main">
|
||||
</div>
|
||||
<!-- <div class="meta-tags" v-if="article.doc.tags && article.doc.tags.length>0">
|
||||
<el-button @click="searchByTag(tag.name)" plain v-for="tag in article.doc.tags" size="mini" :key="tag._id">{{tag.name}}</el-button>
|
||||
</div> -->
|
||||
<div class="meta-bottom">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="14" :md="14" :lg="14" :xl="14">
|
||||
<!-- <div class="like"> <el-button type="primary" plain @click="likeIt(article.doc._id)"><i class="fa fa-heart-o"></i> 喜欢 ({{article.doc.likeNum}})</el-button></div> -->
|
||||
<div class="meta-tags" v-if="article.doc.tags && article.doc.tags.length>0">
|
||||
<el-button type="primary" @click="searchByTag(tag.name)" plain v-for="tag in article.doc.tags" size="mini" :key="tag._id">{{tag.name}}</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="10" :md="10" :lg="10" :xl="10">
|
||||
<div class="share-group" v-if="systemConfig.data">
|
||||
<ul>
|
||||
<li class="like">
|
||||
<i class="fa fa-heart" @click="likeIt(article.doc._id)"></i> <span>{{article.doc.likeNum}}</span>
|
||||
</li>
|
||||
<li class="qq" @click="shareToQq(article.doc)">
|
||||
<a><i class="fa fa-qq"></i></a>
|
||||
</li>
|
||||
<el-popover
|
||||
ref="popover1"
|
||||
placement="top-start"
|
||||
width="200"
|
||||
trigger="click"
|
||||
popper-class="prop-wechat"
|
||||
content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。">
|
||||
<template slot-scope="scope">
|
||||
<h5>打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮</h5>
|
||||
<img :src="'/api/qrImg?detailLink='+systemConfig.data[0].siteDomain+'/details/'+article.doc._id+'.html'" :alt="article.doc.title">
|
||||
</template>
|
||||
</el-popover>
|
||||
<li class="wechat">
|
||||
<a v-popover:popover1>
|
||||
<i class="fa fa-wechat"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="weibo">
|
||||
<a :href="'http://service.weibo.com/share/share.php?url='+systemConfig.data[0].siteDomain+'/details/'+article.doc._id+'.html&title='+article.doc.discription+'&pic='+((article.doc.sImg).indexOf('cdn') > -1 ?'':systemConfig.data[0].siteDomain)+article.doc.sImg+'&appkey=902932546 target=_blank'">
|
||||
<i class="fa fa-weibo"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<RandomArticle :articles="article.randomArticles" />
|
||||
<Messages :userMessageList="messages.data" :contentId="article.doc._id" />
|
||||
</div>
|
||||
@ -37,17 +83,16 @@
|
||||
<div class="grid-content bg-purple-light title">
|
||||
<CatesMenu :typeId="typeId" />
|
||||
<RecentContents :recentItems="recentArticle" />
|
||||
<HotContents :hotItems="hotlist" :typeId="$route.params.typeId" v-if="hotlist.length > 0" />
|
||||
<!-- <RecommendContents :reclist="reclist" :typeId="$route.params.typeId" v-if="reclist.length > 0" /> -->
|
||||
<AdsPannel id="Sk_n90ucb" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<BackTop/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -61,10 +106,11 @@
|
||||
import RandomArticle from '../components/RandomArticle.vue'
|
||||
import RecentContents from '../components/RecentContents.vue'
|
||||
import SearchBox from '../components/SearchBox.vue'
|
||||
import HotContents from '../components/HotContents.vue'
|
||||
import RecommendContents from '../components/RecommendContents.vue'
|
||||
import CatesMenu from '../components/CatesMenu.vue'
|
||||
import AdsPannel from '../components/AdsPannel.vue'
|
||||
|
||||
import BackTop from '../components/BackTop.vue'
|
||||
import api from "~api";
|
||||
export default {
|
||||
name: 'frontend-article',
|
||||
async asyncData({ store, route }) {
|
||||
@ -77,7 +123,7 @@
|
||||
currentId = id;
|
||||
}
|
||||
}
|
||||
store.dispatch('frontend/article/getHotContentList', { typeId: 'indexPage', pageSize: 10})
|
||||
store.dispatch('frontend/article/getRecContentList', { typeId: 'indexPage', pageSize: 10})
|
||||
store.dispatch('global/message/getUserMessageList',{ contentId: currentId, pageSize: 999})
|
||||
store.dispatch('frontend/article/getRecentContentList')
|
||||
await store.dispatch(`frontend/article/getArticleItem`, { id: currentId, path })
|
||||
@ -93,9 +139,11 @@
|
||||
computed: {
|
||||
...mapGetters({
|
||||
article: 'frontend/article/getArticleItem',
|
||||
hotlist: 'frontend/article/getHotContentList',
|
||||
reclist: 'frontend/article/getRecContentList',
|
||||
messages: 'global/message/getUserMessageList',
|
||||
recentArticle: 'frontend/article/getRecentContentList'
|
||||
recentArticle: 'frontend/article/getRecentContentList',
|
||||
loginState: 'frontend/user/getSessionState',
|
||||
systemConfig: 'global/footerConfigs/getSystemConfig'
|
||||
}),
|
||||
cateName() {
|
||||
let catesArr = this.article.doc.categories;
|
||||
@ -119,14 +167,44 @@
|
||||
RandomArticle,
|
||||
RecentContents,
|
||||
SearchBox,
|
||||
HotContents,
|
||||
RecommendContents,
|
||||
CatesMenu,
|
||||
AdsPannel
|
||||
AdsPannel,
|
||||
BackTop
|
||||
},
|
||||
methods: {
|
||||
addTarget(content) {
|
||||
if (!content) return ''
|
||||
return content.replace(/<a(.*?)href="http/g, '<a$1target="_blank" href="http')
|
||||
},
|
||||
likeIt(itemId){
|
||||
if (!this.loginState.logined) {
|
||||
this.$router.push('/users/login');
|
||||
}else{
|
||||
api.get("content/updateLikeNum", { contentId: itemId }).then(result => {
|
||||
let data = result.data;
|
||||
if (data.state == "success") {
|
||||
this.article.doc.likeNum = data.likeNum;
|
||||
} else {
|
||||
this.$message({
|
||||
message: data.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$message.error(err.response.data.error)
|
||||
});
|
||||
}
|
||||
},
|
||||
searchByTag(name){
|
||||
this.$router.push("/tag/" + name);
|
||||
},
|
||||
shareToQq(content){
|
||||
let { title, discription, _id, sImg } = content;
|
||||
let url = this.systemConfig.data[0].siteDomain+'/details/' + _id;
|
||||
let picurl = (sImg.indexOf('cdn') > -1 ? '' : this.systemConfig.data[0].siteDomain) + sImg;
|
||||
let shareqqzonestring='http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?summary='+title+'.'+discription+'&url='+url+'&pics='+picurl;
|
||||
window.open(shareqqzonestring,'newwindow','height=400,width=400,top=100,left=100');
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -153,37 +231,5 @@
|
||||
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.content-detail {
|
||||
color: #3f3f3f;
|
||||
margin-top: 20px;
|
||||
.from {
|
||||
color: #fa5555;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.content-title {
|
||||
margin-top: 0;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
}
|
||||
.content-author {
|
||||
color: #969696;
|
||||
ul {
|
||||
li.author-name {
|
||||
color: #409eff;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-main {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,42 +1,51 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="contentContainer">
|
||||
<div>
|
||||
<div class="mainbody">
|
||||
<el-row :gutter="0">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12" class="content-mainbody-left">
|
||||
<el-row :gutter="24">
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14" class="content-list">
|
||||
<el-row :gutter="15">
|
||||
<el-col :xs="24" :sm="17" :md="17" :lg="17" v-if="topics.data.length > 0">
|
||||
<div class="column-wrap" v-show="typeId != 'indexPage'">
|
||||
<span v-if="$route.params.tagName">{{'标签:' + $route.params.tagName}}</span>
|
||||
<span v-else>{{typeId == 'search' ? '搜索:' + $route.params.searchkey : currentCate.name}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<ItemList v-for="item in topics.data" :item="item" :key="item._id" />
|
||||
</div>
|
||||
<div class="content-pagination">
|
||||
<Pagination :pageInfo="topics.pageInfo" :typeId="typeId" />
|
||||
<div class="main-list">
|
||||
<div class="column-wrap" v-show="typeId != 'indexPage'">
|
||||
<h1 v-if="$route.params.tagName">{{'标签:' + $route.params.tagName}}</h1>
|
||||
<h1 v-else>{{typeId == 'search' ? '搜索:' + $route.params.searchkey : currentCate.name}}</h1>
|
||||
</div>
|
||||
<div>
|
||||
<div class="cate-pannle-menu" v-show="typeId == 'indexPage'">
|
||||
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
|
||||
<el-menu-item index="1">最新文档</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="article-list">
|
||||
<ItemList v-for="item in topics.data" :item="item" :key="item._id" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-pagination">
|
||||
<Pagination :pageInfo="topics.pageInfo" :typeId="typeId" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="17" :md="17" :lg="17" v-else>
|
||||
<div style="height:300px;" v-loading="loadingState"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="0" :sm="7" :md="7" :lg="7" class="content-mainbody-right">
|
||||
<div class="grid-content bg-purple-light title">
|
||||
<el-col :xs="0" :sm="7" :md="7" :lg="7" >
|
||||
<div class="main-right">
|
||||
<AdsPannel id="SJllJUAdcZ" />
|
||||
<div v-if="checkCateList">
|
||||
<CatesMenu :typeId="$route.params.typeId" />
|
||||
</div>
|
||||
<Tag :tags="tags.data" />
|
||||
<HotContents :hotItems="hotlist" :typeId="$route.params.typeId" v-if="hotlist.length > 0" />
|
||||
<RecommendContents :reclist="reclist" :typeId="$route.params.typeId" v-if="reclist.length > 0" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<BackTop/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -50,6 +59,7 @@
|
||||
mapGetters
|
||||
} from 'vuex'
|
||||
import metaMixin from '~mixins'
|
||||
import RecommendContents from '../components/RecommendContents.vue'
|
||||
import HotContents from '../components/HotContents.vue'
|
||||
import SearchBox from '../components/SearchBox.vue'
|
||||
import ItemList from '../views/ItemList.vue'
|
||||
@ -57,64 +67,40 @@
|
||||
import Tag from '../components/Tag.vue'
|
||||
import CatesMenu from '../components/CatesMenu.vue'
|
||||
import AdsPannel from '../components/AdsPannel.vue'
|
||||
import BackTop from '../components/BackTop.vue'
|
||||
|
||||
export default {
|
||||
name: 'frontend-index',
|
||||
async asyncData({
|
||||
store,
|
||||
route
|
||||
}, config = {
|
||||
current: 1,
|
||||
model: 'normal'
|
||||
}) {
|
||||
const {
|
||||
params: {
|
||||
id,
|
||||
key,
|
||||
tagName,
|
||||
current,
|
||||
typeId,
|
||||
searchkey
|
||||
},
|
||||
path
|
||||
} = route
|
||||
const base = { ...config,
|
||||
pageSize: 10,
|
||||
id,
|
||||
path,
|
||||
searchkey,
|
||||
tagName,
|
||||
current,
|
||||
typeId
|
||||
}
|
||||
store.dispatch('frontend/article/getHotContentList', {
|
||||
pageSize: 10,
|
||||
typeId
|
||||
})
|
||||
store.dispatch('global/tags/getTagList', {
|
||||
pageSize: 30
|
||||
})
|
||||
await store.dispatch('frontend/article/getArticleList', base)
|
||||
async asyncData({ store, route }, config = { current: 1, model: 'normal'}) {
|
||||
const { params: { id, key, tagName, current, typeId, searchkey },path} = route
|
||||
const base = { ...config, pageSize: 10, id, path, searchkey, tagName, current, typeId}
|
||||
store.dispatch('frontend/article/getRecContentList', { pageSize: 10,typeId })
|
||||
store.dispatch('frontend/article/getArticleList', base)
|
||||
await store.dispatch('frontend/article/getHotContentList', base)
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
loadingState: false
|
||||
loadingState: false,
|
||||
activeIndex: '1',
|
||||
}
|
||||
},
|
||||
mixins: [metaMixin],
|
||||
components: {
|
||||
ItemList,
|
||||
Pagination,
|
||||
RecommendContents,
|
||||
HotContents,
|
||||
SearchBox,
|
||||
Tag,
|
||||
CatesMenu,
|
||||
AdsPannel
|
||||
AdsPannel,
|
||||
BackTop
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
reclist: 'frontend/article/getRecContentList',
|
||||
hotlist: 'frontend/article/getHotContentList',
|
||||
tags: 'global/tags/getTagList',
|
||||
// tags: 'global/tags/getTagList',
|
||||
systemConfig: 'global/footerConfigs/getSystemConfig'
|
||||
}),
|
||||
topics(){
|
||||
@ -136,29 +122,18 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
handleSelect(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.$options.asyncData({
|
||||
store: this.$store,
|
||||
route: this.$route
|
||||
}, {
|
||||
current: 1
|
||||
})
|
||||
this.$options.asyncData({ store: this.$store, route: this.$route}, { current: 1})
|
||||
},
|
||||
metaInfo() {
|
||||
const systemData = this.systemConfig.data[0];
|
||||
const {
|
||||
siteName,
|
||||
siteDiscription,
|
||||
siteKeywords
|
||||
} = systemData;
|
||||
const { siteName, siteDiscription, siteKeywords } = systemData;
|
||||
let title = '首页';
|
||||
const {
|
||||
tagName,
|
||||
typeId,
|
||||
searchkey
|
||||
} = this.$route.params
|
||||
const { tagName, typeId, searchkey } = this.$route.params
|
||||
if (typeId) {
|
||||
const obj = this.currentCate;
|
||||
if (obj) {
|
||||
@ -189,23 +164,23 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.column-wrap {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 20px;
|
||||
color: #303030;
|
||||
padding-left: 18px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
// .column-wrap {
|
||||
// position: relative;
|
||||
// height: 30px;
|
||||
// line-height: 30px;
|
||||
// font-size: 20px;
|
||||
// color: #303030;
|
||||
// padding-left: 18px;
|
||||
// margin-bottom: 15px;
|
||||
// }
|
||||
|
||||
.column-wrap:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 4px;
|
||||
height: 21px;
|
||||
background: #f63756;
|
||||
left: 0;
|
||||
top: 4px;
|
||||
}
|
||||
// .column-wrap:before {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// width: 4px;
|
||||
// height: 21px;
|
||||
// background: #f63756;
|
||||
// left: 0;
|
||||
// top: 4px;
|
||||
// }
|
||||
</style>
|
@ -1,13 +1,12 @@
|
||||
<template>
|
||||
<article class="case-box">
|
||||
|
||||
<div class="contentContainer">
|
||||
<article class="contentContainer">
|
||||
<div class="mainbody case-box">
|
||||
<el-row :gutter="0">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12">
|
||||
<el-row :gutter="20">
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14" >
|
||||
<div class="case-list">
|
||||
<h3>
|
||||
这些站点在用DoraCMS:
|
||||
<el-button-group>
|
||||
@ -16,9 +15,10 @@
|
||||
</el-button-group>
|
||||
</h3>
|
||||
<AdsPannel id="BkxSmqcaAZ" />
|
||||
</el-row>
|
||||
<div style="clear:both"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -27,22 +27,7 @@
|
||||
</article>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.case-box {
|
||||
min-height: 400px;
|
||||
h3 {
|
||||
margin: 5px 10px 20px;
|
||||
font-size: 15px;
|
||||
color: #878d99;
|
||||
.el-button--mini {
|
||||
padding: 5px 8px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
@ -1,13 +1,5 @@
|
||||
<style lang='scss'>
|
||||
.post-b {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-bottom: 25px;
|
||||
padding: 0px 0px 15px;
|
||||
}
|
||||
|
||||
.post-b:last-child {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="post-b">
|
||||
|
@ -1,7 +1,5 @@
|
||||
<style lang='scss'>
|
||||
.contentContainer {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
|
@ -10,10 +10,10 @@
|
||||
<template>
|
||||
<div class="container min-hight" style="margin-bottom: 20px;background: #FFFFFF">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="2" :sm="2" :md="4" :lg="4">
|
||||
<el-col :xs="1" :sm="1" :md="2" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="20" :sm="20" :md="16" :lg="16">
|
||||
<el-col :xs="22" :sm="22" :md="20" :lg="20" :xl="14">
|
||||
<div class="col-md-12 siteMap">
|
||||
<ul>
|
||||
<li v-for="(item,index) in siteMapList.data" :key="item._id" v-once>
|
||||
@ -22,7 +22,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="2" :sm="2" :md="4" :lg="4">
|
||||
<el-col :xs="1" :sm="1" :md="2" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -1,118 +1,42 @@
|
||||
<template>
|
||||
<article class="content-item">
|
||||
|
||||
<el-row :gutter="30">
|
||||
<el-col :xs="0" :sm="7" :md="7" :lg="7" hidden-xs-only>
|
||||
<div class="grid-content bg-purple contentImg">
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading">
|
||||
<img :src="item.sImg" :alt="item.title" />
|
||||
</router-link>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="17" :md="17" :lg="17" class='discription'>
|
||||
<div class="grid-content bg-purple-light title">
|
||||
<h2>
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading">{{item.title}}</router-link>
|
||||
</h2>
|
||||
<div class="dis">{{item.discription | cutWords(90)}}</div>
|
||||
<ul class="post-meta">
|
||||
<li>
|
||||
<div v-if="item.categories && item.categories.length>1">
|
||||
<router-link :to="{path: '/'+(item.categories)[item.categories.length-1].defaultUrl+ '___'+(item.categories)[item.categories.length-1]._id}">{{(item.categories)[item.categories.length-1].name}}</router-link>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-clock-o" aria-hidden="true"></i> {{item.date}}</li>
|
||||
<li>
|
||||
<i class="fa fa-eye" aria-hidden="true"></i> {{item.clickNum}}</li>
|
||||
<li>
|
||||
<i class="fa fa-comment" aria-hidden="true"></i> {{item.commentNum}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-row :gutter="30" class="row-list">
|
||||
<el-col :xs="24" :sm="8" :md="8" :lg="8" class='image'>
|
||||
<div class="grid-content bg-purple contentImg">
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading">
|
||||
<img :src="item.sImg" :alt="item.title" />
|
||||
</router-link>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="16" :md="16" :lg="16">
|
||||
<div class="discription">
|
||||
<h2>
|
||||
<router-link :to="'/details/'+item._id+'.html'" class="continue-reading">{{item.title}}</router-link>
|
||||
</h2>
|
||||
<div class="dis">{{item.discription | cutWords(90)}}</div>
|
||||
<ul class="post-meta">
|
||||
<li v-if="item.categories">
|
||||
<div v-if="item.categories.length>1">
|
||||
<router-link :to="{path: '/'+(item.categories)[item.categories.length-1].defaultUrl+ '___'+(item.categories)[item.categories.length-1]._id}">{{(item.categories)[item.categories.length-1].name}}</router-link>
|
||||
</div>
|
||||
<div v-else-if="item.categories.length == 1">
|
||||
<router-link :to="{path: '/'+(item.categories)[0].defaultUrl+ '___'+(item.categories)[0]._id}">{{(item.categories)[0].name}}</router-link>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-clock-o" aria-hidden="true"></i> {{item.date}}</li>
|
||||
<li>
|
||||
<i class="fa fa-eye" aria-hidden="true"></i> {{item.clickNum}}</li>
|
||||
<li>
|
||||
<i class="fa fa-comment" aria-hidden="true"></i> {{item.commentNum}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</article>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.content-item {
|
||||
.post-angle {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
height: 21px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #f63756;
|
||||
line-height: 24px;
|
||||
padding: 0 10px;
|
||||
z-index: 101;
|
||||
top: 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.post-angle:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 21px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 6px solid #cd213d;
|
||||
border-left: 10px solid transparent;
|
||||
}
|
||||
.contentImg {
|
||||
img {
|
||||
width: 100%;
|
||||
min-height: 6rem;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
// margin-right: 30px;
|
||||
height: auto;
|
||||
display: block;
|
||||
position: relative;
|
||||
.content-cate {
|
||||
position: absolute;
|
||||
top: 0.4rem;
|
||||
left: 0.4rem;
|
||||
display: block;
|
||||
padding: 0 0.5rem;
|
||||
color: #fff;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
font-size: 0.6rem;
|
||||
text-align: center;
|
||||
border-radius: 1rem;
|
||||
z-index: 11;
|
||||
}
|
||||
}
|
||||
.discription {
|
||||
text-align: left;
|
||||
.post-meta {
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #3ca5f6;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
color: #b4b4b4;
|
||||
margin: 10px 10px 10px 0;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
word-break: break-all;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
.dis {
|
||||
margin: 10px 0;
|
||||
font-size: 13px;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
@ -1,51 +1,43 @@
|
||||
<template>
|
||||
<div class="user-center">
|
||||
<div>
|
||||
<UserBar />
|
||||
<el-row :gutter="0" class="header-main">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<div class="contentContainer">
|
||||
<div class="mainbody user-center">
|
||||
<el-row :gutter="0">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12">
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14">
|
||||
<div class="user-info">
|
||||
<el-form :model="loginState.userInfo" :rules="rules" ref="ruleForm" label-width="150px" class="demo-ruleForm">
|
||||
<div class="user-logo">
|
||||
<el-form-item prop="sImg">
|
||||
<el-upload class="avatar-uploader" action="/system/upload?type=images" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
|
||||
<img v-if="loginState.userInfo.logo" :src="loginState.userInfo.logo" class="avatar">
|
||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="用户名" prop="userName">
|
||||
<el-input size="small" v-model="loginState.userInfo.userName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input size="small" v-model="loginState.userInfo.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phoneNum">
|
||||
<el-input size="small" v-model="loginState.userInfo.phoneNum"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input size="small" v-model="loginState.userInfo.email"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input size="small" placeholder="请输入密码" type="password" v-model="loginState.userInfo.password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input size="small" placeholder="请确认密码" type="password" v-model="loginState.userInfo.confirmPassword"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="comments">
|
||||
<el-input size="small" type="textarea" v-model="loginState.userInfo.comments"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button size="small" type="primary" @click="submitForm('ruleForm')">保存</el-button>
|
||||
<el-button size="small" @click="resetForm('ruleForm')">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row :gutter="30" class="basic-info">
|
||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8" class="left-pannel">
|
||||
<UserCenterLeftMenu @setNewlogo="setFormLogo" :userInfo="loginState.userInfo"/>
|
||||
</el-col>
|
||||
<el-col :xs="16" :sm="16" :md="16" :lg="16" :xl="16" class="right-pannel">
|
||||
<h3 class="top-bar"><i class="fa fa-user"></i><span>基本资料</span></h3>
|
||||
<el-form label-position="top" :model="loginState.userInfo" :rules="rules" ref="ruleForm" label-width="150px" class="info-form">
|
||||
<el-form-item label="用户名" prop="userName">
|
||||
<el-input v-model="loginState.userInfo.userName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="loginState.userInfo.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phoneNum">
|
||||
<el-input v-model="loginState.userInfo.phoneNum"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="loginState.userInfo.email"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="comments">
|
||||
<el-input type="textarea" v-model="loginState.userInfo.comments"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button size="small" type="primary" @click="submitForm('ruleForm')">更新信息</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple">
|
||||
|
||||
</div>
|
||||
@ -57,6 +49,7 @@
|
||||
<script>
|
||||
import api from "~api";
|
||||
import UserBar from "../components/UserBar";
|
||||
import UserCenterLeftMenu from "../components/UserCenterLeftMenu";
|
||||
const validatorUtil = require("../../../utils/validatorUtil.js");
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
export default {
|
||||
@ -67,7 +60,8 @@ export default {
|
||||
};
|
||||
},
|
||||
components: {
|
||||
UserBar
|
||||
UserBar,
|
||||
UserCenterLeftMenu
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -146,40 +140,6 @@ export default {
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (!validatorUtil.checkPwd(value)) {
|
||||
callback(new Error("6-12位,只能包含字母、数字和下划线!"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
confirmPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请确认密码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value !== this.loginState.userInfo.password) {
|
||||
callback(new Error("两次输入密码不一致!"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
comments: [
|
||||
{
|
||||
message: "请填写备注",
|
||||
@ -196,21 +156,8 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleAvatarSuccess(res, file) {
|
||||
this.loginState.userInfo.logo = res;
|
||||
},
|
||||
beforeAvatarUpload(file) {
|
||||
const isJPG = file.type === "image/jpeg";
|
||||
const isPNG = file.type === "image/png";
|
||||
const isGIF = file.type === "image/gif";
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isJPG && !isPNG && !isGIF) {
|
||||
this.$message.error("上传头像图片只能是 JPG,PNG,GIF 格式!");
|
||||
}
|
||||
if (!isLt2M) {
|
||||
this.$message.error("上传头像图片大小不能超过 2MB!");
|
||||
}
|
||||
return (isJPG || isPNG || isGIF) && isLt2M;
|
||||
setFormLogo(res) {
|
||||
this.loginState && (this.loginState.userInfo.logo = res);
|
||||
},
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
@ -239,14 +186,8 @@ export default {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// this.$store.dispatch('simplePage');
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
loginState: "frontend/user/getSessionState"
|
||||
@ -256,45 +197,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.user-center {
|
||||
background-color: #f4f5f5;
|
||||
.user-info {
|
||||
form {
|
||||
width: 50%;
|
||||
}
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: #ffffff;
|
||||
position: relative;
|
||||
.user-logo {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
.avatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,32 +1,39 @@
|
||||
<template>
|
||||
<div class="dr-user-login">
|
||||
<div class="login-form">
|
||||
<div class="contentContainer">
|
||||
<div class="mainbody login-form">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="2" :sm="6" :md="8" :lg="8" :xl="10">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="20" :sm="12" :md="8" :lg="8" :xl="4">
|
||||
<el-form :model="userLoginFormData" :rules="rules" ref="ruleForm" label-width="0px" class="demo-ruleForm login-container">
|
||||
<h3 class="pannel-title">
|
||||
<span>用户登录</span>
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14" class="login-main">
|
||||
<div class="login-box">
|
||||
<el-form label-position="top" :model="userLoginFormData" :rules="rules" ref="ruleForm" label-width="80px" class="demo-ruleForm">
|
||||
<h3 class="title">
|
||||
<span>登录</span>
|
||||
</h3>
|
||||
<el-form-item prop="email">
|
||||
<el-input size="small" placeholder="请填写邮箱" v-model="userLoginFormData.email"></el-input>
|
||||
<el-form-item prop="email" label="邮箱">
|
||||
<el-input placeholder="请填写邮箱" v-model="userLoginFormData.email"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input size="small" placeholder="请输入密码" type="password" @keyup.enter.native="submitForm('ruleForm')" v-model="userLoginFormData.password"></el-input>
|
||||
<el-form-item prop="password" label="密码">
|
||||
<el-input placeholder="请输入密码" type="password" @keyup.enter.native="submitForm('ruleForm')" v-model="userLoginFormData.password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="submit-btn">
|
||||
<el-button size="small" round type="primary" @click="submitForm('ruleForm')">登录</el-button>
|
||||
<el-button size="small" round @click="resetForm('ruleForm')">重置</el-button>
|
||||
<el-form-item>
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-button @click="resetForm('ruleForm')">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="2" :sm="6" :md="8" :lg="8" :xl="10">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -34,6 +41,7 @@
|
||||
import api from "~api";
|
||||
const validatorUtil = require("../../../utils/validatorUtil.js");
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "userLogin",
|
||||
metaInfo() {
|
||||
@ -43,6 +51,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
referPath: "/",
|
||||
rules: {
|
||||
email: [
|
||||
{
|
||||
@ -81,6 +90,11 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
beforeRouteEnter(to, from, next) {
|
||||
next(vm => {
|
||||
from.path && (vm.referPath = from.path);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
@ -90,7 +104,7 @@ export default {
|
||||
.post("users/doLogin", params)
|
||||
.then(result => {
|
||||
if (result.data.state == "success") {
|
||||
window.location = "/";
|
||||
window.location = this.referPath;
|
||||
} else {
|
||||
this.$message({
|
||||
message: result.data.message,
|
||||
@ -111,9 +125,6 @@ export default {
|
||||
this.$refs[formName].resetFields();
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// this.$store.dispatch('simplePage');
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
userLoginFormData: "frontend/user/loginForm"
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="user-center">
|
||||
<div>
|
||||
<UserBar />
|
||||
<el-row :gutter="0" class="header-main">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<div class="contentContainer">
|
||||
<div class="mainbody user-center">
|
||||
<el-row :gutter="0">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12">
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14">
|
||||
<div class="user-message">
|
||||
<UserBar />
|
||||
<div v-if="noticelist.docs.length>0">
|
||||
<UserNoticeDataTable :dataList="noticelist.docs"></UserNoticeDataTable>
|
||||
<div class="content-pagination">
|
||||
@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple">
|
||||
|
||||
</div>
|
||||
@ -64,12 +64,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.user-center {
|
||||
background-color: #f4f5f5;
|
||||
.user-message {
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
139
src/index/views/UserPwd.vue
Normal file
139
src/index/views/UserPwd.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="contentContainer">
|
||||
<div class="mainbody user-center">
|
||||
<el-row :gutter="0">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14">
|
||||
<div class="user-info">
|
||||
<el-row :gutter="30" class="basic-info">
|
||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8" class="left-pannel">
|
||||
<UserCenterLeftMenu @setNewlogo="setFormLogo" :userInfo="loginState.userInfo"/>
|
||||
</el-col>
|
||||
<el-col :xs="16" :sm="16" :md="16" :lg="16" :xl="16" class="right-pannel">
|
||||
<h3 class="top-bar"><i class="fa fa-asterisk"></i><span>修改密码</span></h3>
|
||||
<el-form label-position="top" :model="loginState.userInfo" :rules="rules" ref="ruleForm" label-width="150px" class="info-form">
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input placeholder="请输入密码" type="password" v-model="loginState.userInfo.password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input placeholder="请确认密码" type="password" v-model="loginState.userInfo.confirmPassword"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button size="small" type="primary" @click="submitForm('ruleForm')">更新信息</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple">
|
||||
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import api from "~api";
|
||||
import UserCenterLeftMenu from "../components/UserCenterLeftMenu";
|
||||
const validatorUtil = require("../../../utils/validatorUtil.js");
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
export default {
|
||||
name: "userLogin",
|
||||
metaInfo() {
|
||||
return {
|
||||
title: "用户中心"
|
||||
};
|
||||
},
|
||||
components: {
|
||||
UserCenterLeftMenu
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rules: {
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (!validatorUtil.checkPwd(value)) {
|
||||
callback(new Error("6-12位,只能包含字母、数字和下划线!"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
confirmPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请确认密码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value !== this.loginState.userInfo.password) {
|
||||
callback(new Error("两次输入密码不一致!"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
setFormLogo(res) {
|
||||
this.loginState && (this.loginState.userInfo.logo = res);
|
||||
},
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (valid) {
|
||||
let params = this.loginState.userInfo;
|
||||
api
|
||||
.post("users/updateInfo", params)
|
||||
.then(result => {
|
||||
if (result.data.state == "success") {
|
||||
this.$message({
|
||||
message: "信息更新成功!",
|
||||
type: "success"
|
||||
});
|
||||
} else {
|
||||
this.$message({
|
||||
message: result.data.message,
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error(err.response.data.error);
|
||||
});
|
||||
} else {
|
||||
console.log("error submit!!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
loginState: "frontend/user/getSessionState"
|
||||
})
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
@ -1,33 +1,35 @@
|
||||
<template>
|
||||
<div class="dr-user-login">
|
||||
<div class="login-form">
|
||||
<div class="contentContainer">
|
||||
<div class="mainbody">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="2" :sm="6" :md="8" :lg="8" :xl="10">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="20" :sm="12" :md="8" :lg="8" :xl="4">
|
||||
<el-form :model="userRegFormData" :rules="regRules" ref="regRuleForm" label-width="0px" class="demo-ruleForm login-container">
|
||||
<h3 class="pannel-title">
|
||||
<span>用户注册</span>
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14" class="login-main">
|
||||
<div class="login-box">
|
||||
<el-form label-position="top" :model="userRegFormData" :rules="regRules" ref="regRuleForm" label-width="0px" class="demo-ruleForm login-container">
|
||||
<h3 class="title">
|
||||
<span>注册</span>
|
||||
</h3>
|
||||
<el-form-item prop="userName">
|
||||
<el-input size="small" placeholder="请填写用户名" v-model="userRegFormData.userName"></el-input>
|
||||
<el-form-item prop="userName" label="用户名">
|
||||
<el-input placeholder="请填写用户名" v-model="userRegFormData.userName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="email">
|
||||
<el-input size="small" placeholder="请填写邮箱" v-model="userRegFormData.email"></el-input>
|
||||
<el-form-item prop="email" label="邮箱">
|
||||
<el-input placeholder="请填写邮箱" v-model="userRegFormData.email"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input size="small" placeholder="请输入密码" type="password" v-model="userRegFormData.password"></el-input>
|
||||
<el-form-item prop="password" label="密码">
|
||||
<el-input placeholder="请输入密码" type="password" v-model="userRegFormData.password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="confirmPassword">
|
||||
<el-input size="small" placeholder="请确认密码" type="password" v-model="userRegFormData.confirmPassword"></el-input>
|
||||
<el-form-item prop="confirmPassword" label="重复密码">
|
||||
<el-input placeholder="请确认密码" type="password" v-model="userRegFormData.confirmPassword"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="submit-btn">
|
||||
<el-button size="small" round type="primary" @click="submitRegForm('regRuleForm')">提交</el-button>
|
||||
<el-button type="primary" @click="submitRegForm('regRuleForm')">注册</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="2" :sm="6" :md="8" :lg="8":xl="10" >
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="user-center">
|
||||
<div>
|
||||
<UserBar />
|
||||
<div class="contentContainer">
|
||||
<div class="mainbody user-center">
|
||||
<el-row :gutter="0" class="header-main">
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple"> </div>
|
||||
</el-col>
|
||||
<el-col :xs="22" :sm="22" :md="18" :lg="18" :xl="12">
|
||||
<el-col :xs="22" :sm="22" :md="22" :lg="20" :xl="14">
|
||||
<div class="user-message">
|
||||
<UserBar />
|
||||
<div v-if="replylist">
|
||||
<UserReplieDataTable :dataList="replylist.docs" :userInfo="loginState.userInfo"></UserReplieDataTable>
|
||||
<div class="content-pagination">
|
||||
@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="1" :sm="1" :md="3" :lg="3" :xl="6">
|
||||
<el-col :xs="1" :sm="1" :md="1" :lg="2" :xl="5">
|
||||
<div class="grid-content bg-purple">
|
||||
|
||||
</div>
|
||||
@ -29,22 +29,19 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import api from '~api'
|
||||
import UserBar from '../components/UserBar'
|
||||
import UserReplieDataTable from '../components/UserReplieDataTable';
|
||||
import Pagination from '../components/Pagination.vue'
|
||||
import api from "~api";
|
||||
import UserBar from "../components/UserBar";
|
||||
import UserReplieDataTable from "../components/UserReplieDataTable";
|
||||
import Pagination from "../components/Pagination.vue";
|
||||
|
||||
const validatorUtil = require('../../../utils/validatorUtil.js')
|
||||
import {
|
||||
mapGetters,
|
||||
mapActions
|
||||
} from 'vuex';
|
||||
const validatorUtil = require("../../../utils/validatorUtil.js");
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
export default {
|
||||
name: 'userMessage',
|
||||
name: "userMessage",
|
||||
metaInfo() {
|
||||
return {
|
||||
title: '用户中心'
|
||||
}
|
||||
title: "用户中心"
|
||||
};
|
||||
},
|
||||
components: {
|
||||
UserBar,
|
||||
@ -52,32 +49,20 @@ export default {
|
||||
Pagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
return {};
|
||||
},
|
||||
methods: {},
|
||||
mounted() {
|
||||
this.$store.dispatch('frontend/user/userReplies');
|
||||
this.$store.dispatch("frontend/user/userReplies");
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
replylist: 'frontend/user/replylist',
|
||||
loginState: 'frontend/user/getSessionState'
|
||||
replylist: "frontend/user/replylist",
|
||||
loginState: "frontend/user/getSessionState"
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.user-center {
|
||||
background-color: #f4f5f5;
|
||||
.user-message {
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -75,6 +75,10 @@
|
||||
<el-button size="small" type="warning" plain round @click="getToPage('systemConfig')">
|
||||
<i class="fa fa-fw fa-cog"></i> 系统配置</el-button>
|
||||
</li>
|
||||
<li>
|
||||
<el-button size="small" type="danger" plain round @click="getToPage('backUpData')">
|
||||
<i class="fa fa-fw fa-database"></i> 数据备份</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-card>
|
||||
|
@ -3,7 +3,6 @@ const {
|
||||
} = require('../server/lib/controller');
|
||||
const _ = require('lodash');
|
||||
module.exports = (req, res, next) => {
|
||||
// console.log('---req.originalUrl---', req.originalUrl);
|
||||
req.query.resourcefiles = "_id api";
|
||||
AdminResource.getAllResource(req, res, {
|
||||
type: '1'
|
||||
|
@ -1,11 +1,9 @@
|
||||
/**
|
||||
* Created by Administrator on 2015/9/9.
|
||||
*/
|
||||
// let mongoose = require('mongoose');
|
||||
// let UserModel = mongoose.model('User');
|
||||
let settings = require('../settings');
|
||||
let siteFunc = require('../siteFunc');
|
||||
// let UserNotify = require('../models/UserNotify');
|
||||
|
||||
//用户实体类
|
||||
const { User, UserNotify } = require('../../server/lib/controller');
|
||||
|
||||
|
49
utils/middleware/cache.js
Normal file
49
utils/middleware/cache.js
Normal file
@ -0,0 +1,49 @@
|
||||
var redis = require('./redis');
|
||||
var _ = require('lodash');
|
||||
|
||||
/**
|
||||
* 从cache中取出缓存
|
||||
* @param key 键
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
var get = function (key, callback) {
|
||||
redis.get(key, function (err, data) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!data) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
data = JSON.parse(data);
|
||||
callback(data);
|
||||
});
|
||||
};
|
||||
|
||||
exports.get = get;
|
||||
|
||||
|
||||
/**
|
||||
* 将键值对数据缓存起来
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 参数可选,毫秒为单位,切换为redis以秒为单位,除以1000
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
var set = function (key, value, time, callback) {
|
||||
if (typeof time === 'function') {
|
||||
callback = time;
|
||||
time = null;
|
||||
}
|
||||
callback = callback || _.noop;
|
||||
value = JSON.stringify(value);
|
||||
if (!time) {
|
||||
redis.set(key, value, callback);
|
||||
} else {
|
||||
//将毫秒单位转为秒
|
||||
redis.setex(key, parseInt(time / 1000), value, callback);
|
||||
}
|
||||
};
|
||||
|
||||
exports.set = set;
|
10
utils/middleware/redis.js
Normal file
10
utils/middleware/redis.js
Normal file
@ -0,0 +1,10 @@
|
||||
/*!
|
||||
* redis client
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var settings = require('../settings');
|
||||
var redis = require('redis');
|
||||
var client = redis.createClient(settings.redis_port, settings.redis_host);
|
||||
client.auth(settings.redis_psd);
|
||||
module.exports = client;
|
@ -31,6 +31,12 @@ module.exports = {
|
||||
origin: 'http://cdn.html-js.cn', // cdn域名
|
||||
fsizeLimit: 1024 * 1024 * 5, // 上传文件大小限制默认为5M
|
||||
|
||||
// redis配置
|
||||
openRedis: false, //是否开启,若为true 则下面的信息必须配置正确完整
|
||||
redis_host: '10.0.0.1',
|
||||
redis_port: 6379,
|
||||
redis_psd: 'your redis password',
|
||||
redis_db: 0,
|
||||
// 站点基础信息配置
|
||||
DORACMSAPI: 'http://api.html-js.cn', // 系统服务提供商
|
||||
SYSTEMLOGPATH: '/home/doraData/logsdir/doracms', // 服务器日志保存目录
|
||||
|
Loading…
Reference in New Issue
Block a user