Selaa lähdekoodia

修改客户信息

wushaodong 4 vuotta sitten
vanhempi
sitoutus
ac67c44112

+ 2 - 0
apps/account/views.py

@@ -145,6 +145,7 @@ class EmployeeViewSet(CustomModelViewSet):
 
 
     @action(methods=['post'], detail=True)
     @action(methods=['post'], detail=True)
     def branch(self, request, pk):
     def branch(self, request, pk):
+        # 管理门店
         check_permission(request, 'account.manager_store')
         check_permission(request, 'account.manager_store')
         data = json.loads(request.POST.get('stores'))
         data = json.loads(request.POST.get('stores'))
         try:
         try:
@@ -180,6 +181,7 @@ class EmployeeViewSet(CustomModelViewSet):
 
 
     @action(methods=['post'], detail=True)
     @action(methods=['post'], detail=True)
     def office(self, request, pk):
     def office(self, request, pk):
+        # 任职门店
         check_permission(request, 'account.manager_store')
         check_permission(request, 'account.manager_store')
         data = json.loads(request.POST.get('stores'))
         data = json.loads(request.POST.get('stores'))
         try:
         try:

+ 4 - 2
apps/customer/models.py

@@ -60,15 +60,17 @@ class NewCustomer(models.Model):
     )
     )
     name = models.CharField(max_length=20, verbose_name=u"姓名")
     name = models.CharField(max_length=20, verbose_name=u"姓名")
     tel = models.CharField(max_length=15, verbose_name=u'电话')
     tel = models.CharField(max_length=15, verbose_name=u'电话')
+    gender = models.PositiveSmallIntegerField(choices=settings.GENDER_CHOICES, verbose_name=u'性别',
+                                              default=settings.MALE)
     village = models.CharField(max_length=200, verbose_name=u'小区')
     village = models.CharField(max_length=200, verbose_name=u'小区')
     address = models.CharField(max_length=200, verbose_name=u'地址')
     address = models.CharField(max_length=200, verbose_name=u'地址')
     source = models.ForeignKey(Option, verbose_name=u'来源', related_name='customer_source', on_delete=models.PROTECT)
     source = models.ForeignKey(Option, verbose_name=u'来源', related_name='customer_source', on_delete=models.PROTECT)
     project = models.ManyToManyField(Option, verbose_name=u'项目', related_name='customer_category', editable=False,)
     project = models.ManyToManyField(Option, verbose_name=u'项目', related_name='customer_category', editable=False,)
 
 
     report_customer = models.ForeignKey(ReportCustomer, verbose_name=u'报备客户信息', related_name='report_customer',
     report_customer = models.ForeignKey(ReportCustomer, verbose_name=u'报备客户信息', related_name='report_customer',
-                                        on_delete=models.PROTECT)
+                                        on_delete=models.PROTECT, editable=False,)
     stage_progress = models.ForeignKey(Option, verbose_name=u'阶段进度', related_name='stage_progress',
     stage_progress = models.ForeignKey(Option, verbose_name=u'阶段进度', related_name='stage_progress',
-                                       on_delete=models.PROTECT)
+                                       on_delete=models.PROTECT, editable=False,)
     track_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'跟踪人', related_name='track_user',
     track_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'跟踪人', related_name='track_user',
                                    editable=False, on_delete=models.PROTECT)
                                    editable=False, on_delete=models.PROTECT)
     end_time = models.DateTimeField(verbose_name=u'最后跟踪时间', null=True)
     end_time = models.DateTimeField(verbose_name=u'最后跟踪时间', null=True)

+ 10 - 4
apps/customer/serializers.py

@@ -122,7 +122,7 @@ class NewCustomerSerializer(serializers.ModelSerializer):
 
 
     store_text = serializers.CharField(source='store.name', read_only=True)
     store_text = serializers.CharField(source='store.name', read_only=True)
     source_text = serializers.CharField(source='source.name', read_only=True)
     source_text = serializers.CharField(source='source.name', read_only=True)
