说明:当用户单击退出按钮之后, 页面应该重定向到系统首页,同时删除cookie和redis的登录信息.
说明:当用户点击退出操作之后,应该利用jt-web服务器中的UserController完成该业务.
/**
* 完成用户退出操作
* 1.url: http://www.jt.com/user/logout.html
* 2.没有传递参数
* 3.返回值: string 重定向到系统首页
* 业务实现思路:
* 0.先获取cookie中的数据 NAME=JT_TICKET
* 1.删除redis中的数据 key-value key=cookie中的value
* 2.删除cookie记录 根据cookie名称 设置存活时间即可.
*
* 注意事项: request对象中只能传递cookie的name和value.不能传递其他数据参数.
* 所以如果需要再次操作cookie则最好设定参数,否则可能导致操作失败
*/
@RequestMapping("/logout")
public String logout(HttpServletRequest request,HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
if(cookies !=null && cookies.length >0) {
for (Cookie cookie : cookies) {
if("JT_TICKET".equalsIgnoreCase(cookie.getName())) {
String ticket = cookie.getValue();
//1.删除redis数据
jedisCluster.del(ticket);
//2.删除cookie 立即删除cookie 0 , 暂时不删,关闭浏览器时删除 -1
cookie.setDomain("jt.com");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
break;
}
}
}
//重定向到系统首页
return "redirect:/";
}
当用户看中某一个商品时,点击该商品,应该展现的是商品的详情信息.
说明:编辑manage.jt.com的yml配置文件, 注意duubo端口号及dubbo服务名称.
server:
port: 8091
servlet:
context-path: /
spring:
datasource:
#引入druid数据源
#type: com.alibaba.druid.pool.DruidDataSource
#driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
mvc:
view:
prefix: /WEB-INF/views/
suffix: .jsp
#mybatis-plush配置
mybatis-plus:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/mappers/*.xml
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.jt.mapper: debug
#关于Dubbo配置
dubbo:
scan:
basePackages: com.jt #指定dubbo的包路径
application: #应用名称
name: provider-item #一个接口对应一个服务名称
registry:
address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
protocol: #指定协议
name: dubbo #使用dubbo协议(tcp-ip) web-controller直接调用sso-Service
port: 20881 #每一个服务都有自己特定的端口 不能重复.
@Controller
@RequestMapping("/items")
public class ItemController {
@Reference(check = false) //启动时暂时不校验提供者
private DubboItemService itemService;
/**
* http://www.jt.com/items/562379.html 跳转到商品页面
* ${item.title } 商品信息
* ${itemDesc.itemDesc } 商品详情信息
*
* 业务说明: 根据商品id查询执行的商品/商品详情信息,之后在页面中展现.
* @param itemId
* @return
*/
@RequestMapping("/{itemId}")
public String findItemById(@PathVariable Long itemId,Model model) {
Item item = itemService.findItemById(itemId);
ItemDesc itemDesc = itemService.findItemDescById(itemId);
model.addAttribute("item", item);
model.addAttribute("itemDesc", itemDesc);
return "item"; //item.jsp
}
}
@Service
public class DubboItemServiceImpl implements DubboItemService {
@Autowired
private ItemMapper itemMapper;
@Autowired
private ItemDescMapper itemDescMapper;
@Override
public Item findItemById(Long itemId) {
return itemMapper.selectById(itemId);
}
@Override
public ItemDesc findItemDescById(Long itemId) {
return itemDescMapper.selectById(itemId);
}
}
@TableName("tb_cart")
@Data
@Accessors(chain = true)
public class Cart extends BasePojo{
@TableId(type = IdType.AUTO)
private Long id;
private Long userId;
private Long itemId;
private String itemTitle;
private String itemImage;
private Long itemPrice;
private Integer num;
}
说明: 添加继承/依赖/插件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jt.vip</groupId>
<artifactId>jt</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>jt-cart</artifactId>
<!--添加依赖 -->
<dependencies>
<dependency>
<groupId>com.jt.vip</groupId>
<artifactId>jt-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<!--3.添加插件 -->
<!--负责项目打包 更新 maven操作相关的配置 必须添加 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
server:
port: 8094
servlet:
context-path: /
spring:
datasource:
#引入druid数据源
#type: com.alibaba.druid.pool.DruidDataSource
#driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
mvc:
view:
prefix: /WEB-INF/views/
suffix: .jsp
#mybatis-plush配置
mybatis-plus:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/mappers/*.xml
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.jt.mapper: debug
#关于Dubbo配置
dubbo:
scan:
basePackages: com.jt #指定dubbo的包路径
application: #应用名称
name: provider-cart #一个接口对应一个服务名称
registry:
address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
protocol: #指定协议
name: dubbo #使用dubbo协议(tcp-ip) web-controller直接调用sso-Service
port: 20882 #每一个服务都有自己特定的端口 不能重复.
1).url分析: 当用户发起请求时应该跳转/cart/show.html页面 将来展现的页面名称为:cart.jsp
@Controller
@RequestMapping("/cart")
public class CartController {
@Reference(check = false)
private DubboCartService cartService;
/**
* 业务思路: 当用户点击购物车按钮时,应该根据userId查询购物车信息,之后在列表页面中展现.
* 页面数据展现: 利用${cartList}展现数据
* @return
*/
@RequestMapping("/show")
public String show(Model model) {
//1.获取userId 利用单点登录方式动态获取userID 暂时定死
Long userId = 7L;
//2.根据userId查询购物车数据
List<Cart> cartList = cartService.findCartListByUserId(userId);
//利用model对象将数据填充到域对象中request域
model.addAttribute("cartList", cartList);
return "cart"; //跳转到购物车展现页面
}
}
@Service
public class DubboCartServiceImpl implements DubboCartService {
@Autowired
private CartMapper cartMapper;
@Override
public List<Cart> findCartListByUserId(Long userId) {
QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId);
return cartMapper.selectList(queryWrapper);
}
}
1).页面url分析 /cart/update/num/商品ID/数量
2). 页面JS分析
$(".increment") 代表class选择器. 识别标签元素 class=“increment” 的元素
$(".increment").click(function(){//+
var _thisInput = $(this).siblings("input"); //找到input框
//_thisInput.val() 获取input框中的元素
//eval 进行算数运算
//_thisInput.val(14); 赋值操作
_thisInput.val(eval(_thisInput.val()) + 1);
$.post("/cart/update/num/"+_thisInput.attr("itemId")+"/"+_thisInput.val(),function(data){
TTCart.refreshTotalPrice();
});
});
/**
* 业务需求: 完成购物车更新操作
* 1.url地址: http://www.jt.com/cart/update/num/562379/13
* 2.请求参数: 562379-itemId /13-num
* 3.返回值结果: void
*
*/
@RequestMapping("/update/num/{itemId}/{num}")
@ResponseBody
public void updateCart(Cart cart) { //参数如果和属性名称一致,则可以直接赋值.
//userId和itemId
Long userId = 7L;
cart.setUserId(userId);
cartService.updateCartNum(cart);
}
//update tb_cart set num = #{num},updated = #{updated} where user_id=#{userId} and
//item_id =#{itemId}
@Override
@Transactional
public void updateCartNum(Cart cart) {
Cart cartTemp = new Cart();
cartTemp.setNum(cart.getNum())
.setUpdated(cart.getUpdated());
UpdateWrapper<Cart> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("item_id", cart.getItemId())
.eq("user_id", cart.getUserId());
cartMapper.update(cartTemp, updateWrapper);
}
当查询商品之后,点击新增购物车时.应该跳转到购物车展现页面. 之后完成购物车新增操作.
强调:
1.当用户第一次新增购物车时,应该入库保存
2.当用户重复添加时,应该只更新商品的数量.
/**
* url地址:http://www.jt.com/cart/add/562379.html
* 参数: 表单数据提交 cart
* 返回值: 重定向到购物车展现页面
*/
@RequestMapping("/add/{itemId}")
public String saveCart(Cart cart) {
Long userId = 7L;
cart.setUserId(userId);
cartService.saveCart(cart);
return "redirect:/cart/show.html"; //维护伪静态策略
}
//1.第一次架构 入库
//2.第N次架构 更新数据库
@Override
@Transactional
public void saveCart(Cart cart) {
//1.先查询数据库中是否有该记录 itemId和userId
QueryWrapper<Cart> queryWrapper = new QueryWrapper<Cart>();
queryWrapper.eq("user_id", cart.getUserId());
queryWrapper.eq("item_id", cart.getItemId());
Cart cartDB = cartMapper.selectOne(queryWrapper);
//cartDB几乎所有的数据都不为null 将来可能被当做条件使用.
if(cartDB == null) {
//说明第一次加购
cart.setCreated(new Date())
.setUpdated(cart.getCreated());
cartMapper.insert(cart);
}else {
//只更新商品数量
int num = cart.getNum() + cartDB.getNum();
/**Cart cartTemp = new Cart();
cartTemp.setId(cartDB.getId())
.setNum(num)
.setUpdated(new Date());
cartMapper.updateById(cartTemp); //根据主键更新数据库.
**/
//自己手动操作Sql
cartMapper.updateCartNum(cartDB.getId(),num,new Date());
}
}
1.完成购物车删除操作 执行删除之后应该重定向到购物车首页
2.不使用其他的框架 控制不登录时不允许访问购物车操作 只有登录之后才能访问 权限控制 ------拦截器
3.如何动态的获取userId