Explorar o código

Merge branch 'master' of http://git.zzliaoyuan.com:4000/wushaodong/decorate

lijiangwei %!s(int64=4) %!d(string=hai) anos
pai
achega
adf5d7d4b8

+ 2 - 0
apps/account/consts.py

@@ -8,6 +8,7 @@ CONTENT_TYPE_SORTING = (
     'account-managestoreuser',  # 权限管理
     'option-option',  # 自定义项
     'customer-reportcustomer', # 报备客户
+    'customer-newcustomer', # 潜客跟踪
 
 )
 
@@ -24,6 +25,7 @@ MENU_TO_MODEL = (
     (
         u'潜客作业', (
              'customer-reportcustomer',
+             'customer-newcustomer',
         )
     ),
     (

+ 10 - 1
apps/customer/filters.py

@@ -18,4 +18,13 @@ class NewCustomerFilter(django_filters.FilterSet):
 
     class Meta:
         model = NewCustomer
-        fields = '__all__'
+        fields = '__all__'
+
+
+class ReviewFilter(django_filters.FilterSet):
+    name = django_filters.CharFilter(field_name='customer__name', lookup_expr='icontains')
+    tel = django_filters.CharFilter(field_name='customer__tel', lookup_expr='icontains')
+
+    class Meta:
+        model = NewCustomer
+        fields = '__all__'

+ 17 - 9
apps/customer/models.py

@@ -50,6 +50,12 @@ class ReportCustomer(models.Model):
 
 
 class NewCustomer(models.Model):
+    NORMAL = 1
+    ABANDONED = 2
+    STATUS_CHOICES = (
+        (NORMAL, u'正常'),
+        (ABANDONED, u'放弃'),
+    )
 
     report_customer = models.ForeignKey(ReportCustomer, verbose_name=u'报备客户信息', related_name='customer_source',
                                         on_delete=models.PROTECT)
@@ -60,20 +66,20 @@ class NewCustomer(models.Model):
     track_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'跟踪人', related_name='track_user',
                                    editable=False, on_delete=models.PROTECT)
     end_time = models.DateTimeField(verbose_name=u'最后跟踪时间', null=True)
-    next_time = models.DateTimeField(verbose_name=u'下次跟踪时间', null=True)
+    next_time = models.DateField(verbose_name=u'下次跟踪时间', null=True)
     create_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'建档人', related_name='newcustomer_create_user',
                                     editable=False, on_delete=models.PROTECT)
     create_time = models.DateTimeField(verbose_name=u'建档时间', auto_now_add=True, editable=False)
+    status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"状态", default=NORMAL)
 
     class Meta:
         db_table = 'new_customer'
-        verbose_name = u'客跟踪信息'
+        verbose_name = u'客跟踪'
         ordering = ['-id']
         default_permissions = ()
         permissions = [
             ('view_new_customer', u'查看'),
-            ('update_new_customer', u'跟踪'),
-            ('delete_new_customer', u'删除'),
+            ('add_review', u'跟踪'),
         ]
 
 class Review(models.Model):
@@ -86,14 +92,14 @@ class Review(models.Model):
         (ABANDON, u'放弃'),
     )
 
-    customer = models.ForeignKey(NewCustomer, related_name='review_ref_customer', verbose_name=u"客户", blank=True,
-                                 null=True, on_delete=models.PROTECT)
+    customer = models.ForeignKey(NewCustomer, related_name='review_ref_customer', verbose_name=u"客户",
+                                  on_delete=models.PROTECT)
     description = models.CharField(max_length=5000, verbose_name=u"回访情况")
-    action = models.CharField(max_length=100, verbose_name=u"操作")
     instruction = models.CharField(max_length=200, verbose_name=u"申请支援或放弃", blank=True, null=True)
     is_giveup = models.BooleanField(verbose_name=u"请求放弃", default=False)
-    store = models.ForeignKey(Store, verbose_name=u'门店', editable=False, on_delete=models.PROTECT)
-    create_user = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False, related_name='review_ref_user', verbose_name=u"创建人",
+    is_entry = models.BooleanField(verbose_name=u"是否进店", default=False)
+    store = models.ForeignKey(Store, verbose_name=u'门店', on_delete=models.PROTECT)
+    create_user = models.ForeignKey(settings.AUTH_USER_MODEL,related_name='review_ref_user', verbose_name=u"创建人",
                                     on_delete=models.PROTECT)
     create_time = models.DateTimeField(verbose_name=u"添加时间", default=timezone.now, editable=False)
     check_status = models.PositiveSmallIntegerField(choices=CHECK_STATUS_CHOICES, verbose_name=u"审核状态", default=DEFAULT)
@@ -101,6 +107,8 @@ class Review(models.Model):
     check_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='review_ref_checkuser', verbose_name=u"审核人",
                                    editable=False, blank=True, null=True, on_delete=models.PROTECT)
     check_time = models.DateTimeField(verbose_name=u"审核时间", editable=False, blank=True, null=True)
+    next_time = models.DateTimeField(verbose_name=u"下次回访时间", editable=False, blank=True, null=True)
+
 
     class Meta:
         db_table = "customer_review"

+ 55 - 15
apps/customer/serializers.py

@@ -2,9 +2,10 @@
 import json
 from rest_framework import serializers
 from apps.option.models import Option
+from django.conf import settings
 from utils.exceptions import CustomError
