فهرست منبع

人员管理,权限管理

wushaodong 4 سال پیش
والد
کامیت
4178ac8c2f

+ 61 - 0
apps/account/consts.py

@@ -0,0 +1,61 @@
+# coding=utf-8
+
+CONTENT_TYPE_SORTING = (
+    # 系统设置
+    'agent-agent',  # 代理管理
+    'agent-store',  # 门店管理
+    'account-user',  # 用户管理
+    'account-managestoreuser',  # 权限管理
+    'option-option',  # 自定义项
+
+)
+
+MENU_TO_MODEL = (
+    (
+        u'基础数据', (
+            'account-user',
+            'account-managestoreuser',
+            'agent-agent',
+            'agent-store',
+            'option-option',
+        )
+    ),
+    (
+        u'潜客作业', (
+            'device-device',
+            'type_model-devicetype',
+            'device-godownentry',
+        )
+    ),
+    (
+        u'订单管理', (
+            'order-order',
+        )
+    ),
+
+)
+
+
+class PermissionMenu(object):
+
+    def __init__(self):
+        self.sort = CONTENT_TYPE_SORTING
+        self.menus = MENU_TO_MODEL
+
+    def get_index(self, app_label, model):
+        try:
+            return self.sort.index('{}-{}'.format(app_label, model))
+        except:
+            return 9999
+
+    def sort_perms(self, perms):
+        perms = perms.order_by('content_type__model', 'id')
+        perms = sorted(perms, key=lambda n: self.get_index(n.content_type.app_label, n.content_type.model))
+        return perms
+
+    def get_menuname_of_contenttype(self, app_label, model):
+        for menu in self.menus:
+            val = '{}-{}'.format(app_label, model)
+            if val in menu[1]:
+                return menu[0]
+        return u'未分类'

+ 3 - 2
apps/account/filters.py

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

+ 32 - 3
apps/account/models.py

@@ -7,7 +7,7 @@ from django.utils import timezone
 from rest_framework.utils import model_meta
 from utils.exceptions import CustomError
 from django.conf import settings
-from apps.agent.models import Store
+from apps.agent.models import Store, Agent
 
 class UserManager(BaseUserManager):
 
@@ -51,11 +51,13 @@ class User(AbstractBaseUser, PermissionsMixin):
     ID_card = models.CharField(max_length=18, verbose_name=u"身份证号", null=True, blank=True)
     address = models.CharField(max_length=100, verbose_name=u"家庭住址", null=True, blank=True)
     tel = models.CharField(max_length=15, verbose_name=u"手机")
+    agent = models.ForeignKey(Agent, verbose_name=u"代理商", null=True, blank=True, on_delete=models.PROTECT)
     store = models.ForeignKey(Store, verbose_name=u"所属门店", null=True, blank=True, on_delete=models.PROTECT)
     status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"是否在职", default=INSERVICE)
     check_user = models.ForeignKey('User', verbose_name=u'审核人', related_name='user_check_user', null=True,
                                    on_delete=models.PROTECT)
     check_time = models.DateTimeField(verbose_name=u'审核时间', editable=False, null=True)
+    create_user = models.ForeignKey('self', verbose_name='创建者', blank=True, on_delete=models.PROTECT)
 
     objects = UserManager()
 
@@ -64,7 +66,7 @@ class User(AbstractBaseUser, PermissionsMixin):
 
     class Meta:
         db_table = "auth_user"
-        verbose_name = u"权限管理"
+        verbose_name = u"人员管理"
         unique_together = [
             ('username')
         ]
@@ -79,6 +81,22 @@ class User(AbstractBaseUser, PermissionsMixin):
     def __unicode__(self):
         return self.username
 
+    def get_manager_range(self):
+        stores = []
+        if self.is_superuser:
+            rows = Store.objects.filter(enable=True).values('id')
+            return [row['id'] for row in rows]
+
+        rows = ManageStoreUser.objects.filter(manage_user=self).values('store_id')
+        for row in rows:
+            stores.append(row['store_id'])
+
+        create_stores = Store.objects.filter(create_user=self).values('id')
+        for create_store in create_stores:
+            stores.append(create_store['id'])
+
+        return list(set(stores))
+
     def change_password(self, new_password, confirm_password, old_password):
         if new_password != confirm_password:
             raise CustomError(u'两次输入的密码不一致, 请检查')
@@ -111,6 +129,17 @@ class User(AbstractBaseUser, PermissionsMixin):
         self.save()
         return self
 
+class ManageStoreUser(models.Model):
+
+    store = models.ForeignKey(Store, verbose_name=u"门店", null=True, blank=True, on_delete=models.PROTECT)
+    manage_user = models.ForeignKey(User, verbose_name=u"管理人员",related_name='manger_user_ref_user', on_delete=models.PROTECT)
+
+    class Meta:
+        db_table = "auth_user_manage_store"
+        verbose_name = u"用户管理范围"
+        default_permissions = ()
+        permissions = [
+            ('manager_permissions', u'管理'),
+        ]
 
-Group.add_to_class('display_name', models.CharField(verbose_name=u'名称显示', max_length=80))
 Group.add_to_class('create_user', models.ForeignKey(User, verbose_name=u"创建人", on_delete=models.PROTECT, editable=False))

+ 122 - 1
apps/account/serializers.py

@@ -1,12 +1,16 @@
 # coding=utf-8
 
+import json
 from django.contrib.auth import get_user_model, authenticate
-
 from rest_framework import serializers
 from rest_framework_jwt.serializers import JSONWebTokenSerializer
 from rest_framework_jwt.settings import api_settings
+from django.contrib.auth.models import Group, Permission
 from apps.log.models import BizLog
 from utils import get_remote_addr
+from utils.booleancharfield import BooleanCharField
+from utils.exceptions import CustomError
+from apps.account.models import ManageStoreUser
 
 User = get_user_model()
 jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
