教育行业CRM项目开发


项目开发流程


需求分析

    存储所有的客户咨询信息
    避免重复数据
    客户多次跟踪记录
    客户来源分析、成单率分析
    每个销售只能修改自己的客户信息
    报名流程开发
    
    班级管理
    学员成绩,出勤管理
    问卷调查

    校区管理

    课程管理
        课程大纲、周期、价格、代课老师

    讲师的上课记录


    学员就业情况

    知识库

    权限管理(学员、讲师、老板....查看权限不同)
    角色
            销售
            销售主管
            讲师

           学员

          管理员



思维导图

根据思维导图,我们总结出以下具体需求:

  1. 把用户分为销售\学员\讲师\管理员4种角色,每个角色关心的事情不同,所以有要不同的用户视图,即销售人员登陆后只需要看他与他工作相关的就可以,讲师关心的事情不需要在销售视图里显示
  2. 销售人员可以录入客户信息,和后续跟进信息,因为一个客户可能要跟进好几次才会报名。 可以多种条件过滤查询用户,可以查看自己的销售业绩报表
  3. 学员主要2个功能,查询成绩\提交作业
  4. 讲师的主要功能是管理班级\ 批作业\上课点名
  5. 这个系统里存放着大量的客户信息\学员数据等,都是公司的机密信息,设计系统时就要考虑到权限问题,不同的角色要有不同的权限,同一角色的不同用户也要允许有不同的权限



业务场景分析(用户使用的场景)

为了更加理清我们的项目开发需求,在动手写代码前,建议再有一个业务场景分析的步骤,即从用户角度写出你使用这个项目的具体场景,我们这里分为销售、讲师、学员、管理员4个角色,我分别给每个角色列出了几个使用场景:

销售
    1、销售人员A刚从 百度推广 聊了一个客户,录入crm系统,咨询了python全栈开发课程,但没报名
    2、销售B 从 QQ群聊了客户,且报名了py全栈5期课程,给用户发送了报名连接,待用户填写完毕后,把他添加到python fullstack
    3、销售C 打电话给之前的一个客户,说服他报名linux 36期课程,但没说服成功,更新了跟踪记录
    4、销售d 聊了一个客户,录入时发现 此客户已存在,不能录入,随后通知相应负责人 跟进
    5、销售B 从客户库里过滤出了 所有 超过一个月未跟踪的客户,进行跟踪
    6、销售主管 查看了部门 本月的销售报表,包括来源分析,班级报名数量分析,销售额环比,同比

学员
    1、客户A填写了销售发来的 报名连接,上传了个人证件信息,提交,过了一下会,发现收到了一个邮件,告知他报名python 5期课程成功,并帮他开通了学员账号,
    2、学员A登录了学员系统,看到了自己的合同,报名班级,课程大纲
    3、学员A 提交了PY 5期的 第三节课的作业
    4、学员A查看了自己在py5期的 学习成绩,排名
    5、学员A录入了一条 转介绍信息
    6、学员A 在线 搜索一个问题,发现没有答案,于是提交了一个问题。

讲师
    1、登录了CRM系统,查看了自己管理的班级列表
    2、进入了python 5期,创建了第3节的上课记录,填入了本节内容,作业需求
    3、为python 5 的第三节课 进行点名,发现小东北迟到了,标记他为迟到状态
    4、批量下载了所有学员的py 5期第二节的作业,给每个人在线 批改了成绩 + 批注
   
管理员
    1、创建了,课程Linux,python,
    2、创建了校区 北京,上海
    3、创建了班级python  fullstack 35 和 Linux 36
    4、创建了账号A、B、C、D
    5、创建了销售,讲师,学员三个角色,并把ABCD分配到销售角色里
    6、设置了销售可以操作的权限

原型图
  类似示例(非本项目真实实例)


开发工具选型
    python
    Django
    mysql
    jquery
    bootstrap
    linux
    nginx
    pycharm

创建项目
    设计表结构
    写代码


设计表结构

表结构示意图