-from utils.booleancharfield import BooleanCharField
-from apps.option.serializers import OptionSerializer
+from utils.booleancharfield import BooleanCharField, TimeCharField, DateCharField
+from utils.format import strftime,strfdate
 from .models import ReportCustomer,NewCustomer,Review
 
 class ReportCustomerSerializer(serializers.ModelSerializer):
@@ -59,23 +60,51 @@ class NewCustomerSerializer(serializers.ModelSerializer):
     create_user_text = serializers.CharField(source='create_user.name', read_only=True)
     potential_level_text = serializers.CharField(source='potential_level.name', read_only=True)
     stage_progress_text = serializers.CharField(source='stage_progress.name', read_only=True)
-    create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
-    end_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
-    next_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
+    stage_progress_sort = serializers.CharField(source='stage_progress.sort', read_only=True)
+    status_text = serializers.CharField(source='get_status_display', read_only=True)
+    create_time_f = TimeCharField(source='create_time', read_only=True)
+    end_time_f = TimeCharField(source='end_time', read_only=True)
+    next_time_f = DateCharField(source='next_time', read_only=True)
 
     name = serializers.CharField(source='report_customer.name', read_only=True)
     tel = serializers.CharField(source='report_customer.tel', read_only=True)
     village = serializers.CharField(source='report_customer.village', read_only=True)
     address = serializers.CharField(source='report_customer.address', read_only=True)
     source_text = serializers.CharField(source='report_customer.source.name', read_only=True)
-    project_text = serializers.CharField(source='report_customer.projects.name', read_only=True)
+    gender_text = serializers.SerializerMethodField()
+    project_text = serializers.SerializerMethodField()
+    last_review = serializers.SerializerMethodField()
+    enter_count = serializers.SerializerMethodField()
+    last_enter_time = serializers.SerializerMethodField()
+
+    def get_last_enter_time(self, obj):
+        review = Review.objects.filter(customer=obj, is_entry=True).order_by('-create_time').first()
+        if review:
+            return strftime(review.create_time)
+        else:
+            return ''
+
+    def get_enter_count(self, obj):
+        review = Review.objects.filter(customer=obj, is_entry=True)
+        return review.count()
+
+    def get_last_review(self, obj):
+        review = Review.objects.filter(customer=obj).order_by('-create_time').first()
+        if review:
+            return review.description
+        else:
+            return ''
+
+    def get_project_text(self, obj):
+        project = obj.report_customer.project.all()
+        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:
         model = NewCustomer
-        fields = (
-            'id', 'name', 'tel', 'village', 'address', 'source_text', 'project_text', 'potential_level_text',
-            'stage_progress_text', 'end_time', 'next_time','create_time', 'create_user_text', 'track_user_text',
-        )
+        fields =  '__all__'
 
     def create(self, validated_data):
         validated_data['create_user'] = self.context['request'].user
@@ -90,14 +119,25 @@ class NewCustomerSerializer(serializers.ModelSerializer):
 
 
 class ReviewSerializer(serializers.ModelSerializer):
-
     create_user_text = serializers.CharField(source='create_user.name', read_only=True)
     check_user_text = serializers.CharField(source='check_user.name', read_only=True)
     check_status_text = serializers.CharField(source='get_check_status_display', read_only=True)
-    create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
-    check_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M', read_only=True)
-    is_giveup_text = BooleanCharField(source='enable', read_only=True)
+    create_time_f = TimeCharField(source='create_time', read_only=True)
+    check_time_f = TimeCharField(source='check_time', read_only=True)
+    next_time_f = TimeCharField(source='next_time', read_only=True)
+    is_giveup_text = BooleanCharField(source='is_giveup', read_only=True)
+
+    name = serializers.CharField(source='customer.name', read_only=True)
+    tel = serializers.CharField(source='customer.tel', read_only=True)
+    village = serializers.CharField(source='customer.village', read_only=True)
+    address = serializers.CharField(source='customer.address', read_only=True)
+    track_user_text = serializers.CharField(source='customer.track_user.name', read_only=True)
+    project_text = serializers.SerializerMethodField()
+
+    def get_project_text(self, obj):
+        project = obj.customer.report_customer.project.all()
+        return ','.join(project.values_list('name', flat=True))
 
     class Meta:
         model = Review
-        fields = '__all__'
+        fields = '__all__'

+ 1 - 0
apps/customer/urls.py

