CRM 客戶關係管理系統

CRM(Customer Relationship Manager)客戶關係管理系統javascript

企業爲提升核心競爭力,利用相應的信息技術以及互聯網技術協調企業與顧客間在銷售營銷和服務上的交互,從而提高其管理方式,向客戶提供創新式的個性化的客戶交互和服務的過程。其最終目標是吸引新客戶、保留老客戶以及將已有客戶轉爲忠實客戶,增長市場。css

1. 需求分析

  • 存儲全部客戶諮詢信息
  • 避免重複錄入數據
  • 客戶屢次跟蹤記錄(銷售)
  • 客戶來源、成單率分析
  • 每一個銷售只能修改本身的客戶信息
  • 報名流程開發等

2. 業務場景分析

業務場景分析意在各個用戶使用 CRM 用來作什麼,可以更好地別寫項目。在這裏咱們編寫一個基於培訓機構的 CRM。html

成員及使用場景前端

成員 說明 成員 說明
機構銷售 尋找學員報名、給學員報名,分配班級等 學員 諮詢課程,繳納學費
講師 查看班級列表、建立課程記錄、佈置做業,批改做業等 管理員 建立課程、校區、班級,分配權限等

3. 模型設計

4. 菜單

不一樣的用戶有訪問 crm,看到的菜單也是不同的,這也是最基本的一種權限體現,好比:java

  • 銷售:能夠查看首頁、客戶庫、學員報名
  • 學生:能夠查看首頁、個人課程等
  • 管理員:上述均可以查看

經過用戶、菜單,以及角色模型便可實現:python

菜單分爲固定(absolute)和動態菜單(dynamic)兩種,動態菜單人人均可以看到(如:首頁),而固定菜單不一樣的角色看到的都不同:jquery

另外動態菜單的 url_anem 要與路由中 name 一致:git

crm/views.pygithub

from django.urls import path, re_path
from crm import views

urlpatterns = [
    path('dashboard/', views.dashboard, name='sales_dashboard'),    # 首頁 url_name 與這個 name 一致
    path('student_enrollment/', views.student_enrollment, name='student_enrollment'),
    ...
]

5. 頁面佈局

整個 CRM 整體佈局,咱們以 bootstrap 中的模板爲基礎,在此之上進行修改拓展,採用的樣式爲:django

模板地址:Dashboard

爲了減小代碼重複,在這裏採用模板繼承:

一、base.html

base.html 只是構建了一個總體框架:

