jiaweiqi 3 年之前
父節點
當前提交
331f85f19c

+ 2 - 1
apps/account/filters.py

@@ -8,8 +8,9 @@ User = get_user_model()
 
 class UserFilter(django_filters.FilterSet):
     username = django_filters.CharFilter(field_name='username', lookup_expr='icontains')
+    name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
     is_active = django_filters.CharFilter(field_name='is_active')
 
     class Meta:
         model = User
-        fields = ['username', 'is_active']
+        fields = ['username', 'is_active', 'name']

+ 8 - 0
apps/account/serializers.py

@@ -56,11 +56,19 @@ class JWTSerializer(JSONWebTokenSerializer):
 class UserSerializer(serializers.ModelSerializer):
     type = serializers.IntegerField(read_only=True)
     password = serializers.CharField(write_only=True, allow_blank=True)
+    gender_txt = serializers.CharField(source="get_gender_display", read_only=True)
+    is_active_txt = serializers.SerializerMethodField()
+    create_time = serializers.DateTimeField(source='date_joined', read_only=True)
 
     class Meta:
         model = User
         fields = '__all__'
 
+    def get_is_active_txt(self, obj):
+        if obj.is_active:
+            return u'是'
+        return u'否'
+
     def create(self, validated_data):
         validated_data['type'] = User.ADMINSTRATOR
         if validated_data['password'].strip() == '':

+ 1 - 1
apps/customer/models.py

@@ -15,7 +15,7 @@ User = get_user_model()
 
 class Customer(models.Model):
     app = models.ForeignKey(Wechat, verbose_name=u'小程序', on_delete=models.PROTECT, editable=False)
-    user = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False, related_name='customer_ref_user_id', on_delete=models.PROTECT, verbose_name=u'用户')
+    user = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False, related_name='customer_ref_user_id', on_delete=models.PROTECT, verbose_name=u'用户', null=True)
     openid = models.CharField(max_length=512, verbose_name=u"openid")
     session_key = models.CharField(max_length=512, verbose_name=u'session_key', null=True)
 

+ 15 - 0
apps/customer/serializers.py

@@ -6,6 +6,7 @@ from rest_framework import serializers
 from rest_framework_jwt.settings import api_settings
 
 from apps.customer.models import Customer
+from apps.wechat.models import Wechat
 
 
 User = get_user_model()
@@ -66,3 +67,17 @@ class WechatBindSerializer(serializers.Serializer):
         else:
             msg = '参数无效'
             raise serializers.ValidationError(msg)
+
+
+class StatementSerializer(serializers.ModelSerializer):
+
+    class Meta:
+        model = Wechat
+        fields = ('privacy_statement', )
+
+
+class CustomerSerializer(serializers.ModelSerializer):
+
+    class Meta:
+        model = Customer
+        fields = '__all__'

+ 6 - 2
apps/customer/urls.py

@@ -1,6 +1,6 @@
 # coding=utf-8
 
-from django.conf.urls import url
+from django.conf.urls import url, include
 
 from .views import *
 
@@ -10,7 +10,11 @@ urlpatterns = [
 
     url(r'^code2Session/$', WxLoginView.as_view()),
     url(r'^wxbind/$', WxBindView.as_view()),
-    url(r'^setUserInfo/$', SetUserInfoView.as_view()),
+    url(r'^setinfo/$', SetUserInfoView.as_view()),
+
+    url(r'^list/$', CsutomerListViewSet.as_view()),
+    url(r'^statement/$', StatementViewSet.as_view()),
+    url(r'^vehicle/', include('apps.customer.vehicle.urls')),
 
 ]
 

+ 0 - 0
apps/customer/vehicle/__init__.py


+ 44 - 0
apps/customer/vehicle/serializers.py

