SSM校园商铺平台(二)

SSM校园商铺平台(二)

    • 1. Logback日志记录
      • 1.1 主要模块
      • 1.2 主要标签
      • 1.3使用logback
    • 2.店铺模块
      • 2.1 新增店铺(店铺注册)
      • 2.2 测试输出
    • 3. 图片处理和封装Util
      • 3.1 使用thumbnailator进行图片处理
      • 3.2 封装工具类
    • 4.添加店铺返回类型(用在service层)
      • 4.1 在dto包创建ShopExecution类
      • 4.2在enum包下创建ShopStateEnum枚举类,来标识各种状态
    • 5.添加店铺的Service层设计
      • 5.1 店铺设计的ShopServiceimpl类
      • 5.2 店铺操作异常类
    • 6.前端页面
    • 7.controller层的设计
      • 7.1 测试controller
      • 7.2 创建shopManagementController类
      • 7.3 店铺注册的前端实现

1. Logback日志记录

1.1 主要模块

  • logback-class
  • logback-classic
  • logback-core

1.2 主要标签

  • logger
  • appender
  • layout

1.3使用logback

1.3.1 logback属性配置,在resources创建一个logback.xml

  1. 配置logback刷新时间间隔,60秒
  2. 定义日志级别,TRACE
  3. 定义存储时间,30天
  4. 定义日志文件存放位置
  5. 定义日志显示方式,日期+线程+日志级别+信息+换行

<configuration debug="false">
	<appender name="INFO-FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${catalina.base}/webapps/myo2o/logs/info/info.logfile>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${catalina.base}/webapps/myo2o/logs/info/info.%d{yyyy-MM-dd}.%i.log.zipfileNamePattern>
			<timeBasedFileNamingAndTriggeringPolicy
				class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<maxFileSize>1024MBmaxFileSize>
			timeBasedFileNamingAndTriggeringPolicy>
			<maxHistory>30maxHistory>
		rollingPolicy>
		<layout class="ch.qos.logback.classic.PatternLayout">
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{55} -
				%msg%n
			pattern>
		layout>
	appender>
	
	<appender name="ACCESS-FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>
			${catalina.base}/webapps/myo2o/logs/access/access.logfile>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<FileNamePattern>${catalina.base}/webapps/myo2o/logs/access/access.%d{yyyy-MM-dd}.%i.log.zipFileNamePattern>
			<timeBasedFileNamingAndTriggeringPolicy
				class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<maxFileSize>1024MBmaxFileSize>
			timeBasedFileNamingAndTriggeringPolicy>
			<maxHistory>30maxHistory>
		rollingPolicy>
		<layout class="ch.qos.logback.classic.PatternLayout">
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{55} -
				%msg%n
			pattern>
		layout>
	appender>
	<logger name="com.imooc.myo2o" level="DEBUG" additivity="false">
		<appender-ref ref="ACCESS-FILE" />
	logger>
	<root level="INFO">
		<appender-ref ref="INFO-FILE" />
	root>
configuration>

2.店铺模块

2.1 新增店铺(店铺注册)

2.1.1 创建ShopDao接口
返回值为主键shop_id

public interface ShopDao {
     

	// 新增店铺
	int insertShop(Shop shop);
	
	//更新店铺
	int updateShop(Shop shop);
}

2.1.2 ShopDao.xml文件

  1. 指定名称空间为ShopDao接口
  2. 对于insert语句,设置数据库中的主键keyColum和entity中的主键
  3. useGeneratedKeys指定返回值为主键id
  4. update的parameterType指定传入参数类型