@@ -44,3 +48,120 @@ class JWTSerializer(JSONWebTokenSerializer):
             msg = u'必须包含“{username field}”和“password.'
             msg = msg.format(username_field=self.username_field)
             raise serializers.ValidationError(msg)
+
+class EmployeeSerializer(serializers.ModelSerializer):
+    enable_text = BooleanCharField(source='is_active', read_only=True)
+    agent_text = serializers.CharField(source='agent.name', read_only=True)
+    store_text = serializers.CharField(source='store.name', read_only=True)
+    gender_text = serializers.CharField(source='get_gender_display', read_only=True)
+    groups = serializers.SerializerMethodField()
+    group_ids = serializers.PrimaryKeyRelatedField(source='groups', many=True, read_only=True)
+    manager_barnchs = serializers.SerializerMethodField()
+
+    def get_manager_barnchs(self, obj):
+        stores = ManageStoreUser.objects.filter(manage_user=obj)
+        return ','.join(stores.values_list('store__name', flat=True))
+
+    def get_groups(self, obj):
+        return ','.join(obj.groups.values_list('name', flat=True))
+
+    class Meta:
+        model = User
+        fields = '__all__'
+
+    def create(self, validated_data):
+        username = self.initial_data['username']
+        user = User.objects.filter(username=username).first()
+        if user:
+            raise CustomError(u'账号[{0}]已存在。'.format(username))
+        # 代理商添加的账号,默认就是操作人所在的代理商
+        user = self.context['request'].user
+        validated_data['create_user'] = user
+        instance = super(EmployeeSerializer, self).create(validated_data)
+        instance.set_password(validated_data['password'])
+        instance.save()
+        groups = self.context['request'].data.get('groups', None)
+        if groups:
+            groups = json.loads(groups)
+        else:
+            groups = []
+        for group in groups:
+            instance.groups.add(group)
+        return instance
+
+    def update(self, instance, validated_data):
+        instance.groups.clear()
+        password = instance.password
+        validated_data['is_superuser'] = instance.is_superuser
+        instance = super(EmployeeSerializer, self).update(instance, validated_data)
+        if not 'password' in validated_data or not validated_data['password']:
+            instance.password = instance.password
+        else:
+           instance.set_password(validated_data['password'])
+        instance.save()
+
+        groups = self.context['request'].data.get('groups', None)
+        if groups:
+            groups = json.loads(groups)
+        else:
+            groups = []
+        for group in groups:
+            instance.groups.add(group)
+        return instance
+
+class PermissionSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Permission
+        fields = ('id', 'name',)
+
+class GroupSerializer(serializers.ModelSerializer):
+    employees = serializers.SerializerMethodField()
+    permissions = PermissionSerializer(many=True, read_only=True)
+
+    def get_employees(self, obj):
+        users = obj.user_set.all()
+        data = []
+        for user in users:
+            data.append(user.name)
+        return data
+
+    class Meta:
+        model = Group
+        fields = ('id', 'name', 'permissions', 'employees',)
+
+    def create(self, validated_data):
+        user = self.context['request'].user
+        validated_data['create_user'] = user
+        group = Group.objects.filter(name=validated_data['name']).first()
+        if group:
+            raise CustomError(u'名称为[%s]的权限组已存在' % validated_data['name'])
+
+        permissions = self.context['request'].data.get('permissions', None)
+        if permissions:
+            permissions = json.loads(permissions)
+        else:
+            permissions = []
+        instance = super(GroupSerializer, self).create(validated_data)
+        instance.permissions.set(permissions)
+        return instance
+
+    def update(self, instance, validated_data):
+        group = Group.objects.filter(name=validated_data['name']).exclude(id=instance.id).first()
+        if group:
+            raise CustomError(u'名称为[%s]的权限组已存在' % validated_data['name'])
+        permissions = self.context['request'].data.get('permissions', None)
+        if permissions:
+            permissions = json.loads(permissions)
+        else:
+            permissions = []
+        instance = super(GroupSerializer, self).update(instance, validated_data)
+        instance.permissions.set(permissions)
+        return instance
+
+class GroupDictSerializer(serializers.ModelSerializer):
+    value = serializers.CharField(source='id', read_only=True)
+    # name = serializers.CharField(source='name', read_only=True)
+
+    class Meta:
+        model = Group
+        fields = ('value', 'name',)

+ 9 - 3
apps/account/urls.py

@@ -1,9 +1,15 @@
 from django.conf.urls import url
-
+from rest_framework.routers import SimpleRouter
 from apps.account.views import *
 
-urlpatterns = (
+urlpatterns = [
     url(r'^login/$', LoginView.as_view()),
     url(r'^token_refresh/$', RefreshTokenView.as_view()),
-)
+    url(r'^permission/dict/$', PermissionDictView.as_view()),
+    url(r'^permission/all/$', PermissionsListView.as_view()),
+]
 
+router = SimpleRouter()
+router.register(r'employee', EmployeeViewSet)
+router.register(r'permission', GroupsViewSet)
+urlpatterns += router.urls

+ 147 - 3
apps/account/views.py

@@ -1,10 +1,23 @@
 #coding=utf-8
-
+import traceback
+from django.db.models import Q
+from rest_framework.decorators import action
+from django.db import transaction
+from rest_framework.views import APIView
 from rest_framework.serializers import ValidationError
-
+from utils.permission import permission_required, isLogin
+from django.contrib.auth.models import Group, Permission
 from rest_framework_jwt.views import ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken
 from utils import response_error, response_ok
-from apps.account.serializers import JWTSerializer
+from django.contrib.auth import get_user_model
+User = get_user_model()
+from apps.account.serializers import JWTSerializer, EmployeeSerializer, GroupDictSerializer, GroupSerializer
+from utils.custom_modelviewset import CustomModelViewSet
+from apps.account.filters import UserFilter, GroupFilter
+from apps.account.models import ManageStoreUser
+from apps.log.models import BizLog
+from apps.account.consts import PermissionMenu
+from collections import OrderedDict
 
 class LoginView(ObtainJSONWebToken):
     serializer_class = JWTSerializer
