소스 검색

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	apps/base.py
#	shop/settings.py
#	shop/urls.py
#	uis/views/index.html
wushaodong 1 년 전
부모
커밋
6f163099f8

+ 1 - 0
.gitignore

@@ -24,3 +24,4 @@ yarn-error.log*
 *.bat
 /venv
 *.whl
+/uis/up

+ 2 - 50
apps/base.py

@@ -1,61 +1,13 @@
-#coding=utf-8
+# coding=utf-8
 
-class Formater():
-    @staticmethod
-    def formatStr(value):
-        res = u''
-        if value != None:
-            try:
-                res = unicode(value)
-            except:
-                pass
-        return res
 
-    @staticmethod
-    def formatCount(value):
-        return int(round(float(value or 0) * 100,0))
+class Formater(object):
 
     @staticmethod
     def formatPrice(value):
         return int(round(float(value or 0) * 100,0))
 
-    @staticmethod
-    def formatCountShow(value):
-        return '%.2f' % (float(value or 0)/100.0)
-
     @staticmethod
     def formatPriceShow(value):
         return '%.2f' % (float(value or 0)/100.0)
 
-    @staticmethod
-    def formatAmount(value):
-        return int(round(float(value or 0) * 10000,0))
-
-    @staticmethod
-    def formatAmountShow(value):
-        return '%.2f' % (float(value or 0) / 10000.0 + 0.0000001)
-
-class CustomFormaterByUser():
-    @staticmethod
-    def formatEmptyStr(value,user):
-        return Formater.formatEmptyStr(value)
-
-    @staticmethod
-    def formatEmptyFloat(value, user):
-        #return round(value or 0, 2)
-        return Formater.formatEmptyFloat(value)
-
-    @staticmethod
-    def formatTime(value,user):
-        return Formater.formatTime(value)
-
-    @staticmethod
-    def formatDate(value, user):
-        return Formater.formatDate(value)
-
-    @staticmethod
-    def formatCountShow(value,user):
-        return Formater.formatCountShow(value)
-    @staticmethod
-    def formatPartAmountShow(value, user):
-        return Formater.formatAmountShow(value)

+ 2 - 0
apps/foundation/models.py

@@ -12,10 +12,12 @@ from utils.format import strftime, strfdate
 class Option(models.Model):
     USED_VEHICLE_BRAND = 0
     MAINT_TYPE = 1
+    PRODUCT_CATEGORY = 2
 
     TYPE_CHOICES = (
         (USED_VEHICLE_BRAND, u'二手车品牌'),
         (MAINT_TYPE, u'服务类型'),
+        (PRODUCT_CATEGORY, u'商品类别'),
     )
 
     type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=u"类别")

+ 8 - 1
apps/images/models.py

@@ -55,7 +55,8 @@ class ImagesManager(models.Manager):
         path_map = {
             Images.USEDVEHICLE_FILE: usedvehicle_file,
             Images.USEDVEHICLE_THUMBNAIL: usedvehicle_thumbnail_file,
-
+            Images.PRODUCT_COVER: product_cover,
+            Images.PRODUCT_FILE: product_file,
         }
 
         return path_map[type] + str(user_id) + '/'
@@ -73,13 +74,19 @@ class ImagesManager(models.Manager):
 
 usedvehicle_file = "usedvehicle/detail/"
 usedvehicle_thumbnail_file = "usedvehicle/"
+product_file = "product/file/"
+product_cover = "product/"
 
 class Images(models.Model):
     USEDVEHICLE_FILE = 1
     USEDVEHICLE_THUMBNAIL = 2
+    PRODUCT_COVER = 3
+    PRODUCT_FILE = 4
     TYPE_CHOICES = (
         (USEDVEHICLE_FILE, u'二手车图片'),
         (USEDVEHICLE_THUMBNAIL, u'二手车缩略图'),
+        (PRODUCT_COVER, u'商品封面图'),
+        (PRODUCT_FILE, u'商品图片'),
     )
 
     user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'操作人', on_delete=models.PROTECT)

+ 0 - 0
apps/product/__init__.py


+ 20 - 0
apps/product/filters.py