<mapper namespace="com.imooc.o2o.dao.ShopDao">

	
	<insert id="insertShop" useGeneratedKeys="true" keyColumn="shop_id" keyProperty="shopId">
		insert into
		tb_shop(owner_id,area_id,shop_category_id,shop_name,shop_desc,shop_addr,
		phone,shop_img,priority,create_time,last_edit_time,enable_status,advice)
		values
		(#{owner.userId},#{area.areaId},#{shopCategory.shopCategoryId},#{shopName},#{shopDesc},
		#{shopAddr},#{phone},#{shopImg},#{priority},#{createTime},#{lastEditTime},#{enableStatus},
		#{advice})
		
	insert>
	
	<update id="updateShop" parameterType="com.imooc.o2o.entity.Shop">
		update tb_shop
		<set>
			<if test="shopName != null">shop_name=#{shopName},if>
			<if test="shopDesc != null">shop_desc=#{shopDesc},if>
			<if test="shopAddr != null">shop_addr=#{shopAddr},if>
			<if test="phone != null">phone=#{phone},if>
			<if test="shopImg != null">shop_img=#{shopImg},if>
			<if test="priority != null">priority=#{priority},if>
			<if test="lastEditTime != null">last_edit_time=#{lastEditTime},if>
			<if test="enableStatus != null">enable_status=#{enableStatus},if>
			<if test="advice != null">advice=#{advice},if>
			<if test="area != null">area_id=#{area.areaId},if>
			<if test="shopCategory != null">shop_category_id=#{shopCategory.shopCategoryId},if>
		set>
		where shop_id=#{shopId}
	update>
mapper>

2.2 测试输出

在这里插入图片描述

3. 图片处理和封装Util

3.1 使用thumbnailator进行图片处理

3.1.1 添加图片处理的包

		
		<dependency>
			<groupId>net.coobirdgroupId>
			<artifactId>thumbnailatorartifactId>
			<version>0.4.8version>
		dependency>

3.1.2 该包使用测试

  • 获取当前线程下resources包的路径
  • 调用Thumbnails工具类
  • of 方法指定要处理的图片的位置
  • size方法指定将图片压缩的大小
  • watermark方法指定水印加在的位置、水印图片位置、水印透明度
  • toFile方法自定返回图片的位置
public class ImageUtil {
     

	public static void main(String[] args) throws IOException {
     
		String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
		Thumbnails.of(new File("D:\\TaoTao\\需要的图片\\images\\item\\shop\\15\\20170605234852321010.jpg"))
		.size(200, 200)
		.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath+"\\watermark.png")), 0.25f)
		.outputQuality(0.8)
		.toFile("D:\\TaoTao\\需要的图片\\images\\item\\shop\\15\\watermark.png");
		
	}
}

3.2 封装工具类

3.2.1 在util包下创建PathUtil类

public class PathUtil {
     

	
	private static String seperator = System.getProperty("file.separator");
	
	//返回项目图片的根路径
	public static String getImgBasePath() {
     
		//获取操作系统名称
		String os = System.getProperty("os.name");
		String basePath = "";
		//如果是Windows系统
		if(os.toLowerCase().startsWith("win")) {
     
			basePath = "F:/project/image/";
		}
		else {
     
			basePath = "/home/xiangze/image/";
		}
		//为了使符号/符合各个操作系统,将/替换成操作系统指定的分隔符
		basePath = basePath.replace("/"	, seperator);
		return basePath;
	}
	
	//返回项目图片的子路径
	public static String getShopImagePath(long shopId) {
     
		String imagePath = "/upload/item/shop"+shopId+"/";
		return imagePath.replace("/", seperator);
	}
}

3.2.2 在util包下创建ImageUtil类

public class ImageUtil {
     
	private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
	private static final SimpleDateFormat sDateFormat = new SimpleDateFormat(
			"yyyyMMddHHmmss"); // 时间格式化的格式
	private static final Random r = new Random();
	
	//处理缩略图
	public static String generateThumbnail(CommonsMultipartFile thumbnail, String targetAddr) {
     
		String realFileName = getRandomFileName();
		String extension = getFileExtension(thumbnail);
		makeDirPath(targetAddr);
		String relativeAddr = targetAddr + realFileName + extension;
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		try {
     
			Thumbnails.of(thumbnail.getInputStream()).size(200, 200).outputQuality(0.25f).toFile(dest);
		} catch (IOException e) {
     
			throw new RuntimeException("创建缩略图失败:" + e.toString());
		}
		return relativeAddr;
	}
	