@@ -26,3 +39,134 @@ class RefreshTokenView(RefreshJSONWebToken):
                 return response_ok({'token': ser.validated_data['token']})
         except ValidationError as e:
             return response_error(u'登录状态失效,请重新登录')
+
+class EmployeeViewSet(CustomModelViewSet):
+    permission_classes = [isLogin, ]
+    queryset = User.objects.filter()
+    serializer_class = EmployeeSerializer
+
+    @permission_required('account.browse_user')
+    def filter_queryset(self, queryset):
+        queryset = queryset.filter()
+        user = self.request.user
+        queryset = queryset.filter(
+            Q(store_id__in=self.request.user.get_manager_range()) |
+            Q(id=user.id) |
+            Q(create_user=user))
+
+        f = UserFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+    @permission_required('account.add_user')
+    def perform_create(self, serializer):
+        super(EmployeeViewSet, self).perform_create(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        BizLog.objects.addnew(self.request.user, BizLog.INSERT,
+                              u'添加用户[%s],id=%d' % (instance.name, instance.id), validated_data)
+
+    @permission_required('account.add_user')
+    def perform_update(self, serializer):
+        super(EmployeeViewSet, self).perform_update(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        BizLog.objects.addnew(self.request.user, BizLog.UPDATE,
+                              u'修改用户[%s],id=%d' % (instance.name, instance.id), validated_data)
+
+    @permission_required('account.delete_user')
+    def perform_destroy(self, instance):
+        ManageStoreUser.objects.filter(manage_user=instance).delete()
+        BizLog.objects.filter(user=instance).delete()
+        BizLog.objects.addnew(self.request.user, BizLog.DELETE,
+                              u'删除账号[%s],id=%d' % (instance.username, instance.id))
+        super(EmployeeViewSet, self).perform_destroy(instance)
+
+    @action(methods=['post'], detail=True)
+    def branch(self, request, pk):
+        data = request.POST.get('managers')
+        try:
+            with transaction.atomic():
+                ManageStoreUser.objects.filter(manage_user_id=pk).delete()
+                rows = data.split(',')
+                for row in rows:
+                    branch = row.split('_')[1]
+                    ManageStoreUser.objects.create(store_id=branch,manage_user_id=pk)
+            return response_ok()
+        except Exception as e:
+            traceback.print_exc()
+            return response_error(u'保存失败')
+
+class GroupsViewSet(CustomModelViewSet):
+    permission_classes = [isLogin, ]
+    queryset = Group.objects.filter()
+    serializer_class = GroupSerializer
+
+    @permission_required('account.manager_permissions')
+    def filter_queryset(self, queryset):
+        if not self.request.user.is_superuser:
+            groups =  self.request.user.groups.all()
+            queryset =queryset.filter(id__in=[g.id for g in groups])
+        f = GroupFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+    @permission_required('account.manager_permissions')
+    def perform_create(self, serializer):
+        super(GroupsViewSet, self).perform_create(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        BizLog.objects.addnew(self.request.user, BizLog.INSERT,
+                              u'添加权限组[%s],id=%d' % (instance.name, instance.id), validated_data)
+
+    @permission_required('account.manager_permissions')
+    def perform_update(self, serializer):
+        super(GroupsViewSet, self).perform_update(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        BizLog.objects.addnew(self.request.user, BizLog.UPDATE,
+                              u'修改权限组[%s],id=%d' % (instance.name, instance.id), validated_data)
+
+    @permission_required('account.manager_permissions')
+    def destroy(self, request, *args, **kwargs):
+        with transaction.atomic():
+            instance = self.get_object()
+            # user_count = instance.user_set.all().count()
+            # if user_count:
+            #     raise CustomError(u'该权限组已分配给用户,禁止删除!')
+
+            BizLog.objects.addnew(self.request.user, BizLog.UPDATE,
+                                  u'删除权限组[%s],id=%d' % (instance.name, instance.id))
+            instance.delete()
+        return response_ok()
+
+class PermissionsListView(APIView):
+    permission_classes = [isLogin, ]
+
+    def get(self, request):
+        rows = Permission.objects.all().exclude(name__startswith='Can')
+        perms_menus = PermissionMenu()
+        rows = perms_menus.sort_perms(rows)
+        menus = OrderedDict()
+        for row in rows:
+            item = {'id': row.id, 'name': row.name}
+            mn = perms_menus.get_menuname_of_contenttype(row.content_type.app_label, row.content_type.model)
+            if mn in menus:
+                permissions = menus[mn]
+            else:
+                permissions = menus[mn] = OrderedDict()
+            if row.content_type.name in permissions:
+                if not item in permissions[row.content_type.name]:
+                    permissions[row.content_type.name].append(item)
+            else:
+                permissions[row.content_type.name] = [item, ]
+        return response_ok(menus)
+
+class PermissionDictView(APIView):
+    permission_classes = [isLogin, ]
+    def get(self, request):
+        rows = Group.objects.filter()
+        print()
+        if not request.user.is_superuser:
+            groups = request.user.groups.all()
+            rows =rows.filter(id__in=[g.id for g in groups])
+        serializer = GroupDictSerializer(rows, many=True)
+        return response_ok(serializer.data)

+ 1 - 1
apps/agent/models.py

@@ -12,7 +12,7 @@ class Agent(models.Model):
     tel = models.CharField(verbose_name=u'电话', max_length=20, null=True)
     area = models.CharField(verbose_name=u'区域', max_length=50)
     address = models.CharField(verbose_name=u'地址', max_length=200)
-    create_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'添加人', on_delete=models.PROTECT)
+    create_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'添加人',related_name='agent_create_user', on_delete=models.PROTECT)
     create_time = models.DateTimeField(verbose_name=u'添加时间', auto_now_add=True, editable=False)
 
     class Meta:

+ 12 - 2
apps/agent/serializers.py

@@ -2,11 +2,21 @@
 
 from rest_framework import serializers
 from django.conf import settings
-from .models import Upload
-
+from apps.upload.models import Upload
+from apps.agent.models import Agent,Store
 
 class UploadSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = Upload
         fields = ('picture', 'width', 'height', 'type', 'voice_time')
+
+class AgentComboboxSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Agent
+        fields = ('id', 'name',)
+
+class StoreComboboxSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Store
+        fields = ('id', 'name',)

+ 11 - 0
apps/agent/urls.py

@@ -0,0 +1,11 @@
+from django.conf.urls import url
+from rest_framework.routers import SimpleRouter
+from apps.agent.views import *
+
+urlpatterns = [
+    url(r'^dict/$', AgentDictView.as_view()),
+]
+
+router = SimpleRouter()
+
+urlpatterns += router.urls

+ 35 - 0
apps/agent/views.py

@@ -0,0 +1,35 @@
+# coding=utf-8
+import traceback
+from django.utils import timezone
+from django.db.models import Q
+from rest_framework.decorators import action
+from django.db import transaction
+from rest_framework.serializers import ValidationError
+from utils.permission import permission_required, isLogin
+from rest_framework.views import APIView
+from rest_framework_jwt.views import ObtainJSONWebToken, VerifyJSONWebToken, RefreshJSONWebToken
+from utils import response_error, response_ok
+from django.contrib.auth import get_user_model
+
+User = get_user_model()
+from apps.agent.serializers import AgentComboboxSerializer,StoreComboboxSerializer
+from utils.custom_modelviewset import CustomModelViewSet
+from apps.log.models import BizLog
+from apps.agent.models import Agent, Store
+
+
+class AgentDictView(APIView):
+    permission_classes = [isLogin, ]
+
+    def get(self, request):
+        rows = Agent.objects.filter(Q(create_user=request.user) | Q(id=request.user.agent_id))
+        agents = AgentComboboxSerializer(rows, many=True).data
+        stores = []
+        for row in rows:
+            store = Store.objects.filter(agent=row, enable=True, end_date__gte=timezone.now().date())
+            store_serializer = StoreComboboxSerializer(store, many=True).data
+            stores.append(store_serializer)
+        return response_ok({
+            'agents': agents,
+            'stores': stores,
+        })

+ 1 - 2
apps/new_customer/customer/views.py

@@ -4,7 +4,6 @@ from rest_framework import permissions
 from django.utils import timezone
 
 from utils.custom_modelviewset import CustomModelViewSet
-from utils.permission import IsAdministratorUser,IsTenantUser
 from utils.exceptions import CustomError
 from utils import response_ok, response_error
 from .models import Customer
@@ -61,4 +60,4 @@ class CustomerViewSet(CustomModelViewSet):
             return response_error(e.get_error_msg())
         except Exception as e:
             return response_error(str(e))
-        return response_ok('审核完成!')
+        return response_ok('审核完成!')

+ 1 - 1
apps/option/models.py

@@ -26,7 +26,7 @@ class Option(models.Model):
 
     class Meta:
         db_table = 'system_option'
-        verbose_name = u"系统选项"
+        verbose_name = u"自定义项"
         ordering = ['type', 'sort', ]
         index_together = (
             'type',

+ 0 - 1
apps/option/views.py

@@ -1,5 +1,4 @@
 from utils.custom_modelviewset import CustomModelViewSet
-from utils.permission import IsTenantUser, IsAdministratorUser
 from rest_framework.views import APIView
 from .models import Option
 from .serializers import OptionSerializer

+ 1 - 0
decorate/urls.py

@@ -27,6 +27,7 @@ urlpatterns = [
     url(r'^api/', include('apps.api.urls')),
     url(r'^new_customer/', include('apps.new_customer.urls')),
     url(r'^option/', include('apps.option.urls')),
+    url(r'^agent/', include('apps.agent.urls')),
 ]
 
 urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

+ 207 - 0
uis/views/employee/edit.html

@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>员工信息</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport"
+          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
+    <link rel="stylesheet" href="../../layuiadmin/layui/css/layui.css" media="all">
+    <link rel="stylesheet" href="../../layuiadmin/style/admin.css" media="all">
+    <link rel="stylesheet" type="text/css" href="../../layuiadmin/style/formSelects-v4.css"/>
+    <style>
+        #group_selecter dl {
+            max-height: 200px;
+        }
+    </style>
+</head>
+<body>
+
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15">
+        <div class="layui-col-md6">
+            <div class="layui-card">
+
+                <div class="layui-card-body">
+                    <form class="layui-form" action="" lay-filter="component-form-element">
+                        <div class="layui-row layui-col-space10 layui-form-item">
+
+                            <div class="layui-col-lg6">
+                                <label class="layui-form-label"><font color='red' size="4">*</font>姓名:</label>
+                                <div class="layui-input-block">
+                                    <input type="text" name="name" lay-verify="required" placeholder="请输入姓名"
+                                           autocomplete="off" class="layui-input">
+                                </div>
+                            </div>
+                            <div class="layui-col-lg6">
+                                <label class="layui-form-label"><font color='red' size="4">*</font>电话:</label>
+                                <div class="layui-input-block">
+                                    <input type="text" name="tel" placeholder="请输入电话"  lay-verify="required"
+                                           autocomplete="off" class="layui-input">
+                                </div>
+                            </div>
+
+                            <div class="layui-col-lg6">
+                                <label class="layui-form-label"><font color='red' size="4">*</font>账号:</label>
+                                <div class="layui-input-block">
+                                    <input type="text" name="username" lay-verify="required" placeholder="请输入账号"
+                                           autocomplete="off" class="layui-input">
+                                </div>
+                            </div>
+
+                            <div class="layui-col-lg6">
+                                <label class="layui-form-label">密码:</label>
+                                <div class="layui-input-block">
+                                    <input type="password" name="password" placeholder="请输入密码" autocomplete="off"
+                                           class="layui-input">
+                                    <div class="layui-word-aux">默认密码:1111</div>
+                                </div>
+                            </div>
+
+                            <div class="layui-col-sm6">
+                                <label class="layui-form-label">性别:</label>
+                                <div class="layui-input-block">
+                                    <select name="gender" lay-verify="required">
+                                        <option value="2">男</option>
+                                        <option value="1">女</option>
+                                    </select>
+                                </div>
+                            </div>
+                            <div class="layui-col-sm6">
+                                <div class="layui-col-lg6">
+                                    <label class="layui-form-label"><font color='red' size="4">*</font>代理商:</label>
+                                    <div class="layui-input-block">
+                                        <select id="id_agents" name="agent" lay-verify="required" lay-search="">
+                                            <option value="">选择代理商</option>
+                                        </select>
+                                    </div>
+                                </div>
+                            </div>
+
+                            <div class="layui-col-lg6">
+                                <label class="layui-form-label">是否在用:</label>
+                                <div class="layui-input-block">
+                                    <input type="checkbox" name="is_active" lay-skin="switch" lay-text="是|否" checked=""
+                                           value="1">
+                                </div>
+                            </div>
+
+                            <div class="layui-col-lg6">
+                                <label class="layui-form-label">权限组:</label>
+                                <div class="layui-input-block">
+                                    <select name="groups" xm-select="selectGroup"></select>
+                                </div>
+                            </div>
+                            <button class="layui-btn" id="id_user_save" lay-submit lay-filter="component-form-element"
+                                    style="display: none">保存
+                            </button>
+                        </div>
+
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+
+<script src="../../layuiadmin/layui/layui.js"></script>
+
+<script>
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index',
+        formSelects: 'formSelects-v4'
+    }).use(['index', 'form', 'utils', 'formSelects',], function () {
+        var $ = layui.$
+            , admin = layui.admin
+            , form = layui.form
+            , formSelects = layui.formSelects
+
+        var id = layui.view.getParameterByName('id');
+
+        form.val("component-form-element", {
+            'password': '1111'
+        });
+        var loadData = function () {
+            if (id) {
+                var editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata)); // 框架有Bug所以这么转换
+                form.val("component-form-element", editdata);
+                form.val("component-form-element", {
+                    'password': ''
+                });
+            }
+        }
+        form.render(null, 'component-form-element');
+        admin.req({
+            url: '/agent/dict/',
+            done: function (res) {
+                console.log(3333333333,res)
+                var agents = res.data.agents;
+                var agents_node = $('#id_agents');
+                for (var i in agents) {
+                    var pid = agents[i].id;
+                    var agents_value = agents[i].name;
+                    agents_node.append("<option value='" + pid + "'>" + agents_value + "</option>");
+                }
+                form.render();
+                loadData();
+            }
+        });
+        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';
+                    }
+                }
+                loadData()
+                return result;
+            }
+        });
+        formSelects.data('selectGroup', 'server', {
+            url: '/account/permission/dict/'
+        });
+        form.on('submit(component-form-element)', function (data) {
+            //layer.msg(JSON.stringify(data.field));
+            var submitData = data.field;
+            var groups = formSelects.value('selectGroup', 'val');
+            submitData.groups = JSON.stringify(groups);
+            data.field.type = 1
+
+            if (data.field.is_head && data.field.agent) {
+                layer.msg('代理商和是否总部,只能选择一个')
+                return false
+            }
+
+            if (id) {
+                var url = '/account/employee/' + id + '/';
+                var type = 'put';
+            } else {
+                url = '/account/employee/';
+                type = 'post';
+            }
+            admin.req({
+                url: url
+                , data: data.field
+                , type: type
+                , done: function (res) {
+                    parent.layer.closeAll('iframe');
+                    parent.layui.table.reload('datagrid', {});
+                }
+            });
+            return false;
+        });
+
+        parent.layui.submitChild = function () {
+            $("#id_user_save").click();
+        };
+    });
+</script>
+</body>
+</html>