@@ -0,0 +1,44 @@
+# coding=utf-8
+
+from django.contrib.auth import get_user_model
+
+from rest_framework import serializers
+
+from utils.exceptions import CustomError
+
+from apps.log.models import BizLog
+from apps.vehicle.models import Vehicle
+from apps.xgjsms.models import XGJVCode
+
+User = get_user_model()
+
+
+class VehicleSerializer(serializers.ModelSerializer):
+
+    class Meta:
+        model = Vehicle
+        fields = '__all__'
+
+    def validate(self, attrs):
+        attrs['user'] = self.context['request'].user
+        if 'tel' in attrs:
+            if attrs['user'].tel != attrs['tel']:
+                vcode = self.context['request'].data.get('vcode')
+                if not vcode:
+                    raise CustomError(u'验证码不能为空!')
+                XGJVCode.verify(attrs['tel'], vcode)
+        return attrs
+
+    def create(self, validated_data):
+        vehicle = Vehicle.objects.filter(user=validated_data['user']).count()
+        if vehicle:
+            raise CustomError(u'您已有绑定设备!')
+        instance = super(VehicleSerializer, self).create(validated_data)
+        return instance
+
+    def update(self, instance, validated_data):
+        if instance.user != validated_data['user']:
+            raise CustomError(u'禁止操作他人设备!')
+        instance = super(VehicleSerializer, self).update(instance, validated_data)
+        return instance
+

+ 14 - 0
apps/customer/vehicle/urls.py

@@ -0,0 +1,14 @@
+# coding=utf-8
+
+from django.conf.urls import url
+from rest_framework.routers import SimpleRouter
+from .views import *
+
+urlpatterns = [
+    url(r'^vcode/send/$', VCodeSendView.as_view()),
+    # url(r'^vcode/verify/$', VCodeVerifyView.as_view()),
+]
+
+router = SimpleRouter()
+router.register(r'', VehicleViewSet)
+urlpatterns += router.urls

+ 71 - 0
apps/customer/vehicle/views.py