	//生成随机文件名
	public static String getRandomFileName() {
     
		// 生成随机文件名:当前年月日时分秒+五位随机数(为了在实际项目中防止文件同名而进行的处理)
		int rannum = (int) (r.nextDouble() * (99999 - 10000 + 1)) + 10000; // 获取随机数
		String nowTimeStr = sDateFormat.format(new Date()); // 当前时间
		return nowTimeStr + rannum;
	}
	
	//获取输入文件流的扩展名
	private static String getFileExtension(CommonsMultipartFile cFile) {
     
		String originalFileName = cFile.getOriginalFilename();
		return originalFileName.substring(originalFileName.lastIndexOf("."));
	}
	
	//创建目标路径所涉及到的目录,比如com/immoc/o2o
	//让其自动创建com、imooc,o2o三个文件夹
	private static void makeDirPath(String targetAddr) {
     
		String realFileParentPath = PathUtil.getImgBasePath() + targetAddr;
		File dirPath = new File(realFileParentPath);
		if (!dirPath.exists()) {
     
			dirPath.mkdirs();
		}
	}
}

4.添加店铺返回类型(用在service层)

比如在操作店铺Shop类的时候,添加店铺是成功还是失败,我们需要有一个返回类型,卸载dto包中。返回给controller层去处理

4.1 在dto包创建ShopExecution类

  1. 店铺添加结果的状态(状态码)
  2. 状态标识(状态码对应的名称)
  3. 为了识别状态和状态码,创建了一个枚举类保存所有状态
  4. 店铺数量
  5. 操作的店铺
  6. 店铺列表
public class ShopExecution {
     

	//结果状态
	private int state;
	//状态标识
	private String stateInfo;
	//店铺数量
	private int count;
	//操作的店铺(增删改店铺时用到)
	private Shop shop;
	
	//shop列表(查询店铺的首使用)
	private List<Shop> shopList;

	
	public ShopExecution() {
     

	}

	//店铺操作失败的时候使用的构造器
	public ShopExecution(ShopStateEnum stateEnum) {
     
		this.state = stateEnum.getState();
		this.stateInfo = stateEnum.getStateInfo();
	}
	
	//店铺操作成功的时候使用的构造器
	public ShopExecution(ShopStateEnum stateEnum,Shop shop) {
     
		this.state = stateEnum.getState();
		this.stateInfo = stateEnum.getStateInfo();
		this.shop = shop;
	}
	//店铺操作成功的时候使用的构造器
	public ShopExecution(ShopStateEnum stateEnum,List<Shop> shopList) {
     
		this.state = stateEnum.getState();
		this.stateInfo = stateEnum.getStateInfo();
		this.shopList = shopList;
	}
}

4.2在enum包下创建ShopStateEnum枚举类,来标识各种状态

  1. 该类没有set方法,不能让外界修改枚举类型
  2. 提供了外界查找枚举类型的接口
public enum ShopStateEnum {
     

	CHECK(0,"审核中"),
	OFFLINE(1,"非法店铺"),
	SUCCESS(1,"操作成功"),
	PASS(2,"通过认证"),
	INNER_ERROR(-1001,"内部系统错误"),
	NULL_SHOPID(-1002,"shopId为空");
	
	private int state;
	private String stateInfo;
	
	private ShopStateEnum(int state, String stateInfo) {
     
		this.state = state;
		this.stateInfo = stateInfo;
	}
	
	//外部查找state的枚举类型
	public static ShopStateEnum stateOf(int state) {
     
		for(ShopStateEnum stateEnum:values()) {
     
			if(stateEnum.getState()==state) {
     
				return stateEnum;
			}
		}
		return null;
	}

