程序员社区

【校园商铺SSM-13】店铺信息编辑--Dao+Service+Controller+View层的实现

文章目录

    • 1. 店铺信息编辑之Dao层实现
      • 1. ShopDao接口
      • 2. ShopDao.xml实现类
      • 3. ShopDaoTest
    • 2. 店铺信息编辑之Service层的实现
      • 1. ShopService接口
      • 2. ShopServiceImpl实现类
      • 3. ShopServiceTest测试类
    • 3. 店铺信息编辑之Controller层的实现
    • 4. 店铺信息编辑之View层实现
    • 5. 前后端联调测试

1. 店铺信息编辑之Dao层实现

店铺信息的编辑主要包括:更新店铺信息和展示店铺信息
在dao层中更新店铺信息前面已完成,因此在dao层中主要完成店铺信息的获取
在Shop实体类中有三个pojo对象,
在这里插入图片描述
表现为在数据库中tb_shop表通过三个外键与三张表相关联:
在这里插入图片描述

1. ShopDao接口

在ShopDao接口中增加根据shopId查询店铺信息方法:

/**
 * 查询店铺信息
 * @param shopId
 * @return Shop
 */
Shop queryByShopId(long shopId);

2. ShopDao.xml实现类

在ShopDao.xml文件中增加:

<resultMap id="shopMap" type="com.imooc.o2o.entity.Shop">
	<id column="shop_id" property="shopId"/>
	<result column="shop_name" property="shopName"/>
	<result column="shop_desc" property="shopDesc"/>
	<result column="shop_addr" property="shopAddr"/>
	<result column="phone" property="phone"/>
	<result column="shop_img" property="shopImg"/>
	<result column="priority" property="priority"/>
	<result column="create_time" property="createTime"/>
	<result column="last_edit_time" property="lastEditTime"/>
	<result column="enable_status" property="enableStatus"/>
	<result column="advice" property="advice"/>

	<association property="area" column="area_id" javaType="com.imooc.o2o.entity.Area">
		<id column="area_id" property="areaId"/>
		<result column="area_name" property="areaName"/>
	</association>

	<association property="shopCategory" column="shop_category_id" javaType="com.imooc.o2o.entity.ShopCategory">
		<id column="shop_category_id" property="shopCategoryId"/>
		<result column="shop_category_name" property="shopCategoryName"/>
	</association>
	
	<association property="owner" column="owner_id" javaType="com.imooc.o2o.entity.PersonInfo">
		<id column="user_id" property="userId"/>
		<result column="name" property="name"/>
	</association>
</resultMap>
<select id="queryByShopId" resultMap="shopMap" parameterType="Long">
	select
	s.shop_id,
	s.shop_name,
	s.shop_desc,
	s.shop_addr,
	s.phone,
	s.shop_img,
	s.priority,
	s.create_time,
	s.last_edit_time,
	s.enable_status,
	s.advice,
	a.area_id,
	a.area_name,
	sc.shop_category_id,
	sc.shop_category_name
	from
	tb_shop s,
	tb_area a,
	tb_shop_category sc
	where
	s.area_id=a.area_id
	and
	s.shop_category_id=sc.shop_category_id
	and
	s.shop_id=#{shopId}
</select>

3. ShopDaoTest

在 ShopDaoTest方法中增加一个测试方法:

@Test
public void testQueryShopById(){
    long shopId = 143;
    Shop shop = shopDao.queryByShopId(shopId);
    System.out.println("areaId:"+shop.getArea().getAreaId());
    System.out.println("areaName:"+shop.getArea().getAreaName());
}

在这里插入图片描述

2. 店铺信息编辑之Service层的实现

在service中也要完成两个方法:店铺信息的获取,更新店铺信息

1. ShopService接口

/**
* 通过店铺Id获取店铺信息
* @param shopId
* @return
*/
Shop getByShopId(long shopId);

