• 大概设计

  大概设计就是对需求进行一个整体性分析,把需要实现的功能都列出来,对于客户关系管理系统,我们需要从角色出发,从而确定有哪些需求,最好是画个思维导图

  首先我们是为培训学校这么一个场景来开发的,所以有:学生,讲师,销售,老板这么四个角色,那接下来,我们就要对这几个角色需要实现哪些功能逐一分析了

  第一个,学生,1.交作业 2.查成绩 3.请假 4.合同 5.我的推荐 6.投诉建议

  第二个,讲师, 1.上课点名 2.批作业 3.创建上课记录 4.查看班级成绩 5.课时申报 6.问卷调查

  第三个,销售   1.存储客户信息  2.办理报名手续  3.客户跟踪记录  4.各种维度查询,过滤客户信息

  第四个,老板  1.销售报表分析  2.教学质量报表

  • 详细设计

  对详细设计的话,那就要从业务场景下的客户体验和美观性,安全性,还有在带宽上和并发量进行综合考虑了,这个事一般是架构师进行总体性的一个规划,而在这里的话,由于这个项目只是一个对内的项目,所以对美观性和安全性和带宽上要求就没有那么高了,我们就多关注一下是表的设计即可

  组件上,由于对高并发要求低,Django就非常合适了,前端的话,用bootstrap和jquery就可以了,数据就mysql吧

  首先,我们先创建一个Django项目和一个名为PerfectCRM的数据库(在创建创建数据库时,注意编码,charset utf8),并在django项目下配置数据库

  接下来就models下,建自己基于上面概设分析出来的表类(记住:现在想周全了,后面填坑就少些),主要从值的唯一性,表间关系(一对一,一对多,多对多),可不可空,节省空间上考虑

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib.auth.models import User from django.db import models # Create your models here. class Customer(models.Model):
'''客户信息表'''
name = models.CharField(max_length=32, blank=True, null=True) # blank对admin起作用,而null对数据库起作用,一般两个成对写上
qq = models.CharField(max_length=64, unique=True)
qq_name = models.CharField(max_length=64, blank=True, null=True)
phone = models.CharField(max_length=64, blank=True, null=True)
source_choices = ((0, '转介绍'),
(1, 'QQ群'),
(2, '官网'),
(3, '百度推广'),
(4, '51CTO'),
(5, '知乎'),
(6, '市场推广')
)
source = models.SmallIntegerField(choices=source_choices) # 小数字字段省空间
referral_from = models.CharField(verbose_name='转介绍人qq', max_length=64, blank=True, null=True) consult_course = models.ForeignKey("Course", verbose_name='咨询课程')
content = models.TextField(verbose_name='咨询详情')
tags = models.ManyToManyField('Tag', blank=True, null=True)
consultant = models.ForeignKey('UserProfile', verbose_name='销售顾问')
memo = models.TextField(blank=True, null=True, verbose_name='备注')
date = models.DateTimeField(auto_now_add=True) def __unicode__(self):
return self.qq class Meta:
verbose_name = "客户信息表" #设置了这个,在admin中就可以显示中文,不过这个还会加上一个1个s
verbose_name_plural = "客户信息表" #这个就不会加s class Tag(models.Model):
'''标签表,给客户打标签'''
name = models.CharField(unique=True, max_length=32) def __unicode__(self):
return self.name class Meta:
verbose_name_plural = "标签表" class CustomerFollowUp(models.Model):
'''客户跟踪记录表'''
customer = models.ForeignKey('Customer')
content = models.TextField(verbose_name='跟进内容')
consultant = models.ForeignKey('UserProfile', verbose_name='跟进人')
intention_choices = ((0, '2周内报名'),
(1, '1个月内报名'),
(2, '近期无报名计划'),
(3, '已在其他机构报名'),
(4, '已报名'),
(5, '已拉黑')
) intention = models.SmallIntegerField(choices=intention_choices)
date = models.DateTimeField(auto_now_add=True) def __unicode__(self):
return "<%s : %s>" % (self.customer.qq, self.intention) class Meta:
verbose_name_plural = "客户跟踪记录表" class Course(models.Model):
'''课程表,在这里与班级一对多,一个课程可以多个班,创建班级时,选择课程'''
name = models.CharField(max_length=64, unique=True)
price = models.PositiveSmallIntegerField(verbose_name='课程价格')
period = models.PositiveSmallIntegerField(verbose_name='周期(月)')
outline = models.TextField(verbose_name='课程大纲') def __unicode__(self):
return self.name class Meta:
verbose_name_plural = "课程表" class Branch(models.Model):
'''校区'''
name = models.CharField(max_length=128, unique=True)
addr = models.CharField(max_length=128) def __unicode__(self):
return self.name class Meta:
verbose_name_plural = "校区" class ClassList(models.Model):
'''班级表'''
brance = models.ForeignKey('Branch', verbose_name='校区')
course = models.ForeignKey('Course')
class_type_choices = ((0, '面授(脱产)'),
(1, '面授(周末)'),
(2, '网络班'),
)
class_type = models.SmallIntegerField(choices=class_type_choices, verbose_name='班级类型')
semester = models.PositiveSmallIntegerField(verbose_name='学期')
teachers = models.ManyToManyField('UserProfile')
start_date = models.DateTimeField(verbose_name='开班日期')
end_date = models.DateTimeField(verbose_name='结业日期', blank=True, null=True) def __unicode__(self):
return "%s %s %s" % (self.brance, self.course, self.semester) class Meta:
unique_together = ('brance', 'course', 'semester')
verbose_name_plural = '班级表' class CourseRecord(models.Model):
'''上课记录(课时) 一个班级有多节课,一个课时会有多个学生记录,主要记录哪个老师上,上课时间...'''
from_class = models.ForeignKey("ClassList", verbose_name='班级')
day_num = models.PositiveSmallIntegerField(verbose_name='第几节')
teacher = models.ForeignKey('UserProfile')
has_homework = models.BooleanField(default=True)
homework_title = models.CharField(max_length=128, blank=True, null=True)
homework_content = models.TextField(blank=True, null=True)
outline = models.TextField(verbose_name='本节课程大纲') date = models.DateTimeField(auto_now_add=True) def __unicode__(self):
return "%s %s" % (self.from_class, self.day_num) class Meta:
unique_together = ('from_class', 'day_num')
verbose_name_plural = '上课记录表' class StudyRecord(models.Model):
'''学习记录表'''
student = models.ForeignKey('Enrollment')
course_record = models.ForeignKey('CourseRecord')
attendance_choices = ((0, '已签到'),
(1, '迟到'),
(2, '缺勤'),
(3, '早退'),
)
attendance = models.SmallIntegerField(choices=attendance_choices, default=0)
score_choices = ((100,'A+'),
(90, 'A'),
(85, 'B+'),
(80, 'B'),
(75, 'B-'),
(70, 'C+'),
(60, 'C'),
(40, 'C-'),
(-50, 'D'),
(-100, 'COPY'),
(0, 'N/A'),
)
score = models.SmallIntegerField(choices=score_choices, default=0)
memo = models.TextField(blank=True, null=True, verbose_name='备注')
date = models.DateTimeField(auto_now_add=True) def __unicode__(self):
return "%s %s %s" % (self.student, self.course_record, self.score) class Meta:
unique_together = ('student','course_record')
verbose_name_plural = "学习记录" class Enrollment(models.Model):
'''报名表,主要考虑一个客户可能报多个班'''
customer = models.ForeignKey('Customer')
enrolled_class = models.ForeignKey('ClassList', verbose_name='所报班级') consultant = models.ForeignKey('UserProfile', verbose_name='课程顾问') contract_agreed = models.BooleanField(default=False, verbose_name='学员已同意合同')
contract_approved = models.BooleanField(default=False, verbose_name='合同已审核')
date = models.DateTimeField(auto_now_add=True) def __unicode__(self):
return "%s %s" % (self.customer, self.enrolled_class) class Meta:
unique_together = ('customer', 'enrolled_class')
verbose_name_plural = '报名表' class Payment(models.Model):
'''缴费记录'''
customer = models.ForeignKey('Customer')
course = models.ForeignKey("Course")
amount = models.PositiveIntegerField(verbose_name='数额', default=500)
consultant = models.ForeignKey('UserProfile')
date = models.DateTimeField(auto_now_add=True) def __unicode__(self):
return '%s %s' % (self.customer, self.amount) class Meta:
verbose_name_plural = "缴费记录表" class UserProfile(models.Model):
'''账号表'''
user = models.ForeignKey(User)
name = models.CharField(max_length=32)
roles = models.ManyToManyField('Role', blank=True, null=True) def __unicode__(self):
return self.name class Meta:
verbose_name_plural = "账号表" class Role(models.Model):
'''角色表'''
name = models.CharField(max_length=32, unique=True) def __unicode__(self):
return self.name class Meta:
verbose_name_plural = "角色表"

  涉及知识点:

  • 表字段设计时,blank为True时,是对admin起作用,而null为True时,则是对数据库起作用
  • verbose_name不仅在字段中起标记作用,还可以在Meta定义,在admin中是显示你定义的内容,其中verbose_name_plural会去掉s
  • 在定义字段时,可以充分考虑使用场景,适时使用节省空间的字段类型,比如SmallIntegerField可以用在数字为选择项的时候,还有正数PositiveIntegerField
  • 联合唯一索引  class Meta:unique_together = ('x','y')  x,y为字段名
  • 时间自增  auto_now_add = True
  • django 自带有一张用户常用的验证的表,可以直接继承使用 from django.contrib.auth.models import User  使用时,用外键关联(一对一和一对多都行)

