crm管理系统

CRM客户关系管理系统


  • CRM客户关系管理系统
      • 客户关系管理(CRM)
      • 作用
      • 思维导图
      • 用户场景分析
      • 表结构设计
      • 重点代码段

客户关系管理(CRM)

​ 客户关系管理(customer relationship management)的定义是:企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售、营销和服务上的交互,从而提升其管理方式,向客户提供创新式的个性化的客户交互和服务的过程。其最终目标是吸引新客户、保留老客户以及将已有客户转为忠实客户,增加市场。

作用

1.提高市场营销效果

2.为生产研发提供决策支持

3.提供技术支持的重要手段

4.为财务金融策略提供决策支持

5.为适时调整内部管理提供依据

6.使企业的资源得到合理利用

7.优化企业业务流程

8.提高企业的快速响应和应变能力

9.改善企业服务,提高客户满意度

10.提高企业的销售收入

11.推动了企业文化的变革

12.与QQ集成,可以快速与客户沟通

思维导图

crm管理系统_第1张图片

用户场景分析

销售

  • 销售A 刚从 百度推广 聊了一个客户,录入了CRM系统,咨询了python全栈开发课程,但是没报名
  • 销售B 从 qq群聊了客户,且报名了python全栈9期课程,给用户发送了报名连接,待用户填写完毕后,把他添加到了python fullstack s9的班级里

  • 销售C 打电话给之前的一个客户,说服他报名linux40期,但是没说服成功,更新了跟踪记录

  • 销售D 聊了一个客户,录入时发现,此客户已存在,不能录入,随后通知相应的客户负责人跟进
  • 销售B 从客户库里过滤出了 所有超过一个月未跟踪的客户,然后进行跟踪(如果成了,这客户就算B的)
  • 销售主管 查看了部门 本月的销售报表, 包括来源分析,成单率分析,班级报名数量分析,销售额同比

    学员

  • 客户A 填写了销售发来的报名链接,上传了个人的证件信息,并提交,过了一会儿,发现收到一个邮件,告知他报名python9期课程成功,并帮他开通了学员账号

  • 学员A 登录了学员系统,看到了 自己的合同,报名的班级,以及课程大纲

  • 学员A 提交了python9期的 第1节课的作业
  • 学员A 查看了自己在python9期的学习成绩和排名
  • 学员A 在线搜索一个问题,发现没有答案,于是提交了一个问题

讲师

  • 登录了CRM,查看自己管理的班级列表
  • 进入了python9期,创建了第一节的上课记录,填入了本节内容,作业需求
  • 为python9期的第一节课,进行点名,发现科比迟到了,标记他为迟到状态
  • 批量下载了所有学员的python9期第一节的作业,给每个学生在线 打成绩+批注

    管理员

  • 创建了 课程(linux,python)

  • 创建了 校区(北京,上海)
  • 创建了 班级(python fullstacks9和linux40)
  • 创建了 账号(A,B,C,D)
  • 创建了 销售,讲师,学员三个角色,并把ABCD分配到了销售角色里
  • 设置了销售可以操作的权限

表结构设计

crm管理系统_第2张图片

重点代码段

登录

from django.shortcuts import render,redirect
from django.contrib.auth import authenticate,login


def acc_login(request):
    if request.method == 'POST':
        username = request.POST.get('username',None)
        password = request.POST.get('password',None)
        #user是一个对象
        #验证
        user = authenticate(username=username,password=password)
        if user:
            #登录(已生成session)
            login(request,user)
            #如果有next值就获取next值,没有就跳转到首页
            return redirect(request.GET.get('next','/'))
    return render(request,'login.html')

动态菜单生成

  • 首先获取登录的用户(User)
  • 通过User反向查找到UserProfile(用户信息)
  • 然后通过UserProfile找到用户关联的所有角色
  • 最后通过角色循环遍历出用户所有的菜单

OneToOneField和ForeignKey反向获取

  • OneToOneField反向查,直接request.user.userprofile 后面跟反向的表名(小写)就可以
  • 如果是FK,直接request.user.userprofile_set 后面跟反向的表名(小写)+“_set” 就可以
  • request.user.userprofile.role.select_related等价于request.user.userprofile.role.all

自定义前端kingadmin全局注册时报错NoneType

是因为我们在注册model的时候,有的写了自定义的model类,有的没写,而我们都统一的赋值,导致那些没写自定义model类(空的)赋值的时候就会报NoneType错误

django自带的自定义admin类的写法继承了ModelAdmin,那注册的时候为什么有的没写自定义admin类没有报错呢?

是因为继承的admin.ModelAdmin帮我们写了(里面其实都定义为空了),我们模仿django admin的写法,也写个父类。

crm管理系统_第3张图片

分页

crm管理系统_第4张图片

官方实例

crm管理系统_第5张图片