/**
* 更新店铺信息,包括对图片的处理
* @param shop
* @param shopImgInputStream
* @param fileName
* @return
* @throws ShopOperationException
*/
ShopExecution modifyShop(Shop shop,InputStream shopImgInputStream,String fileName) throws ShopOperationException;

2. ShopServiceImpl实现类

在ImageUtil工具类中编写删除图片的方法:

/**
 * storePath是文件路径还是目录路径
 * 如果storePath是文件路径就删除该文件
 * 如果storePath是目录路径就删除该目录下面的所有文件
 * @param storePath
 */
public static void deleteFileOrPath(String storePath){
    File fileOrPath = new File(PathUtil.getImgBasePath()+storePath);
    if(fileOrPath.exists()){
        //判断文件是否为目录
        if(fileOrPath.isDirectory()){
            File files[] = fileOrPath.listFiles();
            //递归删除目录下面的文件
            for(int i=0;i<files.length;i++){
                files[i].delete();
            }
        }
        fileOrPath.delete();
    }
}

在ShopServiceImpl方法中添加:

@Override
public Shop getByShopId(long shopId) {
    return shopDao.queryByShopId(shopId);
}

@Override
public ShopExecution modifyShop(Shop shop, InputStream shopImgInputStream, String fileName) throws ShopOperationException{
    if(shop==null || shop.getShopId()==null){
        return new ShopExecution(ShopStateEnum.NULL_SHOP);
    }else{
        try {
            //1.判断是否需要处理图片(更换店铺的图片)
            if(shopImgInputStream!=null && fileName!=null &&!"".equals(fileName)){
                Shop tempShop = shopDao.queryByShopId(shop.getShopId());
                //先判断店铺图片存不存在,如果存在就删除
                if(tempShop.getShopImg()!=null){
                    ImageUtil.deleteFileOrPath(tempShop.getShopImg());
                }
                //生成新的店铺图片
                addShopImg(shop,shopImgInputStream,fileName);
            }
            //2.更新店铺信息
            shop.setLastEditTime(new Date());
            int effectedNum = shopDao.updateShop(shop);
            if(effectedNum<=0){
                return new ShopExecution(ShopStateEnum.INNER_ERROR);
            }else {
                shop=shopDao.queryByShopId(shop.getShopId());
                return new ShopExecution(ShopStateEnum.SUCCESS,shop);
            }
        } catch (Exception e) {
            throw new ShopOperationException("modifyShop error:"+e.getMessage());
        }
    }
}

3. ShopServiceTest测试类

@Test
public void testModifyShop() throws ShopOperationException,FileNotFoundException{
    Shop shop = new Shop();
    shop.setShopId(143L);
    shop.setShopName("修改后的店铺名称:");
    //要传入的文件
    File shopImg = new File("F:/XiaoYuanShangPu/dabai.jpg");
    //将图片文件封装为文件流
    InputStream is = new FileInputStream(shopImg);
    //更改图片信息
    ShopExecution shopExecution = shopService.modifyShop(shop,is,shopImg.getName());
    System.out.println(shopExecution.getShop().getShopImg());
}

在这里插入图片描述
在这里插入图片描述

3. 店铺信息编辑之Controller层的实现

在ShopManagementController类中加入:

@RequestMapping(value = "/getshopbyid",method = RequestMethod.GET)
@ResponseBody
private Map<String,Object> getShopById(HttpServletRequest request){
   Map<String,Object> modelMap = new HashMap<>();
   Long shopId=HttpServletRequestUtil.getLong(request,"shopId");
   System.out.println(shopId);
   if(shopId>-1){
       try {
           //根据id获取店铺信息
           Shop shop = shopService.getByShopId(shopId);
           //获取区域列表的信息
           List<Area> areaList = areaService.getAreaList();
           modelMap.put("shop",shop);
           modelMap.put("areaList",areaList);
           modelMap.put("success",true);
       } catch (Exception e) {//保险起见,加一个try/catch
           modelMap.put("success", false);
           modelMap.put("errMsg", e.toString());
       }
   }else {
       modelMap.put("success", false);
       modelMap.put("errMsg", "empty shopId");
   }
   return modelMap;
}