{% load  static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">

    <title>CRM</title>

    <!-- Bootstrap core CSS -->
    <link href="{% static 'css/bootstrap.css' %}" rel="stylesheet">

    <!-- dashboard 這個模板的 css 樣式 -->
    <link href="{% static 'css/dashboard.css' %}" rel="stylesheet">

    {% block extra-css %}

    {% endblock %}

</head>

<body>
    <!--主要內容區-->
    {% block body %}

    {% endblock %}
    
<!-- JS 文件
================================================== -->
<!-- 放置在文檔的末尾,以便頁面加載更快 -->
<script src="{% static 'js/jquery-3.3.1.js' %}"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
</body>
</html>

二、index.html

index.html 繼承 base.html,這裏主要有 "頂部導航欄、左側菜單以及右側主要內容區"

{% extends 'include/base.html' %}

{% block body %}
    <!--頂部導航欄-->
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
                        aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#">{% block title %}Project name{% endblock %}</a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav navbar-right">
                    <li class="dropdown ">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown"
                           role="button">{{ request.user.name }}
                            <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#">我的信息</a></li>
                            <li><a href="{% url 'logout' %}">登出</a></li>

                        </ul>
                    </li>

                </ul>
            </div>
        </div>
    </nav>

    <!--左側菜單和右側內容區-->
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-3 col-md-2 sidebar">
                <ul class="nav nav-sidebar">
                    {% for role in request.user.role.all %}
                        {% for menu in role.menus.all %}
                            {% if request.path == menu.url_name %}
                                <li class="active"><a
                                        href="{% if menu.url_type == 0 %} {{ menu.url_name }}{% else %}{% url menu.url_name %}{% endif %}">{{ menu.name }}</a>
                                </li>
                            {% else %}
                                <li>
                                    <a href="{% if menu.url_type == 0 %} {{ menu.url_name }}{% else %}{% url menu.url_name %}{% endif %}">{{ menu.name }}</a>
                                </li>
                            {% endif %}
                        {% endfor %}

                    {% endfor %}

                </ul>
            </div>
            
            <!--右側內容區-->
            <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
                {% block right-content-container %}
                    <h1 class="page-header">Dashboard</h1>
                {% endblock %}

            </div>
        </div>
    </div>

{% endblock %}

三、CRM 頁面

CRM 頁面只用繼承 index.html 便可,dashboard.html

{% extends 'include/index.html' %}

{% block right-content-container %}
    <h1 class="page-header">首頁</h1>
{% endblock %}

1560563214381

6. 報名流程

整個 CRM 的報名流程大體分爲如下幾步:

  • 銷售:向後臺發起報名,後臺生成報名連接,銷售將連接發給學員填寫
  • 學員:填寫報名表、包括我的信息、學費,上傳我的證件等
  • 銷售:審覈報名表,建立繳費記錄,併爲學員分配班級

crm/urls.py

from django.urls import path, re_path
from crm import views

urlpatterns = [
    path('dashboard/', views.dashboard, name='sales_dashboard'),
    path('student_enrollment/', views.student_enrollment, name='student_enrollment'),   # 發起報名
    re_path(r'^enrollment/(\d+)/$', views.enrollment, name='enrollment'),           # 報名連接
    re_path(r'^enrollment/(\d+)/fielupload/$', views.enrollment_fileupload,         # 證件上傳name='enrollment_fileupload'),

    re_path(r'^student_enrollment/(\d+)/contract_audit/$', views.contract_audit,    # 合同審覈name='contract_audit'),

]

建立報名連接

銷售訪問:<http://127.0.0.1:8002/crm/student_enrollment/> 發起報名,會在後臺建立一條報名記錄,並返回報名連接,銷售將連接發給學員填寫:

@login_required
def student_enrollment(request):
    """銷售分配學員班級,並生成報名連接"""
    customer_data = models.CustomerInfo.objects.all()
    class_list_data = models.ClassList.objects.all()
    if request.method == "POST":
        customer_id = request.POST.get('customer_id')  # 客戶
        class_grade_id = request.POST.get('class_grade_id')  # 班級
        consultant_id = request.user.id  # 課程顧問

        try:
            # 建立報名記錄
            enrollment_obj = models.StudentEnrollment.objects.create(
                customer_id=customer_id,
                class_grade_id=class_grade_id,
                consultant_id=consultant_id
            )
        except IntegrityError as e:
            enrollment_obj = models.StudentEnrollment.objects.get(customer_id=customer_id,
                                                                  class_grade_id=class_grade_id)

            # 學員是否贊成協議,是則跳轉到合同審覈頁面,不然
            # 這裏意思是,若是學員填寫了報名表,那麼 StudentEnrollment 中 contract_agreed 是有記錄的,所以當學員填寫了報名表,銷售再次點擊報名頁面中下一步時,會跳轉到合同審覈頁面
            if enrollment_obj.contract_agreed:
                return redirect('/crm/student_enrollment/%s/contract_audit/' % enrollment_obj.id)

        # 生成報名連接,傳遞給前端,銷售複製發送給學員填寫報名信息
        enrollment_links = 'http://localhost:8002/crm/enrollment/%s/' % enrollment_obj.id

    return render(request, 'crm/student_enrollment.html', locals())

報名表

檢查用戶是否勾選合同協議及是否上傳證件(經過 onsubmit 事件,form 表單提交前執行哪一個函數):

<form method="post" onsubmit="return BeforeRemoveDisabled()" novalidate>
    <!-- 合同協議 -->
    <pre style="height: 400px">{{ enrollment_obj.class_grade.contract_template.content }}</pre>
    <input type="checkbox" name="contract_agreed"> 我已認真閱讀完畢,無條件贊成!

    <input type="submit" value="提交" class="btn btn-info pull-right">
</form>
<script>
    // 表單提交前,移除全部的 disabled,form 表單不能提交 disabled
    function BeforeRemoveDisabled() {
    $(':disabled').removeAttr('disabled');

    // 若是沒有上傳證件信息,提示上傳
    if ($('#uploaded_files').children().length == 0){
        alert('請上傳證件信息!');
        return false
    }

    // 若是沒有勾選協議,表單不能提交
    if (!$("input[name='contract_agreed']").prop('checked')) {
        alert('請勾選合同協議!');
        return false
    }
}
</script>

使用 drop-zone 插件實現證件上傳

官網

<!-- 證件上傳 -->
<div class="file-upload">
    <h3>身份證上傳</h3>

    <ul id="uploaded_files">
      
    </ul>

    <form id="myAwesomeDropzone" action="{% url 'enrollment_fileupload' enrollment_obj.id %}"
          class="dropzone">
        <div class="fallback">
            <input name="file" type="file" multiple/>
        </div>
    </form>

</div>
<script src="{% static 'plugins/dropzone/dropzone.js' %}"></script>
<script>
    // "myAwesomeDropzone" is the camelized version of the HTML element's ID
    Dropzone.options.myAwesomeDropzone = {
    paramName: "file",           // 用於傳輸文件的名稱
    maxFilesize: 2,             // MB      最大不能上傳超過 2 M
    maxFiles: 2,                // 最多上傳 2 個文件
    parallelUploads: 1,         // 單次上傳 1 個
    accept: function (file, done) {
        if (file.name == "justinbieber.jpg") {
            done("Naha, you don't.");
        }
        else {
            done();
        }
    }
};

// 避免重複建立 Dropzone
Dropzone.options.myAwesomeDropzone = false;

// 上傳成功回調,返回值存在 response 中
$(function () {
    // Now that the DOM is fully loaded, create the dropzone, and setup the
    // event listeners
    // Prevent Dropzone from auto discovering this element:
    {#            Dropzone.options.myAwesomeDropzone = false;#}
    var myDropzone = new Dropzone("#myAwesomeDropzone");
     myDropzone.on("success", function (file, response) {
         /* Maybe display some more file information on your page */
         console.log("success", file, file.name, response);
         var response = JSON.parse(response);
         if (!response.status) {
             alert(response.error);
         } else {
             var ele = "<li class='file_title'>" + file.name + ' ' + "<span class='glyphicon glyphicon-remove'></span>" + "</li>" ;
             $("#uploaded_files").append(ele);
             alert(response.message)

         }

     });
    });

    // $('.file_title').children('span')
    /*
     $('#uploaded_files').on('click', 'span', function () {
        alert(123);
    })
     */

    $('#uploaded_files').on('click', 'span', function () {
        $(this).parent().remove();
    })

提交報名表後:


合同審覈

銷售審覈合同後,將跳轉到數據修改頁面:

以上就是 CRM 的大體開發流程,具體源碼可參考:<https://github.com/hj1933/PerfectCRM>

相關文章
相關標籤/搜索