报障单的内容和其实和文章管理内容类似
1:创建数据模型
class Trouble(models.Model): '''报障单''' uuid = models.UUIDField(primary_key=True,auto_created=True, default=uuid.uuid4, editable=False) title = models.CharField(verbose_name="报障标题", max_length=1000) detail = models.TextField(verbose_name='报障详情') reportUser = models.ForeignKey(verbose_name='报修人', to="UserInfo", to_field="uid", related_name="reportUsers", on_delete=models.CASCADE, null=True) processUser = models.ForeignKey(verbose_name='处理人', to="UserInfo", to_field="uid", related_name="processUsers", on_delete=models.CASCADE, null=True) processSolution = models.TextField(verbose_name='处理方法',null=True) createTime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) processTime = models.DateTimeField(verbose_name='处理时间', auto_now_add=True) type_status = [ (0, '已删除'), (1, '待处理'), (2, '处理中'), (3, '已处理'), ] pj_choices = ( (1, '不满意'), (2, '一般'), (3, '很好'), ) status = models.IntegerField(choices=type_status, default=1) evaluate = models.IntegerField(choices=pj_choices, null=True, default=2)
2:url设置
from django.conf.urls import urlfrom django.conf.urls import includefrom .views import user,troubleurlpatterns = [ url(r'^index.html$', user.index), url(r'article-(?P\d+)-(?P \d+).html$', user.article, name='article'), url(r'^add-article.html$',user.add_article), #创建文章路由 url(r'^del-article-(?P \d+).html$', user.del_article),#删除文章路由 url(r'^edit-article-(?P \d+).html$', user.edit_article),#修改文章路由 # 一般用户: 提交报障单,查看,修改(未处理),评分(处理完成,未评分) url(r'^trouble-list.html$', trouble.trouble_list), url(r'^trouble-create.html$', trouble.trouble_create), url(r'^trouble-edit-([a-zA-Z0-9-]+).html$', trouble.trouble_edit),]
3:Form表单
# 引入文件from django import formsfrom django.forms import fieldsfrom django.forms import widgetsfrom repository import modelsclass TroubleForm(forms.Form): title = fields.CharField( max_length=32, widget=widgets.TextInput(attrs={ 'class': 'form-control', 'placeholder': '报障单标题'}) ) detail = fields.CharField( widget=widgets.Textarea(attrs={ 'id': 'detail', 'class': 'kind-content'}) )
4:增删操作。View设置后台逻辑
from django.shortcuts import render,redirect,HttpResponsefrom repository import modelsfrom forms.trouble import TroubleForm #引用form中的文章表单,用于添加、修改文章import datetime #引入时间模块def trouble_list(request): # user_info = request.session.get('user_info') # {id:'',} current_user_id = request.session['user_info']['uid'] result = models.Trouble.objects.filter(reportUser_id=current_user_id).order_by('status').\ only('uuid','title','status','createTime','processUser') return render(request,'Backend/backend_trouble_list.html',{ 'result': result})def trouble_create(request): if request.method == 'GET': form = TroubleForm() else: form = TroubleForm(request.POST) if form.is_valid(): dic = {} dic['reportUser_id'] = request.session['user_info']['uid'] # session中获取 dic['createTime'] = datetime.datetime.now() dic['status'] = 1 dic.update(form.cleaned_data) models.Trouble.objects.create(**dic) return redirect('/backend/trouble-list.html') return render(request, 'Backend/backend_trouble_create.html',{ 'form':form})def trouble_edit(request,uuid): if request.method == "GET": obj = models.Trouble.objects.filter(uuid=uuid, status=1).only('uuid', 'title', 'detail').first() if not obj: return HttpResponse('已处理中的保单章无法修改..') # initial 仅初始化 form = TroubleForm(initial={ 'title': obj.title,'detail': obj.detail,'uuid':obj.uuid}) # 执行error会进行验证 return render(request,'Backend/backend_trouble_edit.html',{ 'form':form,'uuid':uuid}) else: form = TroubleForm(data=request.POST) if form.is_valid(): # 受响应的行数 v = models.Trouble.objects.filter(uuid=uuid, status=1).update(**form.cleaned_data) if not v: return HttpResponse('已经被处理') else: return redirect('/backend/trouble-list.html') return render(request, 'Backend/backend_trouble_edit.html', { 'form': form,'uuid':uuid})
5:前台页面
5.1列表页面
{% extends 'Backend/backend_layout.html' %}{ % block conent %} { % endblock %}{ % block js %}{ % endblock %}
5.2 新增页面
{% extends 'Backend/backend_layout.html' %}{ % block css %} { % endblock %}{ % block conent %}{ % endblock %}{ % block js %} { % endblock %}
5.3 编辑页面
{% extends 'Backend/backend_layout.html' %}{ % block css %} { % endblock %}{ % block conent %}{ % endblock %}{ % block js %} { % endblock %}
6:处理报障单
6.1 url补充
from django.conf.urls import urlfrom django.conf.urls import includefrom .views import user,troubleurlpatterns = [ url(r'^index.html$', user.index), url(r'article-(?P\d+)-(?P \d+).html$', user.article, name='article'), url(r'^add-article.html$',user.add_article), #创建文章路由 url(r'^del-article-(?P \d+).html$', user.del_article),#删除文章路由 url(r'^edit-article-(?P \d+).html$', user.edit_article),#修改文章路由 # 一般用户: 提交报障单,查看,修改(未处理),评分(处理完成,未评分) url(r'^trouble-list.html$', trouble.trouble_list), url(r'^trouble-create.html$', trouble.trouble_create), url(r'^trouble-edit-([a-zA-Z0-9-]+).html$', trouble.trouble_edit), # 工程师: 处理报障单(未被接单的报障单+已经处理过的报障单) url(r'^trouble-kill-list.html$', trouble.trouble_kill_list), url(r'^trouble-kill-(?P [a-zA-Z0-9-]+).html$', trouble.trouble_kill), url(r'^ajaxGetResolveDetail.html$', trouble.getResolveDetail), #通过nid获取解决方案]
6.2 实体类的完善(常见故障类型)
from django.db import modelsimport uuid# Create your models here.class UserInfo(models.Model): '''用户表''' uid = models.BigAutoField(primary_key=True) username = models.CharField(verbose_name="用户名", max_length=64, unique=True) pwd = models.CharField(verbose_name='密码', max_length=64) email = models.EmailField(verbose_name='邮箱', unique=True) img = models.ImageField(verbose_name='头像', null=True) status=models.IntegerField(verbose_name='状态',default=1,null=False)class BlogInfo(models.Model): '''博客信息''' bid = models.BigAutoField(primary_key=True) surfix = models.CharField(verbose_name='博客后缀名', max_length=64) theme = models.CharField(verbose_name='博客主题', max_length=64) title = models.CharField(verbose_name='博客标题', max_length=1000) summary = models.CharField(verbose_name='博客简介', max_length=1000) user = models.OneToOneField(to="UserInfo", to_field="uid", on_delete=models.CASCADE, null=True) status = models.IntegerField(verbose_name='状态', default=1, null=False)class UserFans(models.Model): '''互粉表''' starUser = models.ForeignKey(verbose_name='博主', to="UserInfo", to_field="uid", related_name="starUsers", on_delete=models.CASCADE, null=True) fansUser = models.ForeignKey(verbose_name='粉丝', to="UserInfo", to_field="uid", related_name='fansUsers', on_delete=models.CASCADE, null=True) status = models.IntegerField(verbose_name='状态', default=1, null=False) class Meta: unique_together = [ ('starUser', 'fansUser'), ]class Trouble(models.Model): '''报障单''' uuid = models.UUIDField(primary_key=True,auto_created=True, default=uuid.uuid4, editable=False) title = models.CharField(verbose_name="报障标题", max_length=1000) detail = models.TextField(verbose_name='报障详情') reportUser = models.ForeignKey(verbose_name='报修人', to="UserInfo", to_field="uid", related_name="reportUsers", on_delete=models.CASCADE, null=True) processUser = models.ForeignKey(verbose_name='处理人', to="UserInfo", to_field="uid", related_name="processUsers", on_delete=models.CASCADE, null=True) processSolution = models.TextField(verbose_name='处理方法',null=True) createTime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) processTime = models.DateTimeField(verbose_name='处理时间', auto_now_add=True) type_status = [ (0, '已删除'), (1, '待处理'), (2, '处理中'), (3, '已处理'), ] pj_choices = ( (1, '不满意'), (2, '一般'), (3, '很好'), ) status = models.IntegerField(choices=type_status, default=1) evaluate = models.IntegerField(choices=pj_choices, null=True, default=2)class TroubleResolveType(models.Model): '''报障单--处理类型模板---''' nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name="报障处理类型标题", max_length=1000) detail = models.TextField(verbose_name='详细处理内容') createUser = models.ForeignKey(verbose_name='处理人', to="UserInfo", to_field="uid", related_name="createUser", on_delete=models.CASCADE, null=True) status = models.IntegerField(verbose_name='状态', default=1, null=False)class Tag(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='标签名称', max_length=32) blog = models.ForeignKey(verbose_name='所属博客', to='BlogInfo', to_field='bid', on_delete=models.CASCADE, null=True) status = models.IntegerField(verbose_name='状态', default=1, null=False)class Classification(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='分类名称', max_length=32) blog = models.ForeignKey(verbose_name='所属博客', to='BlogInfo', to_field='bid', on_delete=models.CASCADE, null=True)class Article(models.Model): nid = models.BigAutoField(primary_key=True) title = models.CharField(verbose_name='文章标题', max_length=128) summary = models.CharField(verbose_name='简介', max_length=256) blog = models.ForeignKey(verbose_name='所属博客', to='BlogInfo', to_field='bid', on_delete=models.CASCADE, null=True) create_time = models.DateTimeField(verbose_name='创建时间', null=False) read_count = models.IntegerField(verbose_name='阅读数量',default=0) comment_count = models.IntegerField(verbose_name='评论数量',default=0) up_count = models.IntegerField(verbose_name='点赞数量',default=0) down_count = models.IntegerField(verbose_name='踩数量',default=0) classification_id = models.ForeignKey(verbose_name='文章分类', to='Classification', to_field="nid", on_delete=models.CASCADE, null=True) masterStation_type = [ (1, "Python"), (2, "Linux"), (3, "OpenStack"), (4, "GoLang"), ] ms_Type = models.IntegerField(verbose_name='主站分类', choices=masterStation_type, default=None) tags=models.ManyToManyField( to='Tag', through='Article_Tag', through_fields=('article_id','tag_id') ) status = models.IntegerField(verbose_name='状态', default=1, null=False)class Article_Detail(models.Model): detail = models.TextField(verbose_name='文章详细', max_length=models.Max) article_id = models.OneToOneField(verbose_name='文章id', to='Article', to_field='nid', on_delete=models.CASCADE, null=True) status = models.IntegerField(verbose_name='状态', default=1, null=False)class Article_Tag(models.Model): # 文章标签分类 article_id = models.ForeignKey(verbose_name='文章ID', to='Article', to_field='nid', on_delete=models.CASCADE, null=True) tag_id = models.ForeignKey(verbose_name='标签ID', to='Tag', to_field='nid', on_delete=models.CASCADE, null=True) class Meta: unique_together=[("article_id","tag_id")] status = models.IntegerField(verbose_name='状态', default=1, null=False)class Article_upDown(models.Model): # 文章标签分类 article_id = models.ForeignKey(verbose_name='文章ID', to='Article', to_field='nid', on_delete=models.CASCADE, null=True) user = models.ForeignKey(verbose_name='赞或踩用户', to='UserInfo', to_field='uid',on_delete=models.CASCADE, null=True) up = models.BooleanField(verbose_name='是否赞', default=True) status = models.IntegerField(verbose_name='状态', default=1, null=False) class Meta: unique_together = [ ('article_id', 'user') ]class Article_Comment(models.Model): '''评论表''' id = models.BigAutoField(verbose_name='评论ID', primary_key=True) user = models.ForeignKey(verbose_name='评论人', to='UserInfo', to_field='uid', on_delete=models.CASCADE, null=True) comment = models.CharField(verbose_name='评论内容', max_length=1000) createTime = models.DateTimeField(verbose_name='评论时间', auto_now_add=True) reply = models.ForeignKey(verbose_name='回复评论', to='self', related_name='back', on_delete=models.CASCADE, null=True) article = models.ForeignKey(verbose_name='评论文章', to='Article', to_field='nid',on_delete=models.CASCADE, null=True) status = models.IntegerField(verbose_name='状态', default=1, null=False)
6.3 后台逻辑的完善
from django.shortcuts import render,redirect,HttpResponsefrom repository import modelsfrom forms.trouble import TroubleForm,TroubleKill #引用form中的文章表单,用于添加、修改文章from django.db.models import Qimport jsonimport datetime #引入时间模块def trouble_list(request): # user_info = request.session.get('user_info') # {id:'',} current_user_id = request.session['user_info']['uid'] result = models.Trouble.objects.filter(reportUser_id=current_user_id).order_by('status').\ only('uuid','title','status','createTime','processUser') return render(request,'Backend/backend_trouble_list.html',{ 'result': result})def trouble_create(request): if request.method == 'GET': form = TroubleForm() else: form = TroubleForm(request.POST) if form.is_valid(): dic = {} dic['reportUser_id'] = request.session['user_info']['uid'] # session中获取 dic['createTime'] = datetime.datetime.now() dic['status'] = 1 dic.update(form.cleaned_data) models.Trouble.objects.create(**dic) return redirect('/backend/trouble-list.html') return render(request, 'Backend/backend_trouble_create.html',{ 'form':form})def trouble_edit(request,uuid): if request.method == "GET": obj = models.Trouble.objects.filter(uuid=uuid, status=1).only('uuid', 'title', 'detail').first() if not obj: return HttpResponse('已处理中的保单章无法修改..') # initial 仅初始化 form = TroubleForm(initial={ 'title': obj.title,'detail': obj.detail,'uuid':obj.uuid}) # 执行error会进行验证 return render(request,'Backend/backend_trouble_edit.html',{ 'form':form,'uuid':uuid}) else: form = TroubleForm(data=request.POST) if form.is_valid(): # 受响应的行数 v = models.Trouble.objects.filter(uuid=uuid, status=1).update(**form.cleaned_data) if not v: return HttpResponse('已经被处理') else: return redirect('/backend/trouble-list.html') return render(request, 'Backend/backend_trouble_edit.html', { 'form': form,'uuid':uuid})def trouble_kill_list(request): current_user_id = request.session['user_info']['uid'] result = models.Trouble.objects.filter(Q(reportUser_id=current_user_id)|Q(status=1)).order_by('status') return render(request,'Backend/backend_trouble_kill_list.html',{ 'result':result})def trouble_kill(request,uuid): current_user_id = request.session['user_info']['uid'] troubleResolveType = models.TroubleResolveType.objects.filter(createUser_id=current_user_id, status=1) if request.method == 'GET': ret = models.Trouble.objects.filter(uuid=uuid, processUser_id=current_user_id).count() # 以前未抢到 if not ret: v = models.Trouble.objects.filter(uuid=uuid, status=1).update(processUser_id=current_user_id, status=2) if not v: return HttpResponse('手速太慢...') obj = models.Trouble.objects.filter(uuid=uuid).first() form = TroubleKill(initial={ 'solution': obj.processSolution}) return render(request, 'Backend/backend_trouble_kill.html', { 'obj': obj, 'form': form, 'uuid': uuid,'troubleResolveType':troubleResolveType}) else: ret = models.Trouble.objects.filter(uuid=uuid, processUser_id=current_user_id, status=2).count() if not ret: return HttpResponse('订单已处理,无法修改') form = TroubleKill(request.POST) if form.is_valid(): dic = {} dic['status'] = 3 dic['processSolution'] = form.cleaned_data['solution'] dic['processTime'] = datetime.datetime.now() models.Trouble.objects.filter(uuid=uuid, processUser_id=current_user_id, status=2).update(**dic) return redirect('/backend/trouble-kill-list.html') obj = models.Trouble.objects.filter(uuid=uuid).first() return render(request, 'backend_trouble_kill.html', { 'obj': obj, 'form': form, 'uuid': uuid})def getResolveDetail(request): current_user_id = request.session['user_info']['uid'] nid =request.GET.get("nid") troubleResolveType = models.TroubleResolveType.objects.filter(createUser_id=current_user_id, status=1,nid=nid).first() ret = { 'status': True, 'data': troubleResolveType.detail} return HttpResponse(json.dumps(ret))
6.4 列表页面(展示自己已处理过的报障单,或者未处理的保障单)
{% extends 'Backend/backend_layout.html' %}{ % block conent %}{ % endblock %}{ % block js %}{ % endblock %}
{ % for row in result %} 保障标题 状态 创建时间 创建人 操作 { % endfor %} { { row.title }} { { row.get_status_display }} { { row.createTime }} { { row.reportUser.username }} { % if row.status == 1 %} 抢单 { % elif row.status == 2 %} 处理订单 { % else %} 解决方案 { % endif %} {# |#}{# #}{# #}{# 删除#}{# #}{# |#}{# #}{# #}{# 编辑#}{# #} { { page_str }}
6.5 抢单
6.6 处理报障单(这里需要完善一个处理模板的类--TroubleResolveType)
{% extends 'Backend/backend_layout.html' %}{ % block css %} { % endblock %}{ % block conent %}标题
{ { obj.title }}
{ % endblock %}{ % block js %} { % endblock %}
7:分析报表
下面我们基于HighCharts做一个“工程师每月处理报障数量的分析报表”
在前台页面引入相应的js
{% extends 'Backend/backend_layout.html' %}{ % block css %}{ % endblock %}{ % block conent %}{ % endblock %}{ % block js %} { % endblock %}
# 报表分析 url(r'^trouble-statement.html$', trouble.trouble_statement), url(r'^getTroubleProcessInfo.html$', trouble.getTroubleProcessInfo),
from django.shortcuts import render,redirect,HttpResponsefrom repository import modelsfrom forms.trouble import TroubleForm,TroubleKill #引用form中的文章表单,用于添加、修改文章from django.db.models import Qfrom django.db import connection, connectionsimport jsonimport datetime #引入时间模块def trouble_list(request): # user_info = request.session.get('user_info') # {id:'',} current_user_id = request.session['user_info']['uid'] result = models.Trouble.objects.filter(reportUser_id=current_user_id).order_by('status').\ only('uuid','title','status','createTime','processUser') return render(request,'Backend/backend_trouble_list.html',{ 'result': result})def trouble_create(request): if request.method == 'GET': form = TroubleForm() else: form = TroubleForm(request.POST) if form.is_valid(): dic = {} dic['reportUser_id'] = request.session['user_info']['uid'] # session中获取 dic['createTime'] = datetime.datetime.now() dic['status'] = 1 dic.update(form.cleaned_data) models.Trouble.objects.create(**dic) return redirect('/backend/trouble-list.html') return render(request, 'Backend/backend_trouble_create.html',{ 'form':form})def trouble_edit(request,uuid): if request.method == "GET": obj = models.Trouble.objects.filter(uuid=uuid, status=1).only('uuid', 'title', 'detail').first() if not obj: return HttpResponse('已处理中的保单章无法修改..') # initial 仅初始化 form = TroubleForm(initial={ 'title': obj.title,'detail': obj.detail,'uuid':obj.uuid}) # 执行error会进行验证 return render(request,'Backend/backend_trouble_edit.html',{ 'form':form,'uuid':uuid}) else: form = TroubleForm(data=request.POST) if form.is_valid(): # 受响应的行数 v = models.Trouble.objects.filter(uuid=uuid, status=1).update(**form.cleaned_data) if not v: return HttpResponse('已经被处理') else: return redirect('/backend/trouble-list.html') return render(request, 'Backend/backend_trouble_edit.html', { 'form': form,'uuid':uuid})def trouble_kill_list(request): current_user_id = request.session['user_info']['uid'] result = models.Trouble.objects.filter(Q(reportUser_id=current_user_id)|Q(status=1)).order_by('status') return render(request,'Backend/backend_trouble_kill_list.html',{ 'result':result})def trouble_kill(request,uuid): current_user_id = request.session['user_info']['uid'] troubleResolveType = models.TroubleResolveType.objects.filter(createUser_id=current_user_id, status=1) if request.method == 'GET': ret = models.Trouble.objects.filter(uuid=uuid, processUser_id=current_user_id).count() # 以前未抢到 if not ret: v = models.Trouble.objects.filter(uuid=uuid, status=1).update(processUser_id=current_user_id, status=2) if not v: return HttpResponse('手速太慢...') obj = models.Trouble.objects.filter(uuid=uuid).first() form = TroubleKill(initial={ 'solution': obj.processSolution}) return render(request, 'Backend/backend_trouble_kill.html', { 'obj': obj, 'form': form, 'uuid': uuid,'troubleResolveType':troubleResolveType}) else: ret = models.Trouble.objects.filter(uuid=uuid, processUser_id=current_user_id, status=2).count() if not ret: return HttpResponse('订单已处理,无法修改') form = TroubleKill(request.POST) if form.is_valid(): dic = {} dic['status'] = 3 dic['processSolution'] = form.cleaned_data['solution'] dic['processTime'] = datetime.datetime.now() models.Trouble.objects.filter(uuid=uuid, processUser_id=current_user_id, status=2).update(**dic) return redirect('/backend/trouble-kill-list.html') obj = models.Trouble.objects.filter(uuid=uuid).first() return render(request, 'backend_trouble_kill.html', { 'obj': obj, 'form': form, 'uuid': uuid})def getResolveDetail(request): current_user_id = request.session['user_info']['uid'] nid =request.GET.get("nid") troubleResolveType = models.TroubleResolveType.objects.filter(createUser_id=current_user_id, status=1,nid=nid).first() ret = { 'status': True, 'data': troubleResolveType.detail} return HttpResponse(json.dumps(ret))def trouble_statement(request): return render(request, 'Backend/backend_trouble-statement.html')def getTroubleProcessInfo(request): cursor = connection.cursor() cursor.execute('select strftime("%Y-%m",processTime) as ptime from repository_trouble where status=3 group by strftime("%Y-%m",processTime)') xAxis = cursor.fetchall() #获取x轴上的数据 response = [] user_list = models.UserInfo.objects.filter() cursor2 = connection.cursor() cursor2.execute( """select strftime("%Y-%m",processTime) as processTime,processUser_id,count(strftime("%Y-%m",processTime)) as count from repository_troublewhere status=3group by processUser_id,strftime("%Y-%m",processTime)""" ) result = cursor2.fetchall() #获取统计数据 print(result) u_id = 0; for user in user_list: curTup=[]; for tup in result: if tup[1]==user.uid: curTup.append(tup) else: if user.uid
其逻辑大致是:
利用HighCharts的页面渲染图表,通过ajax调用后台数据