diff --git a/pictures/13b2e8c0-c0fd-4d29-b3d6-820019216b2e.png b/pictures/13b2e8c0-c0fd-4d29-b3d6-820019216b2e.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/13b2e8c0-c0fd-4d29-b3d6-820019216b2e.png differ diff --git a/pictures/26498012-6694-41a1-ab43-560379f9219a.png b/pictures/26498012-6694-41a1-ab43-560379f9219a.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/26498012-6694-41a1-ab43-560379f9219a.png differ diff --git a/pictures/537f94c4-929c-4f3b-935e-b67b6567668e.png b/pictures/537f94c4-929c-4f3b-935e-b67b6567668e.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/537f94c4-929c-4f3b-935e-b67b6567668e.png differ diff --git a/pictures/68984c2e-a8f5-4bde-afba-8417f943143e.png b/pictures/68984c2e-a8f5-4bde-afba-8417f943143e.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/68984c2e-a8f5-4bde-afba-8417f943143e.png differ diff --git a/pictures/6cfd0b0c-1023-46ea-89ca-7fe24df4e288.png b/pictures/6cfd0b0c-1023-46ea-89ca-7fe24df4e288.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/6cfd0b0c-1023-46ea-89ca-7fe24df4e288.png differ diff --git a/pictures/745d73b2-c2c4-44cd-b07c-8da216f36a5a.png b/pictures/745d73b2-c2c4-44cd-b07c-8da216f36a5a.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/745d73b2-c2c4-44cd-b07c-8da216f36a5a.png differ diff --git a/pictures/9b5c4ff5-a7c7-42ea-9747-8b3de08f463a.png b/pictures/9b5c4ff5-a7c7-42ea-9747-8b3de08f463a.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/9b5c4ff5-a7c7-42ea-9747-8b3de08f463a.png differ diff --git a/pictures/ebdbfd76-9f40-4f54-819e-dc4f087afe49.png b/pictures/ebdbfd76-9f40-4f54-819e-dc4f087afe49.png new file mode 100644 index 0000000..a487741 Binary files /dev/null and b/pictures/ebdbfd76-9f40-4f54-819e-dc4f087afe49.png differ diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/component/Constants.java b/src/main/java/cn/edu/ecnu/stu/bookstore/component/Constants.java index ac2014c..11f6179 100644 --- a/src/main/java/cn/edu/ecnu/stu/bookstore/component/Constants.java +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/component/Constants.java @@ -13,6 +13,13 @@ public interface Constants { String SUCCESS_MESSAGE = "ok"; String AUTHENTICATION_ERROR_MESSAGE = "用户未认证或token过期,请先登录"; String PASSWORD_ERROR = "用户名不存在或密码错误"; + String USER_ID_ERROR = "用户名不存在"; + String AUTHORITY_ERROR = "用户权限不足"; + String STORE_NON_EXIST_ERROR = "商铺不存在"; + String PICTURE_ERROR = "图片解码失败"; + String BOOK_ERROR = "商铺不存在或书籍不存在"; + + String STORE_ID_ERROR = "商铺ID已存在"; String URL_PREFIX = "http://127.0.0.1:8080"; } diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/controller/SellerController.java b/src/main/java/cn/edu/ecnu/stu/bookstore/controller/SellerController.java new file mode 100644 index 0000000..bc992d8 --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/controller/SellerController.java @@ -0,0 +1,41 @@ +package cn.edu.ecnu.stu.bookstore.controller; + +import cn.edu.ecnu.stu.bookstore.component.Result; +import cn.edu.ecnu.stu.bookstore.pojo.Book; +import cn.edu.ecnu.stu.bookstore.pojo.Store; +import cn.edu.ecnu.stu.bookstore.service.SellerService; +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/seller") +public class SellerController { + + @Autowired + public SellerService sellerService; + + @PostMapping("/create_store") + public Result createStore(@RequestBody Store store) { + sellerService.createStore(store); + return Result.success(); + } + + @PostMapping("add_book") + public Result addBook(@RequestBody Book book) { + sellerService.addBook(book); + return Result.success(); + } + + @PostMapping("add_stock_level") + public Result addStockLevel(@RequestBody JSONObject body) { + String storeId = body.getString("storeId"); + String bookId = body.getString("bookId"); + int addStockLevel = body.getIntValue("addStockLevel"); + sellerService.addStockLevel(storeId, bookId, addStockLevel); + return Result.success(); + } +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/handler/AuthenticationEntryPointImpl.java b/src/main/java/cn/edu/ecnu/stu/bookstore/handler/AuthenticationEntryPointImpl.java index 5c9fa3d..6a96e4c 100644 --- a/src/main/java/cn/edu/ecnu/stu/bookstore/handler/AuthenticationEntryPointImpl.java +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/handler/AuthenticationEntryPointImpl.java @@ -17,6 +17,6 @@ public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint { response.setStatus(200); response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); - response.getWriter().print(JSON.toJSONString(Result.error(Constants.AUTHENTICATION_ERROR, Constants.AUTHENTICATION_ERROR_MESSAGE))); + response.getWriter().print(JSON.toJSONString(Result.error(Constants.AUTHENTICATION_ERROR, authException.getMessage()))); } } diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/BookMapper.java b/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/BookMapper.java new file mode 100644 index 0000000..dd0bebc --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/BookMapper.java @@ -0,0 +1,36 @@ +package cn.edu.ecnu.stu.bookstore.mapper; + +import cn.edu.ecnu.stu.bookstore.pojo.Book; +import org.apache.ibatis.annotations.*; + +import java.util.List; + +@Mapper +public interface BookMapper { + + @Insert("insert into t_book(book_id, store_id, title, author, publisher," + + "original_title, translator, pub_year, pages, price, binding, isbn, stock_level)" + + "values (#{book.bookId}, #{book.storeId}, #{book.title}, #{book.author}, #{book.publisher}, #{book.originalTitle}, " + + "#{book.translator}, #{book.pubYear}, #{book.pages}, #{book.price}, #{book.binding}, #{book.isbn}, #{book.stockLevel})") + int insert(@Param("book") Book book); + + @Select("select tag from t_book_tag where book_id = #{book_id}") + List selectTags(@Param("book_id") String bookId); + + int insertTags(@Param("book_id") String bookId, @Param("tags") List tags); + + @Select("select picture from t_book_picture where book_id = #{book_id}") + List selectPictureUrl(@Param("book_id") String bookId); + + int insertPictures(@Param("book_id") String bookId, @Param("pictures") List pictures); + + @Insert("insert into t_book_detail(book_id, author_intro, book_intro, content) values " + + "(#{book.bookId}, #{book.authorIntro}, #{book.bookIntro}, #{book.content})") + int insertBookDetail(@Param("book") Book book); + + @Select("select count(*) from t_book where store_id = #{storeId} and book_id = #{bookId}") + int checkBook(@Param("storeId") String storeId, @Param("bookId") String bookId); + + @Update("update t_book set stock_level = stock_level + #{addStockLevel} where store_id = #{storeId} and book_id = #{bookId}") + void addStockLevel(@Param("storeId") String storeId, @Param("bookId") String bookId, @Param("addStockLevel") int addStockLevel); +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/StoreMapper.java b/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/StoreMapper.java new file mode 100644 index 0000000..1ef1e25 --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/StoreMapper.java @@ -0,0 +1,20 @@ +package cn.edu.ecnu.stu.bookstore.mapper; + +import cn.edu.ecnu.stu.bookstore.pojo.Store; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +@Mapper +public interface StoreMapper { + + @Select("select count(*) from t_store where store_id = #{store_id}") + int checkStoreExist(@Param("store_id") String storeId); + + @Select("select count(*) from t_store where store_id = #{store_id} and store_id = #{store_id}") + int checkStore(@Param("seller_id") Integer sellerId, @Param("store_id") String storeId); + + @Insert("insert into t_store(store_id, seller_id) values(#{store.storeId}, #{store.sellerId})") + int insert(@Param("store") Store store); +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/UserMapper.java b/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/UserMapper.java index 4aedea4..d6741e1 100644 --- a/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/UserMapper.java +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/mapper/UserMapper.java @@ -17,6 +17,9 @@ public interface UserMapper { int deleteByName(@Param("username") String username); + @Select("select id, username, password, address, phone from t_user where id = #{id}") + User selectOneById(@Param("id") Integer id); + @Select("select id, username, password, address, phone from t_user where username = #{username}") User selectOneByName(@Param("username") String username); diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Book.java b/src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Book.java new file mode 100644 index 0000000..21f6f96 --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Book.java @@ -0,0 +1,50 @@ +package cn.edu.ecnu.stu.bookstore.pojo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Book { + + private String bookId; + + private String storeId; + + private String title; + + private String author; + + private String publisher; + + private String originalTitle; + + private String translator; + + private String pubYear; + + private Integer pages; + + private BigDecimal price; + + private String binding; + + private String isbn; + + private int stockLevel; + + private List tags; + + private List pictures; + + private String authorIntro; + + private String bookIntro; + + private String content; +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Store.java b/src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Store.java new file mode 100644 index 0000000..1ca1f90 --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Store.java @@ -0,0 +1,19 @@ +package cn.edu.ecnu.stu.bookstore.pojo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.sql.Date; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Store { + + private String storeId; + + private int sellerId; + + private Date createTime; +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/service/SellerService.java b/src/main/java/cn/edu/ecnu/stu/bookstore/service/SellerService.java new file mode 100644 index 0000000..afc3e5f --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/service/SellerService.java @@ -0,0 +1,17 @@ +package cn.edu.ecnu.stu.bookstore.service; + +import cn.edu.ecnu.stu.bookstore.pojo.Book; +import cn.edu.ecnu.stu.bookstore.pojo.Store; + +import java.util.List; + +public interface SellerService { + + void createStore(Store store); + + void addBook(Book book); + + void insertBook(Book book, List tags, List pictures); + + void addStockLevel(String storeId, String bookId, int addStockLevel); +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/service/UserService.java b/src/main/java/cn/edu/ecnu/stu/bookstore/service/UserService.java index f2554cb..0ddc2fd 100644 --- a/src/main/java/cn/edu/ecnu/stu/bookstore/service/UserService.java +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/service/UserService.java @@ -1,83 +1,17 @@ package cn.edu.ecnu.stu.bookstore.service; -import cn.edu.ecnu.stu.bookstore.component.AppException; -import cn.edu.ecnu.stu.bookstore.component.Constants; -import cn.edu.ecnu.stu.bookstore.mapper.UserMapper; -import cn.edu.ecnu.stu.bookstore.pojo.LoginUser; import cn.edu.ecnu.stu.bookstore.pojo.User; -import cn.edu.ecnu.stu.bookstore.utils.JwtUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; -import java.util.concurrent.TimeUnit; +public interface UserService { -@Service -public class UserService { + void register(User user); + void unregister(User user); + User selectUserByName(String username); + String login(User user); - @Autowired - private UserMapper userMapper; + void logout(String username); - @Autowired - private AuthenticationManager authenticationManager; + void changePassword(String username, String oldPassword, String newPassword); - @Autowired - private PasswordEncoder passwordEncoder; - @Autowired - private RedisTemplate redisTemplate; - - public void register(User user) { - if(!StringUtils.hasLength(user.getUsername())) - throw new AppException(Constants.CLIENT_ERROR, Constants.PARAMETER_ERROR_MESSAGE); - if(userMapper.checkUserByUsername(user.getUsername()) != 0) - throw new AppException(Constants.CLIENT_ERROR, Constants.REGISTER_ERROR_MESSAGE); - String encoded = passwordEncoder.encode(user.getPassword()); - user.setPassword(encoded); - userMapper.insert(user); - } - - public void unregister(User user) { - User user1 = userMapper.selectOneByName(user.getUsername()); - if(user1 == null || !passwordEncoder.matches(user.getPassword(), user1.getPassword())) { - throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR); - } - userMapper.deleteByName(user.getUsername()); - } - - public User selectUserByName(String username) { - return userMapper.selectOneByName(username); - } - - public String login(User user) { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()); - Authentication authenticate = authenticationManager.authenticate(token); - LoginUser loginUser = (LoginUser)authenticate.getPrincipal(); - redisTemplate.opsForValue().set("userId:" + loginUser.getUser().getId(), "1", 1, TimeUnit.DAYS); - return JwtUtil.getToken(loginUser.getUser()); - } - - public void logout(String username) { - User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - if(!user.getUsername().equals(username)) { - throw new AppException(Constants.CLIENT_ERROR, Constants.PARAMETER_ERROR_MESSAGE); - } - redisTemplate.delete("userId:" + user.getId()); - } - - public void changePassword(String username, String oldPassword, String newPassword) { - User user = userMapper.selectOneByName(username); - if(user == null || !passwordEncoder.matches(oldPassword, user.getPassword())){ - throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR); - } - newPassword = passwordEncoder.encode(newPassword); - userMapper.updatePassword(username, newPassword); - redisTemplate.delete("userId:" + user.getId()); - } } diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/SellerServiceImpl.java b/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/SellerServiceImpl.java new file mode 100644 index 0000000..de01f9d --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/SellerServiceImpl.java @@ -0,0 +1,74 @@ +package cn.edu.ecnu.stu.bookstore.service.impl; + +import cn.edu.ecnu.stu.bookstore.component.AppException; +import cn.edu.ecnu.stu.bookstore.component.Constants; +import cn.edu.ecnu.stu.bookstore.mapper.BookMapper; +import cn.edu.ecnu.stu.bookstore.mapper.StoreMapper; +import cn.edu.ecnu.stu.bookstore.pojo.Book; +import cn.edu.ecnu.stu.bookstore.pojo.Store; +import cn.edu.ecnu.stu.bookstore.pojo.User; +import cn.edu.ecnu.stu.bookstore.service.SellerService; +import cn.edu.ecnu.stu.bookstore.utils.ImageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class SellerServiceImpl implements SellerService { + + @Autowired + private StoreMapper storeMapper; + + @Autowired + private BookMapper bookMapper; + + @Autowired + @Lazy + private SellerService sellerService; + + public void createStore(Store store) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + store.setSellerId(user.getId()); + if(storeMapper.checkStoreExist(store.getStoreId()) != 0) + throw new AppException(Constants.CLIENT_ERROR, Constants.STORE_ID_ERROR); + storeMapper.insert(store); + } + + public void addBook(Book book) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + int userId = user.getId(); + if(storeMapper.checkStore(userId, book.getStoreId()) == 0) + throw new AppException(Constants.CLIENT_ERROR, Constants.STORE_NON_EXIST_ERROR); + + List tags = book.getTags(); + List pictures = book.getPictures(); + pictures = pictures.stream().map(ImageUtil::convertBase64StrToImage).collect(Collectors.toList()); + sellerService.insertBook(book, tags, pictures); + } + + @Transactional + public void insertBook(Book book, List tags, List pictures) { + bookMapper.insert(book); + bookMapper.insertBookDetail(book); + bookMapper.insertTags(book.getBookId(), tags); + bookMapper.insertPictures(book.getBookId(), pictures); + } + + @Override + public void addStockLevel(String storeId, String bookId, int addStockLevel) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + int userId = user.getId(); + if(storeMapper.checkStore(userId, storeId) == 0) + throw new AppException(Constants.CLIENT_ERROR, Constants.STORE_NON_EXIST_ERROR); + + if(bookMapper.checkBook(storeId, bookId) == 0) + throw new AppException(Constants.CLIENT_ERROR, Constants.BOOK_ERROR); + bookMapper.addStockLevel(storeId, bookId, addStockLevel); + } + +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/service/UserDetailsServiceImpl.java b/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserDetailsServiceImpl.java similarity index 90% rename from src/main/java/cn/edu/ecnu/stu/bookstore/service/UserDetailsServiceImpl.java rename to src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserDetailsServiceImpl.java index cae8160..62dcd1a 100644 --- a/src/main/java/cn/edu/ecnu/stu/bookstore/service/UserDetailsServiceImpl.java +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserDetailsServiceImpl.java @@ -1,9 +1,10 @@ -package cn.edu.ecnu.stu.bookstore.service; +package cn.edu.ecnu.stu.bookstore.service.impl; import cn.edu.ecnu.stu.bookstore.component.AppException; import cn.edu.ecnu.stu.bookstore.component.Constants; import cn.edu.ecnu.stu.bookstore.pojo.LoginUser; import cn.edu.ecnu.stu.bookstore.pojo.User; +import cn.edu.ecnu.stu.bookstore.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserServiceImpl.java b/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..991933b --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserServiceImpl.java @@ -0,0 +1,88 @@ +package cn.edu.ecnu.stu.bookstore.service.impl; + +import cn.edu.ecnu.stu.bookstore.component.AppException; +import cn.edu.ecnu.stu.bookstore.component.Constants; +import cn.edu.ecnu.stu.bookstore.mapper.UserMapper; +import cn.edu.ecnu.stu.bookstore.pojo.LoginUser; +import cn.edu.ecnu.stu.bookstore.pojo.User; +import cn.edu.ecnu.stu.bookstore.service.UserService; +import cn.edu.ecnu.stu.bookstore.utils.JwtUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.concurrent.TimeUnit; + +@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserMapper userMapper; + + @Autowired + private AuthenticationManager authenticationManager; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private RedisTemplate redisTemplate; + + public User selectOneById(Integer id) { + return userMapper.selectOneById(id); + } + + public void register(User user) { + if(!StringUtils.hasLength(user.getUsername())) + throw new AppException(Constants.CLIENT_ERROR, Constants.PARAMETER_ERROR_MESSAGE); + if(userMapper.checkUserByUsername(user.getUsername()) != 0) + throw new AppException(Constants.CLIENT_ERROR, Constants.REGISTER_ERROR_MESSAGE); + String encoded = passwordEncoder.encode(user.getPassword()); + user.setPassword(encoded); + userMapper.insert(user); + } + + public void unregister(User user) { + User user1 = userMapper.selectOneByName(user.getUsername()); + if(user1 == null || !passwordEncoder.matches(user.getPassword(), user1.getPassword())) { + throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR); + } + userMapper.deleteByName(user.getUsername()); + } + + public User selectUserByName(String username) { + return userMapper.selectOneByName(username); + } + + public String login(User user) { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()); + Authentication authenticate = authenticationManager.authenticate(token); + LoginUser loginUser = (LoginUser)authenticate.getPrincipal(); + redisTemplate.opsForValue().set("userId:" + loginUser.getUser().getId(), "1", 1, TimeUnit.DAYS); + return JwtUtil.getToken(loginUser.getUser()); + } + + public void logout(String username) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + if(!user.getUsername().equals(username)) { + throw new AppException(Constants.CLIENT_ERROR, Constants.PARAMETER_ERROR_MESSAGE); + } + redisTemplate.delete("userId:" + user.getId()); + } + + public void changePassword(String username, String oldPassword, String newPassword) { + User user = userMapper.selectOneByName(username); + if(user == null || !passwordEncoder.matches(oldPassword, user.getPassword())){ + throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR); + } + newPassword = passwordEncoder.encode(newPassword); + userMapper.updatePassword(username, newPassword); + redisTemplate.delete("userId:" + user.getId()); + } +} diff --git a/src/main/java/cn/edu/ecnu/stu/bookstore/utils/ImageUtil.java b/src/main/java/cn/edu/ecnu/stu/bookstore/utils/ImageUtil.java new file mode 100644 index 0000000..00a1162 --- /dev/null +++ b/src/main/java/cn/edu/ecnu/stu/bookstore/utils/ImageUtil.java @@ -0,0 +1,93 @@ +package cn.edu.ecnu.stu.bookstore.utils; + +import cn.edu.ecnu.stu.bookstore.component.AppException; +import cn.edu.ecnu.stu.bookstore.component.Constants; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Base64; +import java.util.UUID; + +import javax.imageio.ImageIO; + +public class ImageUtil { + + /** + * 图片转Base64字符串 + * @param imageFileName + * @return + */ + public static String convertImageToBase64Str(String imageFileName) { + ByteArrayOutputStream baos = null; + try { + //获取图片类型 + String suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1); + //构建文件 + File imageFile = new File("pictures/" + imageFileName); + //通过ImageIO把文件读取成BufferedImage对象 + BufferedImage bufferedImage = ImageIO.read(imageFile); + //构建字节数组输出流 + baos = new ByteArrayOutputStream(); + //写入流 + ImageIO.write(bufferedImage, suffix, baos); + //通过字节数组流获取字节数组 + byte[] bytes = baos.toByteArray(); + //获取JDK8里的编码器Base64.Encoder转为base64字符 + return Base64.getEncoder().encodeToString(bytes); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (baos != null) { + baos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + /** + * Base64字符串转图片 + * @param base64String + */ + public static String convertBase64StrToImage(String base64String) { + ByteArrayInputStream bais = null; + try { + //获取图片类型 + String suffix = "png"; + //获取JDK8里的解码器Base64.Decoder,将base64字符串转为字节数组 + byte[] bytes = Base64.getDecoder().decode(base64String); + //构建字节数组输入流 + bais = new ByteArrayInputStream(bytes); + //通过ImageIO把字节数组输入流转为BufferedImage + BufferedImage bufferedImage = ImageIO.read(bais); + String fileName = UUID.randomUUID() + "." + suffix; + String fullPath = "pictures/" + fileName; + //构建文件 + File imageFile = new File(fullPath); + //写入生成文件 + ImageIO.write(bufferedImage, suffix, imageFile); + return fileName; + } catch (Exception e) { + throw new AppException(Constants.CLIENT_ERROR, Constants.PICTURE_ERROR); + } finally { + try { + if (bais != null) { + bais.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + System.out.println(convertImageToBase64Str("d8c8d6d0ffb2a0257a1aa80835cbb81c.jpeg")); + } +} + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1d6cc5b..fc80412 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -13,6 +13,6 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource redis: - host: 106.75.115.165 + host: 106.75.64.112 port: 6379 password: qwe030318 \ No newline at end of file diff --git a/src/main/resources/mapper/BookMapper.xml b/src/main/resources/mapper/BookMapper.xml new file mode 100644 index 0000000..d484475 --- /dev/null +++ b/src/main/resources/mapper/BookMapper.xml @@ -0,0 +1,19 @@ + + + + + insert into t_book_tag(book_id, tag) values + + (#{book_id}, #{tag}) + + + + + insert into t_book_picture(book_id, picture) values + + (#{book_id}, #{picture}) + + + \ No newline at end of file diff --git a/src/main/resources/mapper/StoreMapper.xml b/src/main/resources/mapper/StoreMapper.xml new file mode 100644 index 0000000..1d5c298 --- /dev/null +++ b/src/main/resources/mapper/StoreMapper.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/test/java/cn/edu/ecnu/stu/bookstore/RegisterTest.java b/src/test/java/cn/edu/ecnu/stu/bookstore/AuthTest.java similarity index 89% rename from src/test/java/cn/edu/ecnu/stu/bookstore/RegisterTest.java rename to src/test/java/cn/edu/ecnu/stu/bookstore/AuthTest.java index 333fd80..14c241c 100644 --- a/src/test/java/cn/edu/ecnu/stu/bookstore/RegisterTest.java +++ b/src/test/java/cn/edu/ecnu/stu/bookstore/AuthTest.java @@ -3,32 +3,16 @@ package cn.edu.ecnu.stu.bookstore; import cn.edu.ecnu.stu.bookstore.component.Constants; import cn.edu.ecnu.stu.bookstore.component.Result; import cn.edu.ecnu.stu.bookstore.utils.RequestUtil; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpParams; -import org.apache.http.util.EntityUtils; -import org.apache.tomcat.util.http.ResponseUtil; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; -import java.util.Random; import java.util.UUID; @SpringBootTest -public class RegisterTest { +public class AuthTest { @Test public void testRegister() { @@ -64,7 +48,7 @@ public class RegisterTest { map.put("password", password + "x"); result = RequestUtil.post(url, map, null); - assert result != null && result.getCode() != null && result.getCode().equals(Constants.SYSTEM_ERROR); + assert result != null && result.getCode() != null && result.getCode().equals(Constants.AUTHENTICATION_ERROR); } @Test diff --git a/src/test/java/cn/edu/ecnu/stu/bookstore/BookstoreApplicationTests.java b/src/test/java/cn/edu/ecnu/stu/bookstore/BookstoreApplicationTests.java deleted file mode 100644 index 536cce4..0000000 --- a/src/test/java/cn/edu/ecnu/stu/bookstore/BookstoreApplicationTests.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.edu.ecnu.stu.bookstore; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ValueOperations; - -@SpringBootTest -class BookstoreApplicationTests { - - @Test - void contextLoads() { - } - - @Test - public void SetTest(@Autowired RedisTemplate redisTemplate){ - ValueOperations value = redisTemplate.opsForValue(); - value.set("springBoot","RedisOnSpringBoot"); - } - @Test - public void GetTest(@Autowired RedisTemplate redisTemplate){ - ValueOperations value = redisTemplate.opsForValue(); - Object o = value.get("springBoot"); - System.out.println(o); - } - -} diff --git a/src/test/java/cn/edu/ecnu/stu/bookstore/SellerTest.java b/src/test/java/cn/edu/ecnu/stu/bookstore/SellerTest.java new file mode 100644 index 0000000..ec63d82 --- /dev/null +++ b/src/test/java/cn/edu/ecnu/stu/bookstore/SellerTest.java @@ -0,0 +1,103 @@ +package cn.edu.ecnu.stu.bookstore; + +import cn.edu.ecnu.stu.bookstore.component.Constants; +import cn.edu.ecnu.stu.bookstore.component.Result; +import cn.edu.ecnu.stu.bookstore.utils.ImageUtil; +import cn.edu.ecnu.stu.bookstore.utils.RequestUtil; +import com.alibaba.fastjson.JSONObject; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.util.*; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class SellerTest { + + private String token; + + private final String storeId = "store" + UUID.randomUUID(); + + private final String bookId = "book" + UUID.randomUUID(); + + @PostConstruct + public void init() { + String url = Constants.URL_PREFIX + "/auth/register"; + Map map = new HashMap<>(); + String username = UUID.randomUUID().toString(); + String password = username + "x"; + map.put("username", username); + map.put("password", password); + Result result = RequestUtil.post(url, map, null); + assert result != null && result.getCode() != null && result.getCode().equals(Constants.SUCCESS); + + url = Constants.URL_PREFIX + "/auth/login"; + result = RequestUtil.post(url, map, null); + assert result != null && result.getCode() != null && result.getCode().equals(Constants.SUCCESS); + + JSONObject data = (JSONObject) result.getData(); + token = data.getString("token"); + } + + @Order(1) + @Test + public void testCreateStore() { + String url = Constants.URL_PREFIX + "/seller/create_store"; + HashMap map = new HashMap<>(); + map.put("storeId", storeId); + Result result = RequestUtil.post(url, map, token); + assert result != null && Constants.SUCCESS.equals(result.getCode()); + + result = RequestUtil.post(url, map, token); + assert result != null && Constants.CLIENT_ERROR.equals(result.getCode()); + + } + + @Order(2) + @Test + public void testAddBook() { + testCreateStore(); + String url = Constants.URL_PREFIX + "/seller/add_book"; + String title = "title" + UUID.randomUUID(); + String author = "author" + UUID.randomUUID(); + String publisher = "publisher" + UUID.randomUUID(); + BigDecimal price = new BigDecimal("29.88"); + String authorIntro = "authorIntro" + UUID.randomUUID(); + String bookIntro = "bookIntro" + UUID.randomUUID(); + String content = "content" + UUID.randomUUID(); + List tags = Arrays.asList("tag" + UUID.randomUUID(), "tag" + UUID.randomUUID()); + List pictures = Arrays.asList(ImageUtil.convertImageToBase64Str("13b2e8c0-c0fd-4d29-b3d6-820019216b2e.png")); + HashMap map = new HashMap<>(); + map.put("storeId", storeId); + map.put("bookId", bookId); + map.put("title", title); + map.put("author", author); + map.put("publisher", publisher); + map.put("price", price); + map.put("authorIntro", authorIntro); + map.put("bookIntro", bookIntro); + map.put("content", content); + map.put("tags", tags); + map.put("pictures", pictures); + Result result = RequestUtil.post(url, map, token); + assert result != null && Constants.SUCCESS.equals(result.getCode()); + + } + + @Test + public void testAddStockLevel() { + testAddBook(); + String url = Constants.URL_PREFIX + "/seller/add_stock_level"; + HashMap map = new HashMap<>(); + map.put("storeId", storeId); + map.put("bookId", bookId); + map.put("addStockLevel", 10); + Result result = RequestUtil.post(url, map, token); + assert result != null && Constants.SUCCESS.equals(result.getCode()); + } +}