	public int getState() {
     
		return state;
	}

	public String getStateInfo() {
     
		return stateInfo;
	}

}

5.添加店铺的Service层设计

5.1 店铺设计的ShopServiceimpl类

  1. 自动装载shopDao
  2. 实现接口中的添加店铺的方法
  3. 判断店铺是否为空,为空返回ShopExecution空值的对象,对象包含店铺为空状态和标识info
  4. shop对象不为空,给shop添加初始信息:初始状态:0待审核状态,创建日期和更新日期
  5. 将店铺添加到数据库,返回shopId主键
  6. 返回值<=0则说明添加到数据库失败,否则添加成功
  7. 店铺添加到数据库后,再添加店铺对应的图片到数据库,调用addShopImg方法
  8. addShopImg方法:根据shopId创建保存该店铺图片的路径,并且将上传到服务器的图片保存到该路径,并将shop的img地址修改为当前保存的路径。
  9. addShopImg方法抵用结束后,shop对象被修改了,我们将该对象的修改更新到数据库,抵用dao层的店铺更新方法。再判断更新是否成功,不成功抛出店铺操作异常
  10. 返回ShopExecution对象,表明审核状态。
public class ShopServiceImpl implements ShopService{
     

	@Autowired
	private ShopDao shopDao;
	
	@Override
	public ShopExecution addShop(Shop shop, CommonsMultipartFile shopImg) {
     
		//验证店铺是否为空
		if(shop==null) {
     
			return new ShopExecution(ShopStateEnum.NULL_SHOP);
		}
		try {
     
			//给店铺信息赋初始值
			shop.setEnableStatus(0);
			shop.setCreateTime(new Date());
			shop.setLastEditTime(new Date());
			//添加店铺信息
			int effectedNum = shopDao.insertShop(shop);
			if(effectedNum<=0) {
     
				throw new RuntimeException("店铺创建失败");
			}
			else {
     
				if(shopImg != null) {
     
					//存储图片
					try {
     
						addShopImg(shop,shopImg);
					} catch (Exception e) {
     
						throw new RuntimeException("addShopImg error:"+e.getMessage());
					}
					//更新店铺的图片地址
					effectedNum = shopDao.updateShop(shop);
					if(effectedNum <= 0) {
     
						throw new ShopOperationException("更新图片地址失败");
					}

				}
			}
			
		}catch(Exception e) {
     
			throw new RuntimeException("addShop error:"+e.getMessage());
		}
		return null;
	}

	private void addShopImg(Shop shop, CommonsMultipartFile shopImg) {
     
		//获取shop图片目录的相对路径
		String dest = PathUtil.getShopImagePath(shop.getShopId());
		String shopImgAddr = ImageUtil.generateThumbnail(shopImg, dest);
		//修改shop中的的img地址
		shop.setShopImg(shopImgAddr);
	}
	
	
}

5.2 店铺操作异常类

该类继承自RuntimeException 是为了保证事务的原子性,操作失败进行回滚。也就是如果添加到数据库的数据成功后抛出异常,也会将前面的操作进行回滚,清楚数据库的该条信息。

public class ShopOperationException extends RuntimeException {
     

	/**
	 * 
	 */
	private static final long serialVersionUID = 4771094100507194189L;
	public ShopOperationException(String msg) {
     
		super(msg);
	}
	
}

6.前端页面

前端采用阿里巴巴的SUI mobile框架,源码的git地址https://github.com/sdc-alibaba/SUI-Mobile

7.controller层的设计

由于html文件全部存放在WEB-INF目录下面,无法直接访问,所以要写相应的controller,让controller跳转到WEB-INF下的路径

7.1 测试controller

7.1.1 测试controller

@Controller
@RequestMapping(value="shopadmin",method= {
     RequestMethod.GET})
public class ShopAdminController {
     

	@RequestMapping("/shopedit")
	public String shopOperation() {
     
		return "shop/shopedit";
	}
}

