品优购项目记录:day05

今日目标:

        (1)完成商品分类功能

        (2)了解电商概念:SPU、SKU

        (3)掌握富文本编辑器的使用

        (4)掌握分布式文件服务器:FastDFS

        (5)掌握 angular js 图片上传





1、商品分类


1.1 商品分类列表展示

(1)后端:sellergoods-interface --> ItemCatService(服务接口层)
	/**
	 * 根据上级ID 获取商品分类列表
	 *
	 * @param parentId
	 * @return java.util.List<com.pinyougou.pojo.TbItemCat>
	 */
	List<TbItemCat> findByParentId(Long parentId);

(2)后端:sellergoods-service --> ItemCatServiceImpl(服务实现)
	@Override
	public List<TbItemCat> findByParentId(Long parentId) {
		// 封装查询条件
		TbItemCatExample example = new TbItemCatExample();
		example.createCriteria().andParentIdEqualTo(parentId);
		// 执行查询
		return itemCatMapper.selectByExample(example);
	}

(3)后端:manager-web --> ItemCatController(控制层)
    /**
     * 根据上级ID,查询商品分类列表
     * 
     * @param parentId 上级id
     * @return java.util.List<com.pinyougou.pojo.TbItemCat> 
     */
    @RequestMapping("/findByParentId")
    public List<TbItemCat> findByParentId(Long parentId) {
        return itemCatService.findByParentId(parentId);
    }

(4)前端:编写itemCatService.js,新增方法
    //查询上级id的商品分类列表
	this.findByParentId = function (parentId) {
        return $http.get('../itemCat/findByParentId.do?parentId=' + parentId);
    }


(5)前端:编写itemCatController.js,新增方法
	// 根据上级ID 查询商品分类列表
	$scope.findByParentId = function (parentId) {
		itemCatService.findByParentId(parentId).success(
			function (rtn) {
				$scope.list = rtn;
            }
		);
    }


(6)前端:修改页面,引入JS文件



(7)前端:引入angular js 指令,初始化执行查询列表方法



(8)前端:循环遍历列表,显示数据



(9)前端:为查询下一级按钮绑定单击事件



(10)效果:




1.2 商品分类面包屑导航

(1)编写itemCatController.js
    //当前菜单级别(默认为1):
	//  	顶级菜单:1  二级菜单:2   三级菜单:3
    $scope.grade = 1;
	$scope.setGrade = function (value) {
        $scope.grade = value;
    }

    $scope.selectList = function (p_entity) {
		if($scope.grade == 1) {
            $scope.entity_1 = null;
            $scope.entity_2 = null;
		}
        if($scope.grade == 2) {
            $scope.entity_1 = p_entity;
            $scope.entity_2 = null;
        }
        if($scope.grade == 3) {
            $scope.entity_2 = p_entity;
        }

        $scope.findByParentId(p_entity.id);
    }


(2)编写页面,给面包屑导航,绑定单击事件



(3)修改查询下级按钮的单击事件调用方法为:selectList

(4)效果:


(5)当菜单级别为三时,不显示查询下级,因为没有意义,已经没有下级菜单


注意:需要使用span,将被控制的元素包裹起来


(6)效果:


1.3 新增分类

(1)前端:在itemCatController中定义一个变量,用于记录当前上级分类的ID
    //记录当前上级分类ID,默认为0
	$scope.parentId = 0;


(2)前端:在调用查询下级方法时,记录当前上级分类ID



(3)前端:新增时,设置其parentId的值为当前分类上级ID



(4)前端:页面显示当前上级分类


(5)类型模板下拉菜单

参考之前下拉菜单



1.4 修改商品分类

(1)为修改按钮绑定单击事件




1.5 删除商品分类

(1)为复选框绑定单击事件


(2)为删除按钮绑定单击事件







2、商品录入[1]


2.1 商品基本信息的录入

(1)后端:编写组合实体类(Goods),用于存放前端传递的数据
package com.pinyougou.pojogroup;