@@ -0,0 +1,20 @@
+# coding=utf-8
+
+import django_filters
+
+from .models import Product, ProductImg
+
+
+class ProductFilter(django_filters.FilterSet):
+    name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
+
+    class Meta:
+        model = Product
+        fields = '__all__'
+
+
+class ProductImageFilter(django_filters.FilterSet):
+
+    class Meta:
+        model = ProductImg
+        fields = '__all__'

+ 38 - 0
apps/product/models.py

@@ -0,0 +1,38 @@
+# coding=utf-8
+
+from django.db import models
+from django.conf import settings
+
+from apps.foundation.models import Option
+from apps.images.models import Images
+
+
+class Product(models.Model):
+    category = models.ForeignKey(Option, verbose_name=u'类别', on_delete=models.PROTECT)
+    name = models.CharField(max_length=255, verbose_name=u"名称")
+    describe = models.CharField(verbose_name=u'介绍', max_length=500, null=True, blank=True)
+    price = models.BigIntegerField(verbose_name=u'价格', default=0)
+    enabled = models.BooleanField(verbose_name=u"在用", default=True)
+    cover = models.ForeignKey(Images, verbose_name=u'封面图', on_delete=models.PROTECT, related_name=u'product_thumbnail', null=True)
+    notes = models.CharField(max_length=500, verbose_name=u"备注", blank=True, null=True)
+
+    create_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'创建人', editable=False, on_delete=models.PROTECT)
+    create_time = models.DateTimeField(verbose_name=u"添加时间", auto_now_add=True, editable=False)
+
+    is_deleted = models.BooleanField(verbose_name="删除", default=False)
+
+    class Meta:
+        db_table = "product"
+        verbose_name = u"商品"
+        ordering = ('-id',)
+        default_permissions = ()
+
+
+class ProductImg(models.Model):
+    product = models.ForeignKey(Product, verbose_name=u'商品', on_delete=models.PROTECT)
+    img = models.ForeignKey(Images, verbose_name=u'图片', on_delete=models.PROTECT)
+
+    class Meta:
+        db_table = 'product_img'
+        verbose_name = u'商品图片'
+        default_permissions = ()

+ 73 - 0
apps/product/serializers.py

@@ -0,0 +1,73 @@
+# coding=utf-8
+
+from django.conf import settings
+
+from rest_framework import serializers
+
+from utils.exceptions import CustomError
+
+from apps.base import Formater
+from apps.images.models import Images
+
+from .models import Product, ProductImg
+
+
+class ProductSerializer(serializers.ModelSerializer):
+    category_t = serializers.CharField(source='category.name', read_only=True)
+    price_f = serializers.SerializerMethodField()
+    enabled_t = serializers.SerializerMethodField()
+    create_user_t = serializers.CharField(source='create_user.name', read_only=True)
+    cover_url = serializers.SerializerMethodField()
+
+    def get_cover_url(self, obj):
+        if obj.cover:
+            return '{}{}'.format(settings.MEDIA_URL, obj.cover.picture)
+        return ''
+
+    def get_enabled_t(self, obj):
+        if obj.enabled:
+            return u"是"
+        return u"否"
+
+    def get_price_f(self, obj):
+        return Formater.formatPriceShow(obj.price)
+
+    class Meta:
+        model = Product
+        fields = '__all__'
+
+    def validate(self, attrs):
+        if 'price' in attrs:
+            attrs['price'] = Formater.formatPrice(attrs['price'])
+        return attrs
+
+    def create(self, validated_data):
+        validated_data['create_user'] = self.context['request'].user
+        cover = self.initial_data.get('image', None)
+        if not cover:
+            raise CustomError(u'商品封面图是必填项!')
+        validated_data['cover'] = Images.objects.employee_addnew(validated_data['create_user'], Images.PRODUCT_COVER, cover)
+        instance = super(ProductSerializer, self).create(validated_data)
+        return instance
+
+    def update(self, instance, validated_data):
+        old_cover = None
+        cover = self.initial_data.get('image', None)
+        if cover:
+            old_cover = instance.cover
+            validated_data['cover'] = Images.objects.employee_addnew(self.context['request'].user, Images.PRODUCT_COVER, cover)
+        instance = super(ProductSerializer, self).update(instance, validated_data)
+        if old_cover:
+            old_cover.del_images()
+        return instance
+
+
+class ProductImgSerializer(serializers.ModelSerializer):
+    img_url = serializers.SerializerMethodField()
+
+    def get_img_url(self, obj):
+        return '{}{}'.format(settings.MEDIA_URL, obj.img.picture)
+
+    class Meta:
+        model = ProductImg
+        fields = '__all__'

