소스 검색

更新进度

wushaodong 4 년 전
부모
커밋
abdbc5fb41

+ 1 - 1
apps/customer/models.py

@@ -87,7 +87,7 @@ class NewCustomer(models.Model):
         default_permissions = ()
         permissions = [
             ('view_new_customer', u'查看'),
-            ('add_review', u'跟踪'),
+            ('add_review', u'跟踪报告'),
             ('check_review', u'跟踪审核'),
         ]
 

+ 4 - 4
apps/customer/urls.py

@@ -12,7 +12,7 @@ urlpatterns = [
 ]
 
 router = SimpleRouter()
-router.register(r'report_customer', ReportCustomerViewSet)
-router.register(r'new_customer', NewCustomerViewSet)
-router.register(r'review', ReviewViewSet)
-urlpatterns += router.urls
+router.register(r'report_customer', ReportCustomerViewSet) # 客户报备
+router.register(r'new_customer', NewCustomerViewSet) # 潜客跟踪
+router.register(r'review', ReviewViewSet) # 潜客审核
+urlpatterns += router.urls

+ 50 - 3
apps/customer/views.py

@@ -3,6 +3,7 @@ from rest_framework.views import APIView
 from django.db.models import Q
 import traceback
 import datetime
+from django.db import transaction
 from rest_framework.serializers import ValidationError
 from django.utils import timezone
 from rest_framework.decorators import action
@@ -18,7 +19,7 @@ from .serializers import ReportCustomerSerializer,NewCustomerSerializer, ReviewS
 from .filters import ReportCustomerFilter,NewCustomerFilter,ReviewFilter
 from django.contrib.auth import get_user_model
 User = get_user_model()
-
+from apps.order.serializers import Order, OrderSerializer
 
 class ReportCustomerViewSet(CustomModelViewSet):
     permission_classes = [isLogin]
@@ -201,11 +202,11 @@ class NewCustomerViewSet(CustomModelViewSet):
                 track_day = int(instance.stage_progress.track_day)
             except:
                 pass
-            # 预定客户,提交跟踪报告此字段为空
+            # 预定客户,sort排序大于1,提交跟踪报告此字段为空
             if sort > 1 or not next_time:
                 next_time = (timezone.now() + datetime.timedelta(days=track_day)).strftime('%Y-%m-%d')
             data = {
-                'potential_level':potential_level or None, #预定客户,无客户等级
+                'potential_level':potential_level or None, #预定客户,sort排序大于1,,无客户等级
                 'next_time':next_time,
                 'end_time':timezone.now(),
                 'stage_progress':instance.stage_progress.id,
@@ -223,6 +224,52 @@ class NewCustomerViewSet(CustomModelViewSet):
             return response_error(str(e))
         return response_ok()
 
+    @action(methods=['post'], detail=True)
+    def add_order(self, request, pk):
+        # 更新订单进度
+        check_permission(request, 'order.update_order_process')
+        stage_progress = request.POST.get('stage_progress')
+
+        try:
+            with transaction.atomic():
+                instance = NewCustomer.objects.filter(id=pk).first()
+                if not instance:
+                    raise CustomError('当前客户信息有误,请刷新重试!')
+                order = Order.objects.filter(customer=instance).first()
+                if order:
+                    if order.stage_progress.end_stage:
+                        raise CustomError('当前客户订单进度已到最后阶段,请勿重复更新!')
+                    if order.status == Order.WAIT_DISPATCH:
+                        raise CustomError('当前客户订单等待分配中,请勿重复更新!')
+                    data = {
+                        'status': Order.WAIT_DISPATCH,
+                        'stage_progress': stage_progress,
+                    }
+                    ser = OrderSerializer(order, data=data, partial=True)
+                    if ser.is_valid(raise_exception=True):
+                        ser.save()
+                else:
+                    data = {
+                        'status': Order.WAIT_DISPATCH,
+                        'stage_progress_id': stage_progress,
+                        'customer': instance,
+                        'service_user': instance.track_user,
+                    }
+                    ser = Order.objects.create(**data)
+                    ser.no = ser.get_no()
+                    ser.save()
+                    projects = instance.project.all()
+                    for project in projects:
+                        ser.project.add(project.id)
+                # TODO 订单流程
+        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]

+ 5 - 1
apps/order/models.py

@@ -10,9 +10,11 @@ from apps.customer.models import NewCustomer
 class Order(models.Model):
     NORMAL = 1
     ABANDONED = 2