@@ -14,4 +14,5 @@ urlpatterns = [
 router = SimpleRouter()
 router.register(r'report_customer', ReportCustomerViewSet)
 router.register(r'new_customer', NewCustomerViewSet)
+router.register(r'review', ReviewViewSet)
 urlpatterns += router.urls

+ 101 - 7
apps/customer/views.py

@@ -1,7 +1,9 @@
 # coding=utf-8
 from rest_framework.views import APIView
 from django.db.models import Q
+import traceback
 import datetime
+from rest_framework.serializers import ValidationError
 from django.utils import timezone
 from rest_framework.decorators import action
 from utils.permission import isLogin, permission_required, check_permission
@@ -11,9 +13,9 @@ from utils.exceptions import CustomError
 from apps.log.models import BizLog
 from apps.option.models import Option
 from apps.option.serializers import OptionComboboxSerializer
-from .models import ReportCustomer,NewCustomer
-from .serializers import ReportCustomerSerializer,NewCustomerSerializer
-from .filters import ReportCustomerFilter,NewCustomerFilter
+from .models import ReportCustomer,NewCustomer,Review
+from .serializers import ReportCustomerSerializer,NewCustomerSerializer, ReviewSerializer
+from .filters import ReportCustomerFilter,NewCustomerFilter,ReviewFilter
 from django.contrib.auth import get_user_model
 User = get_user_model()
 
@@ -68,8 +70,8 @@ class ReportCustomerViewSet(CustomModelViewSet):
             BizLog.objects.addnew(request.user, BizLog.INSERT,
                                   u'分配客户报备[%s],id=%d' % (instance.name,  instance.id))
             # 创建潜客跟踪表
-            potential_level = Option.objects.filter(type=Option.POTENTIAL_LEVEL).order_by('sort').first()
-            stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS).order_by('sort').first()
+            potential_level = Option.objects.filter(type=Option.POTENTIAL_LEVEL, enable=True).order_by('sort').first()
+            stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').first()
             if not potential_level.track_day:
                 raise CustomError('当前潜客级别,没有可用跟踪天数!')
             next_time = (timezone.now() + datetime.timedelta(days=potential_level.track_day)).strftime('%Y-%m-%d')
@@ -90,11 +92,15 @@ class ReportCustomerDictView(APIView):
     def get(self, request):
         source = Option.objects.filter(type=Option.CUSTOMER_SOURCE, enable=True)
         project = Option.objects.filter(type=Option.CATEGORY, enable=True)
+        level = Option.objects.filter(type=Option.POTENTIAL_LEVEL, enable=True)
         serializer_source = OptionComboboxSerializer(source, many=True)
         serializer_project = OptionComboboxSerializer(project, many=True)
+        serializer_level = OptionComboboxSerializer(level, many=True)
+
         return response_ok({
             'source': serializer_source.data,
             'project': serializer_project.data,
+            'level': serializer_level.data,
         })
 
 class UserDictView(APIView):
@@ -119,6 +125,55 @@ class NewCustomerViewSet(CustomModelViewSet):
         f = NewCustomerFilter(self.request.GET, queryset=queryset)
         return f.qs
 
+    def paginate_queryset(self, queryset):
+        if self.paginator is None or self.request.GET.get('export'):
+            return None
+        return self.paginator.paginate_queryset(queryset, self.request, view=self)
+
+    @action(methods=['post'], detail=True)
+    def add_review(self, request, pk):
+        check_permission(request, 'customer.add_review')
+        description = request.POST.get('description')
+        instruction = request.POST.get('instruction')
+        is_entry = request.POST.get('is_entry') == '1'
+        is_giveup = request.POST.get('is_giveup') == '1'
+        potential_level = request.POST.get('potential_level')
+        next_time = request.POST.get('next_time')
+        try:
+            instance = NewCustomer.objects.filter(id=pk).first()
+            if not instance:
+                raise CustomError('当前客户信息有误,请刷新重试!')
+            data = {
+                'customer':instance.id,
+                'store':request.user.store.id,
+                'create_user':request.user.id,
+                'description':description,
+                'instruction':instruction,
+                'is_entry':is_entry,
+                'is_giveup':is_giveup,
+            }
+            serializer = ReviewSerializer(data=data)
+            if serializer.is_valid(raise_exception=True):
+                serializer.save()
+
+            data = {
+                'potential_level':potential_level,
+                'next_time':next_time,
+                'end_time':timezone.now(),
+                'stage_progress':instance.stage_progress.id,
+            }
+            ser = self.serializer_class(instance, data=data, partial=True)
+            if ser.is_valid(raise_exception=True):
+                ser.save()
+
+        except ValidationError as e:
+            traceback.print_exc()
+            return response_error('数据格式有误')
+        except CustomError as e:
+            return response_error(e.get_error_msg())
+        except Exception as e:
+            return response_error(str(e))
+        return response_ok()
 
 class StageCountView(APIView):
     permission_classes = [isLogin]
@@ -133,10 +188,49 @@ class StageCountView(APIView):
                                                        Q(track_user__store_id__in=request.user.get_manager_range()),
                                                        stage_progress=stage)
             stage_count = {
+                'stage_id': stage.id,    # 阶段名称
                 'stage': stage.name,    # 阶段名称
-                'total': new_customers.count(),   # 总人数
+                'total_count': new_customers.count(),   # 总人数
                 'today_count': new_customers.filter(next_time=time_now).count(),  # 今日人数
                 'overdue_count': new_customers.filter(next_time__lt=time_now).count()  # 逾期人数
             }
             data.append(stage_count)
-        return response_ok(data)
+        return response_ok(data)
+
+class ReviewViewSet(CustomModelViewSet):
+    permission_classes = []
+    queryset = Review.objects.filter()
+    serializer_class = ReviewSerializer
+
+    def filter_queryset(self, queryset):
+        queryset = queryset.filter()
+        f = ReviewFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+    @action(methods=['post'], detail=True)
+    def track_review(self, request, pk):
+        # 跟踪审核
+        check_status = request.POST.get('check_status')
+        check_comment = request.POST.get('check_comment')
+        next_time = request.POST.get('next_time')
+        try:
+            instance = Review.objects.filter(id=pk).first()
+            instance.check_user = request.user
+            instance.check_status = check_status
+            instance.check_comment = check_comment
+            instance.next_time = next_time
+            instance.check_time = timezone.now()
+            instance.save()
+        except CustomError as e:
+            return response_error(e.get_error_msg())
+        except Exception as e:
+            return response_error(str(e))
+        return response_ok()
+
+
+
+
+
+
+
+