+ 194 - 0
uis/views/employee/index.html

@@ -0,0 +1,194 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>员工管理</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport"
+          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
+    <link rel="stylesheet" href="../../layuiadmin/layui/css/layui.css" media="all">
+    <link rel="stylesheet" href="../../layuiadmin/style/admin.css" media="all">
+    <link rel="stylesheet" type="text/css" href="../../layuiadmin/style/formSelects-v4.css"/>
+    <style type="text/css">
+        .seach_items {
+            display: inline-block;
+            margin-right: 5px;
+            margin-top: 5px;
+        }
+    </style>
+</head>
+<body>
+
+<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="LAY-btns" style="margin-bottom: 10px;">
+                        <div style="float:left; margin-right: 5px; margin-top: 5px;">
+                            <button class="layui-btn" id="btn_add"><i class="layui-icon layui-icon-add-circle"></i>添加
+                            </button>
+                        </div>
+
+                        <div style="float:right;">
+                            <form class="layui-form" lay-filter="query-form-element">
+                                <div class="seach_items">
+                                    <input type="text" name="name" autocomplete="off" class="layui-input"
+                                           placeholder="姓名"/>
+                                </div>
+                                <div class="seach_items">
+                                    <input type="text" name="tel" 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">
+                                    <button class="layui-btn" lay-submit lay-filter="query-form-element"><i
+                                            class="layui-icon layui-icon-search"></i>查询
+                                    </button>
+                                </div>
+                            </form>
+                        </div>
+                        <div style="clear: both;"></div>
+                    </div>
+                    <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"
+                               data-permission="employee.add_employee">修改</a>
+                        </div>
+                        <div class="layui-btn-group">
+                            <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="delete"
+                               data-permission="employee.delete_employee">删除</a>
+                        </div>
+                        <div class="layui-btn-group">
+                            <a class="layui-btn layui-btn-xs layui-btn-warm"
+                               data-permission="employee.add_employee"
+                               lay-event="manage_range">管理网点</a>
+                        </div>
+                    </script>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script src="../../layuiadmin/layui/layui.js?t=1"></script>
+<script>
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index' //主入口模块
+        , formSelects: 'formSelects-v4'
+    }).use(['index', 'table', 'form', 'formSelects'], function () {
+        var $ = layui.$
+            , table = layui.table
+            , form = layui.form;
+        table.render({
+            elem: '#datagrid'
+            , url: '/account/employee/'
+            , cols: [[
+                {field: 'name', title: '姓名', width: 120}
+                , {field: 'gender_text', title: '性别', width: 80}
+                , {field: 'tel', title: '电话', width: 120}
+                , {field: 'username', title: '账号', width: 120}
+                , {field: 'agent_text', title: '代理商', width: 150}
+                , {field: 'store_text', title: '门店', width: 150}
+                , {field: 'enable_text', title: '是否在用', width: 100}
+                , {field: 'groups', title: '权限组', width: 200}
+                , {field: 'manager_barnchs', title: '管理网点', width: 200}
+                , {width: 200, align: 'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
+            ]]
+            , page: true
+            , height: 'full-108'
+        });
+        var _params;
+        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;
+        });
+        //监听工具条
+        table.on('tool(datagrid-operate)', function (obj) {
+            var data = obj.data;
+            if (obj.event === 'edit') {
+                table.editdata = data;
+                layer.open({
+                    type: 2,
+                    title: '修改',
+                    shadeClose: false,
+                    area: ['50%', '80%'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        layui.submitChild();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: 'edit.html?id=' + data.id
+                });
+            } else if (obj.event === 'delete') {
+                layer.confirm('确定要删除吗?', function (index) {
+                    layer.close(index);
+                    layui.admin.req({
+                        notice: true
+                        , url: '/account/employee/' + data.id + '/'
+                        , type: 'delete'
+                        , done: function (res) {
+                            table.reload('datagrid', {});
+                        }
+                    });
+                });
+            }
+            else if (obj.event === 'manage_range') {
+                layer.open({
+                    type: 2,
+                    title: '管理网点',
+                    shadeClose: true,
+                    area: ['650px', '80%'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        layui.submitChild();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: 'manage_range.html?id=' + data.id
+                });
+            }
+        });
+
+        $('#btn_add').on('click', function () {
+            layer.open({
+                type: 2,
+                title: '添加',
+                shadeClose: false,
+                area: ['550px', '80%'],
+                btn: ['保存', '取消'],
+                yes: function (index, dom) {
+                    layui.onSubmitChild = function (data) {
+                        layer.close(index);
+                        table.reload('datagrid', {});
+                    };
+                    layui.submitChild();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: 'edit.html'
+            });
+        });
+    });
+</script>
+</body>
+</html>
+

+ 96 - 0
uis/views/employee/manage_range.html

@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>管理范围</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport"
+          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
+    <link rel="stylesheet" href="../../layuiadmin/layui/css/layui.css" media="all">
+    <link rel="stylesheet" href="../../layuiadmin/style/admin.css" media="all">
+    <link rel="stylesheet" type="text/css" href="../../layuiadmin/style/formSelects-v4.css"/>
+</head>
+<body>
+
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15">
+        <div class="layui-col-md6">
+            <div class="layui-card">
+
+                <div class="layui-card-body">
+                    <form class="layui-form" action="" lay-filter="component-form-element">
+                        <div class="layui-row layui-col-space10 layui-form-item">
+
+                            <div class="layui-col-lg6">
+                                <label class="layui-form-label">网点:</label>
+                                <div class="layui-input-block">
+                                    <select name="managers" xm-select="manager_range">
+                                    </select>
+                                </div>
+                            </div>
+                            <button class="layui-btn" id="id_save" lay-submit lay-filter="component-form-element"
+                                    style="display: none">保存
+                            </button>
+
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script src="../../layuiadmin/layui/layui.js"></script>
+<script>
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index' //主入口模块
+        , formSelects: 'formSelects-v4'
+    }).use(['index', 'form', 'formSelects'], function () {
+        var $ = layui.$
+            , admin = layui.admin
+            , form = layui.form
+            , formSelects = layui.formSelects;
+
+        var id = layui.view.getParameterByName('id');
+        formSelects.value('manager_range', []);
+        admin.req({
+            url: '/account/branch/tree/?id=' + id
+            , done: function (res) {
+                var _nodes = res.data.branchs;
+                var manages = res.data.manages;
+                formSelects.data('manager_range', 'local', {
+                    arr: _nodes,
+                    tree: {
+                        //在点击节点的时候, 如果没有子级数据, 会触发此事件
+                        nextClick: function (id, item, callback) {
+                            return false;
+                        },
+                    }
+                });
+                formSelects.value('manager_range', manages);
+            }
+        });
+
+        form.on('submit(component-form-element)', function (data) {
+            admin.req({
+                url: '/account/employee/' + id + '/branch/'
+                , data: data.field
+                , type:  'post'
+                , done: function (res) {
+                    parent.layer.closeAll('iframe');
+                    parent.layui.table.reload('datagrid', {});
+                }
+            });
+            return false;
+        });
+
+        parent.layui.submitChild = function () {
+            $("#id_save").click();
+        };
+    });
+</script>
+</body>
+</html>