+    WAIT_DISPATCH = 3
     STATUS_CHOICES = (
         (NORMAL, u'正常'),
         (ABANDONED, u'放弃'),
+        (WAIT_DISPATCH, u'进度待分配'),
     )
     no = models.CharField(max_length=50, verbose_name='单号', blank=True)
     project = models.ManyToManyField(Option, verbose_name=u'项目', related_name='order_category', editable=False)
@@ -32,9 +34,11 @@ class Order(models.Model):
         default_permissions = ()
         permissions = [
             ('view_order', u'查看'),
+            ('update_order_process', u'更新进度'),
+            ('order_process_dispatch', u'进度分配'),
         ]
 
     def get_no(self):
         now = timezone.now()
         no = '%s%d-%s' % ('DD', self.service_user.id, now.strftime('%Y%m%d%H%M%S'))
-        return no
+        return no

+ 2 - 2
apps/order/urls.py

@@ -5,9 +5,9 @@ from rest_framework.routers import SimpleRouter
 from .views import *
 
 urlpatterns = [
-
+    url(r'^get_process/$', GetProcessView.as_view()),
 ]
 
 router = SimpleRouter()
 router.register(r'', OrderViewSet)
-urlpatterns += router.urls
+urlpatterns += router.urls

+ 42 - 3
apps/order/views.py

@@ -1,15 +1,54 @@
 # coding=utf-8
+import traceback
 from utils.custom_modelviewset import CustomModelViewSet
 from rest_framework.views import APIView
-from .models import Order
+from utils.exceptions import CustomError
 from .serializers import OrderSerializer
 from .filters import OrderFilter
 from apps.log.models import BizLog
-from utils import response_ok
-from utils.permission import isLogin, permission_required
+from utils import response_ok, response_error
+from utils.permission import isLogin, check_permission
+from apps.customer.models import NewCustomer
+from apps.order.models import Order
+from apps.option.models import Option
+
+class GetProcessView(APIView):
+    permission_classes = [isLogin]
+
+    def get(self, request):
+        customer_id = request.query_params.get('customer_id')
+        instance = NewCustomer.objects.filter(id=customer_id).first()
+        if not instance:
+            raise CustomError('当前客户信息有误,请刷新重试!')
+        if instance.stage_progress.end_stage:
+            raise CustomError('当前客户进度已到最后阶段,请勿重复更新!')
+        order = Order.objects.filter(customer=instance).first()
+        if order and order.status == Order.WAIT_DISPATCH:
+            data = {
+                'error': True,
+                'error_message': u'当前客户订单等待分配中,请勿重复更新!',
+            }
+            return response_ok(data)
+
+        option = Option.objects.filter(type=instance.stage_progress.type, sort__gt=instance.stage_progress.sort,
+                                       enable=True).order_by('sort').first()
+        if option:
+            data = {
+                'now_process_text':instance.stage_progress.name,
+                'next_process_text':option.name,
+                'next_process_id':option.id,
+            }
+            return response_ok(data)
+        else:
+            data = {
+                'error': True,
+                'error_message': u'未找到下个阶段进度,请联系管理员设置!',
+            }
+            return response_ok(data)
 
 
 class OrderViewSet(CustomModelViewSet):
+    permission_classes = [isLogin]
     queryset = Order.objects.filter()
     serializer_class = OrderSerializer
 

+ 9 - 9
uis/views/agent/index.html

@@ -65,7 +65,7 @@
                 <div class="layui-col-md12">
                     <div class="tableContent">
                         <!--总代理商-->
-                        <div style="width: 38%">
+                        <div style="width: 30%">
                             <div class="LAY-btns" style="margin-bottom: 10px;">
                                 <div style="float: left">
                                     <button class="layui-btn" id="total_agent_add" data-permission="agent.add_agent"><i
@@ -85,10 +85,11 @@
                                 </form>
                                 <div style="clear: both;"></div>
                             </div>
-                            <table class="layui-hide" id="total_agent_datagrid" lay-filter="total-agent-operate"></table>
+                            <table class="layui-hide" id="total_agent_datagrid"
+                                   lay-filter="total-agent-operate"></table>
                         </div>
                         <!--代理商-->
-                        <div style="width: 60%">
+                        <div style="width: 68%">
                             <div class="LAY-btns" style="margin-bottom: 10px;">
                                 <div style="float: left">
                                     <button class="layui-btn" id="agent_add" data-permission="agent.add_agent"><i