import com.pinyougou.pojo.TbGoods;
import com.pinyougou.pojo.TbGoodsDesc;
import com.pinyougou.pojo.TbItem;

import java.io.Serializable;
import java.util.List;

/**
 * 商品组合实体类
 * Author xushuai
 * Description
 */
public class Goods implements Serializable {

    /** 商品基本信息 */
    private TbGoods goods;
    /** 商品扩展信息 */
    private TbGoodsDesc goodsDesc;
    /** SKU列表 */
    private List<TbItem> itemList;

    public TbGoods getGoods() {
        return goods;
    }

    public void setGoods(TbGoods goods) {
        this.goods = goods;
    }

    public TbGoodsDesc getGoodsDesc() {
        return goodsDesc;
    }

    public void setGoodsDesc(TbGoodsDesc goodsDesc) {
        this.goodsDesc = goodsDesc;
    }

    public List<TbItem> getItemList() {
        return itemList;
    }

    public void setItemList(List<TbItem> itemList) {
        this.itemList = itemList;
    }
}



(2)后端:改造GoodsService的add方法(sellergoods-interface)
	/**
	 * 增加
	*/
	void add(Goods goods);

(3)后端:改造GoodsServiceImpl中add方法的实现(sellergoods-service)
    /**
     * 增加
     */
    @Override
    public void add(Goods goods) {
        // 补全商品基本信息
        TbGoods tbGoods = goods.getGoods();
        tbGoods.setAuditStatus(TbGoods.STATUS_CREATE);
        // 保存商品基本信息
        goodsMapper.insert(tbGoods);

        // 补全商品扩展信息数据
        TbGoodsDesc tbGoodsDesc = goods.getGoodsDesc();
        tbGoodsDesc.setGoodsId(tbGoods.getId());
        // 保存商品扩展信息
        goodsDescMapper.insert(tbGoodsDesc);

    }
注意:需要注入GoodsDescMapper


(4)后端:改造GoodsController中的add方法
	/**
	 * 增加
	 * @param goods
	 * @return
	 */
	@RequestMapping("/add")
	public Result add(@RequestBody Goods goods){
		try {
			//设置商家id
			String sellerId = SecurityContextHolder.getContext().getAuthentication().getName();
			goods.getGoods().setSellerId(sellerId);
			//保存
			goodsService.add(goods);
			return new Result(true, "增加成功");
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "增加失败");
		}
	}


(5)前端:改造goodsController.js中的save方法,将其修改为add方法
    //增加商品
    $scope.add = function () {
        goodsService.add($scope.entity).success(
            function (response) {
                if (response.success) {
                    // 显示新增成功
                    alert("新增成功");
                    $scope.entity={};
                } else {
                    alert(response.message);
                }
            }
        );
    }


(6)前端:为输入框绑定变量


(7)前端:为保存按钮绑定单击事件




2.2 商品介绍录入

(1)修改goodsController.js的add方法




2.3 商品图片上传

(1)后端:引入FastDFS依赖,以及FastDFS的工具类(pinyougou-common)

package util;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;

/**
 * FastDFS 工具类
 */
public class FastDFSClient {

	private TrackerClient trackerClient = null;
	private TrackerServer trackerServer = null;
	private StorageServer storageServer = null;
	private StorageClient1 storageClient = null;
	
	public FastDFSClient(String conf) throws Exception {
		if (conf.contains("classpath:")) {
			conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
		}
		ClientGlobal.init(conf);
		trackerClient = new TrackerClient();
		trackerServer = trackerClient.getConnection();
		storageServer = null;
		storageClient = new StorageClient1(trackerServer, storageServer);
	}
	
