Jelajahi Sumber

商品分类

wushaodong 3 tahun lalu
induk
melakukan
66252bd43e

+ 8 - 0
apps/option/filters.py

@@ -36,3 +36,11 @@ class StudentFilter(django_filters.FilterSet):
     class Meta:
         model = Student
         fields = '__all__'
+
+class CommodityLevelFilter(django_filters.FilterSet):
+    name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
+    category_name = django_filters.CharFilter(field_name='category__name', lookup_expr='icontains')
+
+    class Meta:
+        model = CommodityLevel
+        fields = '__all__'

+ 13 - 4
apps/option/models.py

@@ -100,11 +100,20 @@ class Student(models.Model):
         ordering = ['-id']
 
 class CommodityLevel(models.Model):
-    name = models.CharField(verbose_name=u'名称', max_length=100, blank=True, null=True)
-    enable = models.BooleanField(verbose_name=u"是否在用", default=True)
+    ONE = 1
+    TWO = 2
+    THREE = 3
+    LEVEL_CHOICES = (
+        (ONE, u'大类'),
+        (TWO, u'品种'),
+        (THREE, u'科目'),
+    )
 
-    def __unicode__(self):
-        return '%s' % (self.name)
+    name = models.CharField(verbose_name=u'名称', max_length=50, blank=True, null=True)
+    enable = models.BooleanField(verbose_name=u"是否在用", default=True)
+    level = models.IntegerField(verbose_name=u'层级', choices=LEVEL_CHOICES)
+    category = models.ForeignKey('CommodityLevel', verbose_name='父类', related_name='commodiey_level_children', on_delete=models.PROTECT,
+                             blank=True, null=True)
 
     class Meta:
         verbose_name = u"商品级别"

+ 8 - 0
apps/option/serializers.py

@@ -81,3 +81,11 @@ class StudentSerializer(serializers.ModelSerializer):
     def update(self, instance, validated_data):
         instance = super(StudentSerializer, self).update(instance, validated_data)
         return instance
+
+class CommodityLevelSerializer(serializers.ModelSerializer):
+    enable_text = BooleanCharField(source='enable', read_only=True)
+    category_text = serializers.CharField(source='category.name', read_only=True)
+
+    class Meta:
+        model = CommodityLevel
+        fields = '__all__'

+ 3 - 0
apps/option/urls.py

@@ -6,6 +6,8 @@ from .views import *
 urlpatterns = [
     url(r'dict/$', DictView.as_view()),
     url(r'get_school/$', SchoolView.as_view()), # 学校管理
+    url(r'get_category/$', CategoryView.as_view()), # 商品分类
+    url(r'get_category_tree/$', CategoryTreeView.as_view()), # 商品分类
     url(r'school_tree/$', SchoolTreeView.as_view()),
     url(r'area_tree/$', AreaTreeView.as_view()),
 ]
@@ -15,5 +17,6 @@ router.register(r'config',ConfigViewSet)
 router.register(r'school',SchoolViewSet)
 router.register(r'grade',GradeViewSet)
 router.register(r'student',StudentViewSet)
+router.register(r'category',CategoryViewSet)
 
 urlpatterns += router.urls

+ 80 - 8
apps/option/views.py

@@ -34,6 +34,54 @@ class SchoolView(APIView):
         data = [{'value': item.id, 'name': item.name} for item in rows]
         return response_ok(data)
 
+class CategoryView(APIView):
+    permission_classes = [isLogin, ]
+
+    def get(self, request):
+        rows = CommodityLevel.objects.filter(level=CommodityLevel.ONE, enable=True)
+        data1 = [{'id': item.id, 'value': item.name} for item in rows]
+        rows2 = CommodityLevel.objects.filter(level=CommodityLevel.TWO, enable=True)
+        category = [{'id': item.id, 'value': item.name} for item in rows2]
+        result = {
+            'level':data1,
+            'category':category,
+        }
+        return response_ok(result)
+
+class AreaTreeView(APIView):
+    permission_classes = [isLogin, ]
+
+    # @cache_response()
+    def get(self, request):
+        area_data = []
+        provinces = Area.objects.filter(level=Area.PROVINCE, province_id__isnull=True).values('id', 'name')
+        for province in provinces:
+            province_item = {
+                'name': province['name'],
+                'value': province['id'],
+                'field': 'province',
+                'children': [],
+            }
+            citys = Area.objects.filter(level=Area.CITY, province_id=province['id'], city_id__isnull=True).values('id', 'name')
+            for city in citys:
+                city_item = {
+                    'name': city['name'],
+                    'value': city['id'],
+                    'field': 'city',
+                    'children': [],
+                }
+                province_item['children'].append(city_item)
+                countys = Area.objects.filter(level=Area.COUNTY, province_id=province['id'], city_id=city['id']).values('id', 'name')
+                for county in countys:
+                    county_item = {
+                        'name': county['name'],
+                        'value': county['id'],
+                        'field': 'county',
+                    }
+                    city_item['children'].append(county_item)
+            area_data.append(province_item)
+
+        return response_ok(area_data)
 
 class SchoolTreeView(APIView):
     permission_classes = [isLogin, ]