+ 10 - 0
uis/views/index.html

@@ -67,6 +67,16 @@
                             <i class="layui-icon layui-icon-set"></i>
                             <cite>基础数据</cite>
                         </a>
+                        <dl class="layui-nav-child">
+                            <dd data-name="nav" data-permission="account.browse_user">
+                                <a lay-href="employee/index.html">人员管理</a>
+                            </dd>
+                        </dl>
+                        <dl class="layui-nav-child">
+                            <dd data-name="nav" data-permission="account.manager_permissions">
+                                <a lay-href="permissions/index.html">权限管理</a>
+                            </dd>
+                        </dl>
                         <dl class="layui-nav-child">
                             <dd data-name="nav" data-permission="option.browse_option">
                                 <a lay-href="option/index.html">自定义项</a>

+ 151 - 0
uis/views/permissions/edit.html

@@ -0,0 +1,151 @@
+<!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">
+</head>
+<body>
+
+<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">
+
+            <form class="layui-form" action="" lay-filter="component-form-element">
+              <div class="layui-row layui-col-space10 layui-form-item">
+
+                <div class="layui-col-md12">
+                  <label class="layui-form-label"><font color='red' size="4">*</font>名称:</label>
+                  <div class="layui-input-block">
+                    <input type="text" name="display_name" lay-verify="required" placeholder="请输入权限组名称" autocomplete="off" class="layui-input">
+                  </div>
+                </div>
+                  <div class="layui-col-md12">
+                  <label class="layui-form-label">权限:</label>
+                  <div class="layui-input-block">
+                    <div id="perms">
+
+                    </div>
+                  </div>
+                </div>
+
+                <button id="id_save" class="layui-btn" lay-submit lay-filter="component-form-element" style="display: none">保存</button>
+
+              </div>
+            </form>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
+
+  <script src="../../layuiadmin/layui/layui.js"></script>
+  <script>
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index' //主入口模块
+  }).use(['index', 'form'], function(){
+    var $ = layui.$
+    ,admin = layui.admin
+    ,element = layui.element
+    ,form = layui.form;
+    var id = layui.view.getParameterByName('id');
+
+    admin.req({
+        url: '/account/permission/all/',
+        type: 'get',
+        beforeSend: function () {
+            layer.load();
+        },
+        done: function (res) {
+            var curPermissions = [];
+            var editdata = null;
+            if (id) {
+                editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata)); // 框架有Bug所以这么转换
+                curPermissions = editdata.permissions;
+            }
+            var data = res.data;
+            var html = '';
+            for (var key1 in data){
+              html += "<div class='layui-colla-item'>\n" +
+                    "<input type='checkbox' title='"+key1+"' lay-filter='clickkey1' lay-skin='primary'>\n" +
+                    "          <div class='layui-colla-content layui-show' style='padding-top: 10px'>\n";
+              for(var key2 in data[key1]){
+                  html += "<input type='checkbox' title='"+key2+"' lay-filter='clickkey2' lay-skin='primary'>\n" +
+                      "          <div class='layui-colla-content layui-show' style='padding-top: 5px'>\n<div>\n";
+                  var item = data[key1][key2];
+                  for(var m in item){
+                      var p = item[m];
+                      var checked = '';
+                      for(var key3 in curPermissions){
+                          if(curPermissions[key3]['id'] === p.id){
+                              checked = 'checked';
+                          }
+                      }
+                      html += "<input type='checkbox' name='permission' value='"+p.id+"' title='"+p.name+"' "+checked+" lay-skin='primary'>";
+                  }
+                  html += "</div></div>"
+              }
+              html += "</div></div>"
+            }
+            $('#perms').after(html);
+            if (editdata) {
+                form.val("component-form-element", editdata);
+            }
+            form.render(null, 'component-form-element');
+            layer.closeAll('loading');
+        }
+    });
+    form.on('checkbox(clickkey1)', function (data) {
+         $(data.elem).parent().children().find(':checkbox').prop('checked', data.elem.checked);
+         form.render();
+    });
+    form.on('checkbox(clickkey2)', function (data) {
+        $(data.elem).next().next().find(':checkbox').prop('checked', data.elem.checked);
+        form.render();
+    });
+
+    form.on('submit(component-form-element)', function(data){
+
+      //layer.msg(JSON.stringify(data.field));
+        var submitData = {display_name:data.field.display_name};
+        var permissions = [];
+        $("input:checkbox[name='permission']:checked").each(function() {
+          permissions.push(parseInt($(this).val()));
+          submitData.permissions = JSON.stringify(permissions)
+        });
+        submitData.name = submitData.display_name;
+        if (id){
+            var url =  '/account/permission/' + id + '/';
+            var type = 'put';
+        }else{
+            url =  '/account/permission/';
+            type = 'post'
+        }
+     admin.req({
+        url: url
+        ,data: submitData
+        ,type: type
+        ,done: function(res){
+            parent.layui.onSubmitChild(res.data);
+        }
+    });
+
+      return false;
+    });
+
+    parent.layui.submitChild = function () {
+      $("#id_save").click();
+    };
+  });
+  </script>
+</body>
+</html>

