上一篇: 微服务(四)—— 用户模块(backend-user).
一、创建项目
首先创建一个SpringBoot项目,具体创建过程和 微服务(三)—— 用户模块(backend-user).一样。
二、项目结构
1.目录结构
项目结构和backend-user模块类似,由于产品需要上传图片文件,所以多了一个上传文件的UpLoadController,和前端的html,SpringBoot的前端页面需要放在resources/templates目录下,然后还有一个需要给前端封装数据的VO类
下面说一下具体的实现类,先看一下产品分类的CategoryManageController类
package com.aiun.product.controller;
/**
* 产品分类
*
* @author lenovo
*/
@Api(tags = "产品分类相关接口")
@RestController
@RequestMapping("/category/manage/")
public class CategoryManageController {
@Autowired
private ICategoryService iCategoryService;
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* 增加品类
*
* @param request 请求
* @param categoryName 品类名称
* @param parentId 父 id
* @return 返回结果
*/
@GetMapping("add_category")
@ApiOperation(value = "增加品类")
public ServerResponse addCategory(HttpServletRequest request, String categoryName, @RequestParam(value = "parentId", defaultValue = "0") int parentId) {
ServerResponse hasLogin = loginHasExpired(request);
System.out.println("request : " + request);
if (hasLogin.isSuccess()) {
User user = (User) hasLogin.getData();
System.out.println("user : " + user);
// 检查是否是管理员
if (user.getRole() == UserConst.Role.ROLE_ADMIN) {
System.out.println("categoryName : " + categoryName);
// 是管理员,处理分类的逻辑
return iCategoryService.addCategory(categoryName, parentId);
} else {
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
}
return hasLogin;
}
/**
* 设置品类名称
*
* @param request 请求
* @param categoryId 品类 id
* @param categoryName 品类名
* @return 返回结果
*/
@PostMapping("set_category_name")
@ApiOperation(value = "设置品类名称")
public ServerResponse setCategoryName(HttpServletRequest request, Integer categoryId, String categoryName) {
ServerResponse hasLogin = loginHasExpired(request);
if (hasLogin.isSuccess()) {
User user = (User) hasLogin.getData();
//检查是否是管理员
if (user.getRole() == UserConst.Role.ROLE_ADMIN) {
//是管理员,处理分类的逻辑
return iCategoryService.updateCategoryName(categoryId, categoryName);
} else {
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
}
return hasLogin;
}
/**
* 获取节点的并且是平级的品类
*
* @param request 请求
* @param categoryId 品类 id
* @return 返回结果
*/
@PostMapping("get_category")
@ApiOperation(value = "获取节点的并且是平级的品类")
@ResponseBody
public ServerResponse getChildrenParallelCategory(HttpServletRequest request, @RequestParam(value = "categoryId", defaultValue = "0") Integer categoryId) {
ServerResponse hasLogin = loginHasExpired(request);
if (hasLogin.isSuccess()) {
User user = (User) hasLogin.getData();
//检查是否是管理员
if (user.getRole() == UserConst.Role.ROLE_ADMIN) {
//查询子节点的品种信息,并且不递归,保持平级
return iCategoryService.getChildrenParallelCategory(categoryId);
} else {
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
}
return hasLogin;
}
/**
* 获取节点并且递归获取子节点的品类
*
* @param request 请求
* @param categoryId 品类 id
* @return 返回结果
*/
@PostMapping("get_deep_category")
@ApiOperation(value = "获取节点并且递归获取子节点的品类")
@ResponseBody
public ServerResponse getCategoryAddDeepChildrenCategory(HttpServletRequest request, @RequestParam(value = "categoryId", defaultValue = "0") Integer categoryId) {
ServerResponse hasLogin = loginHasExpired(request);
if (hasLogin.isSuccess()) {
User user = (User) hasLogin.getData();
// 检查是否是管理员
if (user.getRole() == UserConst.Role.ROLE_ADMIN) {
// 查询当前节点并且递归查询子节点
return iCategoryService.selectCategoryAndChildrenById(categoryId);
} else {
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
}
return hasLogin;
}
/**
* 判断用户登录是否过期
*
* @param request 请求
* @return 结果
*/
private ServerResponse<User> loginHasExpired(HttpServletRequest request) {
String key = request.getHeader(UserConst.AUTHORITY);
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
String value = valueOperations.get(key);
if (StringUtils.isEmpty(value)) {
return ServerResponse.createByErrorMessage(ResponseCode.NEED_LOGIN.getCode(), ResponseCode.NEED_LOGIN.getDesc());
}
User user = JsonUtils.jsonStr2Object(value, User.class);
if (!key.equals(user.getUsername())) {
return ServerResponse.createByErrorMessage(ResponseCode.NEED_LOGIN.getCode(), ResponseCode.NEED_LOGIN.getDesc());
}
valueOperations.set(key, value, 1, TimeUnit.HOURS);
return ServerResponse.createBySuccess(user);
}
}
它调用Service层的接口,下面看一下Service层的实现类CategoryServiceImpl
package com.aiun.product.service.impl;
/**
* @author lenovo
*/
@Service("iCategoryService")
public class CategoryServiceImpl implements ICategoryService {
private Logger logger = LoggerFactory.getLogger(CategoryServiceImpl.class);
@Autowired
private CategoryMapper categoryMapper;
@Override
public ServerResponse<String> addCategory(String categoryName, Integer parentId) {
if (parentId == null || StringUtils.isBlank(categoryName)) {
return ServerResponse.createByErrorMessage("品类参数错误");
}
Category category = new Category();
category.setName(categoryName);
category.setParentId(parentId);
//表示状态可用
category.setStatus(true);
int resultCount = categoryMapper.insert(category);
if (resultCount > 0) {
return ServerResponse.createBySuccessMessage("添加品类成功");
}
return ServerResponse.createByErrorMessage("添加品类失败");
}
@Override
public ServerResponse updateCategoryName(Integer categoryId, String categoryName) {
if (categoryId == null || StringUtils.isBlank(categoryName)) {
return ServerResponse.createByErrorMessage("更新品类参数错误");
}
Category category = new Category();
category.setId(categoryId);
category.setName(categoryName);
int resultCount = categoryMapper.updateByPrimaryKeySelective(category);
if (resultCount > 0) {
return ServerResponse.createBySuccessMessage("更新品类名字成功");
}
return ServerResponse.createByErrorMessage("更新品类名字失败");
}
@Override
public ServerResponse<List<Category>> getChildrenParallelCategory(Integer categoryId) {
List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
if (categoryList.isEmpty()) {
logger.info("未找到当前分类的子分类");
}
return ServerResponse.createBySuccess(categoryList);
}
/**
* 递归查询本节点的id及孩子节点的id
* @param categoryId
* @return
*/
@Override
public ServerResponse<List<Integer>> selectCategoryAndChildrenById(Integer categoryId) {
Set<Category> categorySet = new HashSet<>();
findChildCategory(categorySet, categoryId);
List<Integer> categoryIdList = new ArrayList<>();
if (categoryId != null) {
categorySet.forEach(e->categoryIdList.add(e.getId()));
}
return ServerResponse.createBySuccess(categoryIdList);
}
/**
* 递归找出子节点
* @return
*/
private Set<Category> findChildCategory(Set<Category> categorySet, Integer categoryId) {
Category category = categoryMapper.selectByPrimaryKey(categoryId);
if (category != null) {
categorySet.add(category);
}
//查找子节点,要有退出条件
List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
categoryList.forEach(e->findChildCategory(categorySet, e.getId()));
return categorySet;
}
}
Service层调用DAO层的Mapper接口CategoryMapper
package com.aiun.product.mapper;
/**
* @author lenovo
*/
@Mapper
@Component
public interface CategoryMapper {
/**
* 通过主键删除商品种类
* @param id 主键
* @return 操作影响行数
*/
int deleteByPrimaryKey(Integer id);
/**
* 插入商品种类
* @param record 商品种类类
* @return 操作影响行数
*/
int insert(@Param("record") Category record);
/**
* 有选择的插入
* @param record 商品种类类
* @return 操作影响行数
*/
int insertSelective(@Param("record")