@@ -0,0 +1,71 @@
+# coding=utf-8
+
+import requests
+from django.db import transaction
+from rest_framework.views import APIView
+from rest_framework import generics
+
+
+from utils import response_ok, response_error
+from utils.exceptions import CustomError
+from utils.permission import IsCustomerUser
+from utils.custom_modelviewset import CustomModelViewSet
+
+from apps.xgjsms.models import XGJVCode
+from apps.vehicle.models import Vehicle
+from apps.vehicle.filters import VehicleFilter
+from apps.log.models import BizLog
+from .serializers import *
+
+
+class VCodeSendView(APIView):
+    permission_classes = [IsCustomerUser, ]
+
+    def get(self, request, *args, **kwargs):
+        tel = request.GET.get('tel')
+        appid = request.GET.get('appid')
+
+        try:
+            XGJVCode.send(tel, appid)
+        except CustomError as e:
+            return response_error(e.get_error_msg())
+        return response_ok()
+
+
+# class VCodeVerifyView(APIView):
+#     permission_classes = [IsCustomerUser, ]
+#
+#     def post(self, request):
+#         tel = request.POST.get('tel')
+#         vcode = request.POST.get('vcode')
+#
+#         if not tel:
+#             raise CustomError(u'手机号码不能为空!')
+#         if not vcode:
+#             raise CustomError(u'验证码不能为空!')
+#
+#         XGJVCode.verify(tel, vcode)
+#         return response_ok()
+
+
+class VehicleViewSet(CustomModelViewSet):
+    permission_classes = [IsCustomerUser, ]
+    queryset = Vehicle.objects.filter()
+    serializer_class = VehicleSerializer
+
+    def filter_queryset(self, queryset):
+        queryset = queryset.filter(user=self.request.user)
+        f = VehicleFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+    def perform_create(self, serializer):
+        super(VehicleViewSet, self).perform_create(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        BizLog.objects.addnew(self.request.user, BizLog.INSERT, u'绑定设备,id=%d' % instance.id, validated_data)
+
+    def perform_update(self, serializer):
+        super(VehicleViewSet, self).perform_update(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        BizLog.objects.addnew(self.request.user, BizLog.UPDATE, u'换绑设备,id=%d' % instance.id, validated_data)

+ 29 - 3
apps/customer/views.py

@@ -4,16 +4,19 @@ from django.db import transaction
 from django.conf import settings
 
 from rest_framework.views import APIView
+from rest_framework import generics
 from rest_framework_jwt.views import ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken
 from rest_framework.serializers import ValidationError
 
 from utils import response_ok, response_error
 from utils.exceptions import CustomError
-from utils.permission import IsCustomerUser
+from utils.permission import IsCustomerUser, IsAdministratorUser
 from utils.wx.WXBizDataCrypt import WXBizDataCrypt
 
-from apps.customer.serializers import WechatLoginSerializer, WechatBindSerializer
+from apps.customer.serializers import WechatLoginSerializer, WechatBindSerializer, StatementSerializer, CustomerSerializer
 from apps.customer.models import Customer
+from apps.customer.filters import CustomerFilter
+from apps.wechat.models import Wechat
 
 
 class CustomerRefreshTokenView(RefreshJSONWebToken):
@@ -88,4 +91,27 @@ class SetUserInfoView(APIView):
             user.name = result['nickName']
             user.face = result['avatarUrl']
             user.save()
-        return response_ok()
+        return response_ok({'face': user.face,'name': user.name})
+
+
+class CsutomerListViewSet(generics.ListAPIView):
+    permission_classes = [IsAdministratorUser, ]
+    queryset = Customer.objects.filter()
+    serializer_class = CustomerSerializer
+
+    def filter_queryset(self, queryset):
+        queryset = queryset.filter()
+        f = CustomerFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+
+class StatementViewSet(generics.RetrieveAPIView):
+    '''查看隐私声明'''
+    serializer_class = StatementSerializer
+
+    def retrieve(self, request, *args, **kwargs):
+        instance = Wechat.objects.filter().first()
+        if not instance:
+            raise CustomError(u'未添加小程序!')
+        serializer = self.get_serializer(instance)
+        return response_ok(serializer.data)

+ 12 - 0
apps/vehicle/filters.py

@@ -0,0 +1,12 @@
+# coding=utf-8
+
+import django_filters
+
+from apps.vehicle.models import Vehicle
+
+
+class VehicleFilter(django_filters.FilterSet):
+
+    class Meta:
+        model = Vehicle
+        fields = '__all__'

+ 1 - 1
apps/vehicle/models.py

@@ -5,7 +5,7 @@ from django.utils import timezone
 from django.conf import settings
 
 
-class Wechat(models.Model):
+class Vehicle(models.Model):
     user = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False, related_name='vehicle_ref_user_id', on_delete=models.PROTECT, verbose_name=u'用户')
     tel = models.CharField(verbose_name=u'电话', max_length=50)
     name = models.CharField(verbose_name=u'姓名', max_length=100)

+ 12 - 0
apps/vehicle/serializers.py

@@ -0,0 +1,12 @@
+# coding=utf-8
+
+from rest_framework import serializers
+
+from apps.vehicle.models import Vehicle
+
+
+class VehicleSerializer(serializers.ModelSerializer):
+
+    class Meta:
+        model = Vehicle
+        fields = '__all__'

+ 9 - 0
apps/vehicle/urls.py

@@ -0,0 +1,9 @@
+# coding=utf-8
+
+from django.conf.urls import url
+from rest_framework.routers import SimpleRouter
+from .views import *
+
+urlpatterns = [
+    url(r'^list/$', VehicleListViewSet.as_view()),
+]

+ 19 - 0
apps/vehicle/views.py

@@ -0,0 +1,19 @@
+# coding=utf-8
+
+from rest_framework import generics
+
+from utils.permission import IsAdministratorUser
+
+from apps.vehicle.filters import VehicleFilter
+from .serializers import *
+
+
+class VehicleListViewSet(generics.ListAPIView):
+    permission_classes = [IsAdministratorUser, ]
+    queryset = Vehicle.objects.filter()
+    serializer_class = VehicleSerializer
+
+    def filter_queryset(self, queryset):
+        queryset = queryset.filter()
+        f = VehicleFilter(self.request.GET, queryset=queryset)
+        return f.qs

+ 7 - 7
apps/xgjsms/models.py

@@ -100,7 +100,7 @@ class XGJVCode(models.Model):
         default_permissions = ()
 
     @staticmethod
-    def send(mobile, appid, type, captcha_key=None, captcha=None):
+    def send(mobile, appid, captcha_key=None, captcha=None):
         # 参数说明:
         # token:
         # numbers: 手机号 以半角逗号分隔多个手机号码
@@ -112,9 +112,9 @@ class XGJVCode(models.Model):
             raise CustomError(u"无效的手机号!")
         app = Wechat.objects.filter(appid=appid).first()
         if not app:
-            raise CustomError(u'参数无效')
+            raise CustomError(u'未找到相应小程序')
 
-        vcs = XGJVCode.objects.filter(mobile=mobile, type=type).order_by('-id')
+        vcs = XGJVCode.objects.filter(mobile=mobile).order_by('-id')
         if vcs.count() > 0:
             vc = vcs[0]
             if (timezone.now() - vc.create_time).seconds < 60:
@@ -126,17 +126,17 @@ class XGJVCode(models.Model):
 
         result = sms.send(app.sms_token, app.sms_sign, mobile, str_code)
         if result['Code'] == 'OK':
-            XGJVCode.objects.create(mobile=mobile, vcode=code, type=type)
+            XGJVCode.objects.create(mobile=mobile, vcode=code)
         else:
-            XGJVCode.objects.create(mobile=mobile, vcode=code, type=type, status=XGJVCode.FAILED, error=result['Message'])
+            XGJVCode.objects.create(mobile=mobile, vcode=code, status=XGJVCode.FAILED, error=result['Message'])
             raise CustomError(u"发送失败,请重试!")
 
     @staticmethod
-    def verify(mobile, vcode, type):
+    def verify(mobile, vcode):
         if mobile is None or vcode is None:
             raise CustomError(u'参数错误!')
 
-        vc = XGJVCode.objects.filter(mobile=mobile, type=type).order_by('-id').first()
+        vc = XGJVCode.objects.filter(mobile=mobile).order_by('-id').first()
         if vc:
             if vc.vcode == vcode:
                 if (timezone.now() - vc.create_time).seconds > 600:

+ 1 - 0
car_net/urls.py

@@ -25,6 +25,7 @@ urlpatterns = [
     url(r'^$', index),
     url(r'^account/', include('apps.account.urls')),
     url(r'^wechat/', include('apps.wechat.urls')),
+    url(r'^vehicle/', include('apps.vehicle.urls')),
     url(r'^customer/', include('apps.customer.urls')),
 ]
 

+ 3 - 1
uis/layuiadmin/layui/ueditor/umeditor.js

@@ -6576,7 +6576,9 @@ UM.plugins['paste'] = function () {
         //bk.start.innerHTML = '&nbsp;';
         bk.start.style.display = '';
 
-        pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" +
+        // pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" +
+
+        pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;top:" +
         //要在现在光标平行的位置加入,否则会出现跳动的问题
         $(bk.start).position().top  + 'px';
 

+ 8 - 62
uis/views/employee/edit.html

@@ -21,21 +21,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">
-                    <select id="id_shop" name="shop" lay-verify="required">
-                        <option value=""></option>
-                    </select>
-                  </div>
-              </div>
-                  <div class="layui-col-lg6">
-                  <label class="layui-form-label">权限组:</label>
-                  <div class="layui-input-block" id="group_selecter">
-                    <select name="groups" xm-select="selectGroup"></select>
-                  </div>
-                </div>
                 <div>
                   <label class="layui-form-label"><font color='red' size="4">*</font>姓名:</label>
                   <div class="layui-input-block">
@@ -101,50 +86,14 @@
     ,form = layui.form;
     var id = layui.view.getParameterByName('id');
 
-
-    admin.req({
-        url: '/tenant/employee/dict/',
-        done: function (res) {
-            var shop = res.data.shop;
-            var shop_node = $('#id_shop');
-            for (var i in shop) {
-                var pid = shop[i].id;
-                var value = shop[i].name;
-                shop_node.append("<option value='" + pid + "'>" + value + "</option>");
-            }
-            form.render();
-            loadData();// 赋值完成后调用传值
-        }
-    });
-    
-    var loadData = function () {
-        if(id){
-            var editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata)); // 框架有Bug所以这么转换
-            form.val("component-form-element", editdata);
-        }
+    if(id){
+        var editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata)); // 框架有Bug所以这么转换
+        form.val("component-form-element", editdata);
+    }else{
         form.render(null, 'component-form-element');
-        form.val("component-form-element", {
-                    'password':'1111'
-        });
-    };
-
-    formSelects.config('selectGroup', {
-      beforeSuccess:function(eid, url, searchVal, result){
-          if(id){
-              var groupIds = parent.layui.table.editdata.group_ids;
-              for(var n in result.data){
-                  var item = result.data[n];
-                  if(groupIds.indexOf(parseInt(item.value)) > -1)
-                      item.selected = 'selected';
-              }
-          }
+    form.val("component-form-element", {'password':'1111' });
+    }
 
-          return result;
-      }
-    });
-    formSelects.data('selectGroup', 'server', {
-        url: '/tenant/permission/dict/'
-    });
 
     form.on('submit(component-form-element)', function(data){
       //layer.msg(JSON.stringify(data.field));
@@ -152,14 +101,11 @@
           data.field['is_active'] = 0;
       }
 
-      var submitData = data.field;
-      var groups = formSelects.value('selectGroup', 'val');
-      submitData.groups = JSON.stringify(groups);
       if (id){
-          var url = '/tenant/employee/'+id + '/';
+          var url = '/account/employee/'+ id + '/';
           var type = 'put';
       }else{
-          url =  '/tenant/employee/';
+          url =  '/account/employee/';
           type = 'post';
       }
       admin.req({

+ 12 - 30
uis/views/employee/index.html

@@ -30,7 +30,7 @@
             <div class="LAY-btns" style="margin-bottom: 10px;">
 
                 <div style="float:left; margin-right: 5px; margin-top: 5px;">
-                        <button class="layui-btn" id="btn_add" data-permission="employee.add_employee"><i class="layui-icon layui-icon-add-circle"></i>添加</button>
+                        <button class="layui-btn" id="btn_add"><i class="layui-icon layui-icon-add-circle"></i>添加</button>
                  </div>
                 <div style="float:right;">
 
@@ -38,6 +38,9 @@
                         <div class="seach_items">
                             <input type="text"  name="name" autocomplete="off" class="layui-input" placeholder="姓名"/>
                         </div>
+                        <div class="seach_items">
+                            <input type="text"  name="username" autocomplete="off" class="layui-input" placeholder="帐号"/>
+                        </div>
                         <div class="seach_items">
                             <select  name="is_active">
                                 <option value="">激活</option>
@@ -45,11 +48,6 @@
                                 <option value="0">否</option>
                             </select>
                         </div>
-                        <div class="seach_items">
-                           <select id="id_shop" name="shop">
-                                <option value="">门店</option>
-                            </select>
-                        </div>
 
                         <div class="seach_items">
                             <button class="layui-btn" lay-submit lay-filter="query-form-element"><i class="layui-icon layui-icon-search"></i>查询</button>
@@ -63,7 +61,7 @@
 
             <script type="text/html" id="datagrid-operate-bar">
                 <div class="layui-btn-group">
-                    <a class="layui-btn layui-btn-xs" lay-event="edit" data-permission="employee.edit_employee">修改</a>
+                    <a class="layui-btn layui-btn-xs" lay-event="edit">修改</a>
                 </div>
             </script>
           </div>
@@ -85,38 +83,22 @@
             ,admin = layui.admin
             ,form = layui.form;
 
-    admin.req({
-        url: '/tenant/employee/dict/',
-        done: function (res) {
-            var shop = res.data.shop;
-            var shop_node = $('#id_shop');
-            for (var i in shop) {
-                var pid = shop[i].id;
-                var value = shop[i].name;
-                shop_node.append("<option value='" + pid + "'>" + value + "</option>");
-            }
-            form.render();
-        }
-    });
-
     table.render({
       elem: '#datagrid'
-      ,url: '/tenant/employee/'
+      ,url: '/account/employee/'
       ,cols: [[
-        {field:'shop_name', title:'门店',width: 100}
-        ,{field:'name', title:'姓名',width: 100}
+        {field:'name', title:'姓名',width: 100}
         ,{field:'tel', title:'电话',width: 150}
-        ,{field:'gender_text', title:'性别',width: 80}
-        ,{field:'username', title:'账号',width: 100}
-        ,{field:'groups', title:'权限组', width:200}
-        ,{field:'is_active_text', title:'激活',width: 80}
+        ,{field:'gender_txt', title:'性别',width: 80}
+        ,{field:'username', title:'账号',width: 150}
+        ,{field:'is_active_txt', title:'激活',width: 80}
        ,{field:'create_time', title:'注册时间',width: 200}
         ,{width:100, align:'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
       ]]
       ,page: true
       ,height: 'full-115'
       , done: function () {
-        layui.index.removeNoPermButtons()
+
       }
     });
     form.on('submit(query-form-element)', function(data){
@@ -137,7 +119,7 @@
           type: 2,
           title: '修改',
           shadeClose: false,
-          area: ['600px', '700px'],
+          area: ['600px', '500px'],
           btn: ['保存', '取消'],
           yes: function (index, dom) {
             layui.onSubmitChild = function (data) {

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

@@ -97,7 +97,7 @@
           type: 2,
           title: '隐私声明',
           shadeClose: false,
-          area: ['70%', '95%'],
+          area: ['90%', '95%'],
           btn: ['保存', '取消'],
           yes: function (index, dom) {
             layui.onSubmitChild = function (data) {