# 报障系统
**Repository Path**: zhangyafeii/Reporting_malfunction_system
## Basic Information
- **Project Name**: 报障系统
- **Description**: 知识库(博客系统)、报障处理接单
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 2
- **Created**: 2019-06-03
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 报障系统
## 需求分析
- 报障
> 用户:
提交记账单
自己报障记录
处理着:
查看所有人报障单
处理保障单
- 知识库(博客)
主页:
展示最新文章
展示最热文章
展示评论、赞最多
分类查看
个人博客
个人博客主页
个人文章详细:赞,踩,评论
个人博客分类:标签、分类、时间
个人博客主题定制:后台修改
后台管理
个人信息管理
个人标签
个人分类
个人文章
- 数据库设计:zhangyafei@123
用户表:id,username,pwd,email,img
博客表:bid,surfix,theme,title,summary, FK(用户表,unique=True)==OneToOne(用户表)
互粉表:id, 明星ID(用户表),粉丝ID(用户表)
1 2
2 3
1 3
3 1
报障单:uuid, title, detail, user(用户表), processor(用户表,null), status(待处理,处理中,已处理), 创建时间, 处理时间
分类表:caption FK(博客bid)
标签表:caption FK(博客bid)
文章表:id,title,summary,detail,ctime,作者PK(用户表)FK(个人分类表),主站分类(choices)
文章标签关系:文章ID 标签ID
赞踩文章关系:文章ID 用户ID 赞或踩(True,False) 联合唯一索引(文章ID 用户ID)
评论表:id,content,FK(文章),FK(用户表),ctime,parent_comment_id
- 程序目录结构
>
project
-APP(repository) -数据仓库(操作数据Model)
-APP(backend) -后台管理
-APP(web) -首页,个人博客
-utile -工具包(公共模块)
## 工作安排:
>
1.需求分析
2.数据库设计思路
3.实现数据库设计(admin添加数据)
4.主站:分类(主站)查看+分页
- 标题菜单:母版
- 登录成功: session['username'] = 'root'
- 主页html:
判断是否有用户:显示用户名
否则 : 登录,注册
- 博文内容布局:
div div -> float => 图片下方空白
asdflkjasdfkj => 文字环绕
- URL分类筛选:
url(r'^all/(?P\d+).html$', home.index, name='index'),
url(r'^', home.index),
index根据kwargs判断是否分类查询?
a. 生成分类菜单
b. 考虑是否选中
c. 根据条件model.xxx.objects.filter(**kwargs)
- URL:
from django.urls import reverse
url(r'^all/(?\d+).html$', home.index, name='index'),
在HTML中:{% url "index" article_type_id=1 %} => all/1.html
在views中:reverse('index',kwargs={"article_type_id":1}) =>all/1.html
url(r'^all/(\d+).html$', home.index, name='index'),
在HTML中:{% url "index" 1 %} =>all/1.html
在views中:reverse('index',args=(1,)) =>all/1.html
url(r'^discover.html/$', views.discover,name='discover'),
在HTML中:{% url 'table:discover' %}?id={{ article.id }} ==> "/table/discover/?id={{ article.id }}"
re_path('video2-(?P(\d+))-(?P(\d+))-(?P(\d+)).html',views.video2,name='video2'),
在HTML中 {% url 'video2' direction_id=0 classification_id=kwargs.classification_id level_id=kwargs.level_id %}"
"/video2-{{ kwargs.direction_id }}-{{ item.id }}-{{ kwargs.level_id }}.html"
- 利用reverse+分页组件完成:分类查看+分页
5. 登录,注册
- 密码:数字,字母,特殊字符
- 密码两次输入一致
密码示例:RegexField自定义密码验证规则
password = forms.RegexField(
'^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$\%\^\&\*\(\)])[0-9a-zA-Z!@#$\%\^\&\*\(\)]{8,32}$',
min_length=12,
max_length=32,
error_messages={'required': '密码不能为空.',
'invalid': '密码必须包含数字,字母、特殊字符',
'min_length': "密码长度不能小于8个字符",
'max_length': "密码长度不能大于32个字符"}
)
class RegisterForm(BaseForm, django_forms.Form):
username = django_fields.CharField()
password = django_fields.CharField()
confirm_pwd = django_fields.CharField()
def clean(self):
v1 = self.cleaned_data['password']
v2 = self.cleaned_data['confirm_pwd']
if v1 == v2:
pass
else:
from django.core.exceptions import ValidationError
raise ValidationError('密码输入不一致')
def register(request):
v = RegisterForm(request.POST)
if v.is_valid():
pass
else:
v.errors['username']
v.errors['__all__']
v.errors[NON_FIELD_ERRORS]
{
__all__: [],
username: [],
password: []
confirm_pwd: []
}
return render(request, 'register.html', {'v':v})
register.html
{{v.errors.username.0}}
{{v.non_field_errors}}
补充:验证码
1.点击更换验证码
2.验证码是否有必要是图片?有 阿里刷单事件(验证码为字符串)
3.服务端:
a.session中保存随机字符串,如:23ds
b.在页面里显示图片
客户端:
a.显示图片
b.在cookie中保存sessionid
验证码图片
验证码字符串:87fs
sessionid='asdfasdfasdfasdfasdfasdf09'
{
"asdfasdfasdfasdfasdfasdf09": {'ck': 87fs}
"ffsdfsdfsdfsdfsqq243234234": {'ck': 98fd}
"ffsdfsdfsdfsdfsqq243234234": {'ck': 98fd}
"ffsdfsdfsdfsdfsqq243234234": {'ck': 98fd}
"ffsdfsdfsdfsdfsqq243234234": {'ck': 98fd}
"ffsdfsdfsdfsdfsqq243234234": {'ck': 98fd}
"ffsdfsdfsdfsdfsqq243234234": {'ck': 98fd}
"ffsdfsdfsdfsdfsqq243234234": {'ck': 98fd}
}
ffsdfsdfsdfsdfsqq243234234 : 9999
使用:
check_code.py
Monaco.ttf
def check_code(request):
"""
检测验证码
:param request:
:return:
"""
if request.method == 'GET':
return render(request,'check_code.html')
else:
input_code = request.POST.get('code').lower()
code = request.session['check_code'].lower()
print(input_code)
print(code)
return HttpResponse('恭喜你,验证通过')
def get_check_code(request):
"""
生成验证码图片
:param request:
:return:
"""
img,code = create_validate_code()
file = BytesIO() #存到内存
img.save(file,'PNG')
request.session['check_code'] = code
print(code)
return HttpResponse(file.getvalue())
补充: 一个月免登陆
全局session过期时间:SESSION_COOKIE_AGE = 1209600 默认两周
设置session过期时间:request.session.set_expiry(60 * 60 * 24 * 30) 一个月免登陆
6. 个人博客
个人主页:http://127.0.0.1:8000/wupeiqi.html
/(\w+).html -> func(site) # wupeiqi
# 个人信息
# 博客信息
- 数据库字段+CSS文件名(warm,default)
文章最终:http://127.0.0.1:8000/wupeiqi/5.html
# 根据当前 wupeiqi + 5
obj = article.objects.filter(nid=5,blog=blog).first()
冗余
# 富文本编辑框
CKEditor
UEEditor
TinyEditor
KindEditor
# 下载插件
# 基本使用KindEditor
https://www.cnblogs.com/wupeiqi/articles/6307554.html
个人筛选:
http://127.0.0.1:8000/wupeiqi/tag/2.html
http://127.0.0.1:8000/wupeiqi/category/3.html
http://127.0.0.1:8000/wupeiqi/date/2017-02.html
# 公告
# 分类
# 标签
# 时间
# 过滤
url(r'^(?P\w+)/(?P((tag)|(date)|(category)))/(?P\w+-*\w*).html$', home.filter),
# 当前博客id、
# 数据库内置时间格式化函数
select id,count(id) as num,strftime("%Y-%m",create_time) as ctime from repository_article where blog_id={} group by strftime("%Y-%m",create_time)'.format(blog.id)
注意:个人主题定制
7. 后台管理
用户:
-普通用户(知识库+提交报障单+个人信息)
-管理员(知识库+提交报障单+个人信息+处理保障单)
-超级管理员
-知识库+提交报障单+个人信息+处理报障单+报障统计信息)
-权限管理
菜单:
-知识库管理(form验证)
-文章
-分类
-标签
还债:KindEditor,XSS攻击
-报障管理
-个人报障
-处理报障单
-报障统计信息
画图
-权限管理
-菜单
-权限
-角色
========》后台管理页面======《
依赖:bootstrap,fontawwsome
8.报障单:
后台管理
普通用户
保障列表,创建报障,修改,【查看解决方案】【评分】
工程师:
报障列表【自己 or 未】
列表:
tb.objects.filter(Q(processor_id=1)|Q(status=1)).order_by('status')
查看报障单id=1:
接单:v = tb.objects.filter(id=1,status=1).update(processor_id=11,status=2)
处理:
填写解决方案,提交status=3
===》模板
$('#temp-select').bind('change', function () {
var index = this.selectedIndex;
var index1 = $(this).get(0).selectedIndex;
var v = this.value;
var v1 = $(this).val();
console.log(index,v,index1,v1);
var $ele = this.options[index];
var content = $ele.getAttribute('v');
var content1 = $(this).find('option:selected').attr('v');
console.log(content,content1);
editor.html(content);
})
老板:
查看所有信息
页面:
图
列表
每个处理者
每个月处理了多少订单
id 创建时间 内容 处理者
1 2017-02-01 11:11 1
2 2017-03-01 11:11 11
3 2017-04-01 11:11 2
4 2017-05-01 11:11 1
5 2017-02-02 11:11 1
1. 思路
处理者列表 = select 处理着 from tb
for 处理者 in 处理者列表:
v = select * from tb where 处理者=处理者 group by 创建时间(2017-02)
2. 思路
# 每个月份全部门处理的订单个数
select * from tb group by 创建时间(%Y-%m)
select
创建时间(%Y-%m),
(select count(id) from tb as T2 where 处理者=1 and T2.ctime = T1.ctime ),
(select count(id) from tb as T2 where 处理者=2 and T2.ctime = T1.ctime ),
from tb as T1 group by 创建时间(%Y-%m)
年月 id=1 id=2
2017-02 2
2017-03 0
2017-04 0
2017-05 1
sql注入:username = input('请输入用户名:') xx or 1=1 --
pwd = input('请输入密码:')
sql = "select * from user where username=%s and pwd=%s"%(username,pwd)
或者
"select * from user where username={} and pwd={}".format(username,pwd)
cursor.execute(sql) #"select * from user where username=xx or 1=1 -- and pwd=123" sql中--是注释
cursor.fetchall()
9.权限管理
-动态菜单(关系存在数据库)
-基于角色分配(RBAC) Role Based Access Control
流程:
a.用户登录
b.根据用户获取所有的权限(url+action)
c.根据用户获取所有权限(url+action)根据url去重
d.放在左侧菜单()
作业:
1.登录,获取所有权限(url+action)
2.所有菜单()
v = Menu.objects.values('id','caption','parent_id')
[
{'id':1,'caption':'菜单1','parent_id':None},
{'id':2,'caption':'菜单2','parent_id':None},
{'id':3,'caption':'菜单3','parent_id':None},
{'id':4,'caption':'菜单1.1','parent_id':1},
{'id':5,'caption':'菜单1.2','parent_id':1},
{'id':6,'caption':'菜单1.2.1','parent_id':5},
]
===>
[
{'caption':‘菜单1','child':[{'caption':’菜单1.1'},{'caption':’菜单1.2','child':[{'caption':‘菜单1.2.1’},]}]},
{'caption':'菜单2'},
{'caption':'菜单3'},
]
思考:
a.用递归的形式将所有的菜单的等级管理列显示
b.不显示无权限的菜单
c.仅展开当前访问的菜单,其他闭合
=====> 一个类,一个装饰器,八张表
网易云账号:woshizhangyafei zyf123
一、富文本编辑器:--tinymce
--参考博客:https://blog.csdn.net/weixin_42470545/article/details/80718514
1.pip install django-tinymce
2.settings中注册timymce
INSTALLED_APPS = (
...
'tinymce',
)
3.在根urls中添加路径
urlpatterns = [
...
re_path(r'^tinymce/', include('tinymce.urls')),
]
4.在代码中
from django.db import models
from tinymce.models import HTMLField
class MyModel(models.Model):
...
content = HTMLField()
5.自定义文本编辑器大小与样式
TINYMCE_DEFAULT_CONFIG = {
'theme': 'advanced',
'width': 800,
'height': 600,
'language':'zh',
'style_formats':[ #以下这几个配置的是富文本中的样式
{'title': 'Bold text', 'inline': 'b'},
{'title': 'Red text', 'inline': 'span', 'styles': {'color': '#ff0000'}},
{'title': 'Red header', 'block': 'h1', 'styles': {'color': '#ff0000'}},
{'title': 'Example 1', 'inline': 'span', 'classes': 'example1'},
{'title': 'Example 2', 'inline': 'span', 'classes': 'example2'},
{'title': 'Table styles'},
{'title': 'Table row 1', 'selector': 'tr', 'classes': 'tablerow1'},
]
}
二、django内置的密码加密与解密(pbkdf2_sha256) 参考博客--https://blog.csdn.net/qq_16069927/article/details/81162465
from django.contrib.auth.hashers import make_password, check_password
pwd='4562154'
mpwd=make_password(pwd,None,'pbkdf2_sha256') # 创建django密码,第三个参数为加密算法
pwd_bool=check_password(pwd,mpwd)# 返回的是一个bool类型的值,验证密码正确与否