@@ -74,35 +122,35 @@ class SchoolTreeView(APIView):
 
         return response_ok(source_data)
 
-class AreaTreeView(APIView):
-    permission_classes = [isLogin, ]
+class CategoryTreeView(APIView):
+    # permission_classes = [isLogin, ]
 
     # @cache_response()
     def get(self, request):
         area_data = []
-        provinces = Area.objects.filter(level=Area.PROVINCE, province_id__isnull=True).values('id', 'name')
+        provinces = CommodityLevel.objects.filter(level=CommodityLevel.ONE, category_id__isnull=True).values('id', 'name')
         for province in provinces:
             province_item = {
                 'name': province['name'],
                 'value': province['id'],
-                'field': 'province',
+                'field': 'level',
                 'children': [],
             }
-            citys = Area.objects.filter(level=Area.CITY, province_id=province['id'], city_id__isnull=True).values('id', 'name')
+            citys = CommodityLevel.objects.filter(level=CommodityLevel.TWO, category_id=province['id']).values('id', 'name')
             for city in citys:
                 city_item = {
                     'name': city['name'],
                     'value': city['id'],
-                    'field': 'city',
+                    'field': 'category',
                     'children': [],
                 }
                 province_item['children'].append(city_item)
-                countys = Area.objects.filter(level=Area.COUNTY, province_id=province['id'], city_id=city['id']).values('id', 'name')
+                countys = CommodityLevel.objects.filter(level=CommodityLevel.THREE, category_id=city['id']).values('id', 'name')
                 for county in countys:
                     county_item = {
                         'name': county['name'],
                         'value': county['id'],
-                        'field': 'county',
+                        'field': 'subject',
                     }
                     city_item['children'].append(county_item)
             area_data.append(province_item)
@@ -264,3 +312,27 @@ class StudentViewSet(CustomModelViewSet):
         except Exception as e:
             return response_error(str(e))
 
+class CategoryViewSet(CustomModelViewSet):
+    permission_classes = [isLogin, ]
+    queryset = CommodityLevel.objects.filter()
+    serializer_class = CommodityLevelSerializer
+
+    def filter_queryset(self, queryset):
+        queryset = queryset.filter()
+        f = CommodityLevelFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+    def perform_create(self, serializer):
+        super(CategoryViewSet, 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)
+
+    def perform_update(self, serializer):
+        super(CategoryViewSet, 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)
+

+ 512 - 0
uis/views/commodity/category.html