7.1.2 测试前端显示
SSM校园商铺平台(二)_第1张图片

7.2 创建shopManagementController类

用于注册店铺等
7.2.1 shopManagementController类

  1. registerShop方法注册店铺
  2. 传入前端传过来的request数据
  3. 将前端传过来的request数据中shopStr部分通过JSON转换成shop对象实例
  4. 获取前端传过来的图片字节流shopImg:
  5. 注册店铺
  6. 由于注册店铺调用的addShop需要传入File类型的图片,所以我们为了便于接受来自前端的数据,我们重写了service层的addShop方法,传入3个参数,inputStream字节流文件和文件名fileName
  7. 返回对象
@Controller
@RequestMapping("/shopadmin")
public class ShopManagementController {
     

	@Autowired
	private ShopService shopService;
	
	@RequestMapping(value="/registershop",method= {
     RequestMethod.POST})
	@ResponseBody
	private Map<String,Object> registerShop(HttpServletRequest request) throws IOException{
     
		Map<String,Object> modelMap = new HashMap<>();
		//1.接受并转换相应的参数
		String shopStr = HttpServletRequestUtil.getString(request, "shopStr");
		ObjectMapper mapper = new ObjectMapper();
		Shop shop = null;
		try {
     
			//这是将字符串shopStr转换成Shop.class类的JSON数据格式
			shop = mapper.readValue(shopStr	, Shop.class);
		} catch (Exception e) {
     
			modelMap.put("success", false);
			modelMap.put("errMsg",e.getMessage());
			return modelMap;
		}
		
		//获取前端传递的文件流(图片)
		CommonsMultipartFile shopImg = null;
		CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(
				request.getSession().getServletContext());
		//判断上传的request是否含有图片,是就将图片赋值给shopImg
		if(commonsMultipartResolver.isMultipart(request)) {
     
			MultipartHttpServletRequest httpServletRequest = (MultipartHttpServletRequest) request;
			shopImg = (CommonsMultipartFile) httpServletRequest.getFile("shopImg");
		}
		else {
     
			modelMap.put("success", false);
			modelMap.put("errMsg","上传图片不能为空");
			return modelMap;
		}
		//2.注册店铺
		if(shop!=null && shopImg!=null) {
     
			PersonInfo owner = new PersonInfo();
			//UserId是session传过来的
			owner.setUserId(1L);
			shop.setOwner(owner);
			ShopExecution se = shopService.addShop(shop, shopImg.getInputStream(),shopImg.getOriginalFilename());
			if(se.getState()==ShopStateEnum.CHECK.getState()) {
     
				modelMap.put("success", true);
			}
			else {
     
				modelMap.put("success", false);
				modelMap.put("errMsg", se.getStateInfo());
			}
		}
		else {
     
			modelMap.put("success", false);
			modelMap.put("errMsg","请输入店铺信息");
			return modelMap;
		}
		//3.返回结果
		return modelMap;
	}
	
}

7.3 店铺注册的前端实现

7.3.1 店铺注册页面跳转
首先我们需要通过url跳转到店铺注册页面,因为店铺注册页面的html文件是放在WEB-INF目录下的,不能直接访问,需要controller来实现跳转

@Controller
@RequestMapping(value="shopadmin",method= {
     RequestMethod.GET})
public class ShopAdminController {
     

	@RequestMapping("/shopedit")
	public String shopOperation() {
     
		return "shop/shopedit";
	}
}

7.3.2 店铺注册前端shopedit.html代码

  1. 由于需要显示店铺类别和所属区域的选择项,所以我们需要从后台获取到这两部分内容,显示到前台
  2. 还需要将填写的内容提交到后台
  3. 为了完成这两个操作,我们采用js来实现,所以需要实现shopedit.js代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>商店信息</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<link rel="shortcut icon" href="/favicon.ico">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet"
	href="//g.alicdn.com/msui/sm/0.6.2/css/sm.min.css">