启动tomcat输出下面的请求路径和参数:
在这里插入图片描述
在这里插入图片描述
完成controller层的修改店铺信息,同时更改店铺注册:

    /**
     * @Title: modifyshop
     * @param request
     *            因为是接收前端的请求,而前端的信息都封装在HttpServletRequest中,
     *            所以需要解析HttpServletRequest,获取必要的参数
     *            1. 接收并转换相应的参数,包括shop信息和图片信息 2.修改店铺 3. 返回结果给前台
     * @return
     * @return: Map<String,Object>
     */

    @RequestMapping(value = "/modifyshop", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> modifyshop(HttpServletRequest request) {
        Map<String, Object> modelMap = new HashMap<String, Object>();

        // 0. 验证码校验
        if (!CodeUtil.verifyCode(request)) {
            modelMap.put("success", false);
            modelMap.put("errMsg", "验证码不正确");
            return modelMap;
        }
        // 1. 接收并转换相应的参数,包括shop信息和图片信息
        // 1.1 shop信息
        // shopStr 是和前端约定好的参数值,后端从request中获取request这个值来获取shop的信息
        String shopStr = HttpServletRequestUtil.getString(request, "shopStr");
        // 使用jackson-databind 将json转换为pojo
        ObjectMapper mapper = new ObjectMapper();
        Shop shop = null;
        try {
            // 将json转换为pojo
            shop = mapper.readValue(shopStr, Shop.class);
        } catch (Exception e) {
            e.printStackTrace();
            // 将错误信息返回给前台
            modelMap.put("success", false);
            modelMap.put("errMsg", e.getMessage());
            return modelMap;
        }

        // 1.2 图片信息 基于Apache Commons FileUpload的文件上传 ( 修改商铺信息 图片可以不更新)
        // Spring MVC中的 图片存在CommonsMultipartFile中
        CommonsMultipartFile shopImg = null;
        // 从request的本次会话中的上线文中获取图片的相关内容
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (commonsMultipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            // shopImg是和前端约定好的变量名
            shopImg = (CommonsMultipartFile) multipartRequest.getFile("shopImg");
        }

        // 2. 修改店铺
        if (shop != null && shop.getShopId() != null) {
            // Session 部分的 PersonInfo 修改商铺是不需要的设置的。
            // 修改店铺
            ShopExecution se = null;
            try {
                if (shopImg != null) {
                    se = shopService.modifyShop(shop, shopImg.getInputStream(), shopImg.getOriginalFilename());
                } else {
                    se = shopService.modifyShop(shop, null, null);
                }
                // 成功
                if (se.getState() == ShopStateEnum.SUCCESS.getState()) {
                    modelMap.put("success", true);
                    modelMap.put("errMsg", "修改成功");
                } else {
                    modelMap.put("success", false);
                    modelMap.put("errMsg", se.getStateInfo());
                }
            } catch (Exception e) {
                e.printStackTrace();
                modelMap.put("success", false);
                modelMap.put("errMsg", "ModifyShop Error");
            }
        } else {
            // 将错误信息返回给前台
            modelMap.put("success", false);
            modelMap.put("errMsg", "ShopId不合法");
        }
        return modelMap;
    }
    /**
     * 店铺注册
     * @param request
     * @return
     */
    @RequestMapping(value="/registshop",method = RequestMethod.POST)
    @ResponseBody
    private Map<String,Object> registerShop(HttpServletRequest request){
        Map<String,Object>  modelMap=new HashMap<String,Object>();
        //先判断验证码是否正确
        if (!CodeUtil.verifyCode(request)){//当验证码错误时
            modelMap.put("success",false);
            modelMap.put("errMsg","输入了错误的验证码");
            return modelMap;
        }
        //1.接受转换相应的参数,包括店铺信息和店铺图片信息
        String shopStr = HttpServletRequestUtil.getString(request,"shopStr");//通过转换工具类将前端传来的数据转为字符串
        ObjectMapper mapper=new ObjectMapper();//获取处理json的对象
        //定义一个Shop实体类来接收起前端传来的信息
        Shop shop=null;
        try{
            shop=mapper.readValue(shopStr,Shop.class);//将传入的shopStr转为Shop对象并完成赋值
        }catch (Exception e){//出错后输出错误信息
            modelMap.put("success",false);
            modelMap.put("errMsg",e.getMessage());
            return modelMap;
        }

        //操作添加图片
        CommonsMultipartFile shopImg=null;//spring自带
        CommonsMultipartResolver commonsMultipartResolver=new CommonsMultipartResolver(
                request.getSession().getServletContext()
        );//解析request传来的文件的,通过本次会话的上下文获取相关文件上传的内容
        if (commonsMultipartResolver.isMultipart((request))) {//如果有上传的文件流
            MultipartHttpServletRequest multipartHttpServletRequest= (MultipartHttpServletRequest) request;//这样就能提取出request中的文件流了
            shopImg=(CommonsMultipartFile)multipartHttpServletRequest.getFile("shopImg");//(这个字符串"shopImg"是前端传来的),得到文件
        }else {//如果不具备图片
            modelMap.put("success",false);
            modelMap.put("errMsg","上传图片不能为空");
            return modelMap;
        }
        // 2.注册店铺
        if (shop!=null&&shopImg!=null) {//如果接受完相应的参数
            PersonInfo owner=(PersonInfo)request.getSession().getAttribute("user");//owner的信息可以通过session获取
            shop.setOwner(owner);
            ShopExecution shopExecution= null;//不能直接传文件,因为CommonsMultipartFile和File不能直接转换
            try {
                shopExecution = shopService.addShop(shop,shopImg.getInputStream(),shopImg.getOriginalFilename());
                if (shopExecution.getState()== ShopStateEnum.CHECK.getState()){//如果操作成功
                    modelMap.put("success",true);
                    List<Shop> shopList = (List<Shop>)request.getSession().getAttribute("shopList");
                    if(shopList==null||shopList.size()==0){
                        shopList = new ArrayList<Shop>();
                    }
                    shopList.add(shopExecution.getShop());
                    request.getSession().setAttribute("shopList",shopList);
                }else {
                    modelMap.put("success",false);
                    modelMap.put("errMsg",shopExecution.getStateInfo());
                    return modelMap;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return modelMap;
        }else{
            modelMap.put("success",false);
            modelMap.put("errMsg","请输入店铺信息");
            return modelMap;
        }
    }

4. 店铺信息编辑之View层实现

/o2o/src/main/webapp/resources/js/shop/shopoperation.js文件中增加两个url:

// 通过shopId获取商铺信息的URL
var getShopInfoByShopId = '/o2o/shopadmin/getshopbyid?shopId=' + shopId;
// 修改商铺的URL
var modifyShopUrl = '/o2o/shopadmin/modifyshop';

shopId 如何获取呢?
/o2o/src/main/webapp/resources/js/common/common.js中写个公共方法

function getQueryString(name) {
	var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
	var r = window.location.search.substr(1).match(reg);
	if (r != null) {
		return decodeURIComponent(r[2]);
	}
	return '';
}

在shopoperation.js 调用即可,同时根据请求的URL来判断是注册还是编辑商铺。

// 通过url是否含有shopId来判断是注册还是编辑商铺
var shopId  = getQueryString('shopId');
// shopId非空返回true,空者返回false
var isEdit = shopId ? true :false;

// 根据isEdit 来判断 是注册商品还是修改商铺
if(!isEdit){
	// 调用getShopInitInfo,注册店铺用
	getShopInitInfo();
}else{
	// 调用getShopInfoById,修改店铺用
	getShopInfoById(shopId);
}

编写getShopInfoById(shopId);

/**
 * 通过shopId获取shop信息
 */
function getShopInfoById(shopId){
	$.getJSON(getShopInfoByShopId,function(data){
		if(data.success){
			// 将后台返回的shop通过shop变量接收,方便赋值
			var shop =  data.shop;
			// 赋值   要和shop实体类中的属性名保持一致
			$('#shop-name').val(shop.shopName);
			$('#shop-name').attr('disabled','disabled');
			$('#shop-addr').val(shop.shopAddr);
			$('#shop-phone').val(shop.phone);
			$('#shop-desc').val(shop.shopDesc);
			
			// 商品目录进行赋值   商品目录仅仅加载对应的目录,且不可编辑
			var shopCategory = '<option data-id="'
				+shop.shopCategory.shopCategoryId + '" selected>'
				+shop.shopCategory.shopCategoryName +'</option>';
			$('#shop-category').html(shopCategory);
			// 设置为不可编辑
			$('#shop-category').attr('disabled','disabled');
			
			// 区域进行赋值  区域可以进行编辑,并且初始设置为后台对应的区域
			var tempShopAreaHtml = '';
			data.areaList.map(function(item, index) {
				tempShopAreaHtml += '<option data-id="' + item.areaId
						+ '">' + item.areaName + '</option>';
			});
			$('#shop-area').html(tempShopAreaHtml);
			//初始设置为后台对应的区域 
			$("#shop-area option[data-id='"+shop.area.areaId+"']").attr("selected","selected");

		}else{
			$.toast(data.errMsg);
		}
	});
};

修改submit:

//添加:如果是编辑,需要传入shopId
if(isEdit){
   shop.shopId=shopId;
          }
..... 省略
// 利用ajax提交
$.ajax({
	// 修改url
	url:isEdit ? modifyShopUrl:registerShopUrl,
	..... 省略
});

完整shopoperation.js文件:

$(function() {
    // 通过url是否含有shopId来判断是注册还是编辑商铺
    var shopId  = getQueryString('shopId');
    // shopId非空返回true,空者返回false
    var isEdit = shopId ? true :false;
    // 获取基本信息的URL
    var initUrl = '/o2o/shopadmin/getshopinitinfo';
    // 注册店铺的URL
    var registerShopUrl = '/o2o/shopadmin/registshop';
    // 通过shopId获取商铺信息的URL
    var getShopInfoByShopId = '/o2o/shopadmin/getshopbyid?shopId=' + shopId;
    // 修改商铺的URL
    var modifyShopUrl = '/o2o/shopadmin/modifyshop';


    // 根据isEdit 来判断 是注册商品还是修改商铺
    if(!isEdit){
        // 调用getShopInitInfo,注册店铺用
        getShopInitInfo();
    }else{
        // 调用getShopInfoById,修改店铺用
        getShopInfoById(shopId);
    }
    /**
     * 通过shopId获取shop信息
     */
    function getShopInfoById(shopId){
        $.getJSON(getShopInfoByShopId,function(data){
            if(data.success){
                // 将后台返回的shop通过shop变量接收,方便赋值
                var shop =  data.shop;
                // 赋值要和shop实体类中的属性名保持一致
                $('#shop-name').val(shop.shopName);
                $('#shop-name').attr('disabled','disabled');
                $('#shop-addr').val(shop.shopAddr);
                $('#shop-phone').val(shop.phone);
                $('#shop-desc').val(shop.shopDesc);

                // 商品目录进行赋值商品目录仅仅加载对应的目录,且不可编辑
                var shopCategory = '<option data-id="'
                    +shop.shopCategory.shopCategoryId + '" selected>'
                    +shop.shopCategory.shopCategoryName +'</option>';
                $('#shop-category').html(shopCategory);
                // 设置为不可编辑
                $('#shop-category').attr('disabled','disabled');

                // 区域进行赋值  区域可以进行编辑,并且初始设置为后台对应的区域
                var tempShopAreaHtml = '';
                data.areaList.map(function(item, index) {
                    tempShopAreaHtml += '<option data-id="' + item.areaId
                        + '">' + item.areaName + '</option>';
                });
                $('#shop-area').html(tempShopAreaHtml);
                //初始设置为后台对应的区域
                $("#shop-area option[data-id='"+shop.area.areaId+"']").attr("selected","selected");

            }else{
                $.toast(data.errMsg);
            }
        });
    };
    /**
     * 从后台加载获取下拉菜单的值
     */
    function getShopInitInfo() {
        $.getJSON(initUrl, function(data) {
            if (data.success) {
                var tempShopCategoryHtml = '';
                var tempShopAreaHtml = '';
                data.shopCategoryList.map(function(item, index) {
                    tempShopCategoryHtml += '<option data-id="'
                        + item.shopCategoryId + '">' + item.shopCategoryName
                        + '</option>';
                });
                data.areaList.map(function(item, index) {
                    tempShopAreaHtml += '<option data-id="' + item.areaId
                        + '">' + item.areaName + '</option>';
                });
                // 获取html中对应标签的id 赋值
                $('#shop-category').html(tempShopCategoryHtml);
                $('#shop-area').html(tempShopAreaHtml)

            }else{
                $.toast(data.errMsg);
            }
        });
    };

    /**
     * submit按钮触发的操作
     */
    $('#submit').click(function() {
        // 获取页面的值
        var shop = {};
        // 如果是编辑,需要传入shopId
        if(isEdit){
            shop.shopId=shopId;
        }
        // 注意: 这个地方的变量名称要和Shop实体类中的属性保持一致,因为后台接收到shopStr后,会将Json转换为实体类,如果不一致会抛出异常
        // com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException
        shop.shopName = $('#shop-name').val();
        shop.shopAddr = $('#shop-addr').val();
        shop.phone = $('#shop-phone').val();
        shop.shopDesc = $('#shop-desc').val();
        // 选择id,双重否定=肯定
        shop.shopCategory = {
            // 这里定义的变量要和ShopCategory.shopCategoryId保持一致,否则使用databind转换会抛出异常
            shopCategoryId:$('#shop-category').find('option').not(function(){
                return !this.selected;
            }).data('id')
        };
        shop.area = {
            // 这里定义的变量要和Area.areaId属性名称保持一致,否则使用databind转换会抛出异常
            areaId:$('#shop-area').find('option').not(function(){
                return !this.selected;
            }).data('id')
        };
        // 图片
        var shopImg = $('#shop-img')[0].files[0];
        // 验证码
        var verifyCodeActual =$('#j_kaptcha').val();
        console.log('verifyCodeActual:'+verifyCodeActual);
        if(!verifyCodeActual){
            $.toast('请输入验证码');
            return;
        }
        // 接收数据
        var formData = new FormData();
        // 和后端约定好,利用shopImg和 shopStr接收 shop图片信息和shop信息
        formData.append('shopImg',shopImg);
        // 转成JSON格式,后端收到后将JSON转为实体类
        formData.append('shopStr',JSON.stringify(shop));

        // 将数据封装到formData发送到后台
        formData.append('verifyCodeActual',verifyCodeActual);

        // 利用ajax提交
        $.ajax({
            url:isEdit ? modifyShopUrl:registerShopUrl,
            type:'POST',
            data:formData,
            contentType:false,
            processData:false,
            cache:false,
            success:function(data){
                if(data.success){
                    $.toast('提示信息:'+data.errMsg);
                }else{
                    $.toast('提示信息:' + data.errMsg);
                }
                // 点击提交后 不管成功失败都更换验证码,防止重复提交
                $('#kaptcha_img').click();
            }
        });

    });
});

5. 前后端联调测试

以debug方式打开tomcat,打开后加上断点,重新加载页面,
在这里插入图片描述
加载页面后,在后端代码上加上断点:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 【校园商铺SSM-13】店铺信息编辑--Dao+Service+Controller+View层的实现

相关推荐

  • 暂无文章

一个分享Java & Python知识的社区