-    gender_text = serializers.SerializerMethodField()
+    gender_text = serializers.CharField(source='get_gender_display', read_only=True)
     project_text = serializers.SerializerMethodField()
     project_text = serializers.SerializerMethodField()
     last_review = serializers.SerializerMethodField()
     last_review = serializers.SerializerMethodField()
     enter_count = serializers.SerializerMethodField()
     enter_count = serializers.SerializerMethodField()
@@ -150,9 +150,6 @@ class NewCustomerSerializer(serializers.ModelSerializer):
         project = obj.project.all()
         project = obj.project.all()
         return ','.join(project.values_list('name', flat=True))
         return ','.join(project.values_list('name', flat=True))
 
 
-    def get_gender_text(self, obj):
-        return settings.GENDER_CHOICES[obj.report_customer.gender - 1][1]
-
     class Meta:
     class Meta:
         model = NewCustomer
         model = NewCustomer
         fields =  '__all__'
         fields =  '__all__'
@@ -164,6 +161,15 @@ class NewCustomerSerializer(serializers.ModelSerializer):
         return instance
         return instance
 
 
     def update(self, instance, validated_data):
     def update(self, instance, validated_data):
+        instance.project.clear()
+        projects = self.initial_data['project']
+        if projects:
+            projects = json.loads(projects)
+        else:
+            raise CustomError(u'请选择项目')
+
+        for project in projects:
+            instance.project.add(project)
         instance = super(NewCustomerSerializer, self).update(instance, validated_data)
         instance = super(NewCustomerSerializer, self).update(instance, validated_data)
         return instance
         return instance
 
 

+ 8 - 1
apps/customer/views.py

@@ -84,7 +84,7 @@ class ReportCustomerViewSet(CustomModelViewSet):
                     raise CustomError('当前阶段,没有设置跟踪天数!')
                     raise CustomError('当前阶段,没有设置跟踪天数!')
                 next_time = (timezone.now() + datetime.timedelta(days=stage_progress.track_day)).strftime('%Y-%m-%d')
                 next_time = (timezone.now() + datetime.timedelta(days=stage_progress.track_day)).strftime('%Y-%m-%d')
 
 