+ 15 - 0
apps/product/urls.py

@@ -0,0 +1,15 @@
+# coding=utf-8
+
+from django.conf.urls import url, include
+from rest_framework.routers import SimpleRouter
+
+from .views import *
+
+urlpatterns = [
+
+]
+
+router = SimpleRouter()
+router.register(r'images', ProductImageViewSet)
+router.register(r'', ProductViewSet)
+urlpatterns += router.urls

+ 86 - 0
apps/product/views.py

@@ -0,0 +1,86 @@
+# coding=utf-8
+
+from django.db import transaction
+
+from rest_framework.decorators import action
+
+from utils import response_ok
+from utils.custom_modelviewset import CustomModelViewSet
+
+from apps.foundation.models import BizLog
+from apps.account import tenant_log
+
+from .filters import *
+from .serializers import *
+from .models import *
+
+
+class ProductViewSet(CustomModelViewSet):
+    queryset = Product.objects.filter(is_deleted=False)
+    serializer_class = ProductSerializer
+
+    def filter_queryset(self, queryset):
+        queryset = queryset.filter()
+        f = ProductFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+    def perform_create(self, serializer):
+        super(ProductViewSet, self).perform_create(serializer)
+        instance = serializer.instance
+        validated_data = serializer.validated_data
+        tenant_log(self.request.user, BizLog.INSERT, u'添加商品[%s],id=%d' % (instance.name, instance.id), validated_data)
+
+    @action(methods=['post'], detail=True)
+    def update_obj(self, request, pk):
+        '''由于layui上传文件使用的是post方法,且不能改为put方法,所以不能通过重写update来实现更新实例'''
+        obj = self.get_object()
+        with transaction.atomic():
+            serializer = self.get_serializer(obj, data=request.data)
+            serializer.is_valid(raise_exception=True)
+            self.perform_update(serializer)
+            instance = serializer.instance
+            validated_data = serializer.validated_data
+            tenant_log(self.request.user, BizLog.UPDATE, u'修改商品[%s],id=%d' % (instance.name, instance.id), validated_data)
+        return response_ok()
+
+    def destroy(self, request, *args, **kwargs):
+        with transaction.atomic():
+            instance = self.get_object()
+            tenant_log(self.request.user, BizLog.DELETE, u'删除商品[%s],id=%d' % (instance.name, instance.id))
+            instance.is_deleted = True
+            instance.save()
+        return response_ok()
+
+    @action(methods=['post'], detail=True)
+    def upload_images(self, request, pk):
+        instance = self.get_object()
+        images = request.FILES.get('images', None)
+
+        with transaction.atomic():
+            image = Images.objects.employee_addnew(self.request.user, Images.PRODUCT_FILE, images)
+            ProductImg.objects.create(product=instance, img=image)
+            tenant_log(self.request.user, BizLog.INSERT, u'商品[%s]上传图片儿,id=%d' % (instance.name, instance.id))
+        return response_ok()
+
+
+class ProductImageViewSet(CustomModelViewSet):
+    queryset = ProductImg.objects.filter()
+    serializer_class = ProductImgSerializer
+
+    def filter_queryset(self, queryset):
+        f = ProductImageFilter(self.request.GET, queryset=queryset)
+        return f.qs
+
+    def list(self, request, *args, **kwargs):
+        queryset = self.filter_queryset(self.get_queryset())
+        serializer = self.get_serializer(queryset, many=True)
+        return response_ok(serializer.data)
+
+    def destroy(self, request, *args, **kwargs):
+        with transaction.atomic():
+            instance = self.get_object()
+            tenant_log(self.request.user, BizLog.DELETE, u'删除商品[%s]图片,id=%d' % (instance.product.name, instance.product.id))
+            img = instance.img
+            instance.delete()
+            img.del_images()
+        return response_ok()