@@ -158,8 +159,8 @@
             , url: '/agent/agent/'
             , cols: [[
                 {field: 'name', title: '总代理名称', event: 'showAgent', width: 200}
-                , {field: 'create_time_f', title: '添加时间'}
-                , {width: 150, align: 'center', fixed: 'right', toolbar: '#total-agent-operate-bar'}
+                , {field: 'create_time_f', title: '添加时间', MaxWidth: 150}
+                , {width: 130, align: 'center', fixed: 'right', toolbar: '#total-agent-operate-bar'}
             ]]
             , page: true
             , height: 'full-108'
@@ -169,7 +170,7 @@
             elem: '#agent_datagrid'
             , url: '/agent/agent/'
             , cols: [[
-                {field: 'name', title: '名称', width: 150}
+                {field: 'name', title: '次代理名称', width: 150}
                 , {field: 'tel', title: '联系电话', width: 150}
                 , {field: 'area', title: '区域', width: 200}
                 , {field: 'address', title: '地址', width: 200}
@@ -223,11 +224,10 @@
                     },
                     content: 'edit.html?id=' + data.id
                 });
-            }else if(obj.event === 'showAgent'){
+            } else if (obj.event === 'showAgent') {
                 //点击总代理商获取总代理商对应的所有的代理商
                 table.reload('agent_datagrid', {
-                    url: ''
-                    , where: {name: data.name}
+                    where: {general: data.id}
                     , page: {curr: 1}
                 });
             }

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

@@ -155,7 +155,7 @@
                     source_node.append("<option value='" + pid + "'>" + name + "</option>");
                 }
 
-                var  project_data = res.data.project;
+                var project_data = res.data.project;
                 var project_node = $('#id_project');
                 for (var i in project_data) {
                     var pid1 = project_data[i].id;
@@ -246,7 +246,26 @@
                     },
                     btn2: function (index, layero) {
                         //更新进度
-                        layer.close(index);//关闭当前按钮
+                        layer.open({
+                            type: 2,
+                            title: '更新进度',
+                            area: ['45%', '70%'],
+                            btn: ['保存', '取消'],
+                            yes: function (index, dom) {
+                                layui.onSubmitChild = function (res) {
+                                    if (res.code === 0) {
+                                        layer.msg('更新成功!', {icon: 1})
+                                    }
+                                    layer.close(index);
+                                    table.reload('customer_datagrid', {});
+                                };
+                                layui.submitChild();
+                            },
+                            btn2: function (index, layero) {
+                                layer.close(index);//关闭当前按钮
+                            },
+                            content: '../order/update_process.html?customer_id=' + data.id
+                        });
                     },
                     btn3: function (index, layero) {
                         //取消

+ 1 - 1
uis/views/order/index.html

@@ -213,7 +213,7 @@
                     btn2: function (index, layero) {
                         layer.close(index);//关闭当前按钮
                     },
-                    content: 'update.html?id=' + data.id
+                    content: 'update_process.html?id=' + data.id
                 });
             }
         });

+ 63 - 39
uis/views/order/update.html → uis/views/order/update_process.html

@@ -19,7 +19,8 @@
             background-color: white;
             padding-left: 3px;
         }
-        .processText{
+
+        .processText {
             margin-top: 6px;
         }
 
@@ -27,7 +28,8 @@
             padding: 10px;
             margin-right: 15px;
         }
