二十二、商城 - 商品录入-FastDFS(10)

一、分布式文件服务器FastDFS

1.1 什么是FastDFS

FastDFS是由国人余庆所开发,其项目地址是:https://github.com/happyfish100

在这里插入图片描述

  • FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
  • FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。
  • Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。
  • Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,Storageserver 没有实现自己的文件系统而是利用操作系统 的文件系统来管理文件。可以将storage称为存储服务器。

在这里插入图片描述

服务端两个角色:

  1. Tracker:管理集群,tracker 也可以实现集群。每个 tracker 节点地位平等。收集 Storage 集群的状态。
  2. Storage:实际保存文件 Storage 分为多个组,每个组之间保存的文件是不同的。每个组内部可以有多个成员,组成员内部保存的内容是一样的,组成员的地位是一致的,没有主从的概念。

1.2 文件上传及下载的流程

1.2.1 文件上传流程

在这里插入图片描述

客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

在这里插入图片描述

  • 组名:文件上传后所在的 storage 组名称,在文件上传成功后有 storage 服务器返回,需要客户端自行保存。
  • 虚拟磁盘路径:storage 配置的虚拟路径,与磁盘选项 store_path*对应。如果配置了
    store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推。
  • 数据两级目录:storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据
    文件。
  • 文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储
    服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。

fastdfs文件上传流程

  1. client询问tracker上传到的storage,不需要附加参数;
  2. tracker返回一台可用的storage;
  3. client直接和storage通讯完成文件上传。

1.2.2 文件下载流程

在这里插入图片描述

fastdfs文件下载流程

  1. client询问tracker下载文件的storage,参数为文件标识(组名和文件名);
  2. tracker返回一台可用的storage;
  3. client直接和storage通讯完成文件下载。

1.3 最简单的 FastDFS 架构

在这里插入图片描述

1.4 FastDFS安装

  • 方式一: FastDFS集群搭建 安装步骤非常繁琐,搞不好,就得一天搭建
  • 方式二:直接使用我的镜像咯 👉🏾👉🏾 FastDFS

为了能够快速的搭建FastDFS环境进行代码开发,这里提供了安装好的镜像(上面方式二)。
解压“/FastDFS.rar”,然后 👇🏾👇🏾 打开。

前提 :请设置你的虚拟机NAT主机网段为188哦,因为 FastDFS已经设置死了;

在这里插入图片描述

注意:遇到下列提示选择“我已移动该虚拟机”!

在这里插入图片描述
用户名 root 密码: offcn123

查看地址 ip a

在这里插入图片描述

由此查看IP地址已经固定为192.168.188.146 连接xShell 或 SecureCRT 进行如下操作

在这里插入图片描述

字体调整:

在这里插入图片描述

关闭防火墙

查看防火墙状态: systemctl status firewalld.service

执行关闭命令: systemctl stop firewalld.service

再次执行查看防火墙命令:systemctl status firewalld.service
	
执行开机禁用防火墙自启命令  : systemctl disable firewalld.service

重启  reboot

在这里插入图片描述

1.5 FastDFS 入门小 Demo

需求:将本地 图片 上传至图片服务器,再控制台打印url

在这里插入图片描述

(1)创建Maven工程 fastDFSdemo, pom.xml中引入

在这里插入图片描述

在这里插入图片描述

<dependencies>
    <dependency>
        <groupId>cn.bestwu</groupId>
        <artifactId>fastdfs-client-java</artifactId>
        <version>1.27</version>
    </dependency>
</dependencies>

(2)resources下面添加配置文件fdfs_client.conf ,将其中的服务器地址设置为192.168.188.146

在这里插入图片描述

#tracker服务器IP地址和端口号
tracker_server=192.168.188.146:22122

(3)创建包com.zql.fastDSF并且在下面创建类TestStorageClient,提前D盘下存放一张图片,然后代码如下:

package com.zql.fastDSF;

import org.csource.fastdfs.*;

import java.io.IOException;

/**
 * @Author:Daniel
 * @Version 1.0
 */
public class TestStorageClient {

    public static void main(String[] args) throws Exception {

        // 1、加载配置文件,配置文件中的内容就是 tracker 服务的地址。
        ClientGlobal.init("./src/main/resources/fdfs_client.conf");
        // 2、创建一个 TrackerClient 对象。直接 new 一个。
        TrackerClient trackerClient = new TrackerClient();
        // 3、使用 TrackerClient 对象创建连接,获得一个 TrackerServer 对象。
        TrackerServer trackerServer = trackerClient.getConnection();
        // 4、创建一个 StorageServer 的引用,值为 null
        StorageServer storageServer = null;
        // 5、创建一个 StorageClient 对象,需要两个参数 TrackerServer 对象、StorageServer 的引用
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);