表结构代码

  1 from django.db import models
  2 from django.contrib.auth.models import  User
  3 
  4 # Create your models here.
  5 
  6 
  7 class UserProfile(models.Model):
  8     """用户信息表"""
  9     user = models.OneToOneField(User)
 10     name = models.CharField(max_length=64,verbose_name="姓名")
 11     role = models.ManyToManyField("Role",blank=True,null=True)
 12 
 13 
 14     def __str__(self): #__unicode__
 15         return self.name
 16 
 17 class Role(models.Model):
 18     """角色表"""
 19     name = models.CharField(max_length=64,unique=True)
 20     menus = models.ManyToManyField("Menus",blank=True)
 21     def __str__(self):
 22         return self.name
 23 
 24 
 25 class CustomerInfo(models.Model):
 26     """客户信息表"""
 27     name = models.CharField(max_length=64,default=None)
 28     contact_type_choices = ((0,'qq'),(1,'微信'),(2,'手机'))
 29     contact_type = models.SmallIntegerField(choices=contact_type_choices,default=0)
 30     contact = models.CharField(max_length=64,unique=True)
 31     source_choices = ((0,'QQ群'),
 32                       (1,'51CTO'),
 33                       (2,'百度推广'),
 34                       (3,'知乎'),
 35                       (4,'转介绍'),
 36                       (5,'其它'),
 37                       )
 38     source = models.SmallIntegerField(choices=source_choices)
 39     referral_from = models.ForeignKey("self",blank=True,null=True,verbose_name="转介绍")
 40     consult_courses = models.ManyToManyField("Course",verbose_name="咨询课程")
 41     consult_content = models.TextField(verbose_name="咨询内容")
 42     status_choices = ((0,'未报名'),(1,'已报名'),(2,'已退学'))
 43     status = models.SmallIntegerField(choices=status_choices)
 44     consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问")
 45     date = models.DateField(auto_now_add=True)
 46 
 47     def __str__(self):
 48         return self.name
 49 
 50 class Student(models.Model):
 51     """学员表"""
 52     customer = models.ForeignKey("CustomerInfo")
 53     class_grades = models.ManyToManyField("ClassList")
 54 
 55     def __str__(self):
 56         return self.customer
 57 
 58 
 59 class CustomerFollowUp(models.Model):
 60     """客户跟踪记录表"""
 61     customer = models.ForeignKey("CustomerInfo")
 62     content = models.TextField(verbose_name="跟踪内容")
 63     user = models.ForeignKey("UserProfile",verbose_name="跟进人")
 64     status_choices  = ((0,'近期无报名计划'),
 65                        (1,'一个月内报名'),
 66                        (2,'2周内内报名'),
 67                        (3,'已报名'),
 68                        )
 69     status = models.SmallIntegerField(choices=status_choices)
 70     date = models.DateField(auto_now_add=True)
 71     def __str__(self):
 72         return self.content
 73 
 74 
 75 class Course(models.Model):
 76     """课程表"""
 77     name = models.CharField(verbose_name='课程名称',max_length=64,unique=True)
 78     price = models.PositiveSmallIntegerField()
 79     period = models.PositiveSmallIntegerField(verbose_name="课程周期(月)",default=5)
 80     outline = models.TextField(verbose_name="大纲")
 81 
 82     def __str__(self):
 83         return self.name
 84 
 85 
 86 class ClassList(models.Model):
 87     """班级列表"""
 88     branch = models.ForeignKey("Branch")
 89     course = models.ForeignKey("Course")
 90     class_type_choices = ((0,'脱产'),(1,'周末'),(2,'网络班'))
 91     class_type = models.SmallIntegerField(choices=class_type_choices,default=0)
 92     semester = models.SmallIntegerField(verbose_name="学期")
 93     teachers = models.ManyToManyField("UserProfile",verbose_name="讲师")
 94     start_date = models.DateField("开班日期")
 95     graduate_date = models.DateField("毕业日期",blank=True,null=True)
 96     def __str__(self):
 97 
 98         return "%s(%s)期" %(self.course.name,self.semester)
 99 
100     class Meta:
101         unique_together =  ('branch','class_type','course','semester')
102 
103 
104 class CourseRecord(models.Model):
105     """上课记录"""
106     class_grade = models.ForeignKey("ClassList",verbose_name="上课班级")
107     day_num = models.PositiveSmallIntegerField(verbose_name="课程节次")
108     teacher = models.ForeignKey("UserProfile")
109     title = models.CharField("本节主题",max_length=64)
110     content = models.TextField("本节内容")
111     has_homework = models.BooleanField("本节有作业",default=True)
112     homework = models.TextField("作业需求",blank=True,null=True)
113     date = models.DateTimeField(auto_now_add=True)
114     def __str__(self):
115         return  "%s第(%s)节" %(self.class_grade,self.day_num)
116 
117     class Meta:
118         unique_together = ('class_grade','day_num')
119 
120 
121 
122 class StudyRecord(models.Model):
123     """学习记录表"""
124     course_record = models.ForeignKey("CourseRecord")
125     student = models.ForeignKey("Student")
126 
127     score_choices = ((100,"A+"),
128                      (90,"A"),
129                      (85,"B+"),
130                      (80,"B"),
131                      (75,"B-"),
132                      (70,"C+"),
133                      (60,"C"),
134                      (40,"C-"),
135                      (-50,"D"),
136                      (0,"N/A"), #not avaliable
137                      (-100,"COPY"), #not avaliable
138                      )
139     score = models.SmallIntegerField(choices=score_choices,default=0)
140     show_choices = ((0,'缺勤'),
141                     (1,'已签到'),
142                     (2,'迟到'),
143                     (3,'早退'),
144                     )
145     show_status = models.SmallIntegerField(choices=show_choices,default=1)
146     note = models.TextField("成绩备注",blank=True,null=True)
147 
148     date = models.DateTimeField(auto_now_add=True)
149 
150     def __str__(self):
151 
152         return "%s %s %s" %(self.course_record,self.student,self.score)
153 
154 class Branch(models.Model):
155     """校区"""
156     name = models.CharField(max_length=64,unique=True)
157     addr = models.CharField(max_length=128,blank=True,null=True)
158     def __str__(self):
159         return self.name
160 
161 
162 
163 class Menus(models.Model):
164     """动态菜单"""
165     name = models.CharField(max_length=64)
166     url_type_choices = ((0,'absolute'),(1,'dynamic'))
167     url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
168     url_name = models.CharField(max_length=128)
169 
170     def __str__(self):
171         return self.name
172 
173     class Meta:
174         unique_together = ('name','url_name')
View Code

猜你喜欢

转载自www.cnblogs.com/dylan123/p/10790719.html