<link rel="stylesheet"
	href="//g.alicdn.com/msui/sm/0.6.2/css/sm-extend.min.css">
</head>
<body>
	<header class="bar bar-nav">
		<h1 class="title">商店信息</h1>
	</header>
	<div class="content">
		<div class="list-block">
			<ul>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-name"></i>
						</div>
						<div class="item-inner">
							<div class="item-title label">商铺名称</div>
							<div class="item-input">
								<input type="text" id="shop-name" placeholder="商铺名称">
							</div>
						</div>
					</div>
				</li>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-email"></i>
						</div>
						<div class="item-inner">
							<div class="item-title label">商铺分类</div>
							<div class="item-input">
								<select id="shop-category">
								</select>
							</div>
						</div>
					</div>
				</li>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-email"></i>
						</div>
						<div class="item-inner">
							<div class="item-title label">所属区域</div>
							<div class="item-input">
								<select id="area">
								</select>
							</div>
						</div>
					</div>
				</li>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-email"></i>
						</div>
						<div class="item-inner">
							<div class="item-title label">详细地址</div>
							<div class="item-input">
								<input type="text" id="shop-addr" placeholder="详细地址">
							</div>
						</div>
					</div>
				</li>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-email"></i>
						</div>
						<div class="item-inner">
							<div class="item-title label">联系电话</div>
							<div class="item-input">
								<input type="tel" id="shop-phone" placeholder="联系电话">
							</div>
						</div>
					</div>
				</li>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-email"></i>
						</div>
						<div class="item-inner">
							<div class="item-title label">缩略图</div>
							<div class="item-input">
								<input type="file" id="shop-img" placeholder="联系电话">
							</div>
						</div>
					</div>
				</li>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-email"></i>
						</div>
						<div class="item-inner">
							<div class="item-title label">店铺简介</div>
							<div class="item-input">
								<textarea placeholder="店铺简介" id="shop-desc"></textarea>
							</div>
						</div>
					</div>
				</li>
				<li>
					<div class="item-content">
						<div class="item-media">
							<i class="icon icon-form-email"></i>
						</div>
						<div class="item-inner">
							<label for="j_captcha" class="item-title label">验证码</label> <input
								id="j_captcha" name="j_captcha" type="text"
								class="form-control in" placeholder="验证码" />
							<div class="item-input">
								<img id="captcha_img" alt="点击更换" title="点击更换"
									onclick="changeVerifyCode(this)" src="../Kaptcha" />
							</div>
						</div>
					</div>
				</li>

			</ul>
		</div>
		<div class="content-block">
			<div class="row">
				<div class="col-50">
					<a href="/myo2o/shop/shopmanage"
						class="button button-big button-fill button-danger">返回</a>
				</div>
				<div class="col-50">
					<a href="#" class="button button-big button-fill" id="submit">提交</a>
				</div>
			</div>
		</div>
	</div>



	<script type='text/javascript'
		src='//g.alicdn.com/sj/lib/zepto/zepto.js' charset='utf-8'></script>
	<script type='text/javascript'
		src='//g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script>
	<script type='text/javascript'
		src='//g.alicdn.com/msui/sm/0.6.2/js/sm-extend.min.js' charset='utf-8'></script>
	<script type='text/javascript'
		src='../resources/js/common/commonutil.js' charset='utf-8'></script>
	<script type='text/javascript' src='../resources/js/shop/shopedit.js'
		charset='utf-8'></script>
</body>
</html>

7.3.3 店铺注册前端shopedit.js代码

  1. 从后台获取shopCategoryName和areaName,通过js返回到到前台变量中,供前台显示
  2. 添加提交按钮的事件方法,如果点击提交按钮,执行该方法,将前台数据提交到后台
  3. 提交方法主要获取两部分内容,一部分为字节流文件,就是输入的String类型存到shop中;另一部分为字节流文件,就是图片文件存放在shopImg。将这两个变量封装成JSON数据格式保存到formData中,再通过ajax提交到后台。
  4. 为了使第一个方法自动执行,需要在该js文件中调用该方法,自动获取后台传过来的区域和类别信息
