• Java项目:基于jsp+mysql+Spring+mybatis的SSM在线网络图书商城


    作者主页:夜未央5788

     简介:Java领域优质创作者、Java项目、学习资料、技术互助

    文末获取源码

    项目介绍

    本项目分为前后台,有管理员与用户两种角色;
    管理员角色包含以下功能:
    管理员登录,商品分类管理,商品管理,商品属性管理,商品参数管理,订单管理,退款管理,退货管理,会员等级管理,客户信息管理,评论管理,文章分类管理,公告管理,文章管理,滚动图片管理,广告管理,热门查询管理,查询订单销售,查询商品销售,用户管理,角色管理,资源管理,修改密码,区域管理,配送方式管理,查看系统设置,缓存管理,查询到货通知等功能。

    用户角色包含以下功能:

    用户登录,查看首页,查看商品详情,查看购物车,提交订单,修改个人信息,修改密码,查看我的订单,添加配送地址,查看收藏夹等功能。

    环境需要

    1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
    2.IDE环境:Eclipse;注:本项目目前仅支持Eclipse,暂不支持IDEA;
    3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
    4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 

    5.数据库:MySql 5.7版本;

    6.是否Maven项目:否;

    技术栈

    1. 后端:Spring+SpringMVC+Mbytes

    2. 前端:Freemarker+css+javascript+bootstrap+jQuery

    使用说明

    1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件;
    2. 使用Eclipse导入项目,将项目中src目录下的conf.properties配置文件中的数据库配置改为自己的配置;
    3. 运行项目,在浏览器中输入localhost:8080/ssm_zxbookshop
    用户账号/密码: user/123456
    管理员账号/密码:admin/admin

    运行截图
    用户角色

     

     

     

     

     

     

     

    管理员角色

     

     

     

     

     

     

     

     

     

     

     

    相关代码

    BaseController

    1. package net.jeeshop.web.action;
    2. import net.jeeshop.core.Services;
    3. import net.jeeshop.core.dao.page.PagerModel;
    4. import net.jeeshop.core.front.SystemManager;
    5. import net.jeeshop.web.util.RequestHolder;
    6. import org.slf4j.Logger;
    7. import org.slf4j.LoggerFactory;
    8. import org.springframework.beans.factory.annotation.Autowired;
    9. import org.springframework.ui.ModelMap;
    10. import org.springframework.web.bind.annotation.ModelAttribute;
    11. import org.springframework.web.bind.annotation.RequestMapping;
    12. import org.springframework.web.bind.annotation.RequestMethod;
    13. import org.springframework.web.bind.annotation.ResponseBody;
    14. import org.springframework.web.servlet.mvc.support.RedirectAttributes;
    15. import javax.servlet.http.HttpServletRequest;
    16. /**
    17. * Created by dylan on 15-2-2.
    18. * @author dylan
    19. */
    20. public abstract class BaseControllerextends PagerModel> {
    21. protected Logger logger = LoggerFactory.getLogger(getClass());
    22. protected String page_toList = null;
    23. protected String page_toEdit = null;
    24. protected String page_toAdd = null;
    25. public abstract Services getService();
    26. @Autowired
    27. protected SystemManager systemManager;
    28. /**
    29. * 后台左边导航菜单的初始化查询方法
    30. */
    31. protected void initPageSelect() {
    32. logger.error("initPageSelect..init=n!");
    33. }
    34. /**
    35. * 初始化查询的时候,会清除所有的查询参数(所以在e中的),但可以设置不在e中的参数,然后在此方法中进行e.setXxx(参数)的方式进行保留。
    36. */
    37. protected void setParamWhenInitQuery(E e) {
    38. //BaseAction 的子类如有初始化页面的时候进行相关查询 ,则可以实现此方法。
    39. }
    40. /**
    41. * 公共的分页方法
    42. *
    43. * @return
    44. * @throws Exception
    45. */
    46. @RequestMapping("selectList")
    47. public String selectList(HttpServletRequest request, @ModelAttribute("e") E e) throws Exception {
    48. /**
    49. * 由于prepare方法不具备一致性,加此代码解决init=y查询的时候条件不被清除干净的BUG
    50. */
    51. this.initPageSelect();
    52. setParamWhenInitQuery(e);
    53. int offset = 0;//分页偏移量
    54. if (request.getParameter("pager.offset") != null) {
    55. offset = Integer.parseInt(request.getParameter("pager.offset"));
    56. }
    57. if (offset < 0) offset = 0;
    58. e.setOffset(offset);
    59. PagerModel pager = getService().selectPageList(e);
    60. if (pager == null) {
    61. pager = new PagerModel();
    62. }
    63. // 计算总页数
    64. pager.setPagerSize((pager.getTotal() + pager.getPageSize() - 1) / pager.getPageSize());
    65. selectListAfter(pager);
    66. request.setAttribute("pager", pager);
    67. return page_toList;
    68. }
    69. @RequestMapping("toEdit")
    70. public String toEdit(@ModelAttribute("e") E e, ModelMap model) throws Exception {
    71. e = getService().selectOne(e);
    72. // if(e==null || StringUtils.isBlank(e.getId())){
    73. // throw new NullPointerException("");
    74. // }
    75. model.addAttribute("e", e);
    76. return page_toEdit;
    77. }
    78. @RequestMapping("toAdd")
    79. public String toAdd(@ModelAttribute("e") E e, ModelMap model) throws Exception {
    80. e.clear();
    81. return page_toAdd;
    82. }
    83. /**
    84. * 子类必须要实现的方法当分页查询后.
    85. * 解决了用户先点击新增按钮转到新增页面,然后点击返回按钮返回后,再点分页控件出错的BUG.
    86. * 原因是分页查询后未将pageUrl重新设置为正确的URL所致
    87. */
    88. protected void selectListAfter(PagerModel pager) {
    89. pager.setPagerUrl("selectList");
    90. }
    91. /**
    92. * 返回到查询页面
    93. *
    94. * @return
    95. * @throws Exception
    96. */
    97. @RequestMapping("back")
    98. public String back(@ModelAttribute("e") E e, ModelMap model) throws Exception {
    99. return selectList(RequestHolder.getRequest(), e);
    100. }
    101. /**
    102. * 公共的批量删除数据的方法,子类可以通过重写此方法实现个性化的需求。
    103. *
    104. * @return
    105. * @throws Exception
    106. */
    107. @RequestMapping(value = "deletes", method = RequestMethod.POST)
    108. public String deletes(HttpServletRequest request, String[] ids, @ModelAttribute("e") E e, RedirectAttributes flushAttrs) throws Exception {
    109. // User user = (User) getSession().getAttribute(Global.USER_INFO);
    110. // if(user==null){
    111. // throw new NullPointerException();
    112. // }
    113. // if(user.getDbPrivilegeMap()!=null && user.getDbPrivilegeMap().size()>0){
    114. // if(user.getDbPrivilegeMap().get(Container.db_privilege_delete)==null){
    115. // throw new PrivilegeException(Container.db_privilege_delete_error);
    116. // }
    117. // }
    118. getService().deletes(ids);
    119. addMessage(flushAttrs, "操作成功!");
    120. return "redirect:selectList";
    121. }
    122. /**
    123. * 公共的更新数据的方法,子类可以通过重写此方法实现个性化的需求。
    124. *
    125. * @return
    126. * @throws Exception
    127. */
    128. @RequestMapping(value = "update", method = RequestMethod.POST)
    129. public String update(HttpServletRequest request, @ModelAttribute("e") E e, RedirectAttributes flushAttrs) throws Exception {
    130. // User user = (User) getSession().getAttribute(Global.USER_INFO);
    131. // if(user==null){
    132. // throw new NullPointerException();
    133. // }
    134. // if(user.getDbPrivilegeMap()!=null && user.getDbPrivilegeMap().size()>0){
    135. // if(user.getDbPrivilegeMap().get(Container.db_privilege_update)==null){
    136. // throw new PrivilegeException(Container.db_privilege_update_error);
    137. // }
    138. // }
    139. getService().update(e);
    140. insertAfter(e);
    141. addMessage(flushAttrs, "操作成功!");
    142. return "redirect:selectList";
    143. }
    144. /**
    145. * insert之后,selectList之前执行的动作,一般需要清除添加的E,否则查询会按照E的条件进行查询.
    146. * 部分情况下需要保留某些字段,可以选择不清除
    147. *
    148. * @param e
    149. */
    150. protected void insertAfter(E e){
    151. }
    152. /**
    153. * 公共的插入数据方法,子类可以通过重写此方法实现个性化的需求。
    154. *
    155. * @return
    156. * @throws Exception
    157. */
    158. @RequestMapping(value = "insert",method = RequestMethod.POST)
    159. public String insert(HttpServletRequest request, @ModelAttribute("e") E e, RedirectAttributes flushAttrs) throws Exception {
    160. // User user = (User) getSession().getAttribute(Global.USER_INFO);
    161. // if(user==null){
    162. // throw new NullPointerException();
    163. // }
    164. // if(user.getDbPrivilegeMap()!=null && user.getDbPrivilegeMap().size()>0){
    165. // if(user.getDbPrivilegeMap().get(Container.db_privilege_insert)==null){
    166. // throw new PrivilegeException(Container.db_privilege_insert_error);
    167. // }
    168. // }
    169. getService().insert(e);
    170. insertAfter(e);
    171. addMessage(flushAttrs, "操作成功!");
    172. return "redirect:selectList";
    173. }
    174. /**
    175. * 跳转到编辑页面
    176. *
    177. * @return
    178. * @throws Exception
    179. */
    180. // @RequestMapping("toEdit")
    181. // public String toEdit(@ModelAttribute("e") E e, ModelMap model) throws Exception {
    182. // e = getService().selectOne(e);
    183. if(e==null || StringUtils.isBlank(e.getId())){
    184. throw new NullPointerException("");
    185. }
    186. // return toEdit;
    187. // }
    188. // @RequestMapping("toAdd")
    189. // public String toAdd(@ModelAttribute("e") E e, ModelMap model) throws Exception {
    190. // e.clear();
    191. // return toAdd;
    192. // }
    193. @RequestMapping("loadData")
    194. @ResponseBody
    195. public PagerModel loadData(HttpServletRequest request, E e){
    196. int offset = 0;
    197. int pageSize = 10;
    198. if (request.getParameter("start") != null) {
    199. offset = Integer
    200. .parseInt(request.getParameter("start"));
    201. }
    202. if (request.getParameter("length") != null) {
    203. pageSize = Integer
    204. .parseInt(request.getParameter("length"));
    205. }
    206. if (offset < 0)
    207. offset = 0;
    208. if(pageSize < 0){
    209. pageSize = 10;
    210. }
    211. e.setOffset(offset);
    212. e.setPageSize(pageSize);
    213. PagerModel pager = getService().selectPageList(e);
    214. pager.setRecordsTotal(pager.getTotal());
    215. pager.setRecordsFiltered(pager.getTotal());
    216. return pager;
    217. }
    218. protected void addMessage(ModelMap modelMap, String message) {
    219. modelMap.addAttribute("message", message);
    220. }
    221. protected void addWarning(ModelMap modelMap, String warning) {
    222. modelMap.addAttribute("warning", warning);
    223. }
    224. protected void addError(ModelMap modelMap, String warning) {
    225. modelMap.addAttribute("errorMsg", warning);
    226. }
    227. protected void addMessage(RedirectAttributes flushAttrs, String message) {
    228. flushAttrs.addFlashAttribute("message", message);
    229. }
    230. protected void addWarning(RedirectAttributes flushAttrs, String warning) {
    231. flushAttrs.addFlashAttribute("warning", warning);
    232. }
    233. protected void addError(RedirectAttributes flushAttrs, String warning) {
    234. flushAttrs.addFlashAttribute("errorMsg", warning);
    235. }
    236. }

    CommonController

    1. package net.jeeshop.web.action;
    2. import net.jeeshop.core.front.SystemManager;
    3. import net.jeeshop.core.util.ImageUtils;
    4. import net.jeeshop.services.common.SystemSetting;
    5. import net.sf.json.JSONObject;
    6. import org.slf4j.Logger;
    7. import org.slf4j.LoggerFactory;
    8. import org.springframework.stereotype.Controller;
    9. import org.springframework.web.bind.annotation.RequestMapping;
    10. import org.springframework.web.bind.annotation.RequestParam;
    11. import org.springframework.web.bind.annotation.ResponseBody;
    12. import org.springframework.web.multipart.MultipartFile;
    13. import java.io.File;
    14. import java.text.SimpleDateFormat;
    15. import java.util.Arrays;
    16. import java.util.Date;
    17. import java.util.HashMap;
    18. /**
    19. * @author dylan
    20. * @date 16/2/15 16:29
    21. * Email: dinguangx@163.com
    22. */
    23. @Controller
    24. @RequestMapping("/common")
    25. public class CommonController {
    26. private Logger logger = LoggerFactory.getLogger(getClass());
    27. @RequestMapping("uploadify")
    28. @ResponseBody
    29. public String uploadify(@RequestParam("Filedata")MultipartFile filedata,
    30. @RequestParam(required = false, defaultValue = "1")String thumbnail) {
    31. boolean createThumbnail = "1".equals(thumbnail);
    32. SystemSetting systemSetting = SystemManager.getInstance().getSystemSetting();
    33. //文件保存目录路径
    34. String savePath = SystemManager.getInstance().getProperty("file.upload.path");
    35. //文件保存目录URL
    36. String saveUrl = systemSetting.getImageRootPath();
    37. //定义允许上传的文件扩展名
    38. HashMap extMap = new HashMap();
    39. extMap.put("image", "gif,jpg,jpeg,png,bmp");
    40. extMap.put("flash", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
    41. extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
    42. extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
    43. //最大文件大小
    44. long maxSize = 1000000;
    45. //检查目录
    46. File uploadDir = new File(savePath);
    47. if (!uploadDir.isDirectory()) {
    48. return (getError("上传目录不存在。"));
    49. }
    50. //检查目录写权限
    51. if (!uploadDir.canWrite()) {
    52. return (getError("上传目录没有写权限。"));
    53. }
    54. String dirName = "image";
    55. if (!extMap.containsKey(dirName)) {
    56. return (getError("目录名不正确。"));
    57. }
    58. //创建文件夹
    59. savePath += dirName + "/";
    60. saveUrl += dirName + "/";
    61. String relativePath = dirName + "/";
    62. File saveDirFile = new File(savePath);
    63. if (!saveDirFile.exists()) {
    64. saveDirFile.mkdirs();
    65. }
    66. SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    67. String ymd = sdf.format(new Date());
    68. savePath += ymd + "/";
    69. saveUrl += ymd + "/";
    70. relativePath += ymd + "/";
    71. File dirFile = new File(savePath);
    72. if (!dirFile.exists()) {
    73. dirFile.mkdirs();
    74. }
    75. String fileName = filedata.getOriginalFilename();
    76. //检查扩展名
    77. String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    78. if (!Arrays.asList(extMap.get(dirName).split(",")).contains(fileExt)) {
    79. return (getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。"));
    80. }
    81. String newFileName1 = null;//小图
    82. String newFileName2 = null;//中图
    83. String newFileName3 = null;//大图 ,也是原图
    84. String newFileName0 = String.valueOf(System.currentTimeMillis());
    85. logger.debug("newFileName0=" + newFileName0);
    86. newFileName1 = newFileName0 + "_1";
    87. newFileName2 = newFileName0 + "_2";
    88. newFileName3 = newFileName0 + "_3." + fileExt;
    89. logger.debug("newFileName1=" + newFileName1 + ",newFileName2=" + newFileName2 + ",newFileName3=" + newFileName3);
    90. File uploadedFile3 = new File(savePath, newFileName3);
    91. try {
    92. filedata.transferTo(uploadedFile3);
    93. if(createThumbnail) {
    94. File uploadedFile1 = new File(savePath, newFileName1 + "." + fileExt);
    95. File uploadedFile2 = new File(savePath, newFileName2 + "." + fileExt);
    96. ImageUtils.ratioZoom2(uploadedFile3, uploadedFile1, Double.valueOf(SystemManager.getInstance().getProperty("product_image_1_w")));
    97. ImageUtils.ratioZoom2(uploadedFile3, uploadedFile2, Double.valueOf(SystemManager.getInstance().getProperty("product_image_2_w")));
    98. }
    99. } catch (Exception e) {
    100. logger.error("上传文件异常:" + e.getMessage());
    101. return (getError("上传文件失败。"));
    102. }
    103. JSONObject obj = new JSONObject();
    104. obj.put("error", 0);
    105. obj.put("filePath", relativePath + newFileName3);
    106. return (obj.toString());
    107. }
    108. private String getError(String msg) {
    109. JSONObject obj = new JSONObject();
    110. obj.put("error", 1);
    111. obj.put("msg", msg);
    112. return (obj.toString());
    113. }
    114. }

    ForwardController

    1. package net.jeeshop.web.action;
    2. import org.apache.commons.lang.StringUtils;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import org.springframework.web.bind.annotation.RequestParam;
    6. /**
    7. * Created by dylan on 15-1-18.
    8. */
    9. @Controller
    10. @RequestMapping("forward")
    11. public class ForwardController {
    12. private String p = "/common/404";
    13. @RequestMapping
    14. public String forward(@RequestParam("p")String page){
    15. if(StringUtils.isBlank(page)){
    16. return p;
    17. }
    18. return page.trim();
    19. }
    20. }

    购物车

    1. package net.jeeshop.web.action.front.cart;
    2. import com.alibaba.fastjson.JSON;
    3. import net.jeeshop.core.FrontContainer;
    4. import net.jeeshop.core.Services;
    5. import net.jeeshop.core.front.SystemManager;
    6. import net.jeeshop.services.front.account.bean.Account;
    7. import net.jeeshop.services.front.address.AddressService;
    8. import net.jeeshop.services.front.product.ProductService;
    9. import net.jeeshop.services.front.product.bean.Product;
    10. import net.jeeshop.services.front.product.bean.ProductStockInfo;
    11. import net.jeeshop.services.manage.activity.bean.Activity;
    12. import net.jeeshop.services.manage.spec.SpecService;
    13. import net.jeeshop.services.manage.spec.bean.Spec;
    14. import net.jeeshop.web.action.front.FrontBaseController;
    15. import net.jeeshop.web.action.front.orders.CartInfo;
    16. import net.jeeshop.web.util.RequestHolder;
    17. import org.apache.commons.lang.StringUtils;
    18. import org.slf4j.Logger;
    19. import org.slf4j.LoggerFactory;
    20. import org.springframework.beans.factory.annotation.Autowired;
    21. import org.springframework.stereotype.Controller;
    22. import org.springframework.ui.ModelMap;
    23. import org.springframework.web.bind.annotation.RequestMapping;
    24. import org.springframework.web.bind.annotation.RequestMethod;
    25. import org.springframework.web.bind.annotation.ResponseBody;
    26. import javax.servlet.http.HttpServletRequest;
    27. import java.io.IOException;
    28. import java.text.DecimalFormat;
    29. import java.util.ArrayList;
    30. import java.util.Iterator;
    31. import java.util.LinkedList;
    32. import java.util.List;
    33. /**
    34. * 购物车
    35. *
    36. * @author huangf
    37. *
    38. */
    39. @Controller("frontCartAction")
    40. @RequestMapping("cart")
    41. public class CartAction extends FrontBaseController {
    42. private static final long serialVersionUID = 1L;
    43. private static final Logger logger = LoggerFactory.getLogger(CartAction.class);
    44. @Autowired
    45. private ProductService productService;
    46. @Autowired
    47. private AddressService addressService;
    48. @Autowired
    49. private SpecService specService;
    50. @Override
    51. public Services getService() {
    52. return null;
    53. }
    54. /**
    55. * 查看购物车
    56. * @return
    57. */
    58. @RequestMapping("cart")
    59. public String cart(ModelMap model){
    60. logger.error("AccountAction.cart查看购物车...");
    61. // Account acc = (Account) getSession().getAttribute(FrontContainer.USER_INFO);
    62. // if (acc == null || StringUtils.isBlank(acc.getAccount())) {
    63. // return "toLogin";
    64. // }
    65. List productList = new ArrayList();
    66. CartInfo cartInfo = getMyCart();
    67. if(cartInfo!=null){
    68. productList = cartInfo.getProductList();
    69. } else {
    70. cartInfo = new CartInfo();
    71. }
    72. model.addAttribute("cartInfo", cartInfo);
    73. model.addAttribute("productList", productList);
    74. return "cart";
    75. // String addCart = getRequest().getParameter("addCart");
    76. // CartInfo cartInfo = (CartInfo) getSession().getAttribute(FrontContainer.myCart);
    77. // if(cartInfo==null){
    78. // cartInfo = new CartInfo();
    79. // }
    80. // getSession().setAttribute(FrontContainer.myCart,cartInfo);
    81. // logger.error("===addCart="+(addCart!=null && addCart.equals("1")));
    82. // if(addCart!=null && addCart.equals("1")){
    83. // String productID = getE().getId();
    84. // if(StringUtils.isEmpty(productID)){
    85. // //查询购物车
    86. // return "cart";
    87. // }
    88. //
    89. // if(cartInfo==null){
    90. // cartInfo = new CartInfo();
    91. // getSession().setAttribute(FrontContainer.myCart, cartInfo);
    92. // }
    93. // int inputBuyNum = Integer.valueOf(getRequest().getParameter("inputBuyNum"));
    94. // if(inputBuyNum<=0){
    95. // throw new NullPointerException();
    96. // }
    97. // //检查指定的产品是否已购买到购物车,购买了则数量++,否则查询后添加到购物车
    98. // boolean exists = false;
    99. // for(int i=0;i
    100. // Product p = cartInfo.getProductList().get(i);
    101. // if(p.getId().equals(productID)){
    102. // p.setBuyCount(p.getBuyCount()+inputBuyNum);
    103. // exists = true;
    104. // }
    105. // }
    106. // if(!exists){
    107. // //添加产品到购物车
    108. // System.out.println("id="+productID);
    109. getE().clear();
    110. // Product pp = new Product();
    111. // pp.setId(productID);
    112. // pp.setStatus(1);
    113. // pp = productService.selectOne(pp);
    114. // if(pp==null){
    115. // throw new NullPointerException("根据商品ID="+productID+"查询不到指定的商品信息。");
    116. // }
    117. // pp.setBuyCount(inputBuyNum);
    118. //
    119. // cartInfo.getProductList().add(pp);
    120. // }
    121. // cartInfo.setAmount(cartInfo.cacl());
    122. // getE().clear();
    123. //
    124. // }
    125. //
    126. // //加载配送信息
    127. // Address add = new Address();
    128. // add.setAccount(acc.getAccount());
    129. // List
      addressList = addressService.selectList(add);
    130. // cartInfo.setAddressList(addressList);
    131. // if(addressList!=null && addressList.size()>0){
    132. boolean exist = false;
    133. // for(int i=0;i
    134. // Address addItem = addressList.get(i);
    135. // if(StringUtils.isNotBlank(addItem.getIsdefault()) && addItem.getIsdefault().equals("y")){
    136. // cartInfo.setDefaultAddessID(addItem.getId());
    137. // break;
    138. // }
    139. // }
    140. // }
    141. // logger.error("cartInfo="+cartInfo);
    142. // return "cart";
    143. }
    144. /**
    145. * 从购物车中删除指定的产品
    146. * @return
    147. */
    148. @RequestMapping(value = "delete", method = RequestMethod.POST)
    149. public String delete(ModelMap model, String id){
    150. if(StringUtils.isBlank(id)){
    151. throw new NullPointerException("非法请求!");
    152. }
    153. CartInfo cartInfo = getMyCart();
    154. if(cartInfo==null){
    155. //会话超时,转到登陆页面
    156. return page_toLoginRedirect;
    157. }
    158. for(Iterator it = cartInfo.getProductList().iterator();it.hasNext();){
    159. Product p = it.next();
    160. if(p.getId().equals(id)){
    161. it.remove();
    162. //重新计算总支付金额
    163. // cartInfo.setAmount(cartInfo.totalCacl());
    164. cartInfo.totalCacl();
    165. break;
    166. }
    167. }
    168. return "redirect:/cart/cart.html";
    169. }
    170. DecimalFormat df = new DecimalFormat("0.00");
    171. /**
    172. * 加入购物车,不对金额进行任何的运算。金额的运算在方法CartAction.notifyCart
    173. * @return
    174. * @throws IOException
    175. */
    176. @RequestMapping("addToCart")
    177. @ResponseBody
    178. public String addToCart(ModelMap model) throws IOException{
    179. // Account acc = (Account) getSession().getAttribute(FrontContainer.USER_INFO);
    180. // if (acc == null || StringUtils.isBlank(acc.getAccount())) {
    181. // super.write("1");//需要登录
    182. // return null;
    183. // }
    184. logger.info("ProductAction.cart...");
    185. HttpServletRequest request = RequestHolder.getRequest();
    186. String productID = request.getParameter("productID");//商品ID
    187. int buyCount = Integer.valueOf(request.getParameter("buyCount"));//购买数量
    188. String buySpecID = request.getParameter("buySpecID");//选中的规格ID
    189. if(StringUtils.isEmpty(productID) || buyCount<=0){
    190. throw new NullPointerException("参数错误!");
    191. }
    192. /**
    193. * 检查内存库存是否已超卖,如果超库存不足,则提醒用户
    194. */
    195. ProductStockInfo momeryStockInfo = SystemManager.getInstance().getProductStockMap().get(productID);
    196. if(momeryStockInfo==null){
    197. String jsonError = JSON.toJSONString(new StockErrorProduct(productID,"很抱歉,商品已下架暂时无法购买!"));
    198. logger.info("jsonError=" + jsonError);
    199. return (jsonError);
    200. }
    201. CartInfo cartInfo = getMyCart();
    202. if(cartInfo==null){
    203. cartInfo = new CartInfo();
    204. }
    205. RequestHolder.getSession().setAttribute(FrontContainer.myCart, cartInfo);
    206. //检查指定的产品是否已购买到购物车,购买了则数量++,否则查询后添加到购物车
    207. boolean exists = false;
    208. for(int i=0;i
    209. Product p = cartInfo.getProductList().get(i);
    210. if(p.getId().equals(productID)){
    211. p.setBuyCount(p.getBuyCount()+buyCount);
    212. logger.info("商品已购买,只对数量进行++,总数=" + p.getBuyCount());
    213. if(p.getExchangeScore() > 0){
    214. p.setTotal0("0.00");
    215. p.setTotalExchangeScore(p.getBuyCount() * p.getExchangeScore());
    216. }else{
    217. p.setTotal0(df.format(p.getBuyCount() * Double.valueOf(p.getNowPrice())));
    218. }
    219. exists = true;
    220. }
    221. }
    222. //如果购物车中部存在此商品,则添加到购物车
    223. if(!exists){
    224. Product product = new Product();
    225. product.setId(productID);
    226. // product.setStatus(1);
    227. product = productService.selectOne(product);
    228. if(product==null){
    229. throw new NullPointerException();
    230. }
    231. /**
    232. * 如果此商品为促销活动的商品,则按照活动规则计算商品金额
    233. */
    234. if(StringUtils.isNotBlank(product.getActivityID())){
    235. Activity activity = SystemManager.getInstance().getActivityMap().get(product.getActivityID());
    236. if(activity==null){
    237. String jsonError = JSON.toJSONString(new StockErrorProduct(productID,"活动可能已下架!"));
    238. logger.error("jsonError="+jsonError);
    239. return (jsonError);//活动可能已下架!
    240. }else if(activity.checkActivity()){
    241. String jsonError = JSON.toJSONString(new StockErrorProduct(productID,"活动已结束!"));
    242. logger.error("jsonError="+jsonError);
    243. return (jsonError);//活动已结束!
    244. }
    245. //检查是否符合此活动的会员等级范围
    246. Account acc = getLoginAccount();
    247. if(acc==null){
    248. String jsonError = JSON.toJSONString(new StockErrorProduct(productID,"此商品为促销活动的商品,请先登陆才能购买!!"));
    249. logger.error("jsonError="+jsonError);
    250. return (jsonError);
    251. }
    252. logger.error("acc.getRank() = " + acc.getRank());
    253. logger.error("activity.getAccountRange() = " + activity.getAccountRange());
    254. if(activity.getAccountRange().indexOf(acc.getRank()) < 0){
    255. String jsonError = JSON.toJSONString(new StockErrorProduct(productID,"您的会员等级不在此活动的购买范围内!"));
    256. logger.error("jsonError="+jsonError);
    257. return (jsonError);
    258. }
    259. //计算活动商品的最终结算价
    260. product.setNowPrice(product.caclFinalPrice());
    261. //判断如果是积分商品,则计算所需的积分
    262. if(activity.getActivityType().equals(Activity.activity_activityType_j)){
    263. product.setExchangeScore(activity.getExchangeScore());
    264. }
    265. }
    266. product.setBuyCount(buyCount);
    267. /**
    268. * 加载指定商品的规格信息
    269. */
    270. if(StringUtils.isNotBlank(buySpecID)){
    271. Spec spec = specService.selectById(buySpecID);
    272. if(spec==null){
    273. throw new NullPointerException("根据指定的规格"+buySpecID+"查询不到任何数据!");
    274. }
    275. product.setBuySpecInfo(spec);
    276. //减少以后的逻辑判断,规格的价格等同于商品的价格
    277. product.setNowPrice(spec.getSpecPrice());
    278. }
    279. if(product.getExchangeScore()==0){
    280. product.setTotal0(df.format(product.getBuyCount() * Double.valueOf(product.getNowPrice())));
    281. }else{
    282. product.setTotalExchangeScore(product.getBuyCount() * product.getExchangeScore());
    283. product.setTotal0("0.00");
    284. }
    285. cartInfo.getProductList().add(product);
    286. logger.error("添加商品到购物车!商品ID="+product.getId());
    287. }
    288. cartInfo.totalCacl();//计算购物车中商品总金额
    289. // e.clear();
    290. return ("0");//成功添加商品到购物车
    291. }
    292. /**
    293. * 通知购物车+-商品,然后计算出总金额返回。
    294. * @return
    295. * @throws IOException
    296. */
    297. @RequestMapping(value = "notifyCart", method = RequestMethod.POST)
    298. @ResponseBody
    299. public String notifyCart(ModelMap model) throws IOException{
    300. HttpServletRequest request = RequestHolder.getRequest();
    301. int currentBuyNumber = Integer.valueOf(request.getParameter("currentBuyNumber"));//当前购买的商品的数量
    302. String productID = request.getParameter("productID");//+-的商品ID
    303. logger.error("currentBuyNumber="+currentBuyNumber+",productID="+productID);
    304. if (StringUtils.isBlank(productID) || currentBuyNumber<=0) {
    305. throw new NullPointerException("非法请求!");
    306. }
    307. CartInfo cartInfo = getMyCart();
    308. if(cartInfo==null || cartInfo.getProductList()==null || cartInfo.getProductList().size()==0){
    309. //购物车失效,转到登陆页面
    310. return page_toLoginRedirect;
    311. }
    312. // String msg = null;
    313. CartProductInfo cartProductInfo = new CartProductInfo();
    314. /**
    315. * 检查购买的商品是否超出库存数
    316. */
    317. ProductStockInfo stockInfo = SystemManager.getInstance().getProductStockMap().get(productID);
    318. if(stockInfo==null){
    319. //商品已卖完或已下架,请联系站点管理员!
    320. logger.error("商品已卖完或已下架,请联系站点管理员或从购物车中删除!");
    321. cartProductInfo.code = "notThisProduct";
    322. cartProductInfo.msg = "商品已卖完或已下架,请联系站点管理员或从购物车中删除!";
    323. return (JSON.toJSONString(cartProductInfo));
    324. // super.write("{\"code\":\"notThisProduct\",\"msg\":\"商品已卖完或已下架,请联系站点管理员或从购物车中删除!\"}");
    325. } else if(StringUtils.isNotBlank(stockInfo.getActivityID())){
    326. /**
    327. * 购买的是活动促销的商品,则检查是否超出购买的最大数量
    328. */
    329. Activity activity = SystemManager.getInstance().getActivityMap().get(stockInfo.getActivityID());
    330. if(activity==null || activity.getStatus().equals(Activity.activity_status_n)){
    331. cartProductInfo.code = "buyMore";
    332. cartProductInfo.msg = "此商品为促销活动的商品,最多只能购买" + activity.getMaxSellCount()+"件";
    333. return (JSON.toJSONString(cartProductInfo));
    334. }else if(activity.getMaxSellCount() != 0 && currentBuyNumber > activity.getMaxSellCount()){
    335. // String msg0 = "此商品为促销活动的商品,最多只能购买" + activity.getMaxSellCount()+"件";
    336. // msg = "{\"code\":\"buyMore\",\"msg\":\"" + msg0 + "\",\"maxStock\":\""+stockInfo.getStock()+"\"}";
    337. cartProductInfo.code = "buyMore";
    338. cartProductInfo.msg = "此商品为促销活动的商品,最多只能购买" + activity.getMaxSellCount()+"件";
    339. return (JSON.toJSONString(cartProductInfo));
    340. }
    341. // if(activity.getActivityType().equals(Activity.activity_activityType_j)){
    342. currentBuyNumber * activity.getExchangeScore()
    343. // activity.sete
    344. // }
    345. }else{
    346. if(stockInfo.getStock() < currentBuyNumber){
    347. //购买的商品数超出库存数,则自动当最大库存数计算
    348. currentBuyNumber = stockInfo.getStock();
    349. // String msg0 = "最多只能买"+stockInfo.getStock()+"件";
    350. // msg = "{\"code\":\"buyMore\",\"msg\":\""+msg0+"\",\"maxStock\":\""+stockInfo.getStock()+"\"}";
    351. cartProductInfo.code = "buyMore";
    352. cartProductInfo.msg = "最多只能买"+stockInfo.getStock()+"件";
    353. return (JSON.toJSONString(cartProductInfo));
    354. }
    355. }
    356. /**
    357. * 计算出点击+-的这一个商品的一些信息:小计、所需积分
    358. */
    359. // if(msg==null){
    360. for(int i=0;i
    361. Product pro = cartInfo.getProductList().get(i);
    362. if(pro.getId().equals(productID)){
    363. pro.setBuyCount(currentBuyNumber);//设置指定商品购买的数量
    364. cartInfo.totalCacl();//计算购物车中商品总金额
    365. // msg = "{\"code\":\"ok\",\"amount\":\""+cartInfo.getAmount()+"\"}";
    366. if(pro.getExchangeScore()==0){
    367. pro.setTotal0(df.format(Double.valueOf(pro.getNowPrice()) * pro.getBuyCount()));
    368. }else{
    369. pro.setTotal0("0.00");
    370. pro.setTotalExchangeScore(pro.getBuyCount() * pro.getExchangeScore());
    371. }
    372. cartProductInfo.code = "ok";
    373. cartProductInfo.total0 = pro.getTotal0();
    374. cartProductInfo.amount = cartInfo.getAmount();
    375. cartProductInfo.totalExchangeScore = pro.getBuyCount() * pro.getExchangeScore();
    376. cartProductInfo.amountExchangeScore = cartInfo.getTotalExchangeScore();
    377. // cartProductInfo.msg = "{\"code\":\"ok\",\"amount\":\""+cartInfo.getAmount()+"\"}";
    378. break;
    379. }
    380. }
    381. // }
    382. return (JSON.toJSONString(cartProductInfo));
    383. }
    384. /**
    385. * 正式转到支付之前的最后一次检查库存
    386. * 此方法也可以用于批量错误消息检查,比如在购物车商品列表页面,提交到支付页面的时候进行批量检查(所有商品是否都有货、是否存在超卖、是否已下架、是否活动已结束(未在指定时间内进行支付,且活动已结束))
    387. * @return
    388. * @throws IOException
    389. */
    390. @RequestMapping("checkStockLastTime")
    391. @ResponseBody
    392. public String checkStockLastTime() throws IOException{
    393. logger.error("checkStockLastTime...");
    394. Account acc = getLoginAccount();
    395. if(acc==null){
    396. // throw new NullPointerException("请先登陆!");
    397. logger.error("提示用户需要登录...");
    398. return ("-1");//提示用户需要登录
    399. }
    400. StockErrorProductReturn result = new StockErrorProductReturn();
    401. CartInfo cartInfo = getMyCart();
    402. if(cartInfo==null){
    403. logger.error("login..");
    404. //session超时,转到登陆页面,让用户重新登陆下单,上次未支付的单子只能找不到了。
    405. result.code = "login";
    406. return (JSON.toJSONString(result).toString());
    407. }
    408. result.code = "result";
    409. List list = new LinkedList();
    410. for(int i=0;i
    411. Product pro = cartInfo.getProductList().get(i);
    412. ProductStockInfo stockInfo = SystemManager.getInstance().getProductStockMap().get(pro.getId());
    413. if(stockInfo!=null){
    414. if(StringUtils.isNotBlank(stockInfo.getActivityID())){
    415. /**
    416. * 购买的是活动促销的商品,则检查是否超出购买的最大数量
    417. */
    418. Activity activity = SystemManager.getInstance().getActivityMap().get(stockInfo.getActivityID());
    419. if(activity.getMaxSellCount() != 0 && pro.getBuyCount() > activity.getMaxSellCount()){
    420. String msg0 = "此商品为促销活动的商品,最多只能购买" + activity.getMaxSellCount()+"件";
    421. // msg = "{\"code\":\"buyMore\",\"msg\":\"" + msg0 + "\",\"maxStock\":\""+stockInfo.getStock()+"\"}";
    422. list.add(new StockErrorProduct(pro.getId(),msg0));
    423. }
    424. //如果商品为需要积分兑换的,则检查用户账户上的积分是否足够
    425. if(false){
    426. acc = getLoginAccount();
    427. if(acc==null){
    428. throw new NullPointerException("请先登陆!");
    429. }
    430. //积分不足的错误提示
    431. if(acc.getScore() < activity.getExchangeScore() * pro.getBuyCount()){
    432. list.add(new StockErrorProduct(pro.getId(),"此商品总共所需积分:"+activity.getExchangeScore() * pro.getBuyCount() + "点,可惜您目前只有"+acc.getScore()+"积分"));
    433. }
    434. }
    435. }else{
    436. if(stockInfo.getStock()
    437. //购物车中购买的商品超出库存数
    438. list.add(new StockErrorProduct(pro.getId(),"最多只能购买"+stockInfo.getStock()+"个!"));
    439. }
    440. // if(stockInfo.getStock() < currentBuyNumber){
    441. // //购买的商品数超出库存数,则自动当最大库存数计算
    442. // currentBuyNumber = stockInfo.getStock();
    443. //
    444. // String msg0 = "最多只能买"+stockInfo.getStock()+"件";
    445. // msg = "{\"code\":\"buyMore\",\"msg\":\""+msg0+"\",\"maxStock\":\""+stockInfo.getStock()+"\"}";
    446. // }
    447. }
    448. }else{
    449. //商品可能已经下架或售完!
    450. list.add(new StockErrorProduct(pro.getId(),"商品可能已经下架或售完!"));
    451. }
    452. }
    453. //检查积分是否足够支付此订单消耗的积分
    454. //积分不足的错误提示
    455. if(acc.getScore() < cartInfo.getTotalExchangeScore()){
    456. result.error = "总共所需积分:" + cartInfo.getTotalExchangeScore() + ",可惜您仅有积分:" + acc.getScore();
    457. }
    458. if(list!=null && list.size()>0){
    459. result.list = list;
    460. }
    461. cartInfo.totalCacl();//计算购物车中商品总金额
    462. // logger.error("checkStockLastTime..."+JSON.toJSONString(result).toString());
    463. return (JSON.toJSONString(result).toString());
    464. }
    465. /**
    466. * 库存检查返回的错误对象
    467. * @author huangf
    468. *
    469. */
    470. class StockErrorProductReturn{
    471. String code;
    472. String error;//错误消息,显示到提交按钮边上
    473. List list;
    474. public String getCode() {
    475. return code;
    476. }
    477. public void setCode(String code) {
    478. this.code = code;
    479. }
    480. public List getList() {
    481. return list;
    482. }
    483. public void setList(List list) {
    484. this.list = list;
    485. }
    486. public String getError() {
    487. return error;
    488. }
    489. public void setError(String error) {
    490. this.error = error;
    491. }
    492. }
    493. /**
    494. * 库存检查错误消息对象
    495. */
    496. class StockErrorProduct{
    497. String id;//商品ID
    498. String tips;//错误消息
    499. public StockErrorProduct(){}
    500. public StockErrorProduct(String id,String tips){
    501. this.id = id;
    502. this.tips = tips;
    503. }
    504. public String getId() {
    505. return id;
    506. }
    507. public void setId(String id) {
    508. this.id = id;
    509. }
    510. public String getTips() {
    511. return tips;
    512. }
    513. public void setTips(String tips) {
    514. this.tips = tips;
    515. }
    516. }
    517. /**
    518. * 购物车页面,单个商品返回的信息对象
    519. */
    520. class CartProductInfo {
    521. String code;//返回代码
    522. String msg;//返回消息
    523. String total0;//小计金额
    524. String amount;//总计金额
    525. int totalExchangeScore;//兑换此商品所需总积分
    526. int amountExchangeScore;//积分汇总
    527. public String getCode() {
    528. return code;
    529. }
    530. public void setCode(String code) {
    531. this.code = code;
    532. }
    533. public String getMsg() {
    534. return msg;
    535. }
    536. public void setMsg(String msg) {
    537. this.msg = msg;
    538. }
    539. public String getTotal0() {
    540. return total0;
    541. }
    542. public void setTotal0(String total0) {
    543. this.total0 = total0;
    544. }
    545. public String getAmount() {
    546. return amount;
    547. }
    548. public void setAmount(String amount) {
    549. this.amount = amount;
    550. }
    551. public int getTotalExchangeScore() {
    552. return totalExchangeScore;
    553. }
    554. public void setTotalExchangeScore(int totalExchangeScore) {
    555. this.totalExchangeScore = totalExchangeScore;
    556. }
    557. public int getAmountExchangeScore() {
    558. return amountExchangeScore;
    559. }
    560. public void setAmountExchangeScore(int amountExchangeScore) {
    561. this.amountExchangeScore = amountExchangeScore;
    562. }
    563. }
    564. }

    如果也想学习本系统,下面领取。回复:225ssm 

  • 相关阅读:
    [译]BNF 表示法:深入了解 Python 的语法
    redis(封装jedis)-----面试
    MySQL基础十八章
    公园设施3D可视化:游园新体验,触手可及的未来
    HTML5期末考核大作业——学生网页设计作业源码HTML+CSS+JavaScript 中华美德6页面带音乐文化
    JAVA:实现Sudoku数独算法(附完整源码)
    和monkey的相处日记
    树状数组:leetcode307 区域和检索
    Google Earth Engine ——Landsat 5 和Landsat1-4影像集合
    小程序云开发笔记二
  • 原文地址:https://blog.csdn.net/hanyunlong1989/article/details/126077481