-                customer = NewCustomer.objects.create(report_customer=instance,
+                customer = NewCustomer.objects.create(report_customer=instance, gender=instance.gender,
                                                       track_user_id=user_id, stage_progress=stage_progress,
                                                       track_user_id=user_id, stage_progress=stage_progress,
                                                       create_user=instance.create_user, store=instance.store,
                                                       create_user=instance.create_user, store=instance.store,
                                                       name=instance.name, tel=instance.tel, village=instance.village,
                                                       name=instance.name, tel=instance.tel, village=instance.village,
@@ -183,6 +183,13 @@ class NewCustomerViewSet(CustomModelViewSet):
             return None
             return None
         return self.paginator.paginate_queryset(queryset, self.request, view=self)
         return self.paginator.paginate_queryset(queryset, self.request, view=self)
 
 
+    def perform_update(self, serializer):
+        super(NewCustomerViewSet, self).perform_update(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        BizLog.objects.addnew(self.request.user, BizLog.UPDATE,
+                              u'修改客户信息[%s],id=%d' % (instance.name, instance.id), validated_data)
+
     @action(methods=['post'], detail=True)
     @action(methods=['post'], detail=True)
     def add_review(self, request, pk):
     def add_review(self, request, pk):
         # 添加跟踪报告
         # 添加跟踪报告

+ 184 - 0
uis/views/customer/edit.html

@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>客户信息修改</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport"
+          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
+    <link rel="stylesheet" href="../../layuiadmin/layui/css/layui.css" media="all">
+    <link rel="stylesheet" href="../../layuiadmin/style/admin.css" media="all">
+    <link rel="stylesheet" type="text/css" href="../../layuiadmin/style/formSelects-v4.css"/>
+    <style>
+        .input {
+            border-radius: 2px;
+            height: 38px;
+            border-width: 1px;
+            border-color: lightgray;
+            border-style: solid;
+            background-color: white;
+            padding-left: 3px;
+        }
+    </style>
+</head>
+<body>
+
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15">
+        <div class="layui-card">
+
+            <div class="layui-card-body" pad15>
+                <form class="layui-form" action="" lay-filter="component-form-element">
+                    <div class="layui-row layui-col-space10 layui-form-item">
+                        <div>
+                            <label class="layui-form-label"><font color='red' size="4">*</font>姓名:</label>
+                            <div class="layui-input-block">
+                                <input type="text" name="name" lay-verify="required" placeholder="请输入姓名"
+                                       autocomplete="off" class="layui-input">
+                            </div>
+                        </div>
+                        <div>
+                            <label class="layui-form-label"><font color='red' size="4">*</font>性别:</label>
+                            <div class="layui-input-block">
+                                <input type="radio" name="gender" value="2" title="男" checked>
+                                <input type="radio" name="gender" value="1" title="女">
+                            </div>
+                        </div>
+                        <div>
+                            <label class="layui-form-label"><font color='red' size="4">*</font>电话:</label>
+                            <div class="layui-input-block">
+                                <input type="text" name="tel" class="layui-input" placeholder="请输入电话号码"
+                                       autocomplete="off" lay-verify="required"/>
+                            </div>
+                        </div>
+                        <div>
+                            <label class="layui-form-label"><font color='red' size="4">*</font>小区:</label>
+                            <div class="layui-input-block">
+                                <input type="text" name="village" placeholder="请输入小区"
+                                       autocomplete="off" class="layui-input" lay-verify="required">
+                            </div>
+                        </div>
+                        <div>
+                            <label class="layui-form-label"><font color='red' size="4">*</font>地址:</label>
+                            <div class="layui-input-block">
+                                <input type="text" name="address" placeholder="请输入地址"
+                                       autocomplete="off" class="layui-input" lay-verify="required">
+                            </div>
+                        </div>
+
+                        <div>
+                            <label class="layui-form-label"><font color='red' size="4">*</font>来源:</label>
+                            <div class="layui-input-block">
+                                <select lay-verify="required" name="source" id="id_source">
+                                    <option value="">请选择来源</option>
+                                </select>
+                            </div>
+                        </div>
+
+                        <div>
+                            <label class="layui-form-label"><font color='red' size="4">*</font>项目:</label>
+                            <div class="layui-input-block">
+                                 <select lay-verify="required" name="project" xm-select="selectProject" xm-select-skin="primary">
+                                     <option value="">请选择</option>
+                                 </select>
+                            </div>
+                        </div>
+                        <div>
+                            <label class="layui-form-label">备注:</label>
+                            <div class="layui-input-block">
+                                <textarea type="text" name="notes" class="layui-textarea" placeholder="请输入备注"/></textarea>
+                            </div>
+                        </div>
+
+                        <button id="id_save" class="layui-btn" lay-submit lay-filter="component-form-element"
+                                style="display: none">保存
+                        </button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="../../layuiadmin/layui/layui.js"></script>
+<script>
+    layui.link('../../../layuiadmin/style/autocomplete.css');
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+        , autocomplete: 'autocomplete'
+    }).extend({
+        index: 'lib/index',
+        formSelects: 'formSelects-v4'
+    }).use(['index', 'form', 'autocomplete', 'formSelects'], function () {
+        var $ = layui.$
+            , admin = layui.admin
+            , formSelects = layui.formSelects
+            , form = layui.form
+        var id = layui.view.getParameterByName('id');
+        var editdata = {};
+        if (id) {
+            editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata)); // 框架有Bug所以这么转换
+            editdata['gender'] = editdata['gender'].toString();
+        }
+
+        admin.req({
+            url: '/customer/dict/',
+            done: function (res) {
+                var data_source = res.data.source;
+                var source_node = $('#id_source');
+                for (var i in data_source) {
+                    var pid = data_source[i].id;
+                    var name = data_source[i].name;
+                    source_node.append("<option value='" + pid + "'>" + name + "</option>");
+                }
+
+                var data_project = res.data.project;
+                let tempData = [];
+                if(data_project && data_project.length > 0){
+                    tempData = data_project.map(item=>{
+                        if(id && editdata['project']){
+                           editdata['project'].forEach(item1=>{
+                               if(item.id === item1){
+                                   item.selected = 'selected'
+                               }
+                           })
+                        }
+                        return {value: item.id, name: item.name, selected: item.selected }
+                    });
+                }
+                formSelects.data('selectProject', 'local', {
+                    arr: tempData
+                });
+                form.val("component-form-element", editdata);
+            }
+        });
+
+        //form.render(null, 'component-form-element');
+
+        form.on('submit(component-form-element)', function (data) {
+            if (id) {
+                var url = '/customer/new_customer/' + id + '/';
+                var type = 'put';
+            }
+            var submitData = data.field;
+            var project = formSelects.value('selectProject', 'val');
+            submitData.project = JSON.stringify(project);
+            admin.req({
+                url: url
+                , data: submitData
+                , type: type
+                , done: function (res) {
+                    parent.layui.onSubmitChild(res);
+                }
+            });
+
+            return false;
+        });
+
+        parent.layui.submitChild = function () {
+            $("#id_save").click();
+        };
+    });
+</script>
+</body>
+</html>

