New bee mall project notes
1. Start the project and access the api online documentation
http://localhost:8080/swagger-ui.html
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ge9fugsh-163811491017) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128181427273. PNG)]
1. result class
The author defines a result class for the returned results of api documents as a template for response results
public class Result<T> implements Serializable { private static final long serialVersionUID = 1L; //Business code s, such as success, failure, insufficient permission and so on, can be defined by yourself @ApiModelProperty("Return code") private int resultCode; //Return information. After business processing, the back end returns a prompt message to the front end, which can be defined by itself @ApiModelProperty("Return information") private String message; //Data results, generic, can be lists, single objects, numbers, Booleans, etc @ApiModelProperty("Return data") private T data; public Result() { } public Result(int resultCode, String message) { this.resultCode = resultCode; this.message = message; } public int getResultCode() { return resultCode; } public void setResultCode(int resultCode) { this.resultCode = resultCode; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } @Override public String toString() { return "Result{" + "resultCode=" + resultCode + ", message='" + message + '\'' + ", data=" + data + '}'; } }
Each response body includes three parts
- resultCode
- message
- Data (where data is generic)
example:
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-qm9ukkru-163811491020) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128183745040. PNG)]
2.ResultGenerator
ResultGenerator is a response result generation tool
- Success: there are three kinds of genSuccessResult(), the parameter is empty, message and data;
- Failed: genFailResult()
- Error: genErrorResult()
public class ResultGenerator { private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS"; private static final String DEFAULT_FAIL_MESSAGE = "FAIL"; private static final int RESULT_CODE_SUCCESS = 200; private static final int RESULT_CODE_SERVER_ERROR = 500; public static Result genSuccessResult() { Result result = new Result(); result.setResultCode(RESULT_CODE_SUCCESS); result.setMessage(DEFAULT_SUCCESS_MESSAGE); return result; } public static Result genSuccessResult(String message) { Result result = new Result(); result.setResultCode(RESULT_CODE_SUCCESS); result.setMessage(message); return result; } public static Result genSuccessResult(Object data) { Result result = new Result(); result.setResultCode(RESULT_CODE_SUCCESS); result.setMessage(DEFAULT_SUCCESS_MESSAGE); result.setData(data); return result; } public static Result genFailResult(String message) { Result result = new Result(); result.setResultCode(RESULT_CODE_SERVER_ERROR); if (StringUtils.isEmpty(message)) { result.setMessage(DEFAULT_FAIL_MESSAGE); } else { result.setMessage(message); } return result; } public static Result genErrorResult(int code, String message) { Result result = new Result(); result.setResultCode(code); result.setMessage(message); return result; } }
3. ServiceResultEnum
public enum ServiceResultEnum { ERROR("error"), SUCCESS("success"), DATA_NOT_EXIST("No record found!"), PARAM_ERROR("Parameter error!"), SAME_CATEGORY_EXIST("A category with the same name already exists!"), SAME_LOGIN_NAME_EXIST("User name already exists!"), LOGIN_NAME_NULL("Please enter login name!"), LOGIN_NAME_IS_NOT_PHONE("Please enter the correct mobile phone number!"), LOGIN_PASSWORD_NULL("Please input a password!"), LOGIN_VERIFY_CODE_NULL("Please enter the verification code!"), LOGIN_VERIFY_CODE_ERROR("Verification code error!"), SAME_INDEX_CONFIG_EXIST("The same homepage configuration item already exists!"), GOODS_CATEGORY_ERROR("Classification data exception!"), SAME_GOODS_EXIST("The same product information already exists!"), GOODS_NOT_EXIST("Product does not exist!"), GOODS_PUT_DOWN("The product is off the shelf!"), SHOPPING_CART_ITEM_LIMIT_NUMBER_ERROR("The maximum purchase quantity of a single product is exceeded!"), SHOPPING_CART_ITEM_NUMBER_ERROR("Commodity quantity cannot be less than 1!"), SHOPPING_CART_ITEM_TOTAL_NUMBER_ERROR("The maximum capacity of the shopping cart is exceeded!"), SHOPPING_CART_ITEM_EXIST_ERROR("Already exists! No need to add again!"), LOGIN_ERROR("Login failed!"), NOT_LOGIN_ERROR("Not logged in!"), ADMIN_NOT_LOGIN_ERROR("Administrator is not logged in!"), TOKEN_EXPIRE_ERROR("Invalid authentication! Please login again!"), ADMIN_TOKEN_EXPIRE_ERROR("Administrator login expired! Please login again!"), USER_NULL_ERROR("Invalid user! Please login again!"), LOGIN_USER_LOCKED_ERROR("User has been forbidden to log in!"), ORDER_NOT_EXIST_ERROR("Order does not exist!"), NULL_ADDRESS_ERROR("Address cannot be empty!"), ORDER_PRICE_ERROR("Abnormal order price!"), ORDER_ITEM_NULL_ERROR("Order item exception!"), ORDER_GENERATE_ERROR("Abnormal order generation!"), SHOPPING_ITEM_ERROR("Shopping cart data exception!"), SHOPPING_ITEM_COUNT_ERROR("Insufficient inventory!"), ORDER_STATUS_ERROR("Abnormal order status!"), OPERATE_ERROR("Operation failed!"), REQUEST_FORBIDEN_ERROR("Prohibit this operation!"), NO_PERMISSION_ERROR("No permission!"), DB_ERROR("database error"); private String result; ServiceResultEnum(String result) { this.result = result; } public String getResult() { return result; } public void setResult(String result) { this.result = result; } }
2. Interface analysis
1. New bee mall homepage interface New Bee Mall Index API
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-a5aso1rj-163811491022) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128224011589. PNG)]
/api/v1/index-infos
File: NewBeeMallIndexAPI.java
Function: get home page data
Code analysis:
The objects of two service s are obtained through @ Resource (Spring is injected by Name dependency, @ AutoWired is injected by Type dependency)
@Resource private NewBeeMallCarouselService newBeeMallCarouselService; @Resource private NewBeeMallIndexConfigService newBeeMallIndexConfigService
IndexInfoVo class
The author defines an IndexInfoVO class that inherits Serializable
There are four lists in IndexInfoVO
- Rotation chart (list)
- Home page hot selling goods (list)
- Homepage new product recommendation (list)
- Home page recommended products (list)
@Data public class IndexInfoVO implements Serializable { @ApiModelProperty("Rotation chart(list)") private List<NewBeeMallIndexCarouselVO> carousels; @ApiModelProperty("Home selling goods(list)") private List<NewBeeMallIndexConfigGoodsVO> hotGoodses; @ApiModelProperty("Homepage new product recommendation(list)") private List<NewBeeMallIndexConfigGoodsVO> newGoodses; @ApiModelProperty("Home page recommended products(list)") private List<NewBeeMallIndexConfigGoodsVO> recommendGoodses; }
Rotation chart vo
/** * Home page configuration product VO */ @Data public class NewBeeMallIndexCarouselVO implements Serializable { @ApiModelProperty("Carousel picture address") private String carouselUrl; @ApiModelProperty("Jump path after clicking the rotation chart") private String redirectUrl; }
Commodity VO
/** * Home page configuration product VO */ @Data public class NewBeeMallIndexConfigGoodsVO implements Serializable { @ApiModelProperty("commodity id") private Long goodsId; @ApiModelProperty("Trade name") private String goodsName; @ApiModelProperty("Product introduction") private String goodsIntro; @ApiModelProperty("Product picture address") private String goodsCoverImg; @ApiModelProperty("commodity price") private Integer sellingPrice; @ApiModelProperty("Commodity label") private String tag; }
Get four list procedures
Call the methods in newBeeMallCarouselService and newBeeMallIndexConfigService to obtain four lists and set the four lists to the IndexInfoVO object.
- newBeeMallCarouselService.getCarouselsForIndex
Find the getCarouselsForIndex method of the NewBeeMallCarouselServiceImpl implementation class
NewBeeMallCarouselServiceImpl.java
@Override public List<NewBeeMallIndexCarouselVO> getCarouselsForIndex(int number) { List<NewBeeMallIndexCarouselVO> newBeeMallIndexCarouselVOS = new ArrayList<>(number); List<Carousel> carousels = carouselMapper.findCarouselsByNum(number); if (!CollectionUtils.isEmpty(carousels)) { newBeeMallIndexCarouselVOS = BeanUtil.copyList(carousels, NewBeeMallIndexCarouselVO.class); } return newBeeMallIndexCarouselVOS; }
findCarouselsByNum corresponds to CarouselMapper.xml
<select id="findCarouselList" parameterType="Map" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from tb_newbee_mall_carousel where is_deleted = 0 order by carousel_rank desc <if test="start!=null and limit!=null"> limit #{start},#{limit} </if> </select>
(possible) the method of BeanUtil.copyList is to convert some specific lists into generic lists?
if (!CollectionUtils.isEmpty(carousels)) { newBeeMallIndexCarouselVOS = BeanUtil.copyList(carousels, NewBeeMallIndexCarouselVO.class); }
BeanUtil.java
public static <T> List<T> copyList(List sources, Class<T> clazz) { return copyList(sources, clazz, null); } public static <T> List<T> copyList(List sources, Class<T> clazz, Callback<T> callback) { List<T> targetList = new ArrayList<>(); if (sources != null) { try { for (Object source : sources) { T target = clazz.newInstance(); copyProperties(source, target); if (callback != null) { callback.set(source, target); } targetList.add(target); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return targetList; }
- newBeeMallIndexConfigService.getConfigGoodsesForIndex
Find the getconfiggoldesforindex method of the newBeeMallIndexConfigServiceImpl implementation class
Method key code
List<NewBeeMallGoods> newBeeMallGoods = goodsMapper.selectByPrimaryKeys(goodsIds);
NewBeeMallGoodsMapper.xml
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="ResultMapWithBLOBs"> select <include refid="Base_Column_List"/> , <include refid="Blob_Column_List"/> from tb_newbee_mall_goods_info where goods_id = #{goodsId,jdbcType=BIGINT} </select>
The same conversion to generic processing
newBeeMallIndexConfigGoodsVOS = BeanUtil.copyList(newBeeMallGoods, NewBeeMallIndexConfigGoodsVO.class);
How to deal with the problem of text exceeding due to too long string
for (NewBeeMallIndexConfigGoodsVO newBeeMallIndexConfigGoodsVO : newBeeMallIndexConfigGoodsVOS) { String goodsName = newBeeMallIndexConfigGoodsVO.getGoodsName(); String goodsIntro = newBeeMallIndexConfigGoodsVO.getGoodsIntro(); // The string is too long, causing the text to exceed if (goodsName.length() > 30) { goodsName = goodsName.substring(0, 30) + "..."; newBeeMallIndexConfigGoodsVO.setGoodsName(goodsName); } if (goodsIntro.length() > 22) { goodsIntro = goodsIntro.substring(0, 22) + "..."; newBeeMallIndexConfigGoodsVO.setGoodsIntro(goodsIntro); } }
2. New bee mall user operation related interface New Bee Mall Personal API
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-tf0cb6t7-163811491024) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128224037337. PNG)]
/api/v1/user
File: NewBeeMallPersonalAPI.java
Function: Mall user operation
Code analysis:
a. NewBeeMallPersonalAPI
Whether it is login interface, login interface, user registration and modification of user information subject are written in the same way
- Call the methods in NewBeeMallUserService (login, logout, register, updateUserInfo)
- Call the info method of Logger to add relevant information
- Handling success and failure situations
Example: login interface
@PostMapping("/user/login") @ApiOperation(value = "Login interface", notes = "return token") public Result<String> login(@RequestBody @Valid MallUserLoginParam mallUserLoginParam) { if (!NumberUtil.isPhone(mallUserLoginParam.getLoginName())){ return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_NAME_IS_NOT_PHONE.getResult()); } String loginResult = newBeeMallUserService.login(mallUserLoginParam.getLoginName(), mallUserLoginParam.getPasswordMd5()); logger.info("login api,loginName={},loginResult={}", mallUserLoginParam.getLoginName(), loginResult); //Login succeeded if (!StringUtils.isEmpty(loginResult) && loginResult.length() == Constants.TOKEN_LENGTH) { Result result = ResultGenerator.genSuccessResult(); result.setData(loginResult); return result; } //Login failed return ResultGenerator.genFailResult(loginResult); }
b. NewBeeMallUserServiceImpl
(personal idea: token is actually used to record the online situation)
login
- The selectbyloginnamenandpasswd method is in TB_ newbee_ mall_ The corresponding user is found in the user table. If there is no user, it will be null
MallUser user = mallUserMapper.selectByLoginNameAndPasswd(loginName, passwordMD5);
- Judge whether the returned user is null. Null directly returns the error information. If it is not null, continue to the next step.
if (user != null)
-
There are three situations after login,
The first case: TB for new users who have not logged in_ newbee_ mall_ user_ Add a new token data to the token;
The second case: the user logs in and exits. The token table has no information about him, and he is in TB_ newbee_ mall_ user_ Add a new token data to the token;
The third case: if the user logs in but does not log out, and there is his information in the token table, it will be directly sent to TB_ newbee_ mall_ user_ The user corresponding to the token modifies the token data;
(the author is too clever)
if (user.getLockedFlag() == 1) { return ServiceResultEnum.LOGIN_USER_LOCKED_ERROR.getResult(); } //After logging in, you can modify the token String token = getNewToken(System.currentTimeMillis() + "", user.getUserId()); MallUserToken mallUserToken = newBeeMallUserTokenMapper.selectByPrimaryKey(user.getUserId()); //current time Date now = new Date(); //Expiration time Date expireTime = new Date(now.getTime() + 2 * 24 * 3600 * 1000);//Expiration time: 48 hours if (mallUserToken == null) { mallUserToken = new MallUserToken(); mallUserToken.setUserId(user.getUserId()); mallUserToken.setToken(token); mallUserToken.setUpdateTime(now); mallUserToken.setExpireTime(expireTime); //Add a token data if (newBeeMallUserTokenMapper.insertSelective(mallUserToken) > 0) { //Return after adding successfully return token; } } else { mallUserToken.setToken(token); mallUserToken.setUpdateTime(now); mallUserToken.setExpireTime(expireTime); //to update if (newBeeMallUserTokenMapper.updateByPrimaryKeySelective(mallUserToken) > 0) { //Returned after modification return token; } }
logout
Directly call the delete method to delete the corresponding TB according to the logged in user id_ newbee_ mall_ user_ Token data of token table
@Override public Boolean logout(Long userId) { return newBeeMallUserTokenMapper.deleteByPrimaryKey(userId) > 0; }
register
insert method
@Override public String register(String loginName, String password) { if (mallUserMapper.selectByLoginName(loginName) != null) { return ServiceResultEnum.SAME_LOGIN_NAME_EXIST.getResult(); } MallUser registerUser = new MallUser(); registerUser.setLoginName(loginName); registerUser.setNickName(loginName); registerUser.setIntroduceSign(Constants.USER_INTRO); String passwordMD5 = MD5Util.MD5Encode(password, "UTF-8"); registerUser.setPasswordMd5(passwordMD5); if (mallUserMapper.insertSelective(registerUser) > 0) { return ServiceResultEnum.SUCCESS.getResult(); } return ServiceResultEnum.DB_ERROR.getResult(); }
updateUserInfo
Write separately. First, find the corresponding user with the selett ID, save it to the user, modify the relevant information of the user object, and finally pass the user object to the update method
@Override public Boolean updateUserInfo(MallUserUpdateParam mallUser, Long userId) { MallUser user = mallUserMapper.selectByPrimaryKey(userId); if (user == null) { NewBeeMallException.fail(ServiceResultEnum.DATA_NOT_EXIST.getResult()); } user.setNickName(mallUser.getNickName()); //user.setPasswordMd5(mallUser.getPasswordMd5()); //If the password is empty, it indicates that the user does not intend to change the password and saves it with the original password if (!MD5Util.MD5Encode("", "UTF-8").equals(mallUser.getPasswordMd5())){ user.setPasswordMd5(mallUser.getPasswordMd5()); } user.setIntroduceSign(mallUser.getIntroduceSign()); if (mallUserMapper.updateByPrimaryKeySelective(user) > 0) { return true; } return false; }
Special: get user information
@GetMapping("/user/info") @ApiOperation(value = "Get user information", notes = "") public Result<NewBeeMallUserVO> getUserDetail(@TokenToMallUser MallUser loginMallUser) { //If you have logged in, you can return directly NewBeeMallUserVO mallUserVO = new NewBeeMallUserVO(); BeanUtil.copyProperties(loginMallUser, mallUserVO); return ResultGenerator.genSuccessResult(mallUserVO); }
The copyProperties method of a BeanUtil class is used, (doubt: why not use the select method?)
3. New Bee Mall Goods Category API
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-2cqswjg3-163811491025) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128224054900. PNG)]
/api/v1/categories
File: NewBeeMallGoodsCategoryAPI.java
Function: obtain classification data
Code analysis:
NewBeeMallGoodsCategoryAPI.java
NewBeeMallCategoryService object created
@Resource private NewBeeMallCategoryService newBeeMallCategoryService; @GetMapping("/categories") @ApiOperation(value = "Get classification data", notes = "Classification page usage") public Result<List<NewBeeMallIndexCategoryVO>> getCategories() { List<NewBeeMallIndexCategoryVO> categories = newBeeMallCategoryService.getCategoriesForIndex(); if (CollectionUtils.isEmpty(categories)) { NewBeeMallException.fail(ServiceResultEnum.DATA_NOT_EXIST.getResult()); } return ResultGenerator.genSuccessResult(categories);
getCategoriesForIndex() method in NewBeeMallCategoryServiceImpl
1. Obtain three levels of data
First, take a look at the data part attributes in the table
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-odkwzdzl-163811491026) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128205531699. PNG)]
category_id: classification id
category_level: there are three levels of classification
parent_id: the classification id of the corresponding upper level
Call the selectByLevelAndParentIdsAndNumber method (GoodsCategoryMapper.xml)
According to three categories_ Level to get a list of three classification levels
//Obtain a fixed amount of data for the primary classification List<GoodsCategory> firstLevelCategories = goodsCategoryMapper.selectByLevelAndParentIdsAndNumber(Collections.singletonList(0L), NewBeeMallCategoryLevelEnum.LEVEL_ONE.getLevel(), Constants.INDEX_CATEGORY_NUMBER); if (!CollectionUtils.isEmpty(firstLevelCategories)) { List<Long> firstLevelCategoryIds = firstLevelCategories.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toList()); //Obtain secondary classification data List<GoodsCategory> secondLevelCategories = goodsCategoryMapper.selectByLevelAndParentIdsAndNumber(firstLevelCategoryIds, NewBeeMallCategoryLevelEnum.LEVEL_TWO.getLevel(), 0); if (!CollectionUtils.isEmpty(secondLevelCategories)) { List<Long> secondLevelCategoryIds = secondLevelCategories.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toList()); //Obtain data of three-level classification List<GoodsCategory> thirdLevelCategories = goodsCategoryMapper.selectByLevelAndParentIdsAndNumber(secondLevelCategoryIds, NewBeeMallCategoryLevelEnum.LEVEL_THREE.getLevel(), 0);
2. Processing three levels of data
Let's look at some of the results
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-s7jgx0gi-163811491028) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128210511769. PNG)]
Processing steps
- Save the third level classification to the map according to the parentId
- Each group of parentids corresponds to the categoryId of the second level, and then add the corresponding map in 1 to the "thirdLevelCategoryVOS" attribute of the second level
- Save the second level classification to the map according to the parentId
- Each group of parentids corresponds to the categoryId of the first level, and then add the corresponding map in 3 to the "secondLevelCategoryVOS" attribute of the first level
code:
if (!CollectionUtils.isEmpty(thirdLevelCategories)) { //Group thirdLevelCategories according to parentId Map<Long, List<GoodsCategory>> thirdLevelCategoryMap = thirdLevelCategories.stream().collect(groupingBy(GoodsCategory::getParentId)); List<SecondLevelCategoryVO> secondLevelCategoryVOS = new ArrayList<>(); //Process secondary classification for (GoodsCategory secondLevelCategory : secondLevelCategories) { SecondLevelCategoryVO secondLevelCategoryVO = new SecondLevelCategoryVO(); BeanUtil.copyProperties(secondLevelCategory, secondLevelCategoryVO); //If there is data under the secondary classification, it will be put into the secondLevelCategoryVOS object if (thirdLevelCategoryMap.containsKey(secondLevelCategory.getCategoryId())) { //Take out the three-level classification list in the thirdLevelCategoryMap group according to the id of the two-level classification List<GoodsCategory> tempGoodsCategories = thirdLevelCategoryMap.get(secondLevelCategory.getCategoryId()); secondLevelCategoryVO.setThirdLevelCategoryVOS((BeanUtil.copyList(tempGoodsCategories, ThirdLevelCategoryVO.class))); secondLevelCategoryVOS.add(secondLevelCategoryVO); } } //Process primary classification if (!CollectionUtils.isEmpty(secondLevelCategoryVOS)) { //Group thirdLevelCategories according to parentId Map<Long, List<SecondLevelCategoryVO>> secondLevelCategoryVOMap = secondLevelCategoryVOS.stream().collect(groupingBy(SecondLevelCategoryVO::getParentId)); for (GoodsCategory firstCategory : firstLevelCategories) { NewBeeMallIndexCategoryVO newBeeMallIndexCategoryVO = new NewBeeMallIndexCategoryVO(); BeanUtil.copyProperties(firstCategory, newBeeMallIndexCategoryVO); //If there is data under this primary classification, it will be put into the newBeeMallIndexCategoryVOS object if (secondLevelCategoryVOMap.containsKey(firstCategory.getCategoryId())) { //Take out the secondary classification list in the secondLevelCategoryVOMap group according to the id of the primary classification List<SecondLevelCategoryVO> tempGoodsCategories = secondLevelCategoryVOMap.get(firstCategory.getCategoryId()); newBeeMallIndexCategoryVO.setSecondLevelCategoryVOS(tempGoodsCategories); newBeeMallIndexCategoryVOS.add(newBeeMallIndexCategoryVO); } } } }
Experience: learn the idea of classification and add the attributes to be used in the table of the database_ level ,caparent_id.
4. New Bee Mall Goods API
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-aedyyla1-163811491029) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128224108494. PNG)]
File: NewBeeMallGoodsAPI.java
/api/v1/goods/detail/{goodsId}
Function: Commodity details interface
/api/v1/search
Function: product search interface
Code analysis:
1. Search interface
1.NewBeeMallGoodsAPI.java
Create NewBeeMallGoodsService object
@Resource private NewBeeMallGoodsService newBeeMallGoodsService;
The author defines a PageQueryUtil, which is the parameter of paging query (you can refer to paging in the future)
public class PageQueryUtil extends LinkedHashMap<String, Object> { //Current page number private int page; //Number of entries per page private int limit; public PageQueryUtil(Map<String, Object> params) { this.putAll(params); //Paging parameters this.page = Integer.parseInt(params.get("page").toString()); this.limit = Integer.parseInt(params.get("limit").toString()); this.put("start", (page - 1) * limit); this.put("page", page); this.put("limit", limit); } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } @Override public String toString() { return "PageUtil{" + "page=" + page + ", limit=" + limit + '}'; } }
- Store the keyword ID, order page number and other data passed in from the search interface into the Map (the object name is params)
- Encapsulate the Map into a PageQueryUtil object
- Give the PageQueryUtil object to the searchNewBeeMallGoods method of newBeeMallGoodsService
@GetMapping("/search") @ApiOperation(value = "Product search interface", notes = "According to keywords and classification id Search") public Result<PageResult<List<NewBeeMallSearchGoodsVO>>> search(@RequestParam(required = false) @ApiParam(value = "Search keywords") String keyword, @RequestParam(required = false) @ApiParam(value = "classification id") Long goodsCategoryId, @RequestParam(required = false) @ApiParam(value = "orderBy") String orderBy, @RequestParam(required = false) @ApiParam(value = "Page number") Integer pageNumber, @TokenToMallUser MallUser loginMallUser) { logger.info("goods search api,keyword={},goodsCategoryId={},orderBy={},pageNumber={},userId={}", keyword, goodsCategoryId, orderBy, pageNumber, loginMallUser.getUserId()); Map params = new HashMap(8); //If both search parameters are empty, an exception is returned directly if (goodsCategoryId == null && StringUtils.isEmpty(keyword)) { NewBeeMallException.fail("Illegal search parameters"); } if (pageNumber == null || pageNumber < 1) { pageNumber = 1; } params.put("goodsCategoryId", goodsCategoryId); params.put("page", pageNumber); params.put("limit", Constants.GOODS_SEARCH_PAGE_LIMIT); //Filter the keyword to remove spaces if (!StringUtils.isEmpty(keyword)) { params.put("keyword", keyword); } if (!StringUtils.isEmpty(orderBy)) { params.put("orderBy", orderBy); } //Search for goods on the shelf params.put("goodsSellStatus", Constants.SELL_STATUS_UP); //Encapsulate commodity data PageQueryUtil pageUtil = new PageQueryUtil(params); return ResultGenerator.genSuccessResult(newBeeMallGoodsService.searchNewBeeMallGoods(pageUtil)); }
2. NewBeeMallGoodsServiceImpl.java
- Find the goodsList product list according to the passed in PageUtil
- Record how many items were found
- Convert to generic list
- Handle the problem of long characters
- Save the final result with PageResult (the PageResult class is a paging tool class)
@Override public PageResult searchNewBeeMallGoods(PageQueryUtil pageUtil) { List<NewBeeMallGoods> goodsList = goodsMapper.findNewBeeMallGoodsListBySearch(pageUtil); int total = goodsMapper.getTotalNewBeeMallGoodsBySearch(pageUtil); List<NewBeeMallSearchGoodsVO> newBeeMallSearchGoodsVOS = new ArrayList<>(); if (!CollectionUtils.isEmpty(goodsList)) { newBeeMallSearchGoodsVOS = BeanUtil.copyList(goodsList, NewBeeMallSearchGoodsVO.class); for (NewBeeMallSearchGoodsVO newBeeMallSearchGoodsVO : newBeeMallSearchGoodsVOS) { String goodsName = newBeeMallSearchGoodsVO.getGoodsName(); String goodsIntro = newBeeMallSearchGoodsVO.getGoodsIntro(); // The string is too long, causing the text to exceed if (goodsName.length() > 28) { goodsName = goodsName.substring(0, 28) + "..."; newBeeMallSearchGoodsVO.setGoodsName(goodsName); } if (goodsIntro.length() > 30) { goodsIntro = goodsIntro.substring(0, 30) + "..."; newBeeMallSearchGoodsVO.setGoodsIntro(goodsIntro); } } } PageResult pageResult = new PageResult(newBeeMallSearchGoodsVOS, total, pageUtil.getLimit(), pageUtil.getPage()); return pageResult; }
2. Detailed interface
Pass in the commodity id and get all the information of the corresponding commodity
1.NewBeeMallGoodsAPI.java
@GetMapping("/goods/detail/{goodsId}") @ApiOperation(value = "Product details interface", notes = "Pass reference to commodity id") public Result<NewBeeMallGoodsDetailVO> goodsDetail(@ApiParam(value = "commodity id") @PathVariable("goodsId") Long goodsId, @TokenToMallUser MallUser loginMallUser) { logger.info("goods detail api,goodsId={},userId={}", goodsId, loginMallUser.getUserId()); if (goodsId < 1) { return ResultGenerator.genFailResult("Parameter exception"); } NewBeeMallGoods goods = newBeeMallGoodsService.getNewBeeMallGoodsById(goodsId); if (goods == null) { return ResultGenerator.genFailResult("Parameter exception"); } if (Constants.SELL_STATUS_UP != goods.getGoodsSellStatus()) { NewBeeMallException.fail(ServiceResultEnum.GOODS_PUT_DOWN.getResult()); } NewBeeMallGoodsDetailVO goodsDetailVO = new NewBeeMallGoodsDetailVO(); BeanUtil.copyProperties(goods, goodsDetailVO); goodsDetailVO.setGoodsCarouselList(goods.getGoodsCarousel().split(",")); return ResultGenerator.genSuccessResult(goodsDetailVO); }
2. NewBeeMallGoodsServiceImpl.java
@Override public NewBeeMallGoods getNewBeeMallGoodsById(Long id) { return goodsMapper.selectByPrimaryKey(id); }
5. New Bee Mall Shopping Cart API
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-p0a0pahi-163811491030) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128222948995. PNG)]
1. NewBeeMallShoppingCartAPI.java
For each method, the code body is basically the same. Call the NewBeeMallShoppingCartService method to judge whether it is successful or not
@GetMapping("/shop-cart/page") @ApiOperation(value = "Shopping cart list(Default 5 entries per page)", notes = "Pass reference to page number") public Result<PageResult<List<NewBeeMallShoppingCartItemVO>>> cartItemPageList(Integer pageNumber, @TokenToMallUser MallUser loginMallUser) { Map params = new HashMap(8); if (pageNumber == null || pageNumber < 1) { pageNumber = 1; } params.put("userId", loginMallUser.getUserId()); params.put("page", pageNumber); params.put("limit", Constants.SHOPPING_CART_PAGE_LIMIT); //Encapsulate paging request parameters PageQueryUtil pageUtil = new PageQueryUtil(params); return ResultGenerator.genSuccessResult(newBeeMallShoppingCartService.getMyShoppingCartItems(pageUtil)); }
2. NewBeeMallShoppingCartServiceImpl.java
get method
The three get methods 1, getNewBeeMallCartItemById, getmyshopingcartitems, and getCartItemsForSettle are simple select operations,
delete method
Different userids should be considered and cannot be deleted
@Override public Boolean deleteById(Long shoppingCartItemId, Long userId) { NewBeeMallShoppingCartItem newBeeMallShoppingCartItem = newBeeMallShoppingCartItemMapper.selectByPrimaryKey(shoppingCartItemId); if (newBeeMallShoppingCartItem == null) { return false; } //userId is different and cannot be deleted if (!userId.equals(newBeeMallShoppingCartItem.getUserId())) { return false; } return newBeeMallShoppingCartItemMapper.deleteByPrimaryKey(shoppingCartItemId) > 0; }
insert method
Conditions to consider when adding items
- Item already exists
- Item is empty
- Maximum quantity of goods
@Override public String saveNewBeeMallCartItem(SaveCartItemParam saveCartItemParam, Long userId) { NewBeeMallShoppingCartItem temp = newBeeMallShoppingCartItemMapper.selectByUserIdAndGoodsId(userId, saveCartItemParam.getGoodsId()); if (temp != null) { //Modify the record if it already exists NewBeeMallException.fail(ServiceResultEnum.SHOPPING_CART_ITEM_EXIST_ERROR.getResult()); } NewBeeMallGoods newBeeMallGoods = newBeeMallGoodsMapper.selectByPrimaryKey(saveCartItemParam.getGoodsId()); //Item is empty if (newBeeMallGoods == null) { return ServiceResultEnum.GOODS_NOT_EXIST.getResult(); } int totalItem = newBeeMallShoppingCartItemMapper.selectCountByUserId(userId); //The maximum quantity of a single item is exceeded if (saveCartItemParam.getGoodsCount() < 1) { return ServiceResultEnum.SHOPPING_CART_ITEM_NUMBER_ERROR.getResult(); } //The maximum quantity of a single item is exceeded if (saveCartItemParam.getGoodsCount() > Constants.SHOPPING_CART_ITEM_LIMIT_NUMBER) { return ServiceResultEnum.SHOPPING_CART_ITEM_LIMIT_NUMBER_ERROR.getResult(); } //Maximum quantity exceeded if (totalItem > Constants.SHOPPING_CART_ITEM_TOTAL_NUMBER) { return ServiceResultEnum.SHOPPING_CART_ITEM_TOTAL_NUMBER_ERROR.getResult(); } NewBeeMallShoppingCartItem newBeeMallShoppingCartItem = new NewBeeMallShoppingCartItem(); BeanUtil.copyProperties(saveCartItemParam, newBeeMallShoppingCartItem); newBeeMallShoppingCartItem.setUserId(userId); //Keep records if (newBeeMallShoppingCartItemMapper.insertSelective(newBeeMallShoppingCartItem) > 0) { return ServiceResultEnum.SUCCESS.getResult(); } return ServiceResultEnum.DB_ERROR.getResult(); }
update method
update considerations
- Maximum quantity of goods
- userId different
- If there is no modification, the operation can be omitted
//The maximum quantity of a single item is exceeded if (updateCartItemParam.getGoodsCount() > Constants.SHOPPING_CART_ITEM_LIMIT_NUMBER) { return ServiceResultEnum.SHOPPING_CART_ITEM_LIMIT_NUMBER_ERROR.getResult(); } //The userId of the current login account is different from that in the cartItem to be modified. An error is returned if (!newBeeMallShoppingCartItemUpdate.getUserId().equals(userId)) { return ServiceResultEnum.NO_PERMISSION_ERROR.getResult(); } //If the values are the same, no data operation is performed if (updateCartItemParam.getGoodsCount().equals(newBeeMallShoppingCartItemUpdate.getGoodsCount())) { return ServiceResultEnum.SUCCESS.getResult(); }
6. New Bee Mall User Address API
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-rnm8qn2d-163811491030) (C: \ users \ Chen \ appdata \ roaming \ typora \ user images \ image-20211128223411451. PNG)]
The method of calling NewBeeMallUserAddressService is a relatively simple operation of CRUD. There is one more default receiving address than usual, so there is no more analysis
Example: modify address
- incoming data
- CRUD operation
- Judge success or failure
@PutMapping("/address") @ApiOperation(value = "Modify address", notes = "") public Result<Boolean> updateMallUserAddress(@RequestBody UpdateMallUserAddressParam updateMallUserAddressParam, @TokenToMallUser MallUser loginMallUser) { MallUserAddress mallUserAddressById = mallUserAddressService.getMallUserAddressById(updateMallUserAddressParam.getAddressId()); if (!loginMallUser.getUserId().equals(mallUserAddressById.getUserId())) { return ResultGenerator.genFailResult(ServiceResultEnum.REQUEST_FORBIDEN_ERROR.getResult()); } MallUserAddress userAddress = new MallUserAddress(); BeanUtil.copyProperties(updateMallUserAddressParam, userAddress); userAddress.setUserId(loginMallUser.getUserId()); Boolean updateResult = mallUserAddressService.updateMallUserAddress(userAddress); //Modified successfully if (updateResult) { return ResultGenerator.genSuccessResult(); } //Modification failed return ResultGenerator.genFailResult("Modification failed"); }
The receiving address of, no more analysis
Example: modify address
- incoming data
- CRUD operation
- Judge success or failure
@PutMapping("/address") @ApiOperation(value = "Modify address", notes = "") public Result<Boolean> updateMallUserAddress(@RequestBody UpdateMallUserAddressParam updateMallUserAddressParam, @TokenToMallUser MallUser loginMallUser) { MallUserAddress mallUserAddressById = mallUserAddressService.getMallUserAddressById(updateMallUserAddressParam.getAddressId()); if (!loginMallUser.getUserId().equals(mallUserAddressById.getUserId())) { return ResultGenerator.genFailResult(ServiceResultEnum.REQUEST_FORBIDEN_ERROR.getResult()); } MallUserAddress userAddress = new MallUserAddress(); BeanUtil.copyProperties(updateMallUserAddressParam, userAddress); userAddress.setUserId(loginMallUser.getUserId()); Boolean updateResult = mallUserAddressService.updateMallUserAddress(userAddress); //Modified successfully if (updateResult) { return ResultGenerator.genSuccessResult(); } //Modification failed return ResultGenerator.genFailResult("Modification failed"); }