10.23 crm(3)
2018-10-23 20:34:30
继续增加新的功能!在代码注释里面有!
越努力,越幸运!永远不要高估自己!
还有明天再加上rbca权限管理系统就完美了!
然后crm做完,再过几天不挂针一切好了也快回学校啦!
然后把Django整理一下!说了好久就没整理!发现还是做东西有趣!
from stark.service.stark import site, ModelStark
from django.utils.safestring import mark_safe
from django.conf.urls import url
from django.shortcuts import redirect, render, HttpResponse
from .models import *
from django.http import JsonResponse
from django.db.models import Q
import datetime """
可以配置字段:
1. list_display[] 可以添加自定义展示字段,也可以添加函数名
2. 父类提供的添加该表额外url的接口 def extra_url 重写这个方法即可
2018-10-22 21:33:33
增加部分:
1. 初始化 course_record,studyrecord,
2. 考勤
3. 录入成绩
2018-10-23 20:21:35
增加功能:
1.通过Ajax,调用highchats插件,把学员个人成绩做成柱状图
2.增添了公共客户展示,并且可以选择跟进
3. ---公共客户(公共资源)
1 没有报名
2 3天没有跟进
3 15天没有成单
ps 关于这个条件,可以用linux做一个定时器,定时执行一下脚本,检查符合上述条件的客户进行修改更新信息,
这个理解就好!不做重点!
为了方便,把目前的配置类的各种可访问接口总结一下:
customer/public/ 访问公共资源
customer/mycustomer/ 访问我的个人客户页面 """ # 用户配置表
class UserConfig(ModelStark):
# 自定义展示字段 list_display[]
list_display = ["name", "email", "depart"] # 班级配置表
class ClassConfig(ModelStark):
# 自定义一个展示函数,然后添加到list_display中
def display_classname(self, obj=None, header=False):
if header:
return "班级名称"
class_name = "%s(%s)" % (obj.course.name, str(obj.semester))
return class_name list_display = [display_classname, "tutor", "teachers"] # 客户配置表
class CustomerConfig(ModelStark):
# 自定义展示性别
def display_gender(self, obj=None, header=False):
if header:
return "性别"
return obj.get_gender_display() # 自定义展示课程
def display_course(self, obj=None, header=False):
if header:
return "咨询课程"
temp = []
for course in obj.course.all():
s = "<a href='/stark/crm/customer/cancel_course/%s/%s' style='border:1px solid #369;padding:3px 6px'><span>%s</span></a> " % (
obj.pk, course.pk, course.name,)
temp.append(s)
return mark_safe("".join(temp)) list_display = ["name", display_gender, display_course, "consultant", ] # 取消课程的视图函数
def cancel_course(self, request, customer_id, course_id):
print(customer_id, course_id)
obj = Customer.objects.filter(pk=customer_id).first()
obj.course.remove(course_id)
return redirect(self.get_list_url()) # 展示公共客户的视图函数
def public_customer(self, request):
# 未报名 且3天未跟进或者15天未成单
now = datetime.datetime.now()
'''
datetime.datetime
datetime.time
datetime.date
datetime.timedelta(days=7)
'''
# 三天未跟进 now-last_consult_date>3 --->last_consult_date<now-3
# 15天未成单 now-recv_date>15 --->recv_date<now-15
delta_day3 = datetime.timedelta(days=3)
delta_day15 = datetime.timedelta(days=15)
user_id = 5
# 筛选出符合条件的客户,并且不是该登录者跟进的客户
customer_list = Customer.objects.filter(
Q(last_consult_date__lt=now - delta_day3) | Q(recv_date__lt=now - delta_day15), status=2).exclude(
consultant=user_id)
print(customer_list)
return render(request, "public.html", locals()) # 选择跟进用户的视图函数
def further(self, request, customer_id):
# 由于没有加入rbac权限管理系统,先写死用户id 加入rbac后可用: request.session.get("user_id")
user_id = 3 # alex
now = datetime.datetime.now()
delta_day3 = datetime.timedelta(days=3)
delta_day15 = datetime.timedelta(days=15)
# 为改客户更改课程顾问,和对应时间
ret = Customer.objects.filter(pk=customer_id).filter(
Q(last_consult_date__lt=now - delta_day3) | Q(recv_date__lt=now - delta_day15), status=2).update(
consultant=user_id, last_consult_date=now, recv_date=now)
if not ret:
return HttpResponse("已经被跟进了")
# 在客户跟进表中添加一条新的记录
CustomerDistrbute.objects.create(customer_id=customer_id, consultant_id=user_id, date=now, status=1)
return HttpResponse("跟进成功") # 展示我的客户的视图函数
def mycustomer(self, request):
# 由于没有加入rbac权限管理系统,先写死用户id 加入rbac后可用: request.session.get("user_id")
user_id = 3 # alex
# 在客户跟进表中通过user_id 拿到该用户名下所有的客户跟进记录
customer_distrbute_list = CustomerDistrbute.objects.filter(consultant=user_id)
return render(request, "mycustomer.html", locals()) # 父类给出的添加额外url的接口
def extra_url(self):
temp = []
temp.append(url(r"cancel_course/(\d+)/(\d+)", self.cancel_course))
temp.append(url(r"public/", self.public_customer))
temp.append(url(r"further/(\d+)", self.further))
temp.append(url(r"mycustomer/", self.mycustomer))
return temp # 咨询配置表
class ConsultConfig(ModelStark):
# 自定义展示字段
list_display = ["customer", "consultant", "date", "note"] # 学生配置表
class StudentConfig(ModelStark):
# 查看成绩
def score_view(self,request,sid):
if request.is_ajax():
print(request.GET)
sid=request.GET.get("sid")
cid=request.GET.get("cid")
study_record_list=StudyRecord.objects.filter(student=sid,course_record__class_obj=cid)
data_list=[]
for study_record in study_record_list:
day_num=study_record.course_record.day_num
data_list.append(["day%s"%day_num,study_record.score])
print(data_list)
return JsonResponse(data_list,safe=False)
else:
student=Student.objects.filter(pk=sid).first()
class_list=student.class_list.all()
return render(request,"score_view.html",locals()) def extra_url(self):
temp = []
temp.append(url(r"score_view/(\d+)", self.score_view))
return temp def score_show(self, obj=None, header=False):
if header:
return "查看成绩"
return mark_safe("<a href='/stark/crm/student/score_view/%s'>查看成绩</a>"%obj.pk) list_display = ["customer", "class_list",score_show]
list_display_links = ["customer"] # 学习情况配置表
class StudyConfig(ModelStark):
# 自定义展示字段
list_display = ["student", "course_record", "record", "score"] def patch_late(self, request, queryset):
queryset.update(record="late") # 批量更改为 迟到
patch_late.short_description = "一键迟到"
actions = [patch_late] # 课程记录配置表
class CourseRecordConfig(ModelStark):
# 记录成绩的视图函数
def score(self, request, course_record_id):
if request.method == "POST":
print(request.POST)
data = {}
for key, value in request.POST.items():
if key == "csrfmiddlewaretoken": continue
print("key:", key) # key: score_1
# 取到键值pk 后面数字
field, pk = key.rsplit("_", 1)
if pk in data:
data[pk][field] = value
else:
data[pk] = {field: value} # data {4:{"score":90}}
print("data", data)
# 构建成如下的数据 虽然构建数据有些麻烦,但是节省了储存数据库所需时间
# data {'1': {'score': '100', 'homework_note': '11'}, '2': {'score': '85', 'homework_note': '22'}}
for pk, update_data in data.items():
StudyRecord.objects.filter(pk=pk).update(**update_data)
return redirect(request.path)
else:
# 把数据传入前端,然后渲染列表数据
study_record_list = StudyRecord.objects.filter(course_record=course_record_id)
score_choices = StudyRecord.score_choices
return render(request, "score.html", locals()) # 通过内置接口 分发一个记录成绩的url
def extra_url(self):
temp = []
temp.append(url(r"record_score/(\d+)", self.score))
return temp # 定义考勤的函数
def record(self, obj=None, header=False):
if header:
return "考勤"
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>" % obj.pk) # 定义录入成绩的函数
def record_score(self, obj=None, header=False):
if header:
return "录入成绩"
return mark_safe("<a href='record_score/%s'>录入成绩</a>" % obj.pk) list_display = ["class_obj", "day_num", "teacher", record, record_score] # 批量添加学生学习记录
def patch_studyrecord(self, request, queryset):
print(queryset)
temp = []
for course_record in queryset:
# 与course_record关联的班级对应所有学生
student_list = Student.objects.filter(class_list__id=course_record.class_obj.pk)
for student in student_list:
obj = StudyRecord(student=student, course_record=course_record)
temp.append(obj)
# 在StudyRecord表中批量添加学生学习记录
StudyRecord.objects.bulk_create(temp)
patch_studyrecord.short_description = "批量生成学习记录"
actions = [patch_studyrecord, ] site.register(UserInfo, UserConfig)
site.register(Customer, CustomerConfig)
site.register(Student, StudentConfig)
site.register(ConsultRecord, ConsultConfig)
site.register(StudyRecord, StudyConfig)
site.register(CourseRecord, CourseRecordConfig)
site.register(ClassList, ClassConfig)
site.register(School)
site.register(Department)
site.register(Course)
site.register(CustomerDistrbute)
新增了一张CustomerDistrbute的表!用于记录跟进用户的跟进记录
models.py 为了简洁就放上新的表的代码
from django.db import models
class CustomerDistrbute(models.Model):
customer = models.ForeignKey("Customer", related_name="customers")
consultant = models.ForeignKey(verbose_name="课程顾问", to="UserInfo", limit_choices_to={"depart_id": 1001})
date = models.DateField()
status = (
(1, "正在跟进"),
(2, "已报名"),
(3, "三天未跟进"),
(4, "15天未成单"),
)
status = models.IntegerField(choices=status, default=1) memo = models.CharField(max_length=255) def __str__(self):
return self.customer.name+":"+self.consultant.name
贴上笔记:
day95 crm: 讲师与学生
1 初始化 course_record,studyrecord,
2 考勤
3 录入成绩
4 显示成绩 ajax 查询 5 上传作业(os模块)
6 下载作业 销售与客户(销售) ---公共客户(公共资源)
1 没有报名
2 3天没有跟进
3 15天没有成单 mycustomer: 龙泰 男 yuan 2018-5-1 3天未跟进 mycustomer: 龙泰 男 三江 2018-5-5 15天未成单 mycustomer: 龙泰 男 暴雨 2018-5-21 正在跟进 客户分布表
龙泰 男 yuan 2018-5-1 3天未跟进
龙泰 男 三江 2018-5-5 15天未成单
龙泰 男 暴雨 2018-5-21 正在跟进 ---我的客户
crontab: 2018-5-15 12:00 龙泰 男 三江 2018-5-5 正在跟进 2018-5-16 0:0
2018-5-17 0:0
2018-5-18 0:0
2018-5-19 0:0 龙泰 男 三江 2018-5-5 3天未跟进 key: CustomerDistrbute为什么创建 ,为什么不能直接用Customer 权限组件
10.23 crm(3)的更多相关文章
- 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令
[源码下载] 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 作者:webabcd ...
- 10.23 正睿停课训练 Day7
目录 2018.10.23 正睿停课训练 Day7 A 矩形(组合) B 翻转(思路) C 求和(思路 三元环计数) 考试代码 B1 B2 C 2018.10.23 正睿停课训练 Day7 期望得分: ...
- Daily Scrum 10.23
(写于10.22周四) 说下现在的人员情况: 康家华请假至下周一,刘彦熙至周五18:00,张启东至周六中午. 其他人正常工作. 然后是现在的进度情况: 已经完成服务器数据库搭建,以及基础的注册登陆功能 ...
- Notes of the scrum meeting(2013/10/23)
ps:本来是10月23号周三下午开的会,这几天由于各种事情忙,忘记写博客了,现在补上. 软工项目组buaa_smile开始项目第一次scrum meeting meeting time:4:00~5: ...
- 2017.10.23 Java 面向对象深入学习---final 关键字、static关键字、匿名对象等
今日内容介绍 1.final 关键字 2.static 关键字 3.匿名对象 4.内部类 5.包的声明与访问 6.访问修饰符 7.代码块 第一节课 01(面向对象)final关键字概念.avi 02: ...
- 山东理工大学第七届ACM校赛-学区房问题 分类: 比赛 2015-06-26 10:23 89人阅读 评论(0) 收藏
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 铁牌狗在学区B有一套面积为S1平方米的房子,现在他为了让后代进化成金牌狗,决定在学区A购 ...
- Cheatsheet: 2013 10.09 ~ 10.23
Other 10 Basic Linux Networking and Monitoring Commands You Should Know A simple, portable yet effic ...
- Teamwork——Week 4 Daily Scrum Meeting#1 2013.10.23
一.会议议题 1)根据确立的项目题目,进一步明确PM,DEV,TEST的工作. 2)确定团队分工和预估项目时间. 3)完成项目架构NABC模型. 4)确定第一轮开发团队分工 二.会议时间 2013年1 ...
- 【Dairy】2016.10.23 观火&中彩记
...................... 就第一条可以! 观火10分钟,长郡附近老房子起火...
随机推荐
- ASP.NET Core入门系列教程
微软把这个新的框架叫:Razor Pages,以下文中我们将频繁提及—Razor Pages. 项目目录结构 wwwroot静态资源文件夹首先,Razor Pages项目中多了一个wwwroot的文件 ...
- web打印控件Lodop轻松输出清晰的图表和条码
一.仅用两行语句实现极其复杂的图表打印.类似如下两句: LODOP.ADD_PRINT_CHART(0,0,400,400,5,document.getElementByI d('table001') ...
- GitHub下载安装以及开源项目
Git for Windows安装与使用 http://cioworld.org/freedom/content/git-windows 下载Git-1.8.3-preview20130601.exe ...
- Hadoop2.2.0分布式安装配置详解[2/3]
前言 本文主要通过对hadoop2.2.0集群配置的过程加以梳理,所有的步骤都是通过自己实际测试.文档的结构也是根据自己的实际情况而定,同时也会加入自己在实际过程遇到的问题.搭建环境过程不重要,重要点 ...
- android保持服务不休眠(持续运行)以及唤醒屏幕的方法
假设有这样一个应用场景,一个服务一直在默默的工作(比如即时地获取服务器的消息),即使在屏幕已经因为长时间无操作而关闭,或者用户按了电源键让屏幕关闭,手机进入休眠状态,他必须依然在工作中.一旦从服务器获 ...
- Easyui 弹出加载中的遮罩的两种方法
第一种: //弹出加载层function load() { $("<div class=\"datagrid-mask\"></div> ...
- Spring Boot 2.0 整合Thymeleaf 模板引擎
本节将和大家一起实战Spring Boot 2.0 和thymeleaf 模板引擎 1. 创建项目 2. 使用Spring Initlizr 快速创建Spring Boot 应用程序 3. 填写项目配 ...
- [svc]证书各个字段的含义
证书生成工具 1,openssl 2,jdk自带的keystone 3,cfssl 证书中各个字段的含义 - 查看证书的内容 openssl x509 -in /etc/pki/CA/cacert.p ...
- (1) Mysql高性能优化规范建议
数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意 ...
- 教你一招:[转载]使用 Easy Sysprep v4 封装 Windows 7 精品
(一) 安装与备份系统 1. 安装 Windows 7 先使用第三方分区工具(DiskGenius分区)在虚拟机中分区,然后将封装的母盘文件安装写入指定的安装盘,写入完成后重启系统开始部署. 2. 进 ...