7.1 - CRM系统
一、简介
crm 客户关系管理软件 ( Customer Relationship Management ) ( 详细内容 )
stark组件(仿admin组件)( 详细内容 )
rbac组件(基于角色的权限访问控制)( 详细内容 )
讲师与学生 ...
销售与客户 ...
权限控制 ...
二、数据库
表关系
crm/models.py
from django.db import models# Create your models here.from django.db import modelsclass Department(models.Model):"""部门表如:市场部 1000销售 1001"""title = models.CharField(verbose_name='部门名称', max_length=16)code = models.IntegerField(verbose_name='部门编号', unique=True, null=False)def __str__(self):return self.titleclass UserInfo(models.Model):"""员工表"""name = models.CharField(verbose_name='员工姓名', max_length=16)# username = models.CharField(verbose_name='用户名', max_length=32)# password = models.CharField(verbose_name='密码', max_length=64)email = models.EmailField(verbose_name='邮箱', max_length=64)depart = models.ForeignKey(verbose_name='部门', to="Department", to_field="code")user = models.OneToOneField("rbac.User", null=True)def __str__(self):return self.nameclass Course(models.Model):"""课程表如:Linux基础Linux架构师Python自动化开发精英班Python自动化开发架构师班Python基础班go基础班"""name = models.CharField(verbose_name='课程名称', max_length=32)def __str__(self):return self.nameclass School(models.Model):"""校区表如:北京沙河校区上海校区"""title = models.CharField(verbose_name='校区名称', max_length=32)def __str__(self):return self.titleclass ClassList(models.Model):"""班级表如:Python全栈 面授班 5期 10000 2017-11-11 2018-5-11"""school = models.ForeignKey(verbose_name='校区', to='School')course = models.ForeignKey(verbose_name='课程名称', to='Course')semester = models.IntegerField(verbose_name="班级(期)")price = models.IntegerField(verbose_name="学费")start_date = models.DateField(verbose_name="开班日期")graduate_date = models.DateField(verbose_name="结业日期", null=True, blank=True)memo = models.CharField(verbose_name='说明', max_length=256, blank=True, null=True, )teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo', related_name="abc",limit_choices_to={"depart__in": [1002, 1005]})tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo', related_name='classes',limit_choices_to={"depart": 1001})def __str__(self):return "{0}({1}期)".format(self.course.name, self.semester)class Customer(models.Model):"""客户表"""qq = models.CharField(verbose_name='qq', max_length=64, unique=True, help_text='QQ号必须唯一')name = models.CharField(verbose_name='学生姓名', max_length=16)gender_choices = ((1, '男'), (2, '女'))gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)education_choices = ((1, '重点大学'),(2, '普通本科'),(3, '独立院校'),(4, '民办本科'),(5, '大专'),(6, '民办专科'),(7, '高中'),(8, '其他'))education = models.IntegerField(verbose_name='学历', choices=education_choices, blank=True, null=True, )graduation_school = models.CharField(verbose_name='毕业学校', max_length=64, blank=True, null=True)major = models.CharField(verbose_name='所学专业', max_length=64, blank=True, null=True)experience_choices = [(1, '在校生'),(2, '应届毕业'),(3, '半年以内'),(4, '半年至一年'),(5, '一年至三年'),(6, '三年至五年'),(7, '五年以上'),]experience = models.IntegerField(verbose_name='工作经验', blank=True, null=True, choices=experience_choices)work_status_choices = [(1, '在职'),(2, '无业')]work_status = models.IntegerField(verbose_name="职业状态", choices=work_status_choices, default=1, blank=True,null=True)company = models.CharField(verbose_name="目前就职公司", max_length=64, blank=True, null=True)salary = models.CharField(verbose_name="当前薪资", max_length=64, blank=True, null=True)source_choices = [(1, "qq群"),(2, "内部转介绍"),(3, "官方网站"),(4, "百度推广"),(5, "360推广"),(6, "搜狗推广"),(7, "腾讯课堂"),(8, "广点通"),(9, "高校宣讲"),(10, "渠道代理"),(11, "51cto"),(12, "智汇推"),(13, "网盟"),(14, "DSP"),(15, "SEO"),(16, "其它"),]source = models.SmallIntegerField('客户来源', choices=source_choices, default=1)referral_from = models.ForeignKey('self',blank=True,null=True,verbose_name="转介绍自学员",help_text="若此客户是转介绍自内部学员,请在此处选择内部学员姓名",related_name="internal_referral")course = models.ManyToManyField(verbose_name="咨询课程", to="Course")status_choices = [(1, "已报名"),(2, "未报名")]status = models.IntegerField(verbose_name="状态",choices=status_choices,default=2,help_text=u"选择客户此时的状态")consultant = models.ForeignKey(verbose_name="课程顾问", to='UserInfo', related_name='consultanter',limit_choices_to={'depart_id': 1001})date = models.DateField(verbose_name="咨询日期", auto_now_add=True)recv_date = models.DateField(verbose_name="当前课程顾问的接单日期", null=True)last_consult_date = models.DateField(verbose_name="最后跟进日期", )def __str__(self):return self.nameclass ConsultRecord(models.Model):"""客户跟进记录"""customer = models.ForeignKey(verbose_name="所咨询客户", to='Customer')consultant = models.ForeignKey(verbose_name="跟踪人", to='UserInfo', limit_choices_to={"depart": 1001})date = models.DateField(verbose_name="跟进日期", auto_now_add=True)note = models.TextField(verbose_name="跟进内容...")def __str__(self):return self.customer.name + ":" + self.consultant.nameclass Student(models.Model):"""学生表(已报名)"""customer = models.OneToOneField(verbose_name='客户信息', to='Customer')username = models.CharField(verbose_name='用户名', max_length=32)password = models.CharField(verbose_name='密码', max_length=64)emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='紧急联系人')class_list = models.ManyToManyField(verbose_name="已报班级", to='ClassList', blank=True)company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True)location = models.CharField(max_length=64, verbose_name='所在区域', blank=True, null=True)position = models.CharField(verbose_name='岗位', max_length=64, blank=True, null=True)salary = models.IntegerField(verbose_name='薪资', blank=True, null=True)welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True)date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', blank=True, null=True)memo = models.CharField(verbose_name='备注', max_length=256, blank=True, null=True)def __str__(self):return self.usernameclass CourseRecord(models.Model):"""上课记录表 (班级记录)"""class_obj = models.ForeignKey(verbose_name="班级", to="ClassList")day_num = models.IntegerField(verbose_name="节次", help_text=u"此处填写第几节课或第几天课程...,必须为数字")teacher = models.ForeignKey(verbose_name="讲师", to='UserInfo', limit_choices_to={"depart_id__in": [1002, 1003]})date = models.DateField(verbose_name="上课日期", auto_now_add=True)course_title = models.CharField(verbose_name='本节课程标题', max_length=64, blank=True, null=True)course_memo = models.TextField(verbose_name='本节课程内容概要', blank=True, null=True)has_homework = models.BooleanField(default=True, verbose_name="本节有作业")homework_title = models.CharField(verbose_name='本节作业标题', max_length=64, blank=True, null=True)homework_memo = models.TextField(verbose_name='作业描述', max_length=500, blank=True, null=True)exam = models.TextField(verbose_name='踩分点', max_length=300, blank=True, null=True)def __str__(self):return "{0} day{1}".format(self.class_obj, self.day_num)class StudyRecord(models.Model):'''学生记录表'''course_record = models.ForeignKey(verbose_name="第几天课程", to="CourseRecord")student = models.ForeignKey(verbose_name="学员", to='Student')record_choices = (('checked', "已签到"),('vacate', "请假"),('late', "迟到"),('noshow', "缺勤"),('leave_early', "早退"),)record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)score_choices = ((100, 'A+'),(90, 'A'),(85, 'B+'),(80, 'B'),(70, 'B-'),(60, 'C+'),(50, 'C'),(40, 'C-'),(0, ' D'),(-1, 'N/A'),(-100, 'COPY'),(-1000, 'FAIL'),)score = models.IntegerField("本节成绩", choices=score_choices, default=-1)homework_note = models.CharField(verbose_name='作业评语', max_length=255, blank=True, null=True)note = models.CharField(verbose_name="备注", max_length=255, blank=True, null=True)homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None)stu_memo = models.TextField(verbose_name='学员备注', blank=True, null=True)date = models.DateTimeField(verbose_name='提交作业日期', auto_now_add=True)def __str__(self):return "{0}-{1}".format(self.course_record, self.student)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_choices = ((1, "正在跟进"),(2, "已报名"),(3, "三天未跟进"),(4, "15天未成单"),)status = models.IntegerField(choices=status_choices, default=1)meno = models.CharField(max_length=255)def __str__(self):return self.customer.name + ":" + self.consultant.name
models.py
rbac/models.py
from django.db import models# Create your models here.class User(models.Model):"""用户表"""name = models.CharField(max_length=32)pwd = models.CharField(max_length=32)roles = models.ManyToManyField(to='Role')def __str__(self):return self.nameclass Role(models.Model):"""角色表"""title = models.CharField(max_length=32)permission = models.ManyToManyField(to='Permission')def __str__(self):return self.titleclass Permission(models.Model):"""权限表"""title = models.CharField(max_length=32)url = models.CharField(max_length=64)action = models.CharField(max_length=32, default="")group = models.ForeignKey('PermissionGroup', default=1, on_delete=models.CASCADE)def __str__(self):return self.titleclass PermissionGroup(models.Model):"""权限分组表"""title = models.CharField(max_length=32)def __str__(self):return self.title
models.py
三、讲师与学生
1.讲师创建一条上课记录(/courserecord/add/)2.批量生成学习记录 关联班级对应的学生,批量生成,默认都已签到。3.点名考勤 批量处理迟到(action)4.录入成绩 讲师对一条上课记录,录入对应学生的成绩,批语。5.查看成绩 一个学生可以报多个班,可在每个班下查看每节课的成绩 highcharts(柱状图)显示成绩。
四、销售与客户
1.公共客户(/customer/public/) 没有报名 3天没有跟进 15天没有成单2.公共客户里,可查看跟进记录,以及确认跟进 用户可查询之前与客户的交流内容,方便之后的交流。3.确认跟进 用户点击确认跟进,此客户将在我的客户列表显示 提示正在跟进,此客户将不在公共客户单显示了。4.我的客户(/customer/mycustomer/) 我的客户页面显示: 正在跟进的客户 3天未跟进的客户 15天未成单的客户 就算最后没有成单的,也需要显示,也需要算业绩。
五、权限
1.引入权限组件rbac2.员工表UserInfo与rbac.User表关联 一对一3.创建权限组 客户管理 学习记录 学生管理 校区管理 班级管理 ...4.分配权限 客户管理: 查看客户 添加客户 编辑客户 删除客户 查看公共客户 我的客户 学习记录: 查看学习记录 添加学习记录 删除学习记录 编辑学习记录 学生管理: 查看学生 添加学生 删除学生 编辑学生 查看学生成绩5.角色分配 校长: 拥有所有的权限 ... 销售: 查看客户 添加客户 编辑客户 查看公共客户 我的客户 讲师: 查看学习记录 添加学习记录 编辑学习记录 删除学习记录 学生: 查看学生成绩6.用户分配角色 yuan 123 校长 alex 123 销售 egon 123 讲师 alice 123 学生
六、登录、中间件、模板继承
1.验证通过后,注册session,注册权限 user = User.objects.filter(name=user,pwd=pwd).first() if user: request.session["user_id"] = user.pk # 注册权限到session中,包括注册菜单权限 initial_session(user,request) return HttpResponse("登录成功") 2.中间件 'rbac.service.rbac.ValidPermission', from django.utils.deprecation import MiddlewareMixin class ValidPermission(MiddlewareMixin): def process_request(self, request): pass 1.白名单,(/login/,/reg/)不需要校验 2.校验是否登录,若没登录,跳转到登录页面 3.当前路径与权限字典中的权限url比较,如没有权限,提示无权访问。 ( 权限字典: 类似: {1: {'urls': ['/users/', '/users/add/', '/users/delete/(\\d+)/', '/users/edit/(\\d+)/'], 'actions': ['list', 'add', 'delete', 'edit']}, 2: {'urls': ['/roles/'], 'actions': ['list']}} 菜单权限列表: 类似: [('/users/', '用户管理'), ('/roles/', '角色管理')] ) 3.模板继承 标题和菜单,使用模板继承 菜单提示有哪些查看的权限, 若没有权限,就看不到该列表。 4.可以完成 有添加,编辑,删除权限的才会展示相应的按钮; 思路: 'actions': ['list', 'add', 'delete', 'edit']} class Per(object): def __init__(self,actions): self.actions = actions def add(self): return "add" in self.actions def delete(self): return "delete" in self.actions def edit(self): return "edit" in self.actions def list(self): return "list" in self.actions {% if per.delete %} <a href="" class="btn btn-danger">删除</a> {% endif %} {% if per.edit %} <a href="" class="btn btn-warning">编辑</a> {% endif %}
七、code
code:
https://github.com/alice-bj/my_crm
转载于:https://www.cnblogs.com/alice-bj/p/9239163.html
7.1 - CRM系统相关推荐
- Rushcrm:企业部署CRM系统做什么
现在很流行的一个词就是大数据,很多企业开始重视数据的开发利用.CRM在这样的环境背景下诞生了,但这并不意味着所有的企业都能很好的利用好CRM系统(客户关系管理系统).CRM带来的效益是显而易见的,但是 ...
- CRM系统业务的分析(1)
CRM(Customer Relationship Management),即客户关系管理.这个概念最初由Gartner Group提出来,而在最近开始在企业电子商务中流行.CRM的主要含义就是通过对 ...
- 一旦上了CRM系统 就期待短期见效?
Customer Relationship Management(客户关系管理)的缩写,它是一项综合的IT技术,也是一种新的运作模式,它源于"以客户为中心"的新型商业模式,是一种旨 ...
- CloudCC:为企业业绩而生的CRM系统
在当今信息化不断加速的互联网时代,当企业发展遭遇瓶颈.业绩如何突破困境.冲出生天呢?使用CRM系统可以驱动企业商业模式的创新,提高运营效率,提高销售业绩,最终提高企业竞争力. 要想提高企业业绩,必须科 ...
- CRM系统助力企业找到最大盈利客户
自从无处不在的"二八定律"提出后,这一观点得到了诸多数据的证实,并且广泛应用于人们的经济和社会生活中.而在企业管理中,"二八定律"意味着 20%的客户创造了企业 ...
- crm系统是什么很棒ec实力_CRM系统都有哪些功能?CRM管理系统的主要用途又是什么?...
就目前市面上的CRM系统众多,各个供应商可能都是不太一样的,但是大致上还是离不开这几个功能:即营销自动化.客户管理.销售管理.客服你管理.报表分析等. 其中,销售自动化功能可以说是每个CRM系统的核心 ...
- 基于云的CRM系统到底好在哪里?
高质量的CRM系统不仅能够帮你轻松保存与业务交互的所有信息,而且可以使得团队中的每个人都访问到最新的信息,帮助解决客户或客户关系周期中的特定问题,关注客户留存并推动销售增长. 在之前的文章中,我们讲述 ...
- 眼图在通信系统中有什么意义_解读CRM系统在企业中有什么作用
随着办公系统在国内的普及,CRM系统也在被更多的公司引入,CRM系统也迅速发展.功能越发完善,越来越多的企业看到了CRM系统给企业带来的巨大作用.那么,CRM系统有什么作用?又能给企业带来多大的效益? ...
- 久其通用数据管理平台_银保行业通用的CRM系统,为你轻松化解庞大数据难题
内容简介 本文以中国人寿财产保险股份有限公司某市的分公司为例,介绍智慧平台通过为该公司量身定制银保业通用的CRM系统,让各层级的管理者通过手机/电脑端便能在线提报相关数据,使数据收集.数据管理.流程分 ...
- 简易的CRM系统案例之SpringMVC+JSP+MySQL+hibernate框架版本
继续对上一版本进行改版,变成SpringMVC框架 简易的CRM系统案例之易的CRM系统案例之JSP+MySQL+SSH框架版本 src/spring.xml <?xml version=&qu ...
最新文章
- rrdtool数据备份与迁移
- 我的第一个MapReduce程序(WordCount)
- springmvc常用配置
- Eclipse - CDT使用GDB调试C++的问题-无源文件命名(No source file named)
- FreeBSD下安装postfixl邮件系统
- LeetCode 1033. 移动石子直到连续
- 作者:胡卫生,博士,上海交通大学教授、博士生导师。
- 失落城堡获取服务器信息,《失落城堡》精英服资格获取方法 失落城堡精英服招募...
- 自定义日期输入控件-解决需要用户输入日期的麻烦控制
- bzoj3144 [Hnoi2013]切糕
- 软件项目管理原则谈-转自51testing
- ArcGIS georeference地理配准提高精度
- CSS学习13:表格样式
- Z字型变幻,整数反转
- python实现经典密码学中列移位算法
- 7个快速登录Gmail的技巧
- 中国黑客档案:识别黑客犯罪的蛛丝马迹
- 研发人员在公司内部调岗会发生哪些事情?
- 软件开发外包管理-1-选择供应商
- js-对象属性是否全部为空
热门文章
- 51单片机mysql_[学习笔记]15个QA让你快速入门51单片机开发
- PHP面向对象之方法重写
- Android 基于监听的事件处理机制
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-3.热部署在Eclipse和IDE里面的使用...
- 小D课堂 - 新版本微服务springcloud+Docker教程_3-02CAP理论知识
- Mybatis-实现逆向代理
- 屏幕操作录制成gif图的技巧
- maven 构建spring boot + mysql 的基础项目
- mybatis_Mapped Statements collection already contains value
- 用Java+xml配置方式实现Spring数据事务(编程式事务)