+ 2 - 0
shop/settings.py

@@ -48,6 +48,8 @@ INSTALLED_APPS = [
     'apps.usedvehicle',
     'apps.images',
     'apps.vehicle',
+    'apps.product',
+    # 'apps.shop',
     # 'apps.employee',
     # 'apps.option',
     # 'apps.package',

+ 1 - 0
shop/urls.py

@@ -27,6 +27,7 @@ urlpatterns = [
     url(r'^foundation/', include('apps.foundation.urls')),
     url(r'^usedvehicle/', include('apps.usedvehicle.urls')),
     url(r'^vehicle/', include('apps.vehicle.urls')),
+    url(r'^product/', include('apps.product.urls')),
     # url(r'^customer/', include('apps.customer.urls')),
     # url(r'^api/', include('apps.api.urls')),
 ]

+ 3 - 0
uis/views/index.html

@@ -144,6 +144,9 @@
                             <dd data-name="nav">
                                 <a lay-href="usedvehicle/index.html">二手车档案</a>
                             </dd>
+                            <dd data-name="nav">
+                                <a lay-href="product/index.html">商品管理</a>
+                            </dd>
                             <dd data-name="nav">
                                 <a lay-href="option/index.html">系统选项</a>
                             </dd>

+ 110 - 0
uis/views/product/details.html

@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+<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-tab layui-tab-card">
+                   <ul class="layui-tab-title">
+                       <li class="layui-this">商品信息</li>
+                       <li>商品图片</li>
+                   </ul>
+                   <div class="layui-tab-content">
+                       <div class="layui-tab-item layui-show">
+                           <table class="layui-table">
+                               <tr>
+                                   <th style="width: 80px;">商品类别</th>
+                                   <td id="category_t" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>商品名称</th>
+                                   <td id="name" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>价格</th>
+                                   <td id="price_f" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>在用</th>
+                                   <td id="enabled_t" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>简介</th>
+                                   <td id="describe" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>备注</th>
+                                   <td id="notes" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>添加人</th>
+                                   <td id="create_user_t" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>添加时间</th>
+                                   <td id="create_time" class="cell"></td>
+                               </tr>
+                               <tr>
+                                   <th>封面图</th>
+                                   <td>
+                                       <a id="cover_a" href="#" target="">
+                                       <img class="layui-upload-img" id="cover_url" target="_blank" style="max-height: 250px;">
+                                       </a>
+                                   </td>
+                               </tr>
+
+                           </table>
+                       </div>
+                       <div class="layui-tab-item">
+                           <div class="layui-upload-list" id="images" style="display: flex;flex-wrap: wrap;">
+                           </div>
+                       </div>
+                   </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','laydate', 'utils'], function () {
+            var $ = layui.$;
+            var admin = layui.admin;
+
+            var id = layui.view.getParameterByName('id');
+            var editdata = JSON.parse(JSON.stringify(parent.layui.table.editdata));
+            $('#cover_url').attr('src', editdata.cover_url);
+            $('#cover_a').attr('href', editdata.cover_url);
+            $('#cover_a').attr('target', '_blank');
+            $('.cell').each(function (index, element) {
+                element.innerHTML =  (editdata[element.id])
+            });
+
+            admin.req({
+                 url: '/product/images/?product=' + id,
+                done: function (res) {
+                   $('#images').html('');
+                   var data = res.data;
+                   for (var i in data){
+                       var html = '<div style="margin-top: 10px;"><a href="'+data[i].img_url+'" target="_blank"><img src="'+ data[i].img_url +'" class="layui-upload-img" style="margin-left: 5px;min-width: 80px; height: 100px;max-width: 200px;"></a></div>';
+                        $('#images').append(html)
+                   }
+                }
+             });
+        })
+    </script>
+</body>
+</html>

+ 200 - 0
uis/views/product/edit.html