+ 49 - 21
uis/views/customer/index.html

@@ -122,6 +122,13 @@
                                             <option value="">请选择项目</option>
                                             <option value="">请选择项目</option>
                                         </select>
                                         </select>
                                     </div>
                                     </div>
+                                    <div class="seach_items">
+                                        <select name="status">
+                                            <option value="">请选择状态</option>
+                                            <option value="1" selected>正常</option>
+                                            <option value="2">放弃</option>
+                                        </select>
+                                    </div>
                                 </form>
                                 </form>
                                 <div style="clear: both;"></div>
                                 <div style="clear: both;"></div>
                             </div>
                             </div>
@@ -137,19 +144,20 @@
 <script type="text/html" id="customer_datagrid-operate-bar">
 <script type="text/html" id="customer_datagrid-operate-bar">
     <div class="layui-btn-group">
     <div class="layui-btn-group">
         <a class="layui-btn layui-btn-xs" lay-event="customer_search"
         <a class="layui-btn layui-btn-xs" lay-event="customer_search"
-            >查看</a>
-    </div>
-    <div class="layui-btn-group">
+        >查看</a>
+
+        <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="edit"
+        >修改</a>
+
         <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="add_review"
         <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="add_review"
-            >跟踪报告</a>
-    </div>
-    <div class="layui-btn-group">
-          <a class="layui-btn layui-btn-xs layui-btn-warm" data-permission="customer.inner_review" lay-event="internal_trace"
-            >内部跟踪</a>
-    </div>
-    <div class="layui-btn-group">
-          <a class="layui-btn layui-btn-xs layui-btn-danger" data-permission="customer.again_dispatch" lay-event="again_dispatch"
-            >重新分配</a>
+        >跟踪报告</a>
+
+        <a class="layui-btn layui-btn-xs layui-btn-warm" data-permission="customer.inner_review"
+           lay-event="internal_trace"
+        >内部跟踪</a>
+        <a class="layui-btn layui-btn-xs layui-btn-danger" data-permission="customer.again_dispatch"
+           lay-event="again_dispatch"
+        >重新分配</a>
     </div>
     </div>
 </script>
 </script>
 
 