+ 1 - 1
apps/option/models.py

@@ -21,7 +21,7 @@ class Option(models.Model):
     enable = models.BooleanField(verbose_name=u"在用", default=True)
     create_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"创建人", on_delete=models.PROTECT,
                                     editable=False)
-    track_day = models.IntegerField(verbose_name=u"跟踪天数", null=True)
+    track_day = models.IntegerField(verbose_name=u"跟踪天数", null=True,default=0)
     end_stage = models.BooleanField(verbose_name=u"是否最终阶段", default=False)
 
     class Meta:

+ 1 - 1
apps/option/serializers.py

@@ -43,4 +43,4 @@ class OptionComboboxSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = Option
-        fields = ('id','name')
+        fields = ('id','name','track_day')

+ 39 - 35
uis/views/customer/add_report.html

@@ -9,7 +9,6 @@
           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;
@@ -34,37 +33,44 @@
                         <div>
                             <label class="layui-form-label"><font color='red' size="4">*</font>回访情况:</label>
                             <div class="layui-input-block">
-                                <textarea type="text" name="follow_status" lay-verify="required" class="layui-textarea" placeholder="请填写回访情况"/></textarea>
+                                <textarea type="text" name="description" lay-verify="required" class="layui-textarea"
+                                          placeholder="请填写回访情况"/></textarea>
                             </div>
                         </div>
                         <div>
                             <label class="layui-form-label">申请支援:</label>
                             <div class="layui-input-block">
-                                <textarea type="text" name="apply_help" class="layui-textarea" placeholder="如需支援请填写申请内容"/></textarea>
+                                <textarea type="text" name="instruction" class="layui-textarea"
+                                          placeholder="如需支援请填写申请内容"/></textarea>
                             </div>
                         </div>
                         <div>
                             <label class="layui-form-label">是否进店:</label>
                             <div class="layui-input-block">
-                                <input type="radio" name="isEnter" value="1" title="是">
-                                <input type="radio" name="isEnter" value="2" title="否">
+                                <input type="radio" name="is_entry" value="1" title="是">
+                                <input type="radio" name="is_entry" value="0" title="否" checked>
                             </div>
                         </div>
                         <div>
-                            <label class="layui-form-label">修改级别:</label>
+                            <label class="layui-form-label">申请放弃:</label>
                             <div class="layui-input-block">
-                                <select name="visit_status" id="id_rank">
-                                    <option value="">请选择回访后的客户级别</option>
-                                    <option value="1">有意</option>
-                                    <option value="2">有需</option>
-                                    <option value="3">将成</option>
+                                <input type="radio" name="is_giveup" value="1" title="是">
+                                <input type="radio" name="is_giveup" value="0" title="否" checked>
+                            </div>
+                        </div>
+                        <div class="layui-hide" id="level_div">
+                            <label class="layui-form-label"><font color='red' size="4">*</font>客户级别:</label>
+                            <div class="layui-input-block">
+                                <select name="potential_level" id="id_potential_level">
+                                    <option value="">请选择客户级别</option>
                                 </select>
                             </div>
                         </div>
-                        <div>
+                        <div class="layui-hide" id="next_time_div">
                             <label class="layui-form-label"><font color='red' size="4">*</font>下次回访:</label>
                             <div class="layui-input-block">
-                                 <input type="text" name="next_visit" class="layui-input" id="test1" placeholder="修改下次回访日期">
+                                <input type="text" name="next_time" class="layui-input" id="test1"
+                                       placeholder="修改下次回访日期">
                             </div>
                         </div>
 
@@ -79,47 +85,45 @@
 </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', 'laydate'], function () {
+    }).use(['index', 'form', 'laydate'], function () {
         var $ = layui.$
             , admin = layui.admin
             , laydate = layui.laydate
-            , formSelects = layui.formSelects
             , form = layui.form;
         laydate.render({
             elem: '#test1'
         });
-
+        var customer_id = layui.view.getParameterByName('customer_id');
+        var stage_progress_sort = layui.view.getParameterByName('stage_progress_sort');
+        if(stage_progress_sort && parseFloat(stage_progress_sort) === 1){
+            $('#level_div').removeClass('layui-hide')
+            $('#next_time_div').removeClass('layui-hide')
+        }
+        var level_data = {}
         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>");
-                // }
-                form.val("component-form-element", {});
+                var data = res.data.level;
+                var level_node = $('#id_potential_level');
+                for (var i in data) {
+                    var pid = data[i].id;
+                    var name = data[i].name;
+                    level_data[pid] = data[i].track_day
+                    level_node.append("<option value='" + pid + "'>" + name + "</option>");
+                }
+                form.render('select');
             }
         });
 