@@ -0,0 +1,200 @@
+<!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"/>
+    <link rel="stylesheet" type="text/css" href="../../layuiadmin/layui/ueditor/themes/default/css/umeditor.css"/>
+    <script type="text/javascript" src="../../layuiadmin/layui/ueditor/third-party/jquery.min.js"></script>
+    <script type="text/javascript" charset="utf-8" src="../../layuiadmin/layui/ueditor/umeditor.config.js"></script>
+    <script type="text/javascript" charset="utf-8" src="../../layuiadmin/layui/ueditor/umeditor.js"></script>
+    <script type="text/javascript" src="../../layuiadmin/layui/ueditor/lang/zh-cn/zh-cn.js"></script>
+</head>
+<style>
+
+
+</style>
+<body>
+
+<div class="layui-fluid">
+    <div class="layui-card">
+
+        <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_category" 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"><font color='red' size="4">*</font>价格:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="price_f" lay-verify="required|numberGtZ" placeholder="请输入价格" autocomplete="off" class="layui-input">
+                        </div>
+                    </div>
+                    <div >
+                        <label class="layui-form-label">在用:</label>
+                        <div class="layui-input-block">
+                            <input type="checkbox" name="enabled" lay-skin="switch" lay-text="是|否" checked="" value="1">
+                        </div>
+                    </div>
+                    <div>
+                        <label class="layui-form-label">简介:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="describe" placeholder="请输入简介" autocomplete="off" class="layui-input">
+                        </div>
+                    </div>
+                    <div>
+                        <label class="layui-form-label">备注:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="notes" placeholder="请输入备注" autocomplete="off" class="layui-input">
+                        </div>
+                    </div>
+                    <div>
+                        <label class="layui-form-label"><font color='red' size="4">*</font>封面图:</label>
+                        <div class="layui-input-block">
+                            <button type="button" class="layui-btn-sm" id="test1">上传图片</button><br><br>
+                            <img class="layui-upload-img" id="demo1" style="max-height: 250px;max-width: 300px;">
+                        </div>
+                    </div>
+                    <button class="layui-btn" id="id_save" lay-submit lay-filter="component-form-element" style="display: none">保存</button>
+                    <button class="layui-btn" type="button" id="upload_image" style="display: none"></button>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
+
+
+<script src="../../layuiadmin/layui/layui.js"></script>
+<script type="text/javascript">
+    layui.config({
+        base: '../../../layuiadmin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index',
+        formSelects: 'formSelects-v4'
+    }).use(['index', 'form', 'utils', 'upload'], function(){
+        var $ = layui.$
+            ,admin = layui.admin
+            ,upload = layui.upload
+            ,form = layui.form;
+
+        var id = layui.view.getParameterByName('id');
+
+        admin.req({
+            url: '/foundation/option/?type=2',
+            done: function (res) {
+                var categorys = res.data;
+                var category_node = $('#id_category');
+                for (var i in categorys) {
+                    var pid = categorys[i].id;
+                    var value = categorys[i].name;
+                    category_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(editdata.cover_url){
+                    $('#demo1').attr('src', editdata.cover_url);
+                }
+            }
+        };
+
+
+        form.render(null, 'component-form-element');
+
+        var form_data = {field:{}};
+        if (id){
+            var url = '/product/' +id + '/update_obj/';
+        }else{
+            url =  '/product/';
+        }
+        upload.render({
+            elem: '#test1',
+            url: url,
+            auto: false,
+            field: 'image',
+            bindAction: '#upload_image',
+            choose: function(obj) {
+                obj.preview(
+                    function(index, file, result) {
+                        $('#demo1').attr('src', result);
+                    }
+                );
+            },
+            data:{
+                category: function() {return form_data.field.category},
+                name: function(){return form_data.field.name;},
+                price: function(){return form_data.field.price_f;},
+                enabled: function(){
+                    if (form_data.field.enabled){
+                        return form_data.field.enabled;
+                    }else{
+                        return '0';
+                    }
+                },
+                describe: function(){return form_data.field.describe;},
+                notes: function(){return form_data.field.notes;}
+            },
+            done: function (res) {
+                if (res.code !== 0) {
+                    layer.msg(res.msg);
+                }else {
+                    parent.layui.onSubmitChild(res.data);
+                }
+            },
+            error: function () {
+                layer.msg('保存失败');
+            }
+        });
+
+        form.on('submit(component-form-element)', function (data) {
+            if (!id && !data.field.image) {
+                layer.msg('商品封面图片是必填项',{icon: 5});
+                return false;
+            }
+            if (data.field.image){
+                form_data = data;
+                $('#upload_image').click();
+            } else {
+                var save_data = data.field;
+                save_data['price'] = data.field.price_f;
+                admin.req({
+                    url: url
+                    ,data: save_data
+                    ,type: 'post'
+                    ,done: function(res){
+                        parent.layui.onSubmitChild(res.data);
+                    }
+                });
+            }
+            return false;
+        });
+
+        parent.layui.submitChild = function () {
+            $("#id_save").click();
+        };
+    });
+</script>
+</body>
+</html>

+ 205 - 0
uis/views/product/index.html

@@ -0,0 +1,205 @@
+<!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">
+    .LAY-btns .layui-nav {padding-left:0;padding-right:10px;top:-4px;margin: 0 10px;border: 0;background-color: #009688;}
+    .LAY-btns .layui-nav .layui-nav-item{line-height: 30px;}
+    .LAY-btns .layui-nav .layui-nav-child{top:34px;}
+    .LAY-btns .layui-nav .layui-nav-bar{display: none;}
+    .LAY-btns .layui-nav .layui-nav-child dd.layui-this a{color:#333;background-color:#fff;}
+    .LAY-btns .layui-nav .layui-nav-child dd.layui-this a:hover {background-color: #f2f2f2;color: #000;}
+    .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-md12">
+            <div class="LAY-btns" style="margin-bottom: 10px;">
+                <div class="layui-col-xs2">
+                    <button class="layui-btn" id="btn_add"><i class="layui-icon layui-icon-add-circle"></i>添加</button>
+                </div>
+                <form class="layui-form" lay-filter="query-form-element">
+                    <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>
+                    <div class="seach_items">
+                        <select name="category" id="seach_category">
+                            <option value="">请选择商品类别</option>
+                        </select>
+                    </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="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="detail">查看</a>
+                    <a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="edit">修改</a>
+                    <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="upload">上传图片</a>
+                    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</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.$
+        ,admin = layui.admin
+        ,table = layui.table
+        ,form = layui.form;
+
+    admin.req({
+        url: '/foundation/option/?type=2',
+        done: function (res) {
+            var categorys = res.data;
+            var category_node = $('#seach_category');
+            for (var i in categorys) {
+                var pid = categorys[i].id;
+                var value = categorys[i].name;
+                category_node.append("<option value='" + pid + "'>" + value + "</option>");
+            }
+            form.render();
+        }
+    });
+
+    table.render({
+      elem: '#datagrid'
+      ,url: '/product/'
+      ,cols: [[
+       {field:'category_t', title:'类别',width: 120}
+       ,{field:'name', title:'名称',width: 200}
+       ,{field:'price_f', align: 'right', title:'价格',width: 100}
+       ,{field:'describe', title:'简介',width: 300}
+       ,{field:'enabled_t', title:'在用',width: 70}
+       ,{field:'notes', title:'备注',width: 300}
+       ,{field:'create_user_t', title:'添加人',width: 100}
+       ,{field:'create_time', title:'添加时间',width: 170}
+        ,{width: 200, align:'center', fixed: 'right', toolbar: '#datagrid-operate-bar'}
+      ]]
+      ,page: true
+      ,height: 'full-108'
+      , done: function () {
+        layui.index.removeNoPermButtons()
+      }
+    });
+    form.on('submit(query-form-element)', function(data){
+      //layer.msg(JSON.stringify(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;
+      table.editdata = data;
+        if(obj.event === 'edit'){
+        layer.open({
+          type: 2,
+          title: '修改',
+          shadeClose: false,
+          area: ['50%', '70%'],
+          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 === 'detail'){
+        layer.open({
+          type: 2,
+          title: '查看',
+          shadeClose: true,
+          area: ['60%', '90%'],
+          content: 'details.html?id='+data.id
+        });
+      }else if(obj.event === 'del'){
+         layer.confirm('确定要删除吗?', function(index){
+                layer.close(index);
+                layui.admin.req({
+                    notice: true
+                    ,url: '/product/'+data.id + '/'
+                    ,type: 'delete'
+                    ,done: function(res){
+                        table.reload('datagrid',{});
+                    }
+                });
+            });
+      }else if(obj.event === 'upload'){
+        layer.open({
+          type: 2,
+          title: '上传',
+          area: ['800px', '500px'],
+          btn: ['完成', '取消'],
+          yes: function(index, dom){
+              table.reload('datagrid',{});
+             layer.close(index);
+          },
+          btn2: function(index, layero){
+            layer.close(index);//关闭当前按钮
+          },
+          content: 'upload.html?id='+data.id
+        });
+      }
+    });
+
+    $('#btn_add').on('click', function(){
+        layer.open({
+          type: 2,
+          title: '添加',
+          shadeClose: false,
+          area: ['50%', '70%'],
+          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>
+

+ 113 - 0
uis/views/product/upload.html

@@ -0,0 +1,113 @@
+<!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-upload">
+                          <button type="button" class="layui-btn" id="upload_image">上传图片</button>
+                          <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
+                            已上传图片:
+                            <div class="layui-upload-list" id="show_image" style="display: flex;flex-wrap: wrap;"></div>
+                         </blockquote>
+                        </div>
+
+                        <button class="layui-btn" id="upload_save" lay-submit lay-filter="component-form-element" style="display: none">开始上传</button>
+                    </form>
+
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+  <script src="../../layuiadmin/layui/layui.js"></script>
+  <script>
+   var product_id = null;
+  layui.link('../../../layuiadmin/style/autocomplete.css');
+  layui.config({
+    base: '../../../layuiadmin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index',
+    autocomplete: 'autocomplete'
+  }).use(['index','utils', 'form', 'element', 'upload'], function(){
+    var $ = layui.$
+    ,admin = layui.admin
+    ,element = layui.element
+    ,form = layui.form
+    ,upload = layui.upload;
+
+    var id = layui.view.getParameterByName('id');
+    product_id = id;
+
+    form.render(null, 'component-form-element');
+    element.render('breadcrumb', 'breadcrumb');
+    refresh();
+
+    //多图片上传
+  upload.render({
+    elem: '#upload_image'
+    ,url:  '/product/'+ product_id +'/upload_images/'
+    ,field: 'images'
+    ,exts: 'jpg|png|jpeg|bmp'
+    ,acceptMime: '.jpg,.png,.jpeg,.bmp'
+    ,multiple: true
+    ,done: function (res) {
+        if (res.code !== 0) {
+            layer.msg(res.msg);
+        }else {
+            refresh();
+        }
+    },
+    error: function () {
+        layer.msg('保存失败');
+    }
+  });
+    parent.layui.submitChild = function () {
+      $("#upload_save").click();
+    };
+  });
+
+  function refresh () {
+      var $ = layui.$;
+      layui.admin.req({
+        url: '/product/images/?product=' + product_id,
+        done: function (res) {
+            $('#show_image').html('');
+           var data = res.data;
+           for (var i in data){
+               var html = '<div style="margin-top: 10px;"><a href="'+data[i].img_url+'" target="_blank"><img src="'+ data[i].img_url +'" class="layui-upload-img" style="margin-left: 5px;min-width: 80px; height: 100px;max-width: 200px;"></a>' +
+                      '<div align="center" style="margin-top: 3px;"><button type="button" class="layui-btn layui-btn-danger layui-btn-xs"  onclick="delImage('+data[i].id+')">删除</button></div></div>';
+                $('#show_image').append(html)
+           }
+        }
+    });
+  }
+
+  function delImage(id) {
+
+      layui.admin.req({
+         url: '/product/images/'+id + '/'
+         ,type: 'delete'
+         ,done: function(res){
+             refresh();
+         }
+      });
+  }
+
+  </script>
+</body>
+</html>