        //扩展名不带“.”
        String[] jpgs = storageClient.upload_file("D:/meinv.jpg", "jpg", null);
        // 7、返回数组。包含组名和图片的路径。
        for (String s : jpgs) {

            System.out.println(s);
        }
    }
}

连接图片服务器超时问题处理

注意:如果出现连接图片服务器超时失败的情况,请检查图片linux服务器是否启动、是否开启了端口22122、23000的防火墙端口,如果未开启需要开启。

firewall-cmd --add-port=22122/tcp --permanent
firewall-cmd --add-port=23000/tcp --permanent
firewall-cmd --reload

控制台输出如下结果:

在这里插入图片描述

D:\develop\jdk\bin\java.exe · · ·
group1
M00/00/00/wKi8kmL5O3uAJ3FMAAFw9BYjaao979.jpg

Process finished with exit code 0

在浏览器输入:

http://192.168.188.146/group1/M00/00/00/wKi8kmL5O3uAJ3FMAAFw9BYjaao979.jpg

即可看到所上传的图片 👇🏾👇🏾。

在这里插入图片描述

案例源码

二、商家后台-商品录入【商品图片上传】

2.1 需求分析

在商品录入界面实现多图片上传

在这里插入图片描述
当用户点击新建按钮,弹出上传窗口

2.2 后端代码

2.2.1 工具类

(1)youlexuan_common 工程 pom.xml 引入依赖

<!-- 文件上传组件 -->
<dependency>
   <groupId>cn.bestwu</groupId>
   <artifactId>fastdfs-client-java</artifactId>
   <version>1.27</version>
</dependency>

<!-- 文件上传组件 在父工程pom.xml中copy -->
<dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
</dependency>

<dependency>
   <groupId>commons-io</groupId>
   <artifactId>commons-io</artifactId>
</dependency>	

(2)将资源 FastDFSClient.java 解压拷贝到 youlexuan-common 工程

在这里插入图片描述

youlexuan_shop_web 中得pom.xml 中添加让其依赖

 <dependency>
     <groupId>com.zql</groupId>
     <artifactId>youlexuan_common</artifactId>
     <version>1.0</version>
 </dependency>

2.2.2 配置文件

(1)将“资源/ fastDFSdemo /resources下中的 fdfs_client.conf 拷贝到youlexuan_shop_web工程 config 文件夹

(2)在youlexuan_shop_web工程resources / conf下创建 application.properties 添加如下配置

FILE_SERVER_URL=http://192.168.188.146/

(3)在youlexuan_shop_web 工程 springmvc.xml添加配置:

在这里插入图片描述

<context:property-placeholder location="classpath:conf/*.properties"/>


<!-- 配置文件上传多媒体解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"></property>
    <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
    <property name="maxUploadSize" value="5000242880"></property>
</bean>

注意,一定要加载属性文件,要 不然 在Controler里面没办法使用@Value引用属性值

2.2.3 控制层

在youlexuan_shop_web 新建 UploadController.java

package com.zql.shop.controller;

import com.zql.common.dfs.FastDFSClient;
import com.zql.entity.Result;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Author:Daniel
 * @Version 1.0
 */
@RestController
public class UploadController {

    @Value("${FILE_SERVER_URL}")
    private String FILE_SERVER_URL;//文件服务器地址

    @RequestMapping("/upload")
    public Result upload(MultipartFile file){

        try{

            //1. 创建一个客户端对象
            FastDFSClient fastDFSClient = new FastDFSClient("classpath:conf/fdfs_client.conf");

            //2.获取图片拓展名
            String ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);

            //3.执行上传处理
            String path = fastDFSClient.uploadFile(file.getBytes(), ext);

            //4.拼接返回的 url 和 ip 地址,拼装成完整的 url
            String url = FILE_SERVER_URL + path;

            return new Result(true,url);

        }catch (Exception e){

            e.printStackTrace();

            return new Result(true,"上传失败");
        }

    }
}

2.3 前端代码

2.3.1 服务层

(1)在youlexuan_shop_web工程创建 uploadService.js

//文件上传服务层
app.service("uploadService",function($http){

    this.uploadFile=function(){

        var formData=new FormData();

        formData.append("file",file.files[0]);

        return $http({

            method:'POST',

            url:"../upload.do",

            data: formData,

            headers: {'Content-Type':undefined},

            transformRequest: angular.identity
        });
    }
});
  • anjularjs对于post和get请求默认的Content-Type header 是application/json。通过设置‘Content-Type’: undefined,这样浏览器会帮我们把Content-Type 设置为 multipart/form-data.
  • 通过设置 transformRequest: angular.identity ,anjularjs transformRequest function 将序列化我们的formdata object.