CRM客户关系管理系统-需求概设和详设的更多相关文章

  1. Django CRM客户关系管理系统

    CRM需求分析 随着信息化时代带来的科技创新,CRM客户关系管理系统带来的效益在已经成为很多企业提高竞争优势的一分部,CRM客户关系管理系统将企业管理和客户关系管理集成到统一的平台,其系统功能主要体现 ...

  2. CRM 客户关系管理系统

    CRM(Customer Relationship Manager)客户关系管理系统 企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的交互,从而提升其管理方 ...

  3. CRM客户关系管理系统 北京易信软科信息技术有限公司

    北京易信软科信息技术有限公司 推出大型erp系统,库存管理系统,客户关系管理系统,车辆登记管理系统,员工管理系统,采购管理系统,销售管理系统,为您的企业提供最优质的产品服务 北京易信软科您可信赖的北京 ...

  4. CRM客户关系管理系统(一)

    第一章.CRM介绍和开发流程 1.1.CRM简介 客户关系管理(CRM) 客户关系管理(customer relationship management)的定义是:企业为提高核心竞争力,利用相应的信息 ...

  5. CRM客户关系管理系统有哪些优缺点?

    CRM系统不仅仅是一种技术,也是面向企业的客户管理系统.客户关系管理软件可以帮助销售员快速地找到客户信息,帮助销售员跟踪客户直到完成订单.为提高企业销售效率,CRM被越来越多的企业所采用. 那么,作为 ...

  6. Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL

    #models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...

  7. Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...

  8. Django项目:CRM(客户关系管理系统)--82--72PerfectCRM实现CRM动态菜单和角色

    #models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...

  9. Django项目:CRM(客户关系管理系统)--73--63PerfectCRM实现CRM讲师下载作业

    # teacher_urls.py # ————————62PerfectCRM实现CRM讲师讲课记录———————— from django.conf.urls import url from bp ...