@@ -0,0 +1,512 @@
+<!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">
+    <style type="text/css">
+        .seach_items {
+            float: right;
+            margin-left: 10px;
+        }
+    </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-md4">
+                    <div class="LAY-btns" style="margin-bottom: 10px;">
+                        <div class="layui-col-xs2">
+                            <button class="layui-btn" id="level_add"><i
+                                    class="layui-icon layui-icon-add-circle"></i>添加大类
+                            </button>
+                        </div>
+                        <form class="layui-form" lay-filter="query-form-element1">
+                            <div class="seach_items">
+                                <button class="layui-btn" lay-submit lay-filter="query-form-element1"><i
+                                        class="layui-icon layui-icon-search"></i>查询
+                                </button>
+                            </div>
+                            <div class="seach_items">
+                                <input type="text" name="name" autocomplete="off" class="layui-input"
+                                       placeholder="大类名称"/>
+                            </div>
+                        </form>
+                        <div style="clear: both;"></div>
+                    </div>
+                    <table class="layui-hide" id="level_datagrid" lay-filter="level-operate"></table>
+
+                    <script type="text/html" id="level-operate-bar">
+                        <div class="layui-btn-group">
+                            <a class="layui-btn layui-btn-xs" lay-event="level_edit"
+                            >修改</a>
+                        </div>
+                    </script>
+                </div>
+
+                <div class="layui-col-md4">
+                    <div class="LAY-btns" style="margin-bottom: 10px;">
+                        <div class="layui-col-xs2">
+                            <button class="layui-btn" id="category_add"><i
+                                    class="layui-icon layui-icon-add-circle"></i>添加品种
+                            </button>
+                        </div>
+
+                        <form class="layui-form" lay-filter="query-form-element2">
+                            <div class="seach_items">
+                                <button class="layui-btn" lay-submit lay-filter="query-form-element2"><i
+                                        class="layui-icon layui-icon-search"></i>查询
+                                </button>
+                            </div>
+                            <div class="seach_items">
+                                <input type="text" name="category_name" autocomplete="off" class="layui-input"
+                                       placeholder="大类名称"/>
+                            </div>
+                        </form>
+                        <div style="clear: both;"></div>
+                    </div>
+
+                    <table class="layui-hide" id="category_datagrid" lay-filter="category-operate"></table>
+
+                    <script type="text/html" id="category-operate-bar">
+                        <div class="layui-btn-group">
+                            <a class="layui-btn layui-btn-xs" lay-event="category_edit"
+                            >修改</a>
+                        </div>
+                    </script>
+                </div>
+
+                <div class="layui-col-md4">
+                    <div class="LAY-btns" style="margin-bottom: 10px;">
+                        <div class="layui-col-xs2">
+                            <button class="layui-btn" id="subject_add"><i
+                                    class="layui-icon layui-icon-add-circle"></i>添加科目
+                            </button>
+                        </div>
+
+                        <form class="layui-form" lay-filter="query-form-element3">
+                            <div class="seach_items">
+                                <button class="layui-btn" lay-submit lay-filter="query-form-element3"><i
+                                        class="layui-icon layui-icon-search"></i>查询
+                                </button>
+                            </div>
+                            <div class="seach_items">
+                                <input type="text" name="category_name" autocomplete="off" class="layui-input"
+                                       placeholder="品种名称"/>
+                            </div>
+                        </form>
+                        <div style="clear: both;"></div>
+                    </div>
+
+                    <table class="layui-hide" id="subject_datagrid" lay-filter="subject-operate"></table>
+
+                    <script type="text/html" id="subject-operate-bar">
+                        <div class="layui-btn-group">
+                            <a class="layui-btn layui-btn-xs" lay-event="subject_edit"
+                            >修改</a>
+                        </div>
+                    </script>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div id="id_level" style="display: none">
+    <div class="layui-card-body" pad15>
+        <form class="layui-form" lay-filter="form-level">
+            <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">是否在用:</label>
+                    <div class="layui-input-block">
+                        <input type="checkbox" name="enable" lay-skin="switch" lay-text="是|否" checked=""
+                               value="1">
+                    </div>
+                </div>
+                <div class="layui-form-item" style="text-align:right">
+                    <button class="layui-btn" lay-submit id="level_btn" lay-filter="form-level"
+                            style="display: none">保存
+                    </button>
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+
+<div id="id_category" style="display: none">
+    <div class="layui-card-body" pad15>
+        <form class="layui-form" lay-filter="form-category">
+            <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_category_select" name="category" lay-verify="required">
+                        </select>
+                    </div>
+                </div>
+                <div>
+                    <label class="layui-form-label"><font color='red' size="4">*</font>品种名称:</label>
+                    <div class="layui-input-block">
+                        <input type="text" name="name" lay-verify="required" placeholder="请输入名称"
+                               autocomplete="off" class="layui-input">
+                    </div>
+                </div>
+
+                <div>
+                    <label class="layui-form-label">是否在用:</label>
+                    <div class="layui-input-block">
+                        <input type="checkbox" name="enable" lay-skin="switch" lay-text="是|否" checked=""
+                               value="1">
+                    </div>
+                </div>
+                <div class="layui-form-item" style="text-align:right">
+                    <button class="layui-btn" lay-submit id="category_btn" lay-filter="form-category"
+                            style="display: none">保存
+                    </button>
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+
+<div id="id_subject" style="display: none">
+    <div class="layui-card-body" pad15>
+        <form class="layui-form" lay-filter="form-subject">
+            <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_subject_select" name="category" lay-verify="required">
+                        </select>
+                    </div>
+                </div>
+                <div>
+                    <label class="layui-form-label"><font color='red' size="4">*</font>科目名称:</label>
+                    <div class="layui-input-block">
+                        <input type="text" name="name" lay-verify="required" placeholder="请输入名称"
+                               autocomplete="off" class="layui-input">
+                    </div>
+                </div>
+
+                <div>
+                    <label class="layui-form-label">是否在用:</label>
+                    <div class="layui-input-block">
+                        <input type="checkbox" name="enable" lay-skin="switch" lay-text="是|否" checked=""
+                               value="1">
+                    </div>
+                </div>
+                <div class="layui-form-item" style="text-align:right">
+                    <button class="layui-btn" lay-submit id="subject_btn" lay-filter="form-subject"
+                            style="display: none">保存
+                    </button>
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+
+<script src="../../layuiadmin/layui/layui.js?t=1"></script>
+<script>
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index' //主入口模块
+    }).use(['index', 'table', 'form'], function () {
+        var $ = layui.$;
+        var table = layui.table
+            , form = layui.form
+            , admin = layui.admin;
+        admin.req({
+            url: '/option/get_category/',
+            done: function (res) {
+                var level = res.data.level;
+                var level_node = $('#id_category_select');
+                for (var i in level) {
+                    var pid = level[i].id;
+                    var value = level[i].value;
+                    level_node.append("<option value='" + pid + "'>" + value + "</option>");
+                }
+                var category = res.data.category;
+                var category_node = $('#id_subject_select');
+                for (var i in category) {
+                    var pid = category[i].id;
+                    var value = category[i].value;
+                    category_node.append("<option value='" + pid + "'>" + value + "</option>");
+                }
+                form.render();
+            }
+        });
+
+        // 大类级别
+        table.render({
+            elem: '#level_datagrid'
+            , url: '/option/category/?level=1'
+            , cols: [[
+                {field: 'name', title: '名称', width: 150}
+                , {field: 'enable_text', title: '在用', width: 80}
+                , {width: 110, align: 'center', fixed: 'right', toolbar: '#level-operate-bar'}
+            ]]
+            , page: true
+            , height: 'full-108'
+            , done: function () {
+                layui.index.removeNoPermButtons()
+            }
+        });
+        // 品种
+        table.render({
+            elem: '#category_datagrid'
+            , url:  '/option/category/?level=2'
+            , cols: [[
+                {field: 'name', title: '名称', width: 150}
+                , {field: 'category_text', title: '大类', width: 150}
+                , {field: 'enable_text', title: '在用', width: 80}
+                , {width: 110, align: 'center', fixed: 'right', toolbar: '#category-operate-bar'}
+            ]]
+            , page: true
+            , height: 'full-108'
+            , done: function () {
+                layui.index.removeNoPermButtons()
+            }
+        });
+        // 科目
+        table.render({
+            elem: '#subject_datagrid'
+            , url:  '/option/category/?level=3'
+            , cols: [[
+                {field: 'name', title: '名称', width: 150}
+                , {field: 'category_text', title: '品种', width: 150}
+                , {field: 'enable_text', title: '在用', width: 80}
+                , {width: 110, align: 'center', fixed: 'right', toolbar: '#subject-operate-bar'}
+            ]]
+            , page: true
+            , height: 'full-108'
+            , done: function () {
+                layui.index.removeNoPermButtons()
+            }
+        });
+
+        var level_id = '', category_id = '', subject_id = ''
+        //级别大类
+        table.on('tool(level-operate)', function (obj) {
+            // table.editdata = obj.data;
+            form.val("form-level", obj.data);
+            level_id = obj.data.id
+            if (obj.event === 'level_edit') {
+                layer.open({
+                    type: 1,
+                    title: '编辑大类',
+                    area: ['40%', '60%'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        $('#level_btn').click();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: $('#id_level')
+                });
+            }
+        });
+        form.on('submit(form-level)', function (data) {
+            data.field.level = 1
+            if (level_id) {
+                var url = '/option/category/' + level_id + '/'
+                var type = 'put'
+            } else {
+                var url = '/option/category/'
+                var type = 'post'
+            }
+            admin.req({
+                url: url
+                , data: data.field
+                , type: type
+                , done: function (res) {
+                    layer.closeAll();
+                    table.reload('level_datagrid', {});
+                }
+            });
+            return false;
+        });
+        //品种
+        table.on('tool(category-operate)', function (obj) {
+            form.val("form-category", obj.data);
+            category_id = obj.data.id
+            if (obj.event === 'category_edit') {
+                layer.open({
+                    type: 1,
+                    title: '编辑品种',
+                    area: ['40%', '60%'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        $('#category_btn').click();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: $('#id_category')
+                });
+            }
+        });
+        form.on('submit(form-category)', function (data) {
+            data.field.level = 2
+            if (category_id) {
+                var url = '/option/category/' + category_id + '/'
+                var type = 'put'
+            } else {
+                var url = '/option/category/'
+                var type = 'post'
+            }
+            admin.req({
+                url: url
+                , data: data.field
+                , type: type
+                , done: function (res) {
+                    layer.closeAll();
+                    table.reload('category_datagrid');
+                }
+            });
+            return false;
+        });
+        // 科目
+        table.on('tool(subject-operate)', function (obj) {
+            form.val("form-subject", obj.data);
+            subject_id = obj.data.id
+            if (obj.event === 'subject_edit') {
+                layer.open({
+                    type: 1,
+                    title: '编辑科目',
+                    area: ['40%', '60%'],
+                    btn: ['保存', '取消'],
+                    yes: function (index, dom) {
+                        $('#subject_btn').click();
+                    },
+                    btn2: function (index, layero) {
+                        layer.close(index);//关闭当前按钮
+                    },
+                    content: $('#id_subject')
+                });
+            }
+        });
+        form.on('submit(form-subject)', function (data) {
+            data.field.level = 3
+            if (subject_id) {
+                var url = '/option/category/' + subject_id + '/'
+                var type = 'put'
+            } else {
+                var url = '/option/category/'
+                var type = 'post'
+            }
+            admin.req({
+                url: url
+                , data: data.field
+                , type: type
+                , done: function (res) {
+                    layer.closeAll();
+                    table.reload('subject_datagrid', {});
+                }
+            });
+            return false;
+        });
+
+        form.on('submit(query-form-element1)', function (data) {
+            data.field.level=1
+            table.reload('level_datagrid', {
+                where: data.field
+                , page: {curr: 1}
+            });
+            layer.closeAll();
+            return false
+        });
+
+        form.on('submit(query-form-element2)', function (data) {
+            data.field.level=2
+            table.reload('category_datagrid', {
+                where: data.field
+                , page: {curr: 1}
+            });
+            layer.closeAll();
+            return false
+        });
+
+        form.on('submit(query-form-element3)', function (data) {
+            data.field.level=3
+            table.reload('subject_datagrid', {
+                where: data.field
+                , page: {curr: 1}
+            });
+            layer.closeAll();
+            return false
+        });
+        $('#level_add').on('click', function () {
+            form.render(null, 'form-level');
+            layer.open({
+                type: 1,
+                title: '编辑大类',
+                area: ['40%', '60%'],
+                btn: ['保存', '取消'],
+                yes: function (index, dom) {
+                    $('#level_btn').click();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: $('#id_level')
+            });
+        });
+        $('#category_add').on('click', function () {
+            form.val('form-category', {});
+            layer.open({
+                type: 1,
+                title: '添加品种',
+                area: ['40%', '60%'],
+                btn: ['保存', '取消'],
+                yes: function (index, dom) {
+                    $('#category_btn').click();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: $('#id_category')
+            });
+
+        });
+        $('#subject_add').on('click', function () {
+            form.render(null, 'form-subject');
+            layer.open({
+                type: 1,
+                title: '添加科目',
+                area: ['40%', '60%'],
+                btn: ['保存', '取消'],
+                yes: function (index, dom) {
+                    $('#subject_btn').click();
+                },
+                btn2: function (index, layero) {
+                    layer.close(index);//关闭当前按钮
+                },
+                content: $('#id_subject')
+            });
+
+        });
+    });
+
+</script>
+</body>
+</html>

+ 3 - 0
uis/views/index.html

@@ -88,6 +88,9 @@
                             <dd data-name="nav">
                                 <a lay-href="option/student.html">学生信息</a>
                             </dd>
+                            <dd data-name="nav">
+                                <a lay-href="commodity/category.html">商品分类</a>
+                            </dd>
                             <dd data-name="nav">
                                 <a lay-href="commodity/index.html">商品管理</a>
                             </dd>