优化和添加了一些功能
19
CHANGES.md
Normal file
@ -0,0 +1,19 @@
|
||||
## 版本更新记录
|
||||
|
||||
### 2019-12-01
|
||||
|
||||
- 添加MrDoc全站favicon图标
|
||||
- 添加后台配置关闭注册功能、启用邮箱功能、统计代码、广告代码等功能
|
||||
- 添加通过邮箱找回密码功能
|
||||
- 优化管理员界面退出后403的处理
|
||||
- 优化文档浏览界面文档渲染加载逻辑
|
||||
|
||||
### 2019-11
|
||||
|
||||
- 添加404页面视图
|
||||
- 完善首页文集列表简介样式
|
||||
- 完善后台管理员对文集的权限逻辑
|
||||
|
||||
### 2019-08
|
||||
MrDoc第一版发布
|
||||
|
@ -66,6 +66,7 @@ TEMPLATES = [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'app_admin.context_processors.sys_setting', # 自定义系统设置上下文渲染
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -115,7 +116,7 @@ USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
USE_TZ = False
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
|
38
README.md
@ -1,4 +1,6 @@
|
||||
# MrDoc
|
||||
# MrDoc - 一个简单的文档写作应用
|
||||
|
||||

|
||||
|
||||
## 介绍
|
||||
一个简单的MarkDown文档写作系统。
|
||||
@ -10,11 +12,14 @@ MrDoc拥有以下特点:
|
||||
- 提供文档模板功能,支持文档模板的创建、修改;
|
||||
- 仿GitBook文档阅读页面,支持文档阅读页面的字体缩放,字体类型修改;
|
||||
- 支持三级目录层级显示;
|
||||
- 使用方便、二次开发修改也方便;
|
||||
|
||||
|
||||
在开发过程中,参考和借鉴了GitBook、ShowDoc、Wordbook等应用的功能和样式。
|
||||
|
||||
## 软件架构
|
||||
基于Python Web框架Django构建。
|
||||
|
||||
后端基于Python Web框架Django
|
||||
|
||||
编程语言:Python 3
|
||||
|
||||
@ -50,6 +55,33 @@ Markdown科学公式:Katex.js
|
||||
|
||||
加入MrDoc交流QQ群,群号为735507293,入群密码:mrdoc
|
||||
|
||||
## 版本更新日志
|
||||
|
||||
版本更新日志详见:[CHANGES.md](./CHANGES.md)
|
||||
|
||||
## 版本更新
|
||||
|
||||
关注州的先生微信公众号(ID:zmister2016),及时获取MrDoc版本更新信息。
|
||||
关注州的先生微信公众号(ID:zmister2016)、博客 https://zmister.com,及时获取MrDoc版本更新信息。
|
||||
|
||||
## 更多截图
|
||||
|
||||
### 文档界面
|
||||

|
||||
|
||||
### 登录界面
|
||||

|
||||
|
||||
### 注册界面
|
||||

|
||||
|
||||
### 文档写作界面
|
||||

|
||||
|
||||
### 文档模板界面
|
||||

|
||||
|
||||
### 管理员后台界面
|
||||

|
||||
|
||||
### 普通用户后台界面
|
||||

|
15
app_admin/context_processors.py
Normal file
@ -0,0 +1,15 @@
|
||||
# coding:utf-8
|
||||
# @文件: context_processer.py
|
||||
# @创建者:州的先生
|
||||
# #日期:2019/11/16
|
||||
# 博客地址:zmister.com
|
||||
from app_admin.models import SysSetting
|
||||
|
||||
# 系统设置 - 上下文变量
|
||||
def sys_setting(request):
|
||||
setting_dict = dict()
|
||||
# 获取系统设置状态
|
||||
datas = SysSetting.objects.filter(types="basic")
|
||||
for data in datas:
|
||||
setting_dict[data.name] = data.value
|
||||
return setting_dict
|
@ -1,4 +1,6 @@
|
||||
from django.core.exceptions import PermissionDenied # 权限拒绝异常
|
||||
from django.http import Http404
|
||||
from app_admin.models import SysSetting
|
||||
|
||||
# 超级管理员用户需求
|
||||
def superuser_only(function):
|
||||
@ -11,4 +13,19 @@ def superuser_only(function):
|
||||
raise PermissionDenied
|
||||
return function(request, *args, **kwargs)
|
||||
|
||||
return _inner
|
||||
return _inner
|
||||
|
||||
# 开放注册需求
|
||||
def open_register(function):
|
||||
'''只有开放注册才能访问'''
|
||||
def _inner(request,*args,**kwargs):
|
||||
try:
|
||||
status = SysSetting.objects.get(name='close_register')
|
||||
except:
|
||||
# 如果不存在close_register这个属性,那么表示是开放注册的
|
||||
return function(request, *args, **kwargs)
|
||||
if status.value == 'on':
|
||||
raise Http404
|
||||
return function(request, *args, **kwargs)
|
||||
|
||||
return _inner
|
||||
|
26
app_admin/migrations/0001_initial.py
Normal file
@ -0,0 +1,26 @@
|
||||
# Generated by Django 2.1 on 2019-11-16 15:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SysSetting',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=50, verbose_name='项目')),
|
||||
('value', models.TextField(verbose_name='内容')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '系统设置',
|
||||
'verbose_name_plural': '系统设置',
|
||||
},
|
||||
),
|
||||
]
|
22
app_admin/migrations/0002_auto_20191117_0808.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Generated by Django 2.1 on 2019-11-17 00:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app_admin', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='syssetting',
|
||||
name='id',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='syssetting',
|
||||
name='name',
|
||||
field=models.CharField(max_length=50, primary_key=True, serialize=False, verbose_name='项目'),
|
||||
),
|
||||
]
|
18
app_admin/migrations/0003_auto_20191117_0816.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 2.1 on 2019-11-17 00:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app_admin', '0002_auto_20191117_0808'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='syssetting',
|
||||
name='value',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='内容'),
|
||||
),
|
||||
]
|
33
app_admin/migrations/0004_auto_20191121_2103.py
Normal file
@ -0,0 +1,33 @@
|
||||
# Generated by Django 2.1 on 2019-11-21 13:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app_admin', '0003_auto_20191117_0816'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EmaiVerificationCode',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('email_name', models.EmailField(max_length=254, verbose_name='电子邮箱')),
|
||||
('verification_type', models.CharField(max_length=50, verbose_name='验证码类型')),
|
||||
('verification_code', models.CharField(max_length=10, verbose_name='验证码')),
|
||||
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('expire_time', models.DateTimeField(auto_now=True, verbose_name='过期时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '电子邮件验证码',
|
||||
'verbose_name_plural': '电子邮件验证码',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='syssetting',
|
||||
name='types',
|
||||
field=models.CharField(default='basic', max_length=10, verbose_name='类型'),
|
||||
),
|
||||
]
|
18
app_admin/migrations/0005_auto_20191125_2155.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 2.1 on 2019-11-25 21:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app_admin', '0004_auto_20191121_2103'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='emaiverificationcode',
|
||||
name='expire_time',
|
||||
field=models.DateTimeField(verbose_name='过期时间'),
|
||||
),
|
||||
]
|
@ -1,3 +1,30 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
# 系统设置项模型
|
||||
class SysSetting(models.Model):
|
||||
name = models.CharField(verbose_name="项目",max_length=50,primary_key=True)
|
||||
value = models.TextField(verbose_name="内容",null=True,blank=True)
|
||||
types = models.CharField(verbose_name="类型",max_length=10,default="basic")
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = '系统设置'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
# 电子邮件验证码模型
|
||||
class EmaiVerificationCode(models.Model):
|
||||
email_name = models.EmailField(verbose_name="电子邮箱")
|
||||
verification_type = models.CharField(verbose_name="验证码类型",max_length=50)
|
||||
verification_code = models.CharField(verbose_name="验证码",max_length=10)
|
||||
create_time = models.DateTimeField(verbose_name="创建时间",auto_now_add=True)
|
||||
expire_time = models.DateTimeField(verbose_name="过期时间")
|
||||
|
||||
def __str__(self):
|
||||
return "{}:{}".format(self.verification_type,self.email_name)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '电子邮件验证码'
|
||||
verbose_name_plural = verbose_name
|
@ -11,7 +11,11 @@ urlpatterns = [
|
||||
path('change_pwd',views.admin_change_pwd,name="change_pwd"), # 管理员修改用户密码
|
||||
path('modify_pwd',views.change_pwd,name="modify_pwd"), # 普通用户修改密码
|
||||
path('project_manage/',views.admin_project,name='project_manage'), # 文集管理
|
||||
path('doc_manage/',views.admin_doc,name='doc_manage'), # 文集管理
|
||||
path('doctemp_manage/',views.admin_doctemp,name='doctemp_manage'), # 文集管理
|
||||
path('check_code/',views.check_code,name='check_code'), # 验证码
|
||||
path('doc_manage/',views.admin_doc,name='doc_manage'), # 文档管理
|
||||
path('doctemp_manage/',views.admin_doctemp,name='doctemp_manage'), # 文档模板管理
|
||||
path('setting/',views.admin_setting,name="sys_setting"), # 应用设置
|
||||
path('check_code/',views.check_code,name='check_code'), # 注册验证码
|
||||
path('forget_pwd/',views.forget_pwd,name='forget_pwd'), # 忘记密码
|
||||
path('send_email_vcode/',views.send_email_vcode,name='send_email_vcode'), # 忘记密码发送邮件验证码
|
||||
|
||||
]
|
77
app_admin/utils.py
Normal file
@ -0,0 +1,77 @@
|
||||
# coding:utf-8
|
||||
# @文件: utils.py
|
||||
# @创建者:州的先生
|
||||
# #日期:2019/11/23
|
||||
# 博客地址:zmister.com
|
||||
|
||||
import smtplib
|
||||
from django.conf import settings
|
||||
from email.mime.text import MIMEText
|
||||
from app_admin.models import SysSetting
|
||||
import random
|
||||
|
||||
# 生成数字验证码
|
||||
def generate_vcode(n=6):
|
||||
# 生成数字验证码
|
||||
_num = ''.join(map(str, range(3, 10)))
|
||||
vcode_str = ''.join(random.sample(_num, n))
|
||||
return vcode_str
|
||||
|
||||
# 发送电子邮件
|
||||
def send_email(to_email,vcode_str):
|
||||
email_enable = SysSetting.objects.get(types="basic",name='enable_email')
|
||||
if email_enable.value == 'on':
|
||||
smtp_host = SysSetting.objects.get(types='email',name='smtp_host').value
|
||||
send_emailer = SysSetting.objects.get(types='email', name='send_emailer').value
|
||||
smtp_port = SysSetting.objects.get(types='email', name='smtp_port').value
|
||||
username = SysSetting.objects.get(types='email', name='username').value
|
||||
pwd = SysSetting.objects.get(types='email', name='pwd').value
|
||||
ssl = SysSetting.objects.get(types='email',name='smtp_ssl').value
|
||||
print(smtp_host,smtp_port,send_emailer,username,pwd)
|
||||
|
||||
msg_from = send_emailer # 发件人邮箱
|
||||
passwd = dectry(pwd) # 发件人邮箱密码
|
||||
msg_to = to_email # 收件人邮箱
|
||||
if ssl:
|
||||
s = smtplib.SMTP_SSL(smtp_host, int(smtp_port)) # 发件箱邮件服务器及端口号
|
||||
else:
|
||||
s = smtplib.SMTP(smtp_host, int(smtp_host))
|
||||
subject = "MrDoc - 重置密码验证码"
|
||||
content = "你的验证码为:{},验证码30分钟内有效!".format(vcode_str)
|
||||
|
||||
msg = MIMEText(content, _subtype='html', _charset='utf-8')
|
||||
msg['Subject'] = subject
|
||||
msg['From'] = 'MrDoc助手[{}]'.format(msg_from)
|
||||
msg['To'] = msg_to
|
||||
try:
|
||||
s.login(username, passwd)
|
||||
s.sendmail(msg_from, msg_to, msg.as_string())
|
||||
return True
|
||||
except smtplib.SMTPException as e:
|
||||
print(repr(e))
|
||||
return False
|
||||
finally:
|
||||
s.quit()
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
# 加密
|
||||
def enctry(s):
|
||||
k = settings.SECRET_KEY
|
||||
encry_str = ""
|
||||
for i,j in zip(s,k):
|
||||
# i为字符,j为秘钥字符
|
||||
temp = str(ord(i)+ord(j))+'_' # 加密字符 = 字符的Unicode码 + 秘钥的Unicode码
|
||||
encry_str = encry_str + temp
|
||||
return encry_str
|
||||
|
||||
# 解密
|
||||
def dectry(p):
|
||||
k = settings.SECRET_KEY
|
||||
dec_str = ""
|
||||
for i,j in zip(p.split("_")[:-1],k):
|
||||
# i 为加密字符,j为秘钥字符
|
||||
temp = chr(int(i) - ord(j)) # 解密字符 = (加密Unicode码字符 - 秘钥字符的Unicode码)的单字节字符
|
||||
dec_str = dec_str+temp
|
||||
return dec_str
|
@ -4,10 +4,12 @@ from django.contrib.auth import authenticate,login,logout # 认证相关方法
|
||||
from django.contrib.auth.models import User # Django默认用户模型
|
||||
from django.contrib.auth.decorators import login_required # 登录需求装饰器
|
||||
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage,InvalidPage # 后端分页
|
||||
from app_admin.decorators import superuser_only
|
||||
import json
|
||||
import datetime
|
||||
from app_admin.decorators import superuser_only,open_register
|
||||
import json,datetime,hashlib
|
||||
from app_doc.models import *
|
||||
from app_admin.models import *
|
||||
from app_admin.utils import *
|
||||
|
||||
|
||||
# 返回验证码图片
|
||||
def check_code(request):
|
||||
@ -53,6 +55,7 @@ def log_in(request):
|
||||
|
||||
|
||||
# 注册视图
|
||||
@open_register
|
||||
def register(request):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('/')
|
||||
@ -69,10 +72,10 @@ def register(request):
|
||||
email_exit = User.objects.filter(email=email)
|
||||
username_exit = User.objects.filter(username=username)
|
||||
if email_exit.count() > 0:
|
||||
errormsg = '电子邮箱已经被注册使用,请更换电子邮箱地址!'
|
||||
errormsg = '此电子邮箱已被注册!'
|
||||
return render(request, 'register.html', locals())
|
||||
elif username_exit.count() > 0:
|
||||
errormsg = '用户名已存在,请换一个用户名!'
|
||||
errormsg = '用户名已被使用!'
|
||||
return render(request, 'register.html', locals())
|
||||
elif len(password) < 6:
|
||||
errormsg = '密码必须大于等于6位!'
|
||||
@ -110,6 +113,62 @@ def log_out(request):
|
||||
return redirect(request.META['HTTP_REFERER'])
|
||||
|
||||
|
||||
# 忘记密码
|
||||
def forget_pwd(request):
|
||||
if request.method == 'GET':
|
||||
return render(request,'forget_pwd.html',locals())
|
||||
elif request.method == 'POST':
|
||||
email = request.POST.get("email",None) # 邮箱
|
||||
vcode = request.POST.get("vcode",None) # 验证码
|
||||
new_pwd= request.POST.get('password',None) # 密码
|
||||
new_pwd_confirm = request.POST.get('confirm_password')
|
||||
# 查询验证码和邮箱是否匹配
|
||||
try:
|
||||
data = EmaiVerificationCode.objects.get(email_name=email,verification_code=vcode,verification_type='忘记密码')
|
||||
expire_time = data.expire_time
|
||||
print(expire_time)
|
||||
if expire_time > datetime.datetime.now():
|
||||
user = User.objects.get(email=email)
|
||||
user.set_password(new_pwd)
|
||||
user.save()
|
||||
errormsg = "修改密码成功,请返回登录!"
|
||||
return render(request, 'forget_pwd.html', locals())
|
||||
else:
|
||||
errormsg = "验证码已过期"
|
||||
return render(request, 'forget_pwd.html', locals())
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
errormsg = "验证码错误"
|
||||
return render(request,'forget_pwd.html',locals())
|
||||
|
||||
|
||||
# 发送电子邮箱验证码
|
||||
def send_email_vcode(request):
|
||||
if request.method == 'POST':
|
||||
email = request.POST.get('email',None)
|
||||
is_email = User.objects.filter(email=email)
|
||||
if is_email.count() != 0:
|
||||
vcode_str = generate_vcode()
|
||||
# 发送邮件
|
||||
send_status = send_email(to_email=email, vcode_str=vcode_str)
|
||||
if send_status:
|
||||
# 生成过期时间
|
||||
now_time = datetime.datetime.now()
|
||||
expire_time = now_time + datetime.timedelta(minutes=30)
|
||||
# 创建数据库记录
|
||||
EmaiVerificationCode.objects.create(
|
||||
email_name = email,
|
||||
verification_type = '忘记密码',
|
||||
verification_code = vcode_str,
|
||||
expire_time = expire_time
|
||||
)
|
||||
return JsonResponse({'status':True,'data':'发送成功'})
|
||||
else:
|
||||
return JsonResponse({'status':False,'data':'发送验证码出错,请重试!'})
|
||||
|
||||
else:
|
||||
return JsonResponse({'status':False,'data':'电子邮箱不存在!'})
|
||||
|
||||
# 管理员后台首页 - 用户管理
|
||||
@superuser_only
|
||||
def admin_user(request):
|
||||
@ -317,3 +376,109 @@ def change_pwd(request):
|
||||
return JsonResponse({'status':False,'data':'修改出错'})
|
||||
else:
|
||||
return HttpResponse('方法错误')
|
||||
|
||||
|
||||
# 管理员后台 - 应用设置
|
||||
@superuser_only
|
||||
def admin_setting(request):
|
||||
email_settings = SysSetting.objects.filter(types="email")
|
||||
if email_settings.count() == 6:
|
||||
emailer = email_settings.get(name='send_emailer')
|
||||
email_host = email_settings.get(name='smtp_host')
|
||||
email_port = email_settings.get(name='smtp_port')
|
||||
email_username = email_settings.get(name="username")
|
||||
email_ssl = email_settings.get(name="smtp_ssl")
|
||||
email_pwd = email_settings.get(name="pwd")
|
||||
if request.method == 'GET':
|
||||
return render(request,'app_admin/admin_setting.html',locals())
|
||||
elif request.method == 'POST':
|
||||
types = request.POST.get('type',None)
|
||||
# 基础设置
|
||||
if types == 'basic':
|
||||
close_register = request.POST.get('close_register',None)
|
||||
static_code = request.POST.get('static_code',None)
|
||||
ad_code = request.POST.get('ad_code',None)
|
||||
beian_code = request.POST.get('beian_code',None)
|
||||
enbale_email = request.POST.get("enable_email",None)
|
||||
# 更新开放注册状态
|
||||
SysSetting.objects.update_or_create(
|
||||
name='close_register',
|
||||
defaults={'value':close_register,'types':'basic'}
|
||||
)
|
||||
# 更新统计代码状态
|
||||
SysSetting.objects.update_or_create(
|
||||
name = 'static_code',
|
||||
defaults={'value':static_code,'types':'basic'}
|
||||
)
|
||||
# 更新广告代码状态
|
||||
SysSetting.objects.update_or_create(
|
||||
name = 'ad_code',
|
||||
defaults={'value':ad_code,'types':'basic'}
|
||||
)
|
||||
# 更新备案号
|
||||
SysSetting.objects.update_or_create(
|
||||
name='beian_code',
|
||||
defaults={'value':beian_code,'types':'basic'}
|
||||
)
|
||||
# 更新邮箱启用状态
|
||||
SysSetting.objects.update_or_create(
|
||||
name='enable_email',
|
||||
defaults={'value': enbale_email, 'types': 'basic'}
|
||||
)
|
||||
|
||||
return render(request,'app_admin/admin_setting.html',locals())
|
||||
elif types == 'email':
|
||||
# 读取上传的参数
|
||||
emailer = request.POST.get("send_emailer",None)
|
||||
host = request.POST.get("smtp_host",None)
|
||||
port = request.POST.get("smtp_port",None)
|
||||
username = request.POST.get("smtp_username",None)
|
||||
pwd = request.POST.get("smtp_pwd",None)
|
||||
ssl = request.POST.get("smtp_ssl",None)
|
||||
# 对密码进行加密
|
||||
pwd = enctry(pwd)
|
||||
if emailer != None:
|
||||
# 更新发件箱
|
||||
SysSetting.objects.update_or_create(
|
||||
name = 'send_emailer',
|
||||
defaults={"value":emailer,"types":'email'}
|
||||
)
|
||||
if host != None:
|
||||
# 更新邮箱主机
|
||||
SysSetting.objects.update_or_create(
|
||||
name='smtp_host',
|
||||
defaults={"value": host, "types": 'email'}
|
||||
)
|
||||
if port != None:
|
||||
# 更新邮箱主机端口
|
||||
SysSetting.objects.update_or_create(
|
||||
name='smtp_port',
|
||||
defaults={"value": port, "types": 'email'}
|
||||
)
|
||||
if username != None:
|
||||
# 更新用户名
|
||||
SysSetting.objects.update_or_create(
|
||||
name='username',
|
||||
defaults={"value": username, "types": 'email'}
|
||||
)
|
||||
if pwd != None:
|
||||
# 更新密码
|
||||
SysSetting.objects.update_or_create(
|
||||
name='pwd',
|
||||
defaults={"value": pwd, "types": 'email'}
|
||||
)
|
||||
if ssl != None:
|
||||
# 更新SSL
|
||||
SysSetting.objects.update_or_create(
|
||||
name='smtp_ssl',
|
||||
defaults={"value": ssl, "types": 'email'}
|
||||
)
|
||||
email_settings = SysSetting.objects.filter(types="email")
|
||||
if email_settings.count() == 6:
|
||||
emailer = email_settings.get(name='send_emailer')
|
||||
email_host = email_settings.get(name='smtp_host')
|
||||
email_port = email_settings.get(name='smtp_port')
|
||||
email_username = email_settings.get(name="username")
|
||||
email_ssl = email_settings.get(name="smtp_ssl")
|
||||
email_pwd = email_settings.get(name="pwd")
|
||||
return render(request, 'app_admin/admin_setting.html',locals())
|
||||
|
BIN
docs/mrdoc_admin.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
docs/mrdoc_docdetail.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
docs/mrdoc_doctemp.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
docs/mrdoc_index.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/mrdoc_index.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
docs/mrdoc_login.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/mrdoc_register.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
docs/mrdoc_user.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
docs/mrdoc_write.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
static/404.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
static/favicon_16.png
Normal file
After Width: | Height: | Size: 399 B |
@ -349,3 +349,8 @@ li.active > a{
|
||||
.switch-font{
|
||||
font-family: Serif;
|
||||
}
|
||||
|
||||
/* 广告样式 */
|
||||
.ad-code{
|
||||
margin:10px;
|
||||
}
|
28
static/mrdoc.js
Normal file
@ -0,0 +1,28 @@
|
||||
//修改用户密码
|
||||
changePwd = function(uid,username){
|
||||
layer.open({
|
||||
type:1,
|
||||
title:'修改密码',
|
||||
area:'300px;',
|
||||
id:'changePwd',
|
||||
content:'<div style="padding:10px 0 0 20px;">修改用户[' + username + ']的密码:</div><div style="padding: 20px;"><input class="layui-input" type="password" id="newPwd1" style="margin-bottom:10px;" placeholder="输入新密码" required lay-verify="required"><input class="layui-input" type="password" id="newPwd2" placeholder="再次确认新密码" required lay-verify="required"></div>',
|
||||
btn:['确认修改','取消'],
|
||||
yes:function (index,layero) {
|
||||
data = {
|
||||
'password':$("#newPwd1").val(),
|
||||
'password2':$("#newPwd2").val(),
|
||||
}
|
||||
$.post("{% url 'modify_pwd' %}",data,function(r){
|
||||
if(r.status){
|
||||
//修改成功
|
||||
window.location.reload();
|
||||
//layer.close(index)
|
||||
}else{
|
||||
//修改失败,提示
|
||||
//console.log(r)
|
||||
layer.msg(r.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
};
|
28
template/403.html
Normal file
@ -0,0 +1,28 @@
|
||||
{% load staticfiles %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>拒绝访问 - MrDoc</title>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'mrdoc.css' %}" rel="stylesheet">
|
||||
</head>
|
||||
<body class="layui-layout-body">
|
||||
<!-- 页头 -->
|
||||
{% include 'app_doc/head_base.html' %}
|
||||
<!-- 页头结束 -->
|
||||
|
||||
<div class="layui-main">
|
||||
<div style="text-align: center;margin-top: 40px;">
|
||||
<h1>
|
||||
<strong>你无权访问当前页面……</strong>
|
||||
</h1>
|
||||
<!--<img src="{% static '404.png' %}">-->
|
||||
<p><a href="{% url 'pro_list' %}" >返回首页</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="{% static 'layui/layui.all.js' %}"></script>
|
||||
</body>
|
||||
</html>
|
@ -3,51 +3,20 @@
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>页面未找到 - MrDoc</title>
|
||||
<title>404 页面未找到 - MrDoc</title>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'style.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'mrdoc.css' %}" rel="stylesheet">
|
||||
</head>
|
||||
<body class="layui-layout-body">
|
||||
<div class="layui-header">
|
||||
<div class="layui-main">
|
||||
<a class="logo" href="{% url 'pro_list' %}">
|
||||
{# <img src="/media/logo.png" />#}
|
||||
<h1><strong>MrDoc</strong></h1>
|
||||
</a>
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> {{request.user.username}}
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
{% if request.user.is_superuser %}
|
||||
<dd><a href="{% url 'user_manage' %}">进入后台</a></dd>
|
||||
{% endif %}
|
||||
<dd><a href="{% url 'manage_doc' %}">管理文档</a></dd>
|
||||
<dd><a href="javascript:void(0);">修改密码</a></dd>
|
||||
<dd><a href="{% url 'logout' %}">退出登录</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> 游客
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a href="{% url 'register' %}">注册</a></dd>
|
||||
<dd><a href="{% url 'login' %}">登录</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 页头 -->
|
||||
{% include 'app_doc/head_base.html' %}
|
||||
<!-- 页头结束 -->
|
||||
<div class="layui-main">
|
||||
<div style="text-align: center;margin-top: 20px;">
|
||||
<h1>
|
||||
<strong>页面未找到……</strong>
|
||||
</h1>
|
||||
<div style="text-align: center;margin-top: 40px;">
|
||||
<!--<h1>-->
|
||||
<!--<strong>页面未找到……</strong>-->
|
||||
<!--</h1>-->
|
||||
<img src="{% static '404.png' %}">
|
||||
<p><a href="{% url 'pro_list' %}" >返回首页</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,6 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}{% endblock %} - 后台管理 - MrDoc</title>
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<style>
|
||||
.logo img{
|
||||
@ -52,6 +53,9 @@
|
||||
<li class="layui-nav-item layui-nav-itemed">
|
||||
<a href="{% url 'user_manage' %}"><i class="layui-icon layui-icon-user"></i> 用户管理</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-nav-itemed">
|
||||
<a href="{% url 'sys_setting' %}"><i class="layui-icon layui-icon-user"></i> 应用设置</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
@ -64,7 +68,7 @@
|
||||
|
||||
<div class="layui-footer" style="text-align:center;">
|
||||
<!-- 底部固定区域 -->
|
||||
© <a href="">MrDoc</a>
|
||||
© 2019 <a href="http://mrdoc.zmister.com" target="_blank">MrDoc</a> - 一个简单的文档系统
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -43,8 +43,8 @@
|
||||
<td>{{ doc.create_time }}</td>
|
||||
<td>
|
||||
{# <a href="javascript:void(0);" onclick="insertTemp('{{temp.id}}');">查看</a>#}
|
||||
<a href="{% url 'modify_doc' doc_id=doc.id %}" target="_blank">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delDoc('{{doc.id}}');">删除</a>
|
||||
<a href="{% url 'modify_doc' doc_id=doc.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delDoc('{{doc.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -42,8 +42,8 @@
|
||||
<td>{{ temp.create_time }}</td>
|
||||
<td>
|
||||
{# <a href="javascript:void(0);" onclick="insertTemp('{{temp.id}}');">查看</a>#}
|
||||
<a href="{% url 'modify_doctemp' doctemp_id=temp.id %}" target="_blank">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delTemp('{{temp.id}}');">删除</a>
|
||||
<a href="{% url 'modify_doctemp' doctemp_id=temp.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delTemp('{{temp.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -49,9 +49,9 @@
|
||||
<td>{{ pro.create_time }}</td>
|
||||
<td>{{ pro.create_user }}</td>
|
||||
<td>
|
||||
<a href="{% url 'pro_index' pro_id=pro.id %}" target="_blank">查看</a>
|
||||
<a href="javascript:void(0);" onclick="modifyProject('{{pro.id}}','{{pro.name}}','{{pro.intro}}')">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delProject('{{pro.id}}');">删除</a>
|
||||
<a href="{% url 'pro_index' pro_id=pro.id %}" target="_blank" class="layui-btn layui-btn-normal layui-btn-xs">查看</a>
|
||||
<a href="javascript:void(0);" onclick="modifyProject('{{pro.id}}','{{pro.name}}','{{pro.intro}}')" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delProject('{{pro.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
121
template/app_admin/admin_setting.html
Normal file
@ -0,0 +1,121 @@
|
||||
{% extends 'app_admin/admin_base.html' %}
|
||||
{% load staticfiles %}
|
||||
{% block title %}应用设置{% endblock %}
|
||||
{% block content %}
|
||||
<div class="layui-card-header" style="margin-bottom: 10px;">
|
||||
<div class="layui-row">
|
||||
<span style="font-size:18px;">应用设置
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
<div class="layui-tab">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">基础设置</li>
|
||||
<li>邮箱设置</li>
|
||||
<!--<li>广告设置</li>-->
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<!-- 网站设置 -->
|
||||
<div class="layui-tab-item layui-show">
|
||||
<form class="layui-form" action="{% url 'sys_setting' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="text" name="type" hidden value="basic">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">禁止注册</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="close_register" lay-skin="switch" lay-text="开启|关闭" {% if close_register %}checked{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">启用邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="enable_email" lay-skin="switch" lay-text="开启|关闭" {% if enable_email %}checked{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">统计代码</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="static_code" placeholder="如果需要调用第三方的统计功能,请将第三方统计工具代码输入至此,可以包含<script>标签" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">广告代码</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="ad_code" placeholder="如果需要在文档正文上方添加广告,请将广告相关代码输入至此,可以包含<script>标签" class="layui-textarea">{{ad_code}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="formDemo">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- 网站设置结束 -->
|
||||
<!-- 邮箱设置 -->
|
||||
<div class="layui-tab-item">
|
||||
<form class="layui-form" action="" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="text" name="type" hidden value="email">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发件邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="email" name="send_emailer" class="layui-input" required value="{{emailer.value}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">SMTP 主机</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="smtp_host" class="layui-input" required value="{{email_host.value}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">SMTP 端口</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="smtp_port" class="layui-input" required value="{{email_port.value}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">SMTP 用户名</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="smtp_username" class="layui-input" required value="{{email_username.value}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">SMTP 密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="smtp_pwd" class="layui-input" required value="{{email_pwd.value}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">使用SSL</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="smtp_ssl" lay-skin="switch" lay-text="开启|关闭" {% if email_ssl %}checked{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="formDemo">保存邮箱设置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- 邮箱设置结束 -->
|
||||
<!-- 广告设置 -->
|
||||
<div class="layui-tab-item">内容3</div>
|
||||
<!-- 广告设置结束 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -6,50 +6,21 @@
|
||||
<title>{% block title %}{% endblock %} - MrDoc</title>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.css' %}" />
|
||||
<link href="{% static 'style.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'mrdoc.css' %}" rel="stylesheet">
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
{% block custom_style %}{% endblock %}
|
||||
</head>
|
||||
<body class="layui-layout-body">
|
||||
<div class="layui-header">
|
||||
<div class="layui-main">
|
||||
<a class="logo" href="{% url 'pro_list' %}">
|
||||
{# <img src="/media/logo.png" />#}
|
||||
<h1>
|
||||
<strong>MrDoc</strong>
|
||||
<span style="font-size: 16px;">{% block subtitle %}{% endblock %}</span>
|
||||
</h1>
|
||||
</a>
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> {{request.user.username}}
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a href="{% url 'manage_doc' %}">管理文档</a></dd>
|
||||
{# <dd><a href="javascript:void(0);">修改密码</a></dd>#}
|
||||
<dd><a href="{% url 'logout' %}">退出登录</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> 游客
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<!-- <dd><a href="">基本资料</a></dd> -->
|
||||
<dd><a href="javascript:void(0);">注册</a></dd>
|
||||
<dd><a href="{% url 'login' %}">登录</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 页头 -->
|
||||
{% include 'app_doc/head_base.html' %}
|
||||
<!-- 页头结束 -->
|
||||
|
||||
<!-- 主体开始 -->
|
||||
<div class="layui-main">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<!-- 主体结束 -->
|
||||
|
||||
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="{% static 'layui/layui.all.js' %}"></script>
|
||||
@ -114,7 +85,9 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
<script src="{% static 'mrdoc.js' %}"></script>
|
||||
{% block custom_script %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
40
template/app_doc/head_base.html
Normal file
@ -0,0 +1,40 @@
|
||||
<div class="layui-header">
|
||||
<div class="layui-main">
|
||||
<a class="logo" href="{% url 'pro_list' %}">
|
||||
<h1><strong>MrDoc</strong></h1>
|
||||
</a>
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> {{request.user.username}}
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<!-- <dd><a href="">基本资料</a></dd> -->
|
||||
{% if request.user.is_superuser %}
|
||||
<dd><a href="{% url 'user_manage' %}">进入后台</a></dd>
|
||||
{% endif %}
|
||||
<dd><a href="{% url 'manage_doc' %}">管理文档</a></dd>
|
||||
<dd><a href="javascript:void(0);" onclick="changePwd('{{ request.user.id }}','{{ request.user.username }}' )">修改密码</a></dd>
|
||||
<dd><a href="{% url 'logout' %}">退出登录</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> 游客
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<!-- <dd><a href="">基本资料</a></dd> -->
|
||||
{% if close_register == 'on' %}
|
||||
<dd><a href="{% url 'login' %}">登录</a></dd>
|
||||
{% else %}
|
||||
<dd><a href="{% url 'register' %}">注册</a></dd>
|
||||
<dd><a href="{% url 'login' %}">登录</a></dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
@ -4,8 +4,9 @@
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}{% endblock %} - MrDoc</title>
|
||||
<title>{% block title %}{% endblock %} - 个人中心 - MrDoc</title>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
<style>
|
||||
.logo img{
|
||||
height: 30px;
|
||||
|
@ -46,8 +46,8 @@
|
||||
<td>{{ doc.create_time }}</td>
|
||||
<td>
|
||||
{# <a href="javascript:void(0);" onclick="insertTemp('{{temp.id}}');">查看</a>#}
|
||||
<a href="{% url 'modify_doc' doc_id=doc.id %}" target="_blank">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delDoc('{{doc.id}}');">删除</a>
|
||||
<a href="{% url 'modify_doc' doc_id=doc.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delDoc('{{doc.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -40,8 +40,8 @@
|
||||
<td>{{ temp.create_time }}</td>
|
||||
<td>
|
||||
{# <a href="javascript:void(0);" onclick="insertTemp('{{temp.id}}');">查看</a>#}
|
||||
<a href="{% url 'modify_doctemp' doctemp_id=temp.id %}" target="_blank">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delTemp('{{temp.id}}');">删除</a>
|
||||
<a href="{% url 'modify_doctemp' doctemp_id=temp.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delTemp('{{temp.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -42,9 +42,9 @@
|
||||
<td>{{ pro.intro }}</td>
|
||||
<td>{{ pro.create_time }}</td>
|
||||
<td>
|
||||
<a href="{% url 'pro_index' pro_id=pro.id %}" target="_blank">查看</a>
|
||||
<a href="javascript:void(0);" onclick="modifyProject('{{pro.id}}','{{pro.name}}','{{pro.intro}}')">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delProject('{{pro.id}}');">删除</a>
|
||||
<a href="{% url 'pro_index' pro_id=pro.id %}" target="_blank" class="layui-btn layui-btn-normal layui-btn-xs">查看</a>
|
||||
<a href="javascript:void(0);" onclick="modifyProject('{{pro.id}}','{{pro.name}}','{{pro.intro}}')" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
|
||||
<a href="javascript:void(0);" onclick="delProject('{{pro.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -5,51 +5,15 @@
|
||||
<meta charset="UTF-8">
|
||||
<title>MrDoc - 一个简单的文档写作系统</title>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'style.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'mrdoc.css' %}" rel="stylesheet">
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
</head>
|
||||
<body class="layui-layout-body">
|
||||
<div class="layui-header">
|
||||
<div class="layui-main">
|
||||
<a class="logo" href="{% url 'pro_list' %}">
|
||||
{# <img src="/media/logo.png" />#}
|
||||
<h1><strong>MrDoc</strong></h1>
|
||||
</a>
|
||||
{# <div class="component">#}
|
||||
{# <div class="layui-input-inline">#}
|
||||
{# <input class="layui-input" placeholder="搜索文集"/>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> {{request.user.username}}
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<!-- <dd><a href="">基本资料</a></dd> -->
|
||||
{% if request.user.is_superuser %}
|
||||
<dd><a href="{% url 'user_manage' %}">进入后台</a></dd>
|
||||
{% endif %}
|
||||
<dd><a href="{% url 'manage_doc' %}">管理文档</a></dd>
|
||||
<dd><a href="javascript:void(0);" onclick="changePwd('{{ request.user.id }}','{{ request.user.username }}' )">修改密码</a></dd>
|
||||
<dd><a href="{% url 'logout' %}">退出登录</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="layui-icon layui-icon-username"></i> 游客
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<!-- <dd><a href="">基本资料</a></dd> -->
|
||||
<dd><a href="{% url 'register' %}">注册</a></dd>
|
||||
<dd><a href="{% url 'login' %}">登录</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 页头 -->
|
||||
{% include 'app_doc/head_base.html' %}
|
||||
<!-- 页头结束 -->
|
||||
|
||||
<!-- 主体 -->
|
||||
<div class="layui-main">
|
||||
{% for p in project_list %}
|
||||
<div class="project-item">
|
||||
@ -94,7 +58,7 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主体结束 -->
|
||||
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="{% static 'layui/layui.all.js' %}"></script>
|
||||
{% block custom_script %}
|
||||
@ -187,8 +151,10 @@
|
||||
},
|
||||
})
|
||||
};
|
||||
|
||||
</script>
|
||||
<!-- 统计代码开始 -->
|
||||
{{ static | safe }}
|
||||
<!-- 统计代码结束 -->
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
@ -9,7 +9,8 @@
|
||||
<link rel="stylesheet" href="{% static 'prism/prism.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'katex/katex.min.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'share.js/css/share.min.css' %}" />
|
||||
<link href="{% static 'style.css' %}" rel="stylesheet">
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
<link href="{% static 'mrdoc.css' %}" rel="stylesheet">
|
||||
<style>
|
||||
.doc-content ul li{
|
||||
list-style:disc;
|
||||
@ -69,6 +70,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 左侧目录栏结束 -->
|
||||
|
||||
<!-- 右侧文档栏 -->
|
||||
<div class="doc-body">
|
||||
<!-- 文档导航 -->
|
||||
@ -105,11 +107,12 @@
|
||||
<div class="doc-body-content-div">
|
||||
<!-- 文档内容 -->
|
||||
<div class="doc-content">
|
||||
<!-- 标题 -->
|
||||
<div class="doc-info">
|
||||
{% if doc %}
|
||||
<h1>{{ doc.name }}</h1>
|
||||
<hr>
|
||||
<p style="color: #cccccc;">
|
||||
<p style="color: #666;">
|
||||
<i class="layui-icon layui-icon-date"></i> {{ doc.create_time }}
|
||||
<i class="layui-icon layui-icon-user"></i> {{ doc.create_user.username }}
|
||||
</p>
|
||||
@ -117,7 +120,16 @@
|
||||
<h1>共有{{ search_result.count }}个搜索结果</h1>
|
||||
<hr>
|
||||
{% endif %}
|
||||
<!-- 广告代码开始 -->
|
||||
{% if ad_code %}
|
||||
<div class="ad-code">
|
||||
{{ ad_code | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- 广告代码结束 -->
|
||||
</div>
|
||||
<!-- 标题结束 -->
|
||||
<!-- 正文开始 -->
|
||||
<div class="markdown-body" id="content">
|
||||
{% if doc %}
|
||||
{# {{ doc.content | safe }}#}
|
||||
@ -136,6 +148,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- 正文结束 -->
|
||||
</div>
|
||||
<!-- 文档目录 -->
|
||||
<div class="doc-cata">
|
||||
@ -170,6 +183,17 @@
|
||||
$.ajaxSetup({
|
||||
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
|
||||
});
|
||||
//解析Markdown为HTML
|
||||
editormd.markdownToHTML("content", {
|
||||
htmlDecode : "style,script,iframe",
|
||||
emoji : true,
|
||||
taskList : true,
|
||||
tex : true, // 科学公式
|
||||
flowChart : true, // 流程图
|
||||
sequenceDiagram : true, // 默认不解析
|
||||
tocm : true, //目录
|
||||
//tocContainer : "#toc-container"
|
||||
});
|
||||
//为当前页面的目录链接添加样式
|
||||
$("nav li a").each(function (i) {
|
||||
var $me = $(this);
|
||||
@ -183,17 +207,6 @@
|
||||
$me.parent().removeClass("active");
|
||||
}
|
||||
});
|
||||
//解析Markdown为HTML
|
||||
editormd.markdownToHTML("content", {
|
||||
htmlDecode : "style,script,iframe",
|
||||
emoji : true,
|
||||
taskList : true,
|
||||
tex : true, // 科学公式
|
||||
flowChart : true, // 流程图
|
||||
sequenceDiagram : true, // 默认不解析
|
||||
tocm : true, //目录
|
||||
//tocContainer : "#toc-container"
|
||||
});
|
||||
</script>
|
||||
<!-- 页面初始化字体设置 -->
|
||||
<script>
|
||||
@ -294,6 +307,9 @@
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<!-- 统计代码开始 -->
|
||||
{{ static | safe }}
|
||||
<!-- 统计代码结束 -->
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
129
template/forget_pwd.html
Normal file
@ -0,0 +1,129 @@
|
||||
{% load staticfiles %}
|
||||
<!DOCTYPE html>
|
||||
<html lang='zh-CN'>
|
||||
<head>
|
||||
<title>忘记密码 - MrDoc</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="{% static 'layui/css/layui.css' %}" crossorigin="anonymous">
|
||||
<style>
|
||||
body{
|
||||
background-color: #fafafa;
|
||||
text-align: center;
|
||||
}
|
||||
.container{
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.login-form{
|
||||
margin-top: 15%;
|
||||
{#width: 400px;#}
|
||||
padding: 20px 50px 20px 60px;
|
||||
background-color: #fff;
|
||||
-webkit-box-shadow: #666 0px 0px 10px;
|
||||
-moz-box-shadow: #666 0px 0px 10px;
|
||||
box-shadow: #666 0px 0px 10px;
|
||||
}
|
||||
.register-link{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div class="login-form">
|
||||
<form class="layui-form" action="{% url 'forget_pwd' %}" method='POST'>
|
||||
{% csrf_token %}
|
||||
<div class="layui-form-item">
|
||||
<h2><strong>忘记密码 - MrDoc</strong></h2>
|
||||
</div>
|
||||
<span style='color:red;margin-bottom: 10px;'>{{ errormsg }}</span>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="email" id="email" required lay-verify="required" placeholder="请输入注册邮箱" class="layui-input">
|
||||
</div>
|
||||
<button class="layui-btn layui-btn-normal" type="button" id="send_email_vcode" onclick="getCode(this)">发送验证码</button>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<input type="text" name="vcode" required lay-verify="required" placeholder="请输入验证码" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<input type="password" name="password" required lay-verify="required" placeholder="请输入新密码" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<input type="password" name="confirm_password" required lay-verify="required" placeholder="请确认新密码" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<button class="layui-btn layui-btn-fluid layui-btn-radius layui-btn-normal" lay-submit type="submit">修改密码</button>
|
||||
</div>
|
||||
<a href="{% url 'login' %}" class="register-link">返回登录</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="{% static 'layui/layui.all.js' %}"></script>
|
||||
<script>
|
||||
$.ajaxSetup({
|
||||
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
|
||||
});
|
||||
layer = layui.layer;
|
||||
btn = $("#send_email_vcode");
|
||||
// 发送验证码倒计时60s
|
||||
function getCode(e) {
|
||||
email = document.getElementById("email");
|
||||
if(email.value.length == 0){
|
||||
layer.msg("请输入电子邮箱");
|
||||
}else{
|
||||
if(!(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(email.value))){
|
||||
layer.msg("电子邮箱有误,请重填")
|
||||
}else{
|
||||
//调用获取验证码的接口
|
||||
$.post("{% url 'send_email_vcode' %}",{'email':email.value},function(r){
|
||||
if(r.status){
|
||||
layer.msg("验证码发送成功,请查收!");
|
||||
}else{
|
||||
layer.msg(r.data)
|
||||
}
|
||||
});
|
||||
//按照指定的周期(以毫秒计)来调用函数或计算表达式。
|
||||
//在ajax请求之后再调用函数
|
||||
t = setInterval(function () {
|
||||
countdown(e)
|
||||
}, 1000)
|
||||
//获取验证码成功后调用倒计时函数
|
||||
countdown(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
var time = 60;
|
||||
function countdown(e){
|
||||
if (time == 0) {
|
||||
//这里时设置当时间到0的时候重新设置点击事件,并且默认time修改为60
|
||||
//e.setAttribute("onclick","getcode(this)");
|
||||
|
||||
btn.attr("disabled", false);
|
||||
btn.html("获取验证码");
|
||||
btn.removeClass("disabled");
|
||||
btn.removeClass("layui-btn-disabled")
|
||||
time = 60;
|
||||
clearInterval(t);
|
||||
}else{
|
||||
//这里是显示时间倒计时的时候点击不生效
|
||||
//e.setAttribute("onclick", '');
|
||||
|
||||
btn.addClass("disabled");
|
||||
btn.addClass("layui-btn-disabled")
|
||||
btn.attr("disabled", true);
|
||||
btn.html("重新发送(" + time + ")");
|
||||
|
||||
//document.getElementById("getcode").innerHTML="重新发送"+time;
|
||||
time--;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</html>
|
@ -39,12 +39,12 @@
|
||||
<form class="layui-form" action="{% url 'login' %}" method='POST'>
|
||||
{% csrf_token %}
|
||||
<div class="layui-form-item">
|
||||
<h2><strong>登录 - MrDoc</strong></h2>
|
||||
<h2><strong>登录 - <a href="/">MrDoc</a></strong></h2>
|
||||
</div>
|
||||
<span style='color:red;margin-bottom: 10px;'>{{ errormsg }}</span>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="username" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="username" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
@ -57,7 +57,16 @@
|
||||
<button class="layui-btn layui-btn-fluid layui-btn-radius layui-btn-normal" lay-submit lay-filter="formDemo" type="submit">登录</button>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{% url 'register' %}" class="register-link">注册新账号</a>
|
||||
{% if close_register == 'on' %}
|
||||
本站暂不开放注册
|
||||
{% else %}
|
||||
<a href="{% url 'register' %}" class="register-link">注册账号</a>
|
||||
{% endif %}
|
||||
|
||||
{% if enable_email == 'on' %}
|
||||
<a href="{% url 'forget_pwd' %}" class="register-link">忘记密码</a>
|
||||
{% endif %}
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|