报名页面流程

  • 销售填写客户跟班级,点“下一步”提交
  • 后台获取到客户id和班级id,在数据库中创建记录,并生成一个报名链接,返回到前端
  • 前端显示报名链接,然后销售把报名链接发给用户

学员填写报名信息

  • 添加学员注册url
  • 添加CustomerInfo字段,身份证信息,紧急联络人,性别
  • 有些字段是只读的,填写信息的时候不能修改,因为如果设置了只读(添加属性disabled=true),提交的时候会报这些字段为空,导致提交错误
  • 所以在前段添加了js代码,BeforeFormSubmit 在提交前去掉disable=true(因为数据库中有默认值,提交的时候就不会报错)
  • 防止用户通过前端改html代码的方式改只读字段的信息,所以在form.py里面添加了一个自定义的验证方法(clean),如果只读字段提交的时候信息跟数据库中默认的不一样,就报错
 #只读字段不让用户通过浏览器改html代码的方式改
    def clean(self):
        # 表单级别的错误
        if self.errors:
            raise forms.ValidationError(("Please fix errors before re-submit."))
        # means this is a change form ,should check the readonly fields
        if self.instance.id is not None:
            #取出只读字段,是一个字符串形式
            for field in self.Meta.readonly_fields:
                #通过反射取出字段的值(数据库里的数据)
                old_field_val = getattr(self.instance, field)
                #提交过来的数据
                form_val = self.cleaned_data.get(field)
                #如果两个数据不匹配
                if old_field_val != form_val:
                    #就提示只读字段不能修改
                    #add_error是字段级别的错误
                    self.add_error(field, "Readonly Field: field should be '{value}' ,not '{new_value}' ".format(**{'value': old_field_val, 'new_value': form_val}))

学员报名合同及身份信息上传

  • 必须勾选报名合同协议
  • 必须上传个人证件信息
  • 最多只能上传三个文件
  • 文件大小2M以内
  • 列出已上传文件
@csrf_exempt
def enrollment_fileupload(request,enrollment_id):
    '''学员报名文件上传'''
    enrollment_upload_dir = os.path.join(conf.settings.CRM_FILE_UOLOAD_DIR,enrollment_id)
    #第一次上传图片就创建目录,学员上传第二章图片的时候,会判断目录是否已经存在
    #因为如果目录存在还mkdir就会报错,所以这里要做判断
    if not os.path.isdir(enrollment_upload_dir):
        os.mkdir(enrollment_upload_dir)
    #获取上传文件的对象
    file_obj = request.FILES.get('file')
    #最多只允许上传3个文件
    if len(os.listdir(enrollment_upload_dir)) <= 3:
        #把图片名字拼接起来(file.name:上传的文件名字)
        with open(os.path.join(enrollment_upload_dir,file_obj.name),'wb') as f:
            for chunks in file_obj.chunks():
                f.write(chunks)
    else:
        return HttpResponse(json.dumps({'status':False,'err_msg':'最多只能上传三个文件'}))

    return HttpResponse(json.dumps({'status':True,}),)

    # 列出学员已上传的文件
    upload_files = []
    enrollment_upload_dir = os.path.join(conf.settings.CRM_FILE_UOLOAD_DIR, enrollment_id)
    if os.path.isdir(enrollment_upload_dir):
        upload_files = os.listdir(enrollment_upload_dir)

合同审核

  • 学员提交报名信息后,应该是等待审核状态
  • 管理员改审核状态为ture, 并保存提交时间

所有权限

perm_dic = {
    # 'crm_table_index': ['table_index', 'GET', [], {}, ],  # 可以查看CRM APP里所有数据库表

    # 可以查看每张表里所有的数据
    'crm_table_list': ['table_obj_list', 'GET', [], {}],  
    # 'crm_table_list': ['table_obj_list', 'GET', [], {'source':0,'status':0}],  # 添加参数:只能访问来源是qq和未报名的客户
    # 可以访问表里每条数据的修改页
    'crm_table_list_view': ['table_obj_change',  'GET', [], {}],  
    # 可以对表里的每条数据进行修改
    'crm_table_list_change': ['table_obj_change', 'POST', [], {}],  
    # 可以访问数据增加页
    'crm_table_list_add_view': ['table_obj_add ',  'GET', [], {}],
    # 可以添加表数据
    'crm_table_list_add': ['table_obj_add ', 'POST', [], {}],  

}

*per_name和split用法

> a,*b,c=[1,2,3,4,5,6]
>a
1
>c
6
>b
[2,3,4,5]
>>>a='crm_table_list'
>>>a.split('_')
['crm','table','list']
>>>
>>>app_name,*per_name=a.split('_')
>>>
>>>app_name
'crm'
>>>per_name
# 权限
['table','list']

你可能感兴趣的:(#,python后端-Django)