$(function() {

	var shopId = getQueryString('shopId');

	var isEdit = shopId ? true : false;

	var shopInfoUrl = '/myo2o/shop/getshopbyid?shopId=1';
	// var shopInfoUrl = '/myo2o/shop/getshopbyid?shopId=' + shopId;
	//用于获取店铺的info信息
	var initUrl = '/o2o/shop/getshopinitinfo';
	//注册店铺
	var editShopUrl = '/o2o/shop/registershop';
	if (isEdit) {
		editShopUrl = '/myo2o/shop/modifyshop';
	}

	function getInfo(shopId) {
		$.getJSON(shopInfoUrl, function(data) {
			if (data.success) {
				var shop = data.shop;
				$('#shop-name').val(shop.shopName);
				$('#shop-addr').val(shop.shopAddr);
				$('#shop-phone').val(shop.phone);
				$('#shop-desc').val(shop.shopDesc);
				var shopCategory = '';
				var tempAreaHtml = '';
				data.areaList.map(function(item, index) {
					tempAreaHtml += '';
				});
				$('#shop-category').html(shopCategory);
				$('#shop-category').attr('disabled','disabled');
				$('#area').html(tempAreaHtml);
				$('#area').attr('data-id',shop.areaId);
			}
		});
	}

	//1. 获取从后台获取shopCategoryName和areaName,并显示到前台变量中
	function getCategory() {
		$.getJSON(initUrl, function(data) {
			if (data.success) {
				var tempHtml = '';
				var tempAreaHtml = '';
				data.shopCategoryList.map(function(item, index) {
					tempHtml += '';
				});
				data.areaList.map(function(item, index) {
					tempAreaHtml += '';
				});
				$('#shop-category').html(tempHtml);
				$('#shop-category').removeAttr('disabled');
				$('#area').html(tempAreaHtml);
			}
		});
	}
	alert(initUrl);
	if (isEdit) {
		getInfo(shopId);
	} else {
		getCategory();
	}
	//2. 该函数用于执行点击提交,就将前台数据提交到后台
	$('#submit').click(function() {
		var shop = {};

		shop.shopName = $('#shop-name').val();
		shop.shopAddr = $('#shop-addr').val();
		shop.phone = $('#shop-phone').val();
		shop.shopDesc = $('#shop-desc').val();

		shop.shopCategory = {
			shopCategoryId : $('#shop-category').find('option').not(function() {
				return !this.selected;
			}).data('id')
		};
		shop.area = {
			areaId : $('#area').find('option').not(function() {
				return !this.selected;
			}).data('id')
		};
		//上传文件流
		var shopImg = $("#shop-img")[0].files[0];
		var formData = new FormData();
		formData.append('shopImg', shopImg);
		//上传shopStr字符流
		formData.append('shopStr', JSON.stringify(shop));
		var verifyCodeActual = $('#j_captcha').val();
		if (!verifyCodeActual) {
			$.toast('请输入验证码!');
			return;
		}
		formData.append("verifyCodeActual", verifyCodeActual);
		//将formData提交到后台
		$.ajax({
			url : editShopUrl,
			type : 'POST',
			// contentType: "application/x-www-form-urlencoded; charset=utf-8",
			data : formData,
			contentType : false,
			processData : false,
			cache : false,
			success : function(data) {
				if (data.success) {
					$.toast('提交成功!');
					if (isEdit){
						$('#captcha_img').click();
					} else{
						window.location.href="/shop/shoplist";
					}
				} else {
					$.toast('提交失败!');
					$('#captcha_img').click();
				}
			}
		});
	});

});

对于从后台获取店铺类别和区域信息在下一节讲到。

你可能感兴趣的:(SSM校园商铺平台)