@@ -202,7 +210,7 @@
 
 
         table.render({
         table.render({
             elem: '#customer_datagrid'
             elem: '#customer_datagrid'
-            , url: '/customer/new_customer/'
+            , url: '/customer/new_customer/?status=1'
             , title: '潜客跟踪'
             , title: '潜客跟踪'
             , cols: [[
             , cols: [[
                 {field: 'name', title: '姓名', width: 110}
                 {field: 'name', title: '姓名', width: 110}
@@ -224,7 +232,7 @@
                 , {field: 'create_time_f', title: '建档时间', width: 150}
                 , {field: 'create_time_f', title: '建档时间', width: 150}
                 , {field: 'create_user_text', title: '建档人', width: 100}
                 , {field: 'create_user_text', title: '建档人', width: 100}
                 , {field: 'notes', title: '备注', width: 200}
                 , {field: 'notes', title: '备注', width: 200}
-                , {width: 300, align: 'center', fixed: 'right', toolbar: "#customer_datagrid-operate-bar"}
+                , {width: 290, align: 'center', fixed: 'right', toolbar: "#customer_datagrid-operate-bar"}
             ]]
             ]]
             , page: true
             , page: true
             , height: 'full-108'
             , height: 'full-108'
@@ -258,7 +266,7 @@
                             store_id = obj.data.id;
                             store_id = obj.data.id;
                             field = obj.data.field;
                             field = obj.data.field;
                             table.reload('customer_log', {
                             table.reload('customer_log', {
-                                where: {type:field,id:store_id}
+                                where: {type: field, id: store_id}
                             });
                             });
                         }
                         }
                     });
                     });
@@ -295,8 +303,8 @@
         //监听工具条
         //监听工具条
         table.on('tool(customer-operate)', function (obj) {
         table.on('tool(customer-operate)', function (obj) {
             var data = obj.data;
             var data = obj.data;
+            table.editdata = data;
             if (obj.event === 'customer_search') {
             if (obj.event === 'customer_search') {
-                table.editdata = data;
                 layer.open({
                 layer.open({
                     skin: 'demo-class',
                     skin: 'demo-class',
                     type: 2,
                     type: 2,
@@ -334,7 +342,28 @@
                     },
                     },
                     content: 'detail.html?customer=' + data.id
                     content: 'detail.html?customer=' + data.id
                 });
                 });
-            } else if (obj.event === 'add_review') {
+            } else if (obj.event === 'edit') {
+                layer.open({
+                    type: 2,
+                    title: '修改',
+                    shadeClose: false,
+                    area: ['45%', '80%'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        layui.onSubmitChild = function (res) {
+                            layer.close(index);
+                            table.reload('customer_datagrid', {});
+                        };
+                        layui.submitChild();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: 'edit.html?id=' + data.id
+                });
+            }
+
+            else if (obj.event === 'add_review') {
                 //添加跟踪报告
                 //添加跟踪报告
                 createFollowReport(data.id, data.stage_progress_sort)
                 createFollowReport(data.id, data.stage_progress_sort)
             } else if (obj.event === 'internal_trace') {
             } else if (obj.event === 'internal_trace') {
@@ -357,13 +386,12 @@
                     },
                     },
                     content: 'internal_trace.html?customer_id=' + data.id + '&stage_progress_sort=' + data.stage_progress_sort
                     content: 'internal_trace.html?customer_id=' + data.id + '&stage_progress_sort=' + data.stage_progress_sort
                 });
                 });
-            }else if(obj.event === 'again_dispatch'){
-                table.editdata = data;
+            } else if (obj.event === 'again_dispatch') {
                 layer.open({
                 layer.open({
                     type: 2,
                     type: 2,
                     title: '重新分配',
                     title: '重新分配',
                     area: ['40%', '40%'],
                     area: ['40%', '40%'],
-                    btn: ['保存','取消'],
+                    btn: ['保存', '取消'],
                     yes: function (index, dom) {
                     yes: function (index, dom) {
                         layui.onSubmitChild = function (res) {
                         layui.onSubmitChild = function (res) {
                             if (res.code === 0) {
                             if (res.code === 0) {
@@ -386,7 +414,7 @@
         table.on('tool(customer-operate-log)', function (obj) {
         table.on('tool(customer-operate-log)', function (obj) {
             var data = obj.data;
             var data = obj.data;
             let tool_event = obj.event;
             let tool_event = obj.event;
-            let params = {count_param:tool_event};
+            let params = {count_param: tool_event};
             params['stage_progress'] = data.stage_id;
             params['stage_progress'] = data.stage_id;
             if (field && store_id) {
             if (field && store_id) {
                 params['param'] = field + '_' + store_id;
                 params['param'] = field + '_' + store_id;