+ 128 - 0
uis/views/permissions/index.html

@@ -0,0 +1,128 @@
+<!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">
+</head>
+<body>
+
+  <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="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>
+            </div>
+
+            <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" data-permission="account.add_group">修改</a>
+              </div>
+              <div class="layui-btn-group">
+              <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del" data-permission="account.delete_group">删除</a>
+              </div>
+            </script>
+          </div>
+        </div>
+        </div>
+    </div>
+  </div>
+
+  <script src="../../layuiadmin/layui/layui.js?t=1"></script>
+  <script>
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index' //主入口模块
+  }).use(['index', 'table'], function(){
+    var $ = layui.$;
+    var table = layui.table;
+
+    table.render({
+      elem: '#datagrid'
+      ,url: '/account/permission/'
+      ,type:'get'
+      ,cols: [[
+        {field:'name', title:'名称', width:130}
+        ,{field:'employees', title:'人员'}
+        ,{width:130, align:'left', fixed: 'right', toolbar: '#datagrid-operate-bar'}
+      ]]
+      ,page: true
+      ,height: 'full-104'
+      ,done: function () {
+        layui.index.removeNoPermButtons();
+      }
+    });
+
+    //监听工具条
+    table.on('tool(datagrid-operate)', function(obj){
+      var data = obj.data;
+        if(obj.event === 'edit'){
+        table.editdata = data;
+
+        layer.open({
+          type: 2,
+          title: '修改',
+          shadeClose: false,
+          area: ['90%', '90%'],
+          btn: ['保存', '取消'],
+          yes: function(index, dom){
+             layui.onSubmitChild = function (data) {
+              layer.close(index);
+              table.reload('datagrid',{});
+            };
+            layui.submitChild();
+          },
+          btn2: function(index, layero){
+            layer.close(index);//关闭当前按钮
+          },
+          content: 'edit.html?id='+data.id
+        });
+      }else if(obj.event === 'del') {
+            layer.confirm('确定要删除吗?', function (index) {
+              layer.close(index);
+                layui.admin.req({
+                    url: '/account/permission/'+data.id+'/'
+                    ,type: 'delete'
+                    , done: function (res) {
+                        table.reload('datagrid', {});
+                    }
+                });
+            });
+        }
+    });
+
+    $('#btn_add').on('click', function () {
+      layer.open({
+        type: 2,
+        title: '添加',
+        shadeClose: false,
+        area: ['90%', '90%'],
+        btn: ['保存', '取消'],
+        yes: function (index, dom) {
+          layui.onSubmitChild = function (data) {
+            layer.close(index);
+            table.reload('datagrid', {});
+          };
+          layui.submitChild();
+        },
+        btn2: function (index, layero) {
+          layer.close(index);//关闭当前按钮
+        },
+        content: 'edit.html'
+      });
+    });
+  });
+  </script>
+</body>
+</html>
+