	/**
	 * 上传文件方法
	 * <p>Title: uploadFile</p>
	 * <p>Description: </p>
	 * @param fileName 文件全路径
	 * @param extName 文件扩展名,不包含(.)
	 * @param metas 文件扩展信息
	 * @return
	 * @throws Exception
	 */
	public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
		String result = storageClient.upload_file1(fileName, extName, metas);
		return result;
	}
	
	public String uploadFile(String fileName) throws Exception {
		return uploadFile(fileName, null, null);
	}
	
	public String uploadFile(String fileName, String extName) throws Exception {
		return uploadFile(fileName, extName, null);
	}
	
	/**
	 * 上传文件方法
	 * <p>Title: uploadFile</p>
	 * <p>Description: </p>
	 * @param fileContent 文件的内容,字节数组
	 * @param extName 文件扩展名
	 * @param metas 文件扩展信息
	 * @return
	 * @throws Exception
	 */
	public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
		
		String result = storageClient.upload_file1(fileContent, extName, metas);
		return result;
	}
	
	public String uploadFile(byte[] fileContent) throws Exception {
		return uploadFile(fileContent, null, null);
	}
	
	public String uploadFile(byte[] fileContent, String extName) throws Exception {
		return uploadFile(fileContent, extName, null);
	}
}

(2)后端:引入FastDFS的配置文件,并配置访问图片时的URL前缀(shop-web)


(3)后端:配置 Spring MVC 多媒体解析器(shop-web),配置在springmvc.xml中

(4)后端:书写上传控制层(shop-web)
package com.pinyougou.shop.controller;

import 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;
import util.FastDFSClient;

/**
 * 文件上传控制器
 * Author xushuai
 * Description
 */
@RestController
public class UploadController {

    @Value("${FILE_SERVER_URL}")
    private String FILE_SERVER_URL;

    /**
     * 文件上传
     *
     * @param file 上传的文件
     * @return entity.Result
     */
    @RequestMapping("/upload")
    public Result upload(MultipartFile file) {
        try {
            // 创建FastDFS工具类对象
            FastDFSClient dfsClient = new FastDFSClient("classpath:config/fdfs_client.conf");
            // 获取扩展名
            String originalFilename = file.getOriginalFilename();
            String exName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            // 执行上传
            String file_id = dfsClient.uploadFile(file.getBytes(), exName);
            file_id = FILE_SERVER_URL + file_id;
            return Result.success(file_id);
        }catch (Exception e){
            e.printStackTrace();
            return Result.error("上传失败");
        }
    }
}


(5)前端:编写uploadService.js 文件
app.service('uploadService', function ($http) {

    // 上传文件
    this.uploadFile = function () {
        // FormData对象,对数据进行二进制序列化
        var formData = new FormData();
        // 将文件转换为二进制数据进行传输
        formData.append('file', file.files[0]);

        /*
         必须设置Content-Type为undefined
         transformRequest:angular.identity 对表单进行序列化
          */
        return $http({
            url:'../upload.do',
            method:'post',
            data:formData,
            headers:{'Content-Type':undefined},
            transformRequest:angular.identity
        });
    }
});


(6)前端:编写goodsController.js,新增方法
    // 上传文件
    $scope.uploadFile = function () {
        uploadService.uploadFile().success(
            function (rtn) {
                if(rtn.success) {
                    $scope.image_entity.url = rtn.message;
                } else {
                    alert(rtn.message);
                }
            }
        );
    }

(7)为输入框绑定变量,并给上传按钮绑定单击事件

(8)效果:



(9)为显示图片表格绑定变量,循环展示图片信息


(10)编写goodsController.js,新增方法
    // 初始化
    $scope.entity={goodsDesc:{itemImages:[]}}
    // image_entity到表格中
    $scope.add_image_entity = function () {
        // 将文件信息放入item
        $scope.entity.goodsDesc.itemImages.push($scope.image_entity);
    }

(11)每次单击新建按钮时,清空数据


(12)为保存按钮绑定单击事件


(13)效果:


(14)编写goodsController.js,新增方法
    // 删除表格中展示的图片
    $scope.remove_image_entity = function (index) {
        $scope.entity.goodsDesc.itemImages.splice(index,1);
    }

(15)为删除按钮,绑定单击事件


猜你喜欢

转载自blog.csdn.net/qq1031893936/article/details/81028551