(2)将uploadService服务注入到goodsController 中 uploadService

在这里插入图片描述
(3)在goods_edit.html引入js

<script type="text/javascript" src="../js/service/uploadService.js"></script>

在这里插入图片描述

2.3.2 上传图片

(1)goodsController 编写代码

$scope.uploadFile = function () {

	uploadService.uploadFile().success(function (response) {

		if(response.success){  //如果上传成功,就取出url

			$scope.image_entity.url = response.message;//设置文件地址
			
		}else{

			alert(response.message);
		}

   		}).error(function () {

    		alert("上传发生错误");

    })
}

(2)在 goods_edit.html 中修改图片上传窗口,调用上传方法,回显上传图片

在这里插入图片描述

在这里插入图片描述

<!--图片上传-->
<div class="tab-pane" id="pic_upload">
   <div class="row data-type">
       <!-- 颜色图片 -->
       <div class="btn-group">
           <button type="button" class="btn btn-default" title="新建" ng-click="image_entity={}" data-target="#uploadModal"
                   data-toggle="modal"><i class="fa fa-file-o"></i> 新建
           </button>

       </div>

       <table class="table table-bordered table-striped table-hover dataTable">
           <thead>
           <tr>

               <th class="sorting">颜色</th>
               <th class="sorting">图片</th>
               <th class="sorting">操作</th>
           </thead>
           <tbody>
           <tr>
               <td>

               </td>
               <td>
                   <img alt="" src="" width="100px" height="100px">
               </td>
               <td>
                   <button type="button" class="btn btn-default" title="删除"><i
                           class="fa fa-trash-o"></i> 删除
                   </button>
               </td>
           </tr>
           </tbody>
       </table>

   </div>
</div>
<!-- 上传窗口 -->
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h3 id="myModalLabel">上传商品图片</h3>
            </div>
            <div class="modal-body">

                <table class="table table-bordered table-striped">
                    <tr>
                        <td>颜色</td>
                        <td><input class="form-control"  ng-model="image_entity.color" placeholder="颜色"></td>
                    </tr>
                    <tr>
                        <td>商品图片</td>
                        <td>
                            <table>
                                <tr>
                                    <td>
                                        <input type="file"  id="file"/>
                                        <button class="btn btn-primary" type="button" ng-click="uploadFile()">
                                            上传
                                        </button>
                                    </td>
                                    <td>
                                        <img src="{{image_entity.url}}" width="200px" height="200px">
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                </table>

            </div>
            <div class="modal-footer">
                <button class="btn btn-success" data-dismiss="modal" aria-hidden="true">保存</button>
                <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭</button>
            </div>
        </div>
    </div>
</div>

测试: 启动两服务器,启动 youlexuan_sellergoods_service 和 youlexuan_shop_web

http://127.0.0.1:9102/admin/index.html

在这里插入图片描述

2.3.3 图片列表 & 移除图片

(1)在goodsController.js 增加方法



//遍历上传得图片
$scope.add_entity_images = function () {

     $scope.entity.goodsDesc.itemImages.push($scope.image_entity);

}

//删除
$scope.delete_entity_images = function (index) {

	$scope.entity.goodsDesc.itemImages.splice(index,1)

}

并且添加如下:

在这里插入图片描述

(2)修改上传窗口的保存按钮 ng-click="add_entity_images()"

在这里插入图片描述

(3)遍历图片列表和修改列表中的删除按钮 ng-click="delete_entity_images($index)"

在这里插入图片描述

注意图片属性采用了ng-src,可以保证有属性值的时候在加载图片,避免出现404错误

再次测试: 启动两服务器,启动 youlexuan_sellergoods_service 和 youlexuan_shop_web

http://127.0.0.1:9102/admin/index.html

在这里插入图片描述

在这里插入图片描述
当前完整代码 goods_edit.html