+ 128 - 0
utils/booleancharfield.py

@@ -0,0 +1,128 @@
+#coding=utf-8
+
+from rest_framework import serializers
+from utils.format import strftime,strfdate
+from apps.base import Formater
+class BooleanCharField(serializers.BooleanField):
+    def get_attribute(self, obj):
+        return obj
+
+    def to_representation(self, obj):
+        if '.' in self.source:
+            k = self.source.split('.')
+            has_r = hasattr(obj, k[0])
+            if has_r:
+                r = getattr(obj, k[0])
+                if hasattr(r, k[1]):
+                    val = getattr(r, k[1])
+                else:
+                    val = self.get_attribute(obj)
+            else:
+                return u'未知'
+        else:
+            val = getattr(obj, self.source)
+        return u'是' if val else u'否'
+
+class TimeCharField(serializers.CharField):
+    def get_attribute(self, obj):
+        return obj
+
+    def to_representation(self, obj):
+        if '.' in self.source:
+            k = self.source.split('.')
+            has_r = hasattr(obj, k[0])
+            if has_r:
+                r = getattr(obj, k[0])
+                if hasattr(r, k[1]):
+                    val = getattr(r, k[1])
+                else:
+                    val = self.get_attribute(obj)
+            else:
+                return ''
+        else:
+            val = getattr(obj, self.source)
+
+        return strftime(val)
+
+class DateCharField(serializers.CharField):
+    def get_attribute(self, obj):
+        return obj
+
+    def to_representation(self, obj):
+        if '.' in self.source:
+            k = self.source.split('.')
+            has_r = hasattr(obj, k[0])
+            if has_r:
+                r = getattr(obj, k[0])
+                if hasattr(r, k[1]):
+                    val = getattr(r, k[1])
+                else:
+                    val = self.get_attribute(obj)
+            else:
+                return ''
+        else:
+            val = getattr(obj, self.source)
+        return strfdate(val)
+
+class AmountShowCharField(serializers.CharField):
+    def get_attribute(self, obj):
+        return obj
+
+    def to_representation(self, obj):
+        if '.' in self.source:
+            k = self.source.split('.')
+            has_r = hasattr(obj, k[0])
+            if has_r:
+                r = getattr(obj, k[0])
+                if hasattr(r, k[1]):
+                    val = getattr(r, k[1])
+                else:
+                    val = self.get_attribute(obj)
+            else:
+                return ''
+        else:
+            val = getattr(obj, self.source)
+
+        return Formater.formatAmountShow(val)
+
+class PriceShowCharField(serializers.CharField):
+    def get_attribute(self, obj):
+        return obj
+
+    def to_representation(self, obj):
+        if '.' in self.source:
+            k = self.source.split('.')
+            has_r = hasattr(obj, k[0])
+            if has_r:
+                r = getattr(obj, k[0])
+                if hasattr(r, k[1]):
+                    val = getattr(r, k[1])
+                else:
+                    val = self.get_attribute(obj)
+            else:
+                return ''
+        else:
+            val = getattr(obj, self.source)
+
+        return Formater.formatPriceShow(val)
+
+class CountShowCharField(serializers.CharField):
+    def get_attribute(self, obj):
+        return obj
+
+    def to_representation(self, obj):
+        if '.' in self.source:
+            k = self.source.split('.')
+            has_r = hasattr(obj, k[0])
+            if has_r:
+                r = getattr(obj, k[0])
+                if hasattr(r, k[1]):
+                    val = getattr(r, k[1])
+                else:
+                    val = self.get_attribute(obj)
+            else:
+                return ''
+        else:
+            val = getattr(obj, self.source)
+
+        return Formater.formatCountShow(val)

+ 0 - 19
utils/permission.py

@@ -11,25 +11,6 @@ class isLogin(permissions.BasePermission):
             return False
         return True
 
-class IsTenantUser(permissions.BasePermission):
-    def has_permission(self, request, view):
-        if not request.user or not request.user.is_authenticated:
-            return False
-        return request.user.is_admin()
-
-class IsEmployee(permissions.BasePermission):
-    def has_permission(self, request, view):
-        if not request.user or not request.user.is_authenticated:
-            return False
-        return request.user.is_employee()
-
-class IsAdministratorUser(permissions.BasePermission):
-    def has_permission(self, request, view):
-        if not request.user or not request.user.is_authenticated:
-            return False
-        return request.user.is_administrator()
-
-
 decorator_with_arguments = lambda decorator: lambda *args, **kwargs: lambda func: decorator(func, *args, **kwargs)
 
 @decorator_with_arguments