-        //form.render(null, 'component-form-element');
-
         form.on('submit(component-form-element)', function (data) {
-            var url = '/customer/report_customer/';
-            var type = 'post';
-            var submitData = data.field;
             admin.req({
-                url: url
-                , data: submitData
-                , type: type
+                url: '/customer/new_customer/'+customer_id+'/add_review/'
+                , data: data.field
+                , type: 'post'
                 , done: function (res) {
                     parent.layui.onSubmitChild(res);
                 }

+ 1 - 1
uis/views/customer/detail.html

@@ -58,7 +58,7 @@
             </tr>
             <tr>
               <td style="background: #f8f8f8; width: 70px">备注:</td>
-              <td colspan="3">{{ d.notes }}</td>
+              <td colspan="3">{{ d.notes || ""}}</td>
             </tr>
           </tbody>
         </table>

+ 87 - 93
uis/views/customer/index.html

@@ -47,17 +47,19 @@
             color: #000;
         }
 
-        .tableContent{
+        .tableContent {
             width: 100%;
             display: flex;
             justify-content: space-between;
             flex-direction: row;
         }
-        .demo-class .layui-layer-btn0{
+
+        .demo-class .layui-layer-btn0 {
             background-color: #009688 !important;
             color: #fff;
         }
-        .demo-class .layui-layer-btn1{
+
+        .demo-class .layui-layer-btn1 {
             background-color: red;
             color: #fff;
         }
@@ -73,20 +75,11 @@
                 <div class="layui-col-md12">
                     <div class="LAY-btns" style="margin-bottom: 10px;">
                         <div style="float: left">
-                            <button class="layui-btn" id="customer_add"><i
-                                    class="layui-icon layui-icon-add-circle"></i>跟踪报告
-                            </button>
                             <button class="layui-btn" id="customer_order"><i
                                     class="layui-icon layui-icon-add-circle"></i>预约量房
                             </button>
-                            <button class="layui-nav">
-                                <div class="layui-nav-item">
-                                    <a href="javascript:;" style="color:#fff;">导出</a>
-                                    <dl class="layui-nav-child">
-                                        <dd><a href="#" id="btn_list">列表</a></dd>
-                                        <dd><a href="#" id="btn_detail">明细</a></dd>
-                                    </dl>
-                                </div>
+                            <button class="layui-btn" id="btn_list"><i
+                                    class="layui-icon layui-icon-download-circle"></i>导出
                             </button>
                         </div>
                         <form class="layui-form" lay-filter="query-form-element">
@@ -108,10 +101,10 @@
                     </div>
 
                     <div class="tableContent">
-                        <div style="width: 405px">
+                        <div style="width: 375px">
                             <table class="layui-hide" id="customer_log" lay-filter="customer-operate-log"></table>
                         </div>
-                        <div style="width: calc(100% - 450px)">
+                        <div style="width: calc(100% - 390px)">
                             <table class="layui-hide" id="customer_datagrid" lay-filter="customer-operate"></table>
                         </div>
                     </div>
@@ -120,6 +113,9 @@
                         <div class="layui-btn-group">
                             <a class="layui-btn layui-btn-xs" lay-event="customer_search"
                             >查看</a>
+                            <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="add_review"
+                               data-permission="customer.view_new_customer"
+                            >跟踪报告</a>
                         </div>
                     </script>
                 </div>
@@ -144,40 +140,44 @@
             , url: '/customer/stage_count/'
             , cols: [[
                 {field: 'stage', title: '阶段', width: 100}
-                , {field: 'total', title: "总人数", width: 100, sort: true}
-                , {field: 'today_count', title: '今日', width: 100, sort: true}
-                , {field: 'overdue_count', title: '逾期', width: 100, sort: true}
+                , {field: 'total_count', title: "总人数", width: 90, sort: true}
+                , {field: 'today_count', title: '今日', width: 90, sort: true}
+                , {field: 'overdue_count', title: '逾期', width: 90, sort: true}
             ]]
         });
 
         table.render({
             elem: '#customer_datagrid'
-            , url: '/api/dataTable.json'
+            , url: '/customer/new_customer/'
+            , title: '潜客跟踪'
             , cols: [[
                 {field: 'name', title: '姓名', width: 110}
                 , {field: 'gender_text', title: "性别", width: 70}
-                , {field: 'tel', title: '电话', width: 120}
+                , {field: 'tel', title: '电话', width: 130}
                 , {field: 'village', title: '小区', width: 150}
                 , {field: 'address', title: '地址', width: 200}
                 , {field: 'source_text', title: '来源', width: 100}
+                , {field: 'project_text', title: '项目', width: 100}
+                , {field: 'stage_progress_text', title: '阶段进度', width: 100}
+                , {field: 'potential_level_text', title: '客户级别', width: 100}
                 , {field: 'notes', title: '备注', width: 200}
-                , {field: 'follow_user', title: '跟踪人', width: 100}
-                , {field: 'last_follow', title: '最后跟踪', width: 150}
-                , {field: 'follow_status', title: '跟踪情况', width: 200}
+                , {field: 'status_text', title: '状态', width: 80}
+                , {field: 'track_user_text', title: '跟踪人', width: 100}
+                , {field: 'end_time_f', title: '最后跟踪时间', width: 120}
+                , {field: 'last_review', title: '最后跟踪情况', width: 200}
+                , {field: 'next_time_f', title: '下次跟踪时间', width: 120}
                 , {field: 'follow_count', title: '跟踪次数', width: 100}
                 , {field: 'enter_count', title: '进店次数', width: 100}
-                , {field: 'last_enter', title: '最后进店时间', width: 150}
-                , {field: 'rank', title: '级别', width: 100}
-                , {field: 'status', title: '状态', width: 100}
-                , {field: 'create_time', title: '建档时间', width: 150}
-                , {field: 'create_user', title: '建档人', width: 150}
-                , {width: 80, align: 'center', fixed: 'right', toolbar: '#customer-operate-bar'}
+                , {field: 'last_enter_time', title: '最后进店时间', width: 150}
+                , {field: 'create_time_f', title: '建档时间', width: 150}
+                , {field: 'create_user_text', title: '建档人', width: 100}
+                , {width: 130, align: 'center', fixed: 'right', toolbar: '#customer-operate-bar'}
             ]]
             , page: true
             , height: 'full-108'
         });
 
-        function createFollowReport(){
+        function createFollowReport(customer_id, stage_progress_sort) {
             layer.open({
                 type: 2,
                 title: '添加跟踪报告',
@@ -185,9 +185,9 @@
                 btn: ['保存', '取消'],
                 yes: function (index, dom) {
                     layui.onSubmitChild = function (res) {
-                        if(res.code === 0){
+                        if (res.code === 0) {
                             layer.msg('添加成功!', {icon: 1})
-                         }
+                        }
                         layer.close(index);
                         table.reload('customer_datagrid', {});
                     };
@@ -196,70 +196,54 @@
                 btn2: function (index, layero) {
                     layer.close(index);//关闭当前按钮
                 },
-                content: 'add_report.html'
+                content: 'add_report.html?customer_id=' + customer_id + '&stage_progress_sort=' + stage_progress_sort
             });
         };
-        //导出列表
-        var _params1 = {};
-        $('#btn_list').on('click', function () {
-            $.get({
-                url: '/order/?export=true',
-                dataType: 'json',
-                data: _params1,
-                success: function (res) {
-                    if (res.code === 1) {
-                        layer.msg(res.msg);
-                        return;
-                    }
-                    table.exportFile('datagrid', res,)
-                }
-            })
-        });
-        //导出明细
-        var _params2 = {};
-        $('#btn_detail').on('click', function () {
-            $.get({
-                url: '/order/?export=true',
-                dataType: 'json',
-                data: _params2,
-                success: function (res) {
-                    if (res.code === 1) {
-                        layer.msg(res.msg);
-                        return;
-                    }
-                    table.exportFile('datagrid', res,)
-                }
-            })
-        });
         //监听工具条
         table.on('tool(customer-operate)', function (obj) {
             var data = obj.data;
             if (obj.event === 'customer_search') {
-               table.editdata = data;
-               layer.open({
-                skin: 'demo-class',
-                type: 2,
-                title: '查看客户详情',
-                area: ['45%', '90%'],
-                btn: ['跟踪报告', '更新进度', '取消'],
-                yes: function (index, dom) {
-                    //添加跟踪报告
-                    createFollowReport()
-                },
-                btn2: function (index, layero) {
-                    //更新进度
-                    layer.close(index);//关闭当前按钮
-                },
-                btn3: function (index, layero) {
-                    //取消
-                    layer.close(index);//关闭当前按钮
-                },
-                content: 'detail.html'
-            });
+                table.editdata = data;
+                layer.open({
+                    skin: 'demo-class',
+                    type: 2,
+                    title: '查看客户详情',
+                    area: ['45%', '90%'],
+                    btn: ['跟踪报告', '更新进度', '取消'],
+                    yes: function (index, dom) {
+                        //添加跟踪报告
+                        createFollowReport(data.id, data.stage_progress_sort)
+                    },
+                    btn2: function (index, layero) {
+                        //更新进度
+                        layer.close(index);//关闭当前按钮
+                    },
+                    btn3: function (index, layero) {
+                        //取消
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: 'detail.html'
+                });
+            } else if (obj.event === 'add_review') {
+                //添加跟踪报告
+                createFollowReport(data.id, data.stage_progress_sort)
             }
         });
 
+        table.on('row(customer-operate-log)', function (obj) {
+            var data = obj.data;
+            table.reload('customer_datagrid', {
+                where: {stage_progress: data.stage_id}
+                , page: {curr: 1}
+            });
+
+            //标注选中样式
+            obj.tr.addClass('layui-table-click').siblings().removeClass('layui-table-click');
+        });
+
+        var _params = {};
         form.on('submit(query-form-element)', function (data) {
+            _params = data.field;
             table.reload('customer_datagrid', {
                 where: data.field
                 , page: {curr: 1}
@@ -267,10 +251,20 @@
             layer.closeAll();
             return false
         });
-
-        //添加跟踪报告
-        $('#customer_add').on('click', function () {
-            createFollowReport()
+        //导出列表
+        $('#btn_list').on('click', function () {
+            $.get({
+                url: '/customer/new_customer/?export=true',
+                dataType: 'json',
+                data: _params,
+                success: function (res) {
+                    if (res.code === 1) {
+                        layer.msg(res.msg);
+                        return;
+                    }
+                    table.exportFile('customer_datagrid', res,)
+                }
+            })
         });
 
         $('#customer_order').on('click', function () {
@@ -281,9 +275,9 @@
                 btn: ['保存', '取消'],
                 yes: function (index, dom) {
                     layui.onSubmitChild = function (res) {
-                        if(res.code === 0){
+                        if (res.code === 0) {
                             layer.msg('添加成功!', {icon: 1})
-                         }
+                        }
                         layer.close(index);
                         table.reload('customer_datagrid', {});
                     };

+ 161 - 154
uis/views/foundation/option.html

@@ -1,188 +1,195 @@
 <!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">
+    <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">
 </head>
 <body>
 
-  <div class="layui-fluid">
+<div class="layui-fluid">
     <div class="layui-card">
         <div class="layui-card-body" pad15>
-        <div class="layui-row layui-col-space15">
-          <div class="layui-col-md12">
+            <div class="layui-row layui-col-space15">
+                <div class="layui-col-md12">
 
-            <div class="LAY-btns" style="margin-bottom: 10px;">
-              <button class="layui-btn layui-btn-sm" id="btn_add"><i class="layui-icon layui-icon-add-circle"></i>添加</button>
-              <button class="layui-btn layui-btn-sm" id="btn_query"><i class="layui-icon layui-icon-search"></i>查询</button>
-            </div>
+                    <div class="LAY-btns" style="margin-bottom: 10px;">
+                        <button class="layui-btn layui-btn-sm" id="btn_add"><i
+                                class="layui-icon layui-icon-add-circle"></i>添加
+                        </button>
+                        <button class="layui-btn layui-btn-sm" id="btn_query"><i
+                                class="layui-icon layui-icon-search"></i>查询
+                        </button>
+                    </div>
 
-            <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>
+                    <table class="layui-hide" id="datagrid" lay-filter="datagrid-operate"></table>
 
-            <script type="text/html" id="datagrid-operate-bar">
-                <div class="layui-btn-group">
-              <a class="layui-btn layui-btn-xs" lay-event="edit">修改</a>
-              <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
+                    <script type="text/html" id="datagrid-operate-bar">
+                        <div class="layui-btn-group">
+                            <a class="layui-btn layui-btn-xs" lay-event="edit">修改</a>
+                            <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
+                        </div>
+                    </script>
                 </div>
-            </script>
-          </div>
-        </div>
+            </div>
         </div>
     </div>
-  </div>
-  <div id="dlg_query" style="display: none">
+</div>
+<div id="dlg_query" style="display: none">
     <div class="layui-card-body" pad15>
         <form class="layui-form" lay-filter="query-form-element">
-          <div class="layui-row layui-col-space10 layui-form-item">
-              <div class="layui-col-xs12 layui-col-sm12">
-                <label class="layui-form-label">名称:</label>
-                <div class="layui-input-block">
-                   <input type="text" class="layui-input" name="name">
+            <div class="layui-row layui-col-space10 layui-form-item">
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">名称:</label>
+                    <div class="layui-input-block">
+                        <input type="text" class="layui-input" name="name">
+                    </div>
                 </div>
-              </div>
-              <div class="layui-col-xs12 layui-col-sm12">
-                <label class="layui-form-label">是否在用:</label>
-                <div class="layui-input-block">
-                    <select name="enabled">
-                        <option value=""></option>
-                        <option value="1">是</option>
-                        <option value="0">否</option>
-                    </select>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">是否在用:</label>
+                    <div class="layui-input-block">
+                        <select name="enabled">
+                            <option value=""></option>
+                            <option value="1"></option>
+                            <option value="0">否</option>
+                        </select>
+                    </div>
                 </div>
-              </div>
-              <div class="layui-col-xs12 layui-col-sm12">
-                <label class="layui-form-label">类别:</label>
-                <div class="layui-input-block">
-                    <select name="type">
-                        <option value=""></option>
-                        <option value="0">客户类型</option>
-                        <option value="1">收银方式</option>
-                        <option value="2">维修类型</option>
-                        <option value="3">会员类别</option>
-                        <option value="4">供应商</option>
-                        <option value="5">保险公司</option>
-                    </select>
+                <div class="layui-col-xs12 layui-col-sm12">
+                    <label class="layui-form-label">类别:</label>
+                    <div class="layui-input-block">
+                        <select name="type">
+                            <option value=""></option>
+                            <option value="0">客户类型</option>
+                            <option value="1">收银方式</option>
+                            <option value="2">维修类型</option>
+                            <option value="3">会员类别</option>
+                            <option value="4">供应商</option>
+                            <option value="5">保险公司</option>
+                        </select>
+                    </div>
                 </div>
-              </div>
-          </div>
-          <div class="layui-form-item" style="text-align:right">
-                <button class="layui-btn" lay-submit lay-filter="query-form-element" id="query_btn" style="display: none;">查询</button>
-          </div>
+            </div>
+            <div class="layui-form-item" style="text-align:right">
+                <button class="layui-btn" lay-submit lay-filter="query-form-element" id="query_btn"
+                        style="display: none;">查询
+                </button>
+            </div>
         </form>
     </div>
-  </div>
+</div>
 
-  <script src="../../layuiadmin/layui/layui.js?t=1"></script>
-  <script>
-  layui.config({
-    base: '../../../layuiadmin/' //静态资源所在路径
-  }).extend({
-    index: 'lib/index' //主入口模块
-  }).use(['index', 'table','form'], function(){
-    var $ = layui.$;
-    var table = layui.table
-        ,form = layui.form;
+<script src="../../layuiadmin/layui/layui.js?t=1"></script>
+<script>
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index' //主入口模块
+    }).use(['index', 'table', 'form'], function () {
+        var $ = layui.$;
+        var table = layui.table
+            , form = layui.form;
 
-    table.render({
-      elem: '#datagrid'
-      ,url: '/foundation/option/data/'
-      ,cols: [[
-        {field:'name', title:'名称', width:200}
-        ,{field:'type_text', title:'类别', width:200}
-        ,{field:'notes', title:'备注', minWidth: 150}
-        ,{field:'enabled_text', title:'在用', width:80}
-        ,{width:110, align:'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
-      ]]
-      ,page: true
-      ,height: 'full-103'
-    });
+        table.render({
+            elem: '#datagrid'
+            , url: '/foundation/option/data/'
+            , cols: [[
+                {field: 'name', title: '名称', width: 200}
+                , {field: 'type_text', title: '类别', width: 200}
+                , {field: 'notes', title: '备注', minWidth: 150}
+                , {field: 'enabled_text', title: '在用', width: 80}
+                , {width: 110, align: 'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
+            ]]
+            , page: true
+            , height: 'full-103'
+        });
 
-    //监听工具条
-    table.on('tool(datagrid-operate)', function(obj){
-      var data = obj.data;
-      if(obj.event === 'detail'){
-        layer.msg('ID:'+ data.id + ' 的查看操作');
-      } else if(obj.event === 'del'){
-        layer.confirm('确定要删除吗?', function(index){
-          layer.close(index);
-          layui.admin.req({
-            url: '/foundation/option/delete/?id='+data.id
-            ,done: function(res){
-              table.reload('datagrid',{});
+        //监听工具条
+        table.on('tool(datagrid-operate)', function (obj) {
+            var data = obj.data;
+            if (obj.event === 'detail') {
+                layer.msg('ID:' + data.id + ' 的查看操作');
+            } else if (obj.event === 'del') {
+                layer.confirm('确定要删除吗?', function (index) {
+                    layer.close(index);
+                    layui.admin.req({
+                        url: '/foundation/option/delete/?id=' + data.id
+                        , done: function (res) {
+                            table.reload('datagrid', {});
 
-              //obj.del();
+                            //obj.del();
+                        }
+                    });
+                });
+            } else if (obj.event === 'edit') {
+                table.editdata = data;
+                layer.open({
+                    type: 2,
+                    title: '修改',
+                    shadeClose: false,
+                    area: ['450px', '470px'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        $(window.frames["layui-layer-iframe" + index].document).contents().find("#btn_save").click();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: 'option_edit.html?id=' + data.id
+                });
             }
-          });
         });
-      } else if(obj.event === 'edit'){
-        table.editdata = data;
-        layer.open({
-          type: 2,
-          title: '修改',
-          shadeClose: false,
-          area: ['450px', '470px'],
-          btn:['保存','取消'],
-          yes: function(index, dom){
-             $(window.frames["layui-layer-iframe"+index].document).contents().find("#btn_save").click();
-          },
-          btn2: function(index, layero){
-            layer.close(index);//关闭当前按钮
-          },
-          content: 'option_edit.html?id='+data.id
-        });
-      }
-    });
 
-    $('#btn_add').on('click', function(){
-        layer.open({
-          type: 2,
-          title: '添加',
-          shadeClose: false,
-          area: ['450px', '470px'],
-          btn:['保存','取消'],
-          yes: function(index, dom){
-             $(window.frames["layui-layer-iframe"+index].document).contents().find("#btn_save").click();
-          },
-          btn2: function(index, layero){
-            layer.close(index);//关闭当前按钮
-          },
-          content: 'option_edit.html'
+        $('#btn_add').on('click', function () {
+            layer.open({
+                type: 2,
+                title: '添加',
+                shadeClose: false,
+                area: ['450px', '470px'],
+                btn: ['保存', '取消'],
+                yes: function (index, dom) {
+                    $(window.frames["layui-layer-iframe" + index].document).contents().find("#btn_save").click();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: 'option_edit.html'
+            });
         });
-    });
-    $('#btn_query').on('click', function(){
-        layer.open({
-          type: 1,
-          shadeClose: false,
-          area: ['500px', '550px'],
-          title: '查询',
-          btn: ['查询', '取消'],
-          yes: function(index, dom){
-             $("#query_btn").click();
-          },
-          btn2: function(index, layero){
-            layer.close(index);//关闭当前按钮
-          },
-          content: $('#dlg_query')
+        $('#btn_query').on('click', function () {
+            layer.open({
+                type: 1,
+                shadeClose: false,
+                area: ['500px', '550px'],
+                title: '查询',
+                btn: ['查询', '取消'],
+                yes: function (index, dom) {
+                    $("#query_btn").click();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: $('#dlg_query')
+            });
+        });
+        form.on('submit(query-form-element)', function (data) {
+            //layer.msg(JSON.stringify(data.field));
+            _params = data.field;
+            table.reload('datagrid', {
+                where: data.field
+                , page: {curr: 1}
+            });
+            layer.closeAll();
+            return false
         });
-    });
-    form.on('submit(query-form-element)', function(data){
-      //layer.msg(JSON.stringify(data.field));
-      _params = data.field;
-      table.reload('datagrid', {
-          where: data.field
-          ,page:{curr:1}
-      });
-      layer.closeAll();
-      return false
-    });
 
-  });
-  </script>
+    });
+</script>
 </body>
 </html>
 

+ 1 - 1
uis/views/index.html

@@ -99,7 +99,7 @@
                             <dd data-name="nav" data-permission="customer.check_report_customer">
                                 <a lay-href="report_check/index.html">报备审核</a>
                             </dd>
-                            <dd data-name="nav" data-permission="customer.view_report_customer">
+                            <dd data-name="nav" data-permission="customer.view_new_customer">
                                 <a lay-href="customer/index.html">潜客跟踪</a>
                             </dd>
                             <dd data-name="nav" data-permission="customer.view_report_customer">