<!DOCTYPE html>
<html>
<head>
    <!-- 页面meta -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>商品编辑</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">

    <link rel="stylesheet" href="../plugins/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="../plugins/adminLTE/css/AdminLTE.css">
    <link rel="stylesheet" href="../plugins/adminLTE/css/skins/_all-skins.min.css">
    <link rel="stylesheet" href="../css/style.css">
    <script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>
    <script src="../plugins/bootstrap/js/bootstrap.min.js"></script>

    <!-- 富文本编辑器 -->
    <link rel="stylesheet" href="../plugins/kindeditor/themes/default/default.css"/>
    <script charset="utf-8" src="../plugins/kindeditor/kindeditor-min.js"></script>
    <script charset="utf-8" src="../plugins/kindeditor/lang/zh_CN.js"></script>

    <script type="text/javascript">
        var editor; //编辑器对象名称是editor,要不然会取不到值
        KindEditor.ready(function (K) {
            editor = K.create('textarea[name="content"]', {
                allowFileManager: true
            });
        });
    </script>

    <script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
    <script type="text/javascript" src="../js/base.js"></script>

    <script type="text/javascript" src="../js/service/uploadService.js"></script>

    <script type="text/javascript" src="../js/service/goodsService.js"></script>
    <script type="text/javascript" src="../js/controller/baseController.js"></script>
    <script type="text/javascript" src="../js/controller/goodsController.js"></script>

</head>

<body class="hold-transition skin-red sidebar-mini" ng-app="youlexuan" ng-controller="goodsController">