-        .imgsContent{
+
+        .imgsContent {
             display: flex;
             justify-content: flex-start;
             flex-direction: row;
@@ -38,11 +40,12 @@
             width: 150px;
             height: auto;
         }
-        .imgItem{
+
+        .imgItem {
             margin: 0 10px;
         }
 
-         .option {
+        .option {
             display: flex;
             justify-content: space-between;
             flex-direction: row;
@@ -67,13 +70,6 @@
             <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="checkbox" name="end" lay-skin="switch" lay-text="是|否" checked=""
-                                       value="1">
-                            </div>
-                        </div>
                         <div>
                             <label class="layui-form-label">当前进度:</label>
                             <div class="layui-input-block processText" id="current_process"></div>
@@ -85,12 +81,13 @@
                         <div>
                             <label class="layui-form-label">备注:</label>
                             <div class="layui-input-block">
-                                <textarea type="text" name="notes" class="layui-textarea" placeholder="请输入备注"/></textarea>
+                                <textarea type="text" name="notes" class="layui-textarea"
+                                          placeholder="请输入备注"/></textarea>
                             </div>
                         </div>
                         <div>
-                           <label class="layui-form-label"><font color='red' size="4">*</font>上传图片:</label>
-                           <div class="imgsContent">
+                            <label class="layui-form-label"><font color='red' size="4">*</font>上传图片:</label>
+                            <div class="imgsContent">
                                 <div class="layui-upload-drag" id="upload_img">
                                     <div id="upload_img">
                                         <p style="padding-bottom: 10px">多选,最多选6张</p>
@@ -119,9 +116,9 @@
     var imgsList = [];
 
     //渲染待上传的图片列表
-    var renderImgsList = function(list){
+    var renderImgsList = function (list) {
         var html = "";
-        list.forEach((item, index)=>{
+        list.forEach((item, index) => {
             html += "<div class='imgItem'>\n";
             html += "<img src='" + item + "' class='image'>\n";
             html += '<div class="option">\n';
@@ -134,11 +131,11 @@
     }
 
     var showImg = function (index) {
-        var newPage=window.open();
-        newPage.document.write("<img src="+imgsList[index]+" />")
+        var newPage = window.open();
+        newPage.document.write("<img src=" + imgsList[index] + " />")
     };
 
-    var deleteImg = function(index){
+    var deleteImg = function (index) {
         filesList.splice(index, 1);
         imgsList.splice(index, 1);
         renderImgsList(imgsList);
@@ -155,13 +152,36 @@
             , admin = layui.admin
             , upload = layui.upload
             , form = layui.form;
-        var id = layui.view.getParameterByName('id');
+
+        var customer_id = layui.view.getParameterByName('customer_id');
         //form.render(null, 'component-form-element');
+        var next_process_id = ''
+        admin.req({
+            url: '/order/get_process/?customer_id=' + customer_id
+            , type: 'get'
+            , done: function (res) {
+                if (res.data.error) {
+                    layer.open({
+                        type: 1
+                        , offset: 'auto' //具体配置参考:http://www.layui.com/doc/modules/layer.html#offset
+                        , id: 'layerDemo' + customer_id //防止重复弹出
+                        , content: '<div style="padding: 20px 100px;">' + res.data.error_message + '</div>'
+                        , btn: '关闭'
+                        , btnAlign: 'c' //按钮居中
+                        , shade: 0 //不显示遮罩
+                        , yes: function () {
+                            parent.layer.closeAll();
+                        }
+                    });
+                }
+                //当前进度
+                $('#current_process').append(res.data.now_process_text)
+                //下一进度
+                $('#next_process').append(res.data.next_process_text);
+                next_process_id = res.data.next_process_id
+            }
+        });
 
-        //当前进度
-        $('#current_process').append('<span>已约量房</span>')
-        //下一进度
-        $('#next_process').append('<span>方案设计</span>');
 
         //拖拽上传
         upload.render({
@@ -173,36 +193,40 @@
             , multiple: true
             , number: 6
             , auto: false
-            , choose: function(obj) {
-                if(imgsList.length >= 6){
+            , choose: function (obj) {
+                if (imgsList.length >= 6) {
                     layer.msg("图片最多只允许上传6张", {icon: 2});
                     return
                 }
-              //预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
-              obj.preview(function(index, file, result){
-                  filesList.push(file);
-                  imgsList.push(result);
-                  // 有图片列表的话渲染图片
-                  if(imgsList.length > 0){
-                      renderImgsList(imgsList)
-                  }
-              });
+                //预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
+                obj.preview(function (index, file, result) {
+                    filesList.push(file);
+                    imgsList.push(result);
+                    // 有图片列表的话渲染图片
+                    if (imgsList.length > 0) {
+                        renderImgsList(imgsList)
+                    }
+                });
             }
         });
 
 
         form.on('submit(component-form-element)', function (data) {
-            if(filesList.length === 0) {
+            if (filesList.length === 0) {
                 layer.msg("请先选择图片!", {icon: 2});
                 return false
             }
+            if (!next_process_id) {
+                layer.msg("下个进度阶段有误,请刷新重试!", {icon: 2});
+                return false
+            }
             var formData = new FormData();
-            formData.append("end", data.field.end);
+            formData.append("stage_progress", next_process_id);
             formData.append("notes", data.field.notes);
-            filesList.forEach((item, index)=>{
+            filesList.forEach((item, index) => {
                 formData.append(`file${index}`, item)
             });
-            var url = '/agent/agent/' + id + '/';
+            var url = '/customer/new_customer/' + customer_id + '/add_order/';
             admin.req({
                 url: url
                 , data: formData