• CRM客户关系管理系统-需求概设和详设


    • 大概设计

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

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

      第一个,学生,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  使用时,用外键关联(一对一和一对多都行)
  • 相关阅读:
    设计模式面试题(总结最全面的面试题!!!)
    一文彻底搞懂CAS实现原理
    从前慢ShardingJDBC
    Azure Storage (30) Azure Storage费用和事务相关的问题
    数据库界的Swagger:一键生成数据库文档!
    异步编程利器:CompletableFuture
    Android recyclerview的滑动到指定的item
    android 获取 item的位置,RecyclerView 滚动和获取指定位置Item的完整方案
    Android Recyclerview适配器 加载头部 以及自定义View
    基础python的快速学习
  • 原文地址:https://www.cnblogs.com/xinsiwei18/p/8280819.html
Copyright © 2020-2023  润新知