<!-- 正文区域 -->
<section class="content">

    <div class="box-body">

        <!--tab页-->
        <div class="nav-tabs-custom">

            <!--tab头-->
            <ul class="nav nav-tabs">
                <li class="active">
                    <a href="#home" data-toggle="tab">商品基本信息</a>
                </li>
                <li>
                    <a href="#pic_upload" data-toggle="tab">商品图片</a>
                </li>
                <li>
                    <a href="#customAttribute" data-toggle="tab">扩展属性</a>
                </li>
                <li>
                    <a href="#spec" data-toggle="tab">规格</a>
                </li>
            </ul>
            <!--tab头/-->

            <!--tab内容-->
            <div class="tab-content">

                <!--表单内容-->
                <div class="tab-pane active" id="home">
                    <div class="row data-type">
                        <div class="col-md-2 title">商品分类</div>

                        <div class="col-md-10 data">
                            <table>
                                <tr>
                                    <td>
                                        <select class="form-control">
                                        </select>
                                    </td>
                                    <td>
                                        <select class="form-control select-sm"></select>
                                    </td>
                                    <td>
                                        <select class="form-control select-sm"></select>
                                    </td>
                                    <td>
                                        模板ID:19
                                    </td>
                                </tr>
                            </table>
                        </div>

                        <div class="col-md-2 title">商品名称</div>
                        <div class="col-md-10 data">
                            <input type="text" class="form-control" ng-model="entity.goods.goodsName" placeholder="商品名称"
                                   value="">
                        </div>

                        <div class="col-md-2 title">品牌</div>
                        <div class="col-md-10 data">
                            <select class="form-control"></select>
                        </div>

                        <div class="col-md-2 title">副标题</div>
                        <div class="col-md-10 data">
                            <input type="text" class="form-control" ng-model="entity.goods.caption" placeholder="副标题"
                                   value="">
                        </div>

                        <div class="col-md-2 title">价格</div>
                        <div class="col-md-10 data">
                            <div class="input-group">
                                <span class="input-group-addon">¥</span>
                                <input type="text" class="form-control" ng-model="entity.goods.price" placeholder="价格"
                                       value="">
                            </div>
                        </div>

                        <div class="col-md-2 title editer">商品介绍</div>
                        <div class="col-md-10 data editer">
                            <textarea name="content" ng-model="entity.goods.introduction"
                                      style="width:800px;height:400px;visibility:hidden;"></textarea>
                        </div>

                        <div class="col-md-2 title rowHeight2x">包装列表</div>
                        <div class="col-md-10 data rowHeight2x">

                            <textarea rows="4" class="form-control" ng-model="entity.goodsDesc.packageList"
                            placeholder="包装列表"></textarea>
                        </div>

                        <div class="col-md-2 title rowHeight2x">售后服务</div>
                        <div class="col-md-10 data rowHeight2x">
                            <textarea rows="4" class="form-control" ng-model="entity.goodsDesc.saleService"
                            placeholder="售后服务"></textarea>
                        </div>

                    </div>
                </div>

                <!--图片上传-->
                <div class="tab-pane" id="pic_upload">
                    <div class="row data-type">
                        <!-- 颜色图片 -->
                        <div class="btn-group">
                            <button type="button" class="btn btn-default" title="新建" ng-click="image_entity={}" data-target="#uploadModal"
                                    data-toggle="modal"><i class="fa fa-file-o"></i> 新建
                            </button>

                        </div>

                        <table class="table table-bordered table-striped table-hover dataTable">
                            <thead>
                            <tr>

                                <th class="sorting">颜色</th>
                                <th class="sorting">图片</th>
                                <th class="sorting">操作</th>
                            </thead>
                            <tbody>
                            <tr ng-repeat="pojo in entity.goodsDesc.itemImages">
                                <td>
                                    {{pojo.color}}
                                </td>
                                <td>
                                    <img alt="" src="{{pojo.url}}" width="100px" height="100px">
                                </td>
                                <td>
                                    <button type="button" class="btn btn-default" title="删除"  ng-click="delete_entity_images($index)"><i
                                            class="fa fa-trash-o"></i> 删除
                                    </button>
                                </td>
                            </tr>
                            </tbody>
                        </table>

                        {{entity.goodsDesc.itemImages}}

                    </div>
                </div>

                <!--扩展属性-->
                <div class="tab-pane" id="customAttribute">
                    <div class="row data-type">
                        <div>
                            <div class="col-md-2 title">扩展属性1</div>
                            <div class="col-md-10 data">
                                <input class="form-control" placeholder="扩展属性1">
                            </div>
                        </div>
                        <div>
                            <div class="col-md-2 title">扩展属性2</div>
                            <div class="col-md-10 data">
                                <input class="form-control" placeholder="扩展属性2">
                            </div>
                        </div>
                    </div>
                </div>

                <!--规格-->
                <div class="tab-pane" id="spec">
                    <div class="row data-type">
                        <div class="col-md-2 title">是否启用规格</div>
                        <div class="col-md-10 data">
                            <input type="checkbox">
                        </div>
                    </div>
                    <p>
                    <div>
                        <div class="row data-type">

                            <div>
                                <div class="col-md-2 title">屏幕尺寸</div>
                                <div class="col-md-10 data">
					                               
		                            <span>
		                            	<input type="checkbox">4.0
		                            </span>
                                              <span>
		                            	<input type="checkbox">4.5
		                            </span>
                                             <span>
		                            	<input type="checkbox">5.0
		                            </span>

                                </div>
                            </div>
                            <div>
                                <div class="col-md-2 title">网络制式</div>
                                <div class="col-md-10 data">
					                              
		                            <span>
		                            	<input type="checkbox">2G
		                            </span>
                                              <span>
		                            	<input type="checkbox">3G
		                            </span>
                                              <span>
		                            	<input type="checkbox">4G
		                            </span>
                                </div>
                            </div>
                        </div>
                        <div class="row data-type">
                            <table class="table table-bordered table-striped table-hover dataTable">
                                <thead>
                                <tr>
                                    <th class="sorting">屏幕尺寸</th>
                                    <th class="sorting">网络制式</th>
                                    <th class="sorting">价格</th>
                                    <th class="sorting">库存</th>
                                    <th class="sorting">是否启用</th>
                                    <th class="sorting">是否默认</th>
                                </tr>
                                </thead>
                                <tbody>
                                <tr>
                                    <td>
                                        4.0
                                    </td>
                                    <td>
                                        3G
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="价格">
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="库存数量">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        4.0
                                    </td>
                                    <td>
                                        4G
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="价格">
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="库存数量">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        5.0
                                    </td>
                                    <td>
                                        3G
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="价格">
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="库存数量">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        5.0
                                    </td>
                                    <td>
                                        4G
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="价格">
                                    </td>
                                    <td>
                                        <input class="form-control" placeholder="库存数量">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                    <td>
                                        <input type="checkbox">
                                    </td>
                                </tr>

                                </tbody>
                            </table>

                        </div>

                    </div>
                </div>

            </div>
            <!--tab内容/-->
            <!--表单内容/-->
        </div>
    </div>
    <div class="btn-toolbar list-toolbar">
        <button class="btn btn-primary" ng-click="add()"><i class="fa fa-save" ></i>保存</button>
        <button class="btn btn-default">返回列表</button>
    </div>

</section>

<!-- 上传窗口 -->
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h3 id="myModalLabel">上传商品图片</h3>
            </div>
            <div class="modal-body">

                <table class="table table-bordered table-striped">
                    <tr>
                        <td>颜色</td>
                        <td><input class="form-control"  ng-model="image_entity.color" placeholder="颜色"></td>
                    </tr>
                    <tr>
                        <td>商品图片</td>
                        <td>
                            <table>
                                <tr>
                                    <td>
                                        <input type="file"  id="file"/>
                                        <button class="btn btn-primary" type="button" ng-click="uploadFile()">
                                            上传
                                        </button>
                                    </td>
                                    <td>
                                        <img src="{{image_entity.url}}" width="200px" height="200px">
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                </table>

            </div>
            <div class="modal-footer">
                <button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="add_entity_images()">保存</button>
                <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭</button>
            </div>
        </div>
    </div>
</div>
</body>
</html>

当前 youlexuan 所有完整代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Daniel521-Spark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值