# 报障系统 **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: 判断是否有用户:显示用户名 否则 : 登录,注册
{% if request.session.username %} {{ request.session.username }} {% else %} 登录注册 {% endif %}
- 博文内容布局: 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类型的值,验证密码正确与否