随机推荐

  1. oracle备份还原数据库

    首先到对应bin目录下打开cmd(windows),linux用相应终端链接:eg:D:\app\sun\product\11.2.0\dbhome_1\BIN 用户备份:exp u_tdms/p_t ...

  2. HTML输入验证提示信息

    1.oninvali事件通过setCustomValidity方法来自定义提示信息 <form action=""> <label> 数字: <inp ...

  3. MQTT压力测试之Tsung的使用

    简介 Tsung 是一个压力测试工具,可以测试包括HTTP, WebDAV, PostgreSQL, MySQL, LDAP, and XMPP/Jabber等服务器.针对 HTTP 测试,Tsung ...

  4. 构建基于Javascript的移动web CMS入门——简单介绍

    看到项目上的移动框架,网上寻找了一下,发现原来这些一開始都有. 于是,找了个演示样例開始构建一个移动平台的CMS--墨颀 CMS,方便项目深入理解的同一时候.也能够自己维护一个CMS系统. 构建框架 ...

  5. C++ Primer Plus的若干收获--(二)

    哎,真是不想吐槽考驾照的艰辛历程了.跑到大西郊,顶着大太阳,一天就能摸上个十几分钟二十分钟的车,简直不要太坑爹,这两天真是做的我屁股疼的不行. .. 今天果断不去了.仅仅可惜我的大阿根廷啊,坚持到最后 ...

  6. GoogLeNet模型的微调

    我从零开始训练了GoogLeNet模型. 但它没有给我带来希望的结果. 作为替代,我想对我的数据集中的GoogLeNet模型进行微调. 有谁知道我应该遵循什么步骤? 采纳答案: 假设你正在尝试做图像分 ...

  7. Atitit.得到网络邻居列表java php c#.net python

    Atitit.得到网络邻居列表java php c#.net python 1. 获取workgroup  net view /domain1 2. 得到网络邻居列表1 3. 得到机器的ip  通过p ...

  8. Atitit. 二进制数据ascii表示法,与base64编码解码api 设计标准化总结java php c#.net

    Atitit. 二进制数据ascii表示法,与base64编码解码api 设计标准化总结java php c#.net 1. Base64编码, 1 1.1. 子模式 urlsafe Or  url  ...

  9. Gradle build.gradle to Maven pom.xml ,终于找到你了。

    尊重原创:https://blog.csdn.net/kevin_luan/article/details/50996109 根据build.gradle 生成maven pox.xml 1.将以下配 ...

  10. 使用NGINX反向代理做小偷站

    用Nginx的反向代理可以轻松山寨对方的网站,但是反向代理后的网站还是有对方的绝对链接时,怎么办?所以要用替换链接方法. 1 使用官方的的模块 编译参数–with-http_sub_moduleub_ ...