Browse Source

finish 60% and tests

master
朱天祥 11 months ago
parent
commit
f9e964a041
94 changed files with 582 additions and 28 deletions
  1. +0
    -0
      pictures/10c84590-d382-42fa-8a11-4776fab415f3.png
  2. +0
    -0
      pictures/10cbefb6-7f3e-4a21-95c2-8e62a8a329b7.png
  3. +0
    -0
      pictures/124610f7-d5e2-457b-8865-f65f6c5a023e.png
  4. +0
    -0
      pictures/17aab56f-afdf-4e60-a73d-6c51f3c0970c.png
  5. +0
    -0
      pictures/1e4740d6-71e1-4393-92f8-1d85fb35ae7c.png
  6. +0
    -0
      pictures/2394fe94-1cf1-4af1-828c-c6d750dc539c.png
  7. +0
    -0
      pictures/252e1d5d-b604-4525-a619-5e86a087a489.png
  8. +0
    -0
      pictures/2854044e-8a1e-412f-9340-beb629914d37.png
  9. BIN
      pictures/296ae937-41bd-49b8-bb85-581922351f09.png
  10. BIN
      pictures/2bbbb76d-693c-448f-9d6a-613a181ac2a9.png
  11. BIN
      pictures/327934d0-6cf6-444d-bc76-d1fbc17bbc8a.png
  12. BIN
      pictures/32cd3f6b-3583-4f20-aa4a-c7f137a0e5a3.png
  13. BIN
      pictures/36ab7efa-1de0-483e-9260-f6bf1bf8b57a.png
  14. BIN
      pictures/36ea74f7-6137-411f-8558-2a4aa7f82cd0.png
  15. BIN
      pictures/3efc8e58-9826-49bb-9669-62536fa5fc28.png
  16. BIN
      pictures/40cdd8e6-db74-4674-b772-e9f605df6849.png
  17. BIN
      pictures/410b6791-c59c-489e-ae3f-231799a5ef1a.png
  18. BIN
      pictures/42305a14-6925-4e1a-bcca-e26852bd2276.png
  19. BIN
      pictures/48b5ade4-e209-41ac-b9b5-d5fc87617d07.png
  20. BIN
      pictures/52dce7ea-9c57-4ac5-9186-336bffa167f9.png
  21. BIN
      pictures/539d7a60-3ef0-4d50-84ce-be40466a1009.png
  22. BIN
      pictures/5434592c-2a3a-4884-9ec4-dc0842b84aae.png
  23. BIN
      pictures/5b28e51a-59ac-48f6-b4fb-eadca40695fe.png
  24. BIN
      pictures/5c5aed7a-8821-4057-a792-20e07b6929af.png
  25. BIN
      pictures/5cedeeaa-bef8-4750-8906-d221654f49d2.png
  26. BIN
      pictures/5d7265e9-09da-44b8-8a85-7f4aa7876b43.png
  27. BIN
      pictures/62eb90b9-ca10-43a9-ab06-c08f98abb682.png
  28. BIN
      pictures/633c8296-24f0-490f-8154-3a7ea1aedff1.png
  29. BIN
      pictures/68f09be7-9adc-4b3a-adb2-f1986619e1f8.png
  30. BIN
      pictures/6a535bcf-3b1d-4ecd-9b47-fd1fbc1b3aa8.png
  31. BIN
      pictures/6cf0b6c5-a071-456f-948b-e91dc84ada3c.png
  32. BIN
      pictures/6f18beab-c776-42df-a983-976171b03fae.png
  33. BIN
      pictures/72c4c05c-3b8b-4d92-af6d-9a791aa4e3b3.png
  34. BIN
      pictures/731b8537-4ca8-4b2e-9827-dbb4b1d8bca5.png
  35. BIN
      pictures/770d31de-8734-49ba-933b-afb7f930150c.png
  36. BIN
      pictures/7960fb3b-44ef-47f8-b96f-d9af58d90330.png
  37. BIN
      pictures/89b61577-8e07-41c8-92a5-edab1979fd3c.png
  38. BIN
      pictures/8c1fb03c-e521-4f4d-81a1-bd29ad14327c.png
  39. BIN
      pictures/8cf06bdd-a29c-4ccd-b09f-45114a6dff39.png
  40. BIN
      pictures/8f6faaf7-6996-4a2b-befa-2e0a8ddd8c03.png
  41. BIN
      pictures/9315e1ec-d66c-4443-bbf3-96e81d32c2fe.png
  42. BIN
      pictures/968d8c17-64ad-48b7-b051-31a7d6d37b9f.png
  43. BIN
      pictures/97838d7e-4471-488e-bac8-efe8f6ff468b.png
  44. BIN
      pictures/9d3d893b-d5b9-4c8b-88c6-0fff8c2c66bb.png
  45. BIN
      pictures/9debade0-b108-4f9a-838d-714111846911.png
  46. BIN
      pictures/ac270c75-7976-4a00-88b7-ca8519c001e1.png
  47. BIN
      pictures/ae35405c-7471-4d7a-b495-2252520cef9d.png
  48. BIN
      pictures/b1d2b77e-c061-43e2-8a6f-09ae4318d613.png
  49. BIN
      pictures/b5e7832b-e7db-40d8-b4e8-e18fd23be974.png
  50. BIN
      pictures/b90d8e08-8b18-41aa-8918-00969368c1cc.png
  51. BIN
      pictures/bb81c89a-b6a3-4ad0-9b17-3e66d24d13f5.png
  52. BIN
      pictures/bd7ba0a0-aa49-4f5a-8e8c-046b97524ae3.png
  53. BIN
      pictures/c334c980-16ec-4055-85ac-930bfd45e96e.png
  54. BIN
      pictures/c41a3184-a805-42ec-871e-8021cbabcd4b.png
  55. BIN
      pictures/d484953e-f3cd-4d99-ac9f-589a96a4c19c.png
  56. BIN
      pictures/d690247d-24a1-450f-8732-583fdef04c30.png
  57. BIN
      pictures/dd26ae8d-2fdc-4527-b921-7f628166a3f2.png
  58. BIN
      pictures/e1d3b516-00a8-4ba9-ace1-94210ae4561a.png
  59. BIN
      pictures/e2276fbe-f957-4b4b-a7f0-9e3fed8b6cd3.png
  60. BIN
      pictures/e43dc4a2-1511-407c-8592-62f30aa7748c.png
  61. BIN
      pictures/ea841421-d2af-429c-a218-47a56901e8b0.png
  62. BIN
      pictures/eae0edcd-970f-4238-8fc2-111ee42cb2a8.png
  63. BIN
      pictures/eba0dcd6-bc1e-4f76-b2d5-172df9f745a7.png
  64. BIN
      pictures/fdd306f8-9480-46e0-b0f7-f49a48fd0551.png
  65. BIN
      pictures/ff3c65cd-497e-4b17-aa55-5882a38ed2fd.png
  66. +5
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/component/Constants.java
  67. +1
    -1
      src/main/java/cn/edu/ecnu/stu/bookstore/config/SecurityConfig.java
  68. +1
    -4
      src/main/java/cn/edu/ecnu/stu/bookstore/controller/AuthController.java
  69. +47
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/controller/BuyerController.java
  70. +32
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/handler/OrderStatusTypeHandler.java
  71. +8
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/mapper/BookMapper.java
  72. +29
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/mapper/OrderMapper.java
  73. +10
    -5
      src/main/java/cn/edu/ecnu/stu/bookstore/mapper/UserMapper.java
  74. +30
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Order.java
  75. +54
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/pojo/OrderStatus.java
  76. +10
    -1
      src/main/java/cn/edu/ecnu/stu/bookstore/pojo/User.java
  77. +18
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/pojo/vo/NewOrderVO.java
  78. +3
    -1
      src/main/java/cn/edu/ecnu/stu/bookstore/service/UserService.java
  79. +114
    -0
      src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/BuyerService.java
  80. +9
    -3
      src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserServiceImpl.java
  81. +0
    -4
      src/main/java/cn/edu/ecnu/stu/bookstore/utils/ImageUtil.java
  82. +5
    -2
      src/main/resources/application.yml
  83. +9
    -0
      src/main/resources/mapper/BookMapper.xml
  84. +28
    -0
      src/main/resources/mapper/OrderMapper.xml
  85. +159
    -0
      src/test/java/cn/edu/ecnu/stu/bookstore/BuyerTest.java
  86. +10
    -7
      src/test/java/cn/edu/ecnu/stu/bookstore/SellerTest.java

pictures/13b2e8c0-c0fd-4d29-b3d6-820019216b2e.png → pictures/10c84590-d382-42fa-8a11-4776fab415f3.png View File


pictures/26498012-6694-41a1-ab43-560379f9219a.png → pictures/10cbefb6-7f3e-4a21-95c2-8e62a8a329b7.png View File


pictures/537f94c4-929c-4f3b-935e-b67b6567668e.png → pictures/124610f7-d5e2-457b-8865-f65f6c5a023e.png View File


pictures/68984c2e-a8f5-4bde-afba-8417f943143e.png → pictures/17aab56f-afdf-4e60-a73d-6c51f3c0970c.png View File


pictures/6cfd0b0c-1023-46ea-89ca-7fe24df4e288.png → pictures/1e4740d6-71e1-4393-92f8-1d85fb35ae7c.png View File


pictures/745d73b2-c2c4-44cd-b07c-8da216f36a5a.png → pictures/2394fe94-1cf1-4af1-828c-c6d750dc539c.png View File


pictures/9b5c4ff5-a7c7-42ea-9747-8b3de08f463a.png → pictures/252e1d5d-b604-4525-a619-5e86a087a489.png View File


pictures/ebdbfd76-9f40-4f54-819e-dc4f087afe49.png → pictures/2854044e-8a1e-412f-9340-beb629914d37.png View File


BIN
pictures/296ae937-41bd-49b8-bb85-581922351f09.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/2bbbb76d-693c-448f-9d6a-613a181ac2a9.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/327934d0-6cf6-444d-bc76-d1fbc17bbc8a.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/32cd3f6b-3583-4f20-aa4a-c7f137a0e5a3.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/36ab7efa-1de0-483e-9260-f6bf1bf8b57a.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/36ea74f7-6137-411f-8558-2a4aa7f82cd0.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/3efc8e58-9826-49bb-9669-62536fa5fc28.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/40cdd8e6-db74-4674-b772-e9f605df6849.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/410b6791-c59c-489e-ae3f-231799a5ef1a.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/42305a14-6925-4e1a-bcca-e26852bd2276.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/48b5ade4-e209-41ac-b9b5-d5fc87617d07.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/52dce7ea-9c57-4ac5-9186-336bffa167f9.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/539d7a60-3ef0-4d50-84ce-be40466a1009.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/5434592c-2a3a-4884-9ec4-dc0842b84aae.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/5b28e51a-59ac-48f6-b4fb-eadca40695fe.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/5c5aed7a-8821-4057-a792-20e07b6929af.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/5cedeeaa-bef8-4750-8906-d221654f49d2.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/5d7265e9-09da-44b8-8a85-7f4aa7876b43.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/62eb90b9-ca10-43a9-ab06-c08f98abb682.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/633c8296-24f0-490f-8154-3a7ea1aedff1.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/68f09be7-9adc-4b3a-adb2-f1986619e1f8.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/6a535bcf-3b1d-4ecd-9b47-fd1fbc1b3aa8.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/6cf0b6c5-a071-456f-948b-e91dc84ada3c.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/6f18beab-c776-42df-a983-976171b03fae.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/72c4c05c-3b8b-4d92-af6d-9a791aa4e3b3.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/731b8537-4ca8-4b2e-9827-dbb4b1d8bca5.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/770d31de-8734-49ba-933b-afb7f930150c.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/7960fb3b-44ef-47f8-b96f-d9af58d90330.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/89b61577-8e07-41c8-92a5-edab1979fd3c.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/8c1fb03c-e521-4f4d-81a1-bd29ad14327c.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/8cf06bdd-a29c-4ccd-b09f-45114a6dff39.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/8f6faaf7-6996-4a2b-befa-2e0a8ddd8c03.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/9315e1ec-d66c-4443-bbf3-96e81d32c2fe.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/968d8c17-64ad-48b7-b051-31a7d6d37b9f.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/97838d7e-4471-488e-bac8-efe8f6ff468b.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/9d3d893b-d5b9-4c8b-88c6-0fff8c2c66bb.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/9debade0-b108-4f9a-838d-714111846911.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/ac270c75-7976-4a00-88b7-ca8519c001e1.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/ae35405c-7471-4d7a-b495-2252520cef9d.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/b1d2b77e-c061-43e2-8a6f-09ae4318d613.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/b5e7832b-e7db-40d8-b4e8-e18fd23be974.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/b90d8e08-8b18-41aa-8918-00969368c1cc.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/bb81c89a-b6a3-4ad0-9b17-3e66d24d13f5.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/bd7ba0a0-aa49-4f5a-8e8c-046b97524ae3.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/c334c980-16ec-4055-85ac-930bfd45e96e.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/c41a3184-a805-42ec-871e-8021cbabcd4b.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/d484953e-f3cd-4d99-ac9f-589a96a4c19c.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/d690247d-24a1-450f-8732-583fdef04c30.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/dd26ae8d-2fdc-4527-b921-7f628166a3f2.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/e1d3b516-00a8-4ba9-ace1-94210ae4561a.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/e2276fbe-f957-4b4b-a7f0-9e3fed8b6cd3.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/e43dc4a2-1511-407c-8592-62f30aa7748c.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/ea841421-d2af-429c-a218-47a56901e8b0.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/eae0edcd-970f-4238-8fc2-111ee42cb2a8.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/eba0dcd6-bc1e-4f76-b2d5-172df9f745a7.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/fdd306f8-9480-46e0-b0f7-f49a48fd0551.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

BIN
pictures/ff3c65cd-497e-4b17-aa55-5882a38ed2fd.png View File

Before After
Width: 260  |  Height: 268  |  Size: 28 KiB

+ 5
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/component/Constants.java View File

@ -18,8 +18,13 @@ public interface Constants {
String STORE_NON_EXIST_ERROR = "商铺不存在";
String PICTURE_ERROR = "图片解码失败";
String BOOK_ERROR = "商铺不存在或书籍不存在";
String STOCK_LEVEL_ERROR = "库存不足";
String STORE_ID_ERROR = "商铺ID已存在";
String ORDER_IS_NULL_ERROR = "订单不能为空";
String BALANCE_ERROR = "余额不足";
String URL_PREFIX = "http://127.0.0.1:8080";
}

+ 1
- 1
src/main/java/cn/edu/ecnu/stu/bookstore/config/SecurityConfig.java View File

@ -42,7 +42,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/*").permitAll()
.antMatchers("/auth/*", "/buyer/add_funds", "/buyer/payment").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class);

+ 1
- 4
src/main/java/cn/edu/ecnu/stu/bookstore/controller/AuthController.java View File

@ -30,10 +30,7 @@ public class AuthController {
@PostMapping("/login")
public Result login(@RequestBody User user) {
String token = userService.login(user);
HashMap<String, Object> map = new HashMap<>();
map.put("token", token);
return Result.success(map);
return Result.success(userService.login(user));
}
@PostMapping("/password")

+ 47
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/controller/BuyerController.java View File

@ -0,0 +1,47 @@
package cn.edu.ecnu.stu.bookstore.controller;
import cn.edu.ecnu.stu.bookstore.component.Result;
import cn.edu.ecnu.stu.bookstore.pojo.vo.NewOrderVO;
import cn.edu.ecnu.stu.bookstore.service.impl.BuyerService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
@RestController
@RequestMapping("/buyer")
public class BuyerController {
@Autowired
private BuyerService buyerService;
@PostMapping("/new_order")
public Result newOrder(@RequestBody NewOrderVO newOrderVO) {
buyerService.newOrder(newOrderVO);
return Result.success();
}
@PostMapping("/payment")
public Result payment(@RequestBody JSONObject object) {
Integer userId = object.getInteger("userId");
String orderId = object.getString("orderId");
String password = object.getString("password");
buyerService.payment(userId, orderId, password);
return Result.success();
}
@PostMapping("/add_funds")
public Result addFunds(@RequestBody JSONObject object) {
String username = object.getString("username");
String password = object.getString("password");
BigDecimal addValue = object.getBigDecimal("addValue");
buyerService.addFunds(username, password, addValue);
return Result.success();
}
@GetMapping("/order")
public Result order() {
return Result.success(buyerService.getOrderList());
}
}

+ 32
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/handler/OrderStatusTypeHandler.java View File

@ -0,0 +1,32 @@
package cn.edu.ecnu.stu.bookstore.handler;
import cn.edu.ecnu.stu.bookstore.pojo.OrderStatus;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class OrderStatusTypeHandler implements TypeHandler<OrderStatus> {
@Override
public void setParameter(PreparedStatement preparedStatement, int i, OrderStatus status, JdbcType jdbcType) throws SQLException {
preparedStatement.setInt(i, status.getValue());
}
@Override
public OrderStatus getResult(ResultSet resultSet, String s) throws SQLException {
return OrderStatus.getByValue(resultSet.getInt(s));
}
@Override
public OrderStatus getResult(ResultSet resultSet, int i) throws SQLException {
return OrderStatus.getByValue(resultSet.getInt(i));
}
@Override
public OrderStatus getResult(CallableStatement callableStatement, int i) throws SQLException {
return OrderStatus.getByValue(callableStatement.getInt(i));
}
}

+ 8
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/mapper/BookMapper.java View File

@ -1,9 +1,12 @@
package cn.edu.ecnu.stu.bookstore.mapper;
import cn.edu.ecnu.stu.bookstore.pojo.Book;
import cn.edu.ecnu.stu.bookstore.pojo.vo.NewOrderVO;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Mapper
public interface BookMapper {
@ -33,4 +36,9 @@ public interface BookMapper {
@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);
List<Book> batchSelect(@Param("storeId") String storeId, @Param("books") Set<String> books);
@Update("update t_book set stock_level = stock_level - #{count} where book_id = #{bookId}")
int minusStockLevel(@Param("bookId") String bookId, @Param("count") int count);
}

+ 29
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/mapper/OrderMapper.java View File

@ -0,0 +1,29 @@
package cn.edu.ecnu.stu.bookstore.mapper;
import cn.edu.ecnu.stu.bookstore.pojo.Book;
import cn.edu.ecnu.stu.bookstore.pojo.Order;
import cn.edu.ecnu.stu.bookstore.pojo.OrderStatus;
import org.apache.ibatis.annotations.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Mapper
public interface OrderMapper {
@Insert("insert into t_order(order_id, buyer_id, from_address, to_address, price, status, store_id, create_time) values " +
"(#{order.orderId}, #{order.buyerId}, #{order.fromAddress}, #{order.toAddress}, #{order.price}, #{order.status.value}, " +
"#{order.storeId}, #{order.createTime})")
int insert(@Param("order")Order order);
int insertOrderBook(@Param("orderId") String orderId, @Param("books") List<Map<String, Object>> books);
@Select("select price from t_order where order_id = #{orderId}")
BigDecimal selectPrice(@Param("orderId") String orderId);
@Update("update t_order set status = #{status.value} where order_id = #{orderId}")
void updateOrderStatus(@Param("orderId") String orderId, @Param("status") OrderStatus status);
List<Order> select(@Param("buyerId") Integer buyerId, @Param("status") OrderStatus status);
}

+ 10
- 5
src/main/java/cn/edu/ecnu/stu/bookstore/mapper/UserMapper.java View File

@ -6,6 +6,8 @@ import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.math.BigDecimal;
@Mapper
public interface UserMapper {
@ -17,15 +19,18 @@ public interface UserMapper {
int deleteByName(@Param("username") String username);
@Select("select id, username, password, address, phone from t_user where id = #{id}")
@Select("select id, username, password, address, phone, balance 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}")
@Select("select id, username, password, address, phone, balance from t_user where username = #{username}")
User selectOneByName(@Param("username") String username);
@Select("select count(*) from t_user where username = #{username} and password = #{password}")
int checkPassword(@Param("username") String username, @Param("password") String password);
@Update("update t_user set password = #{password} where username = #{username}")
int updatePassword(@Param("username") String username, @Param("password") String password);
@Update("update t_user set balance = balance - #{price} where id = #{userId}")
int minusBalance(@Param("userId") int userId, @Param("price") BigDecimal price);
@Update("update t_user set balance = balance + #{addValue} where id = #{userId}")
void addFunds(@Param("userId") Integer userId,@Param("addValue") BigDecimal addValue);
}

+ 30
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/pojo/Order.java View File

@ -0,0 +1,30 @@
package cn.edu.ecnu.stu.bookstore.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.sql.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private String orderId;
private Integer buyerId;
private String fromAddress;
private String toAddress;
private BigDecimal price;
private OrderStatus status;
private String storeId;
private Date createTime;
}

+ 54
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/pojo/OrderStatus.java View File

@ -0,0 +1,54 @@
package cn.edu.ecnu.stu.bookstore.pojo;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
public enum OrderStatus implements AbstractOrderStatus{
WAIT_PAYMENT(0),
WAIT_SEND(1),
WAIT_RECEIVE(2),
COMPLETED(3),
CANCEL(4);
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
@Override
public void nextOrder() {
if(value == CANCEL.value)
return;
value += 1;
}
@Override
public void cancelOrder() {
value = CANCEL.value;
}
public static OrderStatus getByValue(int val) {
for(OrderStatus status : values()) {
if(status.value == val)
return status;
}
return null;
}
}
interface AbstractOrderStatus {
void nextOrder();
void cancelOrder();
}

+ 10
- 1
src/main/java/cn/edu/ecnu/stu/bookstore/pojo/User.java View File

@ -1,21 +1,30 @@
package cn.edu.ecnu.stu.bookstore.pojo;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {
private int id;
private String username;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
private int balance;
@Builder.Default
private BigDecimal balance = BigDecimal.ZERO;
private String phone;

+ 18
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/pojo/vo/NewOrderVO.java View File

@ -0,0 +1,18 @@
package cn.edu.ecnu.stu.bookstore.pojo.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NewOrderVO {
private String storeId;
private List<Map<String, Object>> books;
}

+ 3
- 1
src/main/java/cn/edu/ecnu/stu/bookstore/service/UserService.java View File

@ -2,12 +2,14 @@ package cn.edu.ecnu.stu.bookstore.service;
import cn.edu.ecnu.stu.bookstore.pojo.User;
import java.util.Map;
public interface UserService {
void register(User user);
void unregister(User user);
User selectUserByName(String username);
String login(User user);
Map<String, Object> login(User user);
void logout(String username);

+ 114
- 0
src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/BuyerService.java View File

@ -0,0 +1,114 @@
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.OrderMapper;
import cn.edu.ecnu.stu.bookstore.mapper.UserMapper;
import cn.edu.ecnu.stu.bookstore.pojo.Book;
import cn.edu.ecnu.stu.bookstore.pojo.Order;
import cn.edu.ecnu.stu.bookstore.pojo.OrderStatus;
import cn.edu.ecnu.stu.bookstore.pojo.User;
import cn.edu.ecnu.stu.bookstore.pojo.vo.NewOrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class BuyerService {
@Autowired
private BookMapper bookMapper;
@Autowired
private OrderMapper orderMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private PasswordEncoder encoder;
@Autowired
@Lazy
private BuyerService buyerService;
public void newOrder(NewOrderVO newOrderVO) {
List<Map<String, Object>> bookList = newOrderVO.getBooks();
if(bookList.size() < 1)
throw new AppException(Constants.CLIENT_ERROR, Constants.ORDER_IS_NULL_ERROR);
HashMap<String, Integer> bookMap = new HashMap<>();
for(Map<String, Object> map : bookList) {
bookMap.put((String) map.get("id"), (Integer) map.get("count"));
}
String storeId = newOrderVO.getStoreId();
buyerService.insertOrder(storeId, bookMap, bookList);
}
@Transactional
public void insertOrder(String storeId, HashMap<String, Integer> bookMap, List<Map<String, Object>> bookList) {
List<Book> books = bookMapper.batchSelect(storeId, bookMap.keySet());
if(books.size() != bookList.size())
throw new AppException(Constants.CLIENT_ERROR, Constants.BOOK_ERROR);
List<Map<String, Object>> list = books.stream().map(book -> {
int count = bookMap.get(book.getBookId());
if(count > book.getStockLevel())
throw new AppException(Constants.CLIENT_ERROR, Constants.STOCK_LEVEL_ERROR);
Map<String, Object> map = new HashMap<>();
map.put("count", count);
map.put("book", book);
return map;
}).collect(Collectors.toList());
BigDecimal sum = new BigDecimal(0);
for(Book book : books) {
sum = sum.add(book.getPrice().multiply(BigDecimal.valueOf(bookMap.get(book.getBookId()))));
}
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String orderId = UUID.randomUUID().toString();
Order order = new Order(orderId, user.getId(), null, null, sum, OrderStatus.WAIT_PAYMENT, storeId, null);
orderMapper.insert(order);
orderMapper.insertOrderBook(order.getOrderId(), list);
for (Map<String, Object> map : list) {
Book book = (Book)map.get("book");
bookMapper.minusStockLevel(book.getBookId(), (int)map.get("count"));
}
}
public void payment(Integer userId, String orderId, String password) {
User user = userMapper.selectOneById(userId);
if(!encoder.matches(password, user.getPassword()))
throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR);
BigDecimal price = orderMapper.selectPrice(orderId);
if(price.compareTo(user.getBalance()) > 0)
throw new AppException(Constants.CLIENT_ERROR, Constants.BALANCE_ERROR);
buyerService.updateBalanceAndOrder(orderId, userId, price);
}
@Transactional
public void updateBalanceAndOrder(String orderId, Integer userId, BigDecimal price) {
orderMapper.updateOrderStatus(orderId, OrderStatus.WAIT_SEND);
userMapper.minusBalance(userId, price);
}
public void addFunds(String username, String password, BigDecimal addValue) {
User user = userMapper.selectOneByName(username);
if(!encoder.matches(password, user.getPassword()))
throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR);
userMapper.addFunds(user.getId(), addValue);
}
public List<Order> getOrderList() {
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return orderMapper.select(user.getId(), OrderStatus.WAIT_PAYMENT);
}
}

+ 9
- 3
src/main/java/cn/edu/ecnu/stu/bookstore/service/impl/UserServiceImpl.java View File

@ -17,6 +17,8 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
@ -60,12 +62,16 @@ public class UserServiceImpl implements UserService {
return userMapper.selectOneByName(username);
}
public String login(User user) {
public Map<String, Object> 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());
User user1 = loginUser.getUser();
redisTemplate.opsForValue().set("userId:" + user1.getId(), "1", 1, TimeUnit.DAYS);
Map<String, Object> map = new HashMap<>();
map.put("token", JwtUtil.getToken(user1));
map.put("user", user1);
return map;
}
public void logout(String username) {

+ 0
- 4
src/main/java/cn/edu/ecnu/stu/bookstore/utils/ImageUtil.java View File

@ -85,9 +85,5 @@ public class ImageUtil {
}
}
}
public static void main(String[] args) {
System.out.println(convertImageToBase64Str("d8c8d6d0ffb2a0257a1aa80835cbb81c.jpeg"));
}
}

+ 5
- 2
src/main/resources/application.yml View File

@ -4,6 +4,9 @@ server:
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: cn.edu.ecnu.stu.bookstore.pojo
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
datasource:
@ -13,6 +16,6 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
redis:
host: 106.75.64.112
host: 106.75.98.95
port: 6379
password: qwe030318
password: qwe030318

+ 9
- 0
src/main/resources/mapper/BookMapper.xml View File

@ -16,4 +16,13 @@
(#{book_id}, #{picture})
</foreach>
</insert>
<select id="batchSelect" resultType="cn.edu.ecnu.stu.bookstore.pojo.Book">
select book_id, store_id, title, author, publisher, original_title, translator, pub_year, pages, price, binding, isbn, stock_level from t_book
where store_id = #{storeId} and book_id in (
<foreach collection="books" item="id" separator=",">
#{id}
</foreach>
)
</select>
</mapper>

+ 28
- 0
src/main/resources/mapper/OrderMapper.xml View File

@ -0,0 +1,28 @@
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.edu.ecnu.stu.bookstore.mapper.OrderMapper">
<insert id="insertOrderBook">
insert into t_order_book(order_id, book_id, count, single_price) values
<foreach collection="books" item="map" separator=",">
(#{orderId}, #{map.book.bookId}, #{map.count}, #{map.book.price})
</foreach>
</insert>
<resultMap id="orderMap" type="order">
<id property="orderId" column="order_id"/>
<result property="buyerId" column="buyer_id"/>
<result property="fromAddress" column="from_address"/>
<result property="toAddress" column="to_address"/>
<result property="price" column="price"/>
<result property="storeId" column="store_id"/>
<result property="createTime" column="create_time"/>
<result property="status" column="status" typeHandler="cn.edu.ecnu.stu.bookstore.handler.OrderStatusTypeHandler"/>
</resultMap>
<select id="select" resultMap="orderMap">
select order_id, buyer_id, from_address, to_address, price, status, store_id, create_time from t_order
where buyer_id = #{buyerId} and status = #{status.value}
</select>
</mapper>

+ 159
- 0
src/test/java/cn/edu/ecnu/stu/bookstore/BuyerTest.java View File

@ -0,0 +1,159 @@
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.pojo.User;
import cn.edu.ecnu.stu.bookstore.utils.ImageUtil;
import cn.edu.ecnu.stu.bookstore.utils.RequestUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;
@SpringBootTest
public class BuyerTest {
private String token;
private final String storeId = "store" + UUID.randomUUID();
private List<String> bookIds;
private Integer userId;
private String username;
private String password;
public void init() {
if(username != null)
return;
String url = Constants.URL_PREFIX + "/auth/register";
Map<String, Object> map = new HashMap<>();
username = UUID.randomUUID().toString();
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");
userId = data.getObject("user", User.class).getId();
url = Constants.URL_PREFIX + "/seller/create_store";
map = new HashMap<>();
map.put("storeId", storeId);
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());
url = Constants.URL_PREFIX + "/seller/add_book";
String bookId = UUID.randomUUID().toString();
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<String> tags = Arrays.asList("tag" + UUID.randomUUID(), "tag" + UUID.randomUUID());
List<String> pictures = Arrays.asList(ImageUtil.convertImageToBase64Str("ff3c65cd-497e-4b17-aa55-5882a38ed2fd.png"));
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 = RequestUtil.post(url, map, token);
assert result != null && Constants.SUCCESS.equals(result.getCode());
map.put("bookId", bookId + "x");
bookIds = Arrays.asList(bookId, bookId + "x");
result = RequestUtil.post(url, map, token);
assert result != null && Constants.SUCCESS.equals(result.getCode());
url = Constants.URL_PREFIX + "/seller/add_stock_level";
map = new HashMap<>();
map.put("storeId", storeId);
map.put("addStockLevel", 100);
for (String id : bookIds) {
map.put("bookId", id);
result = RequestUtil.post(url, map, token);
assert result != null && Constants.SUCCESS.equals(result.getCode());
}
}
@Test
public void testNewOrder() {
init();
String url = Constants.URL_PREFIX + "/buyer/new_order";
HashMap<String, Object> map = new HashMap<>();
map.put("storeId", storeId);
List<Map<String, Object>> list = new LinkedList<>();
int c = 1;
for (String bookId : bookIds) {
HashMap<String, Object> map0 = new HashMap<>();
map0.put("id", bookId);
map0.put("count", c++);
list.add(map0);
}
map.put("books", list);
Result result = RequestUtil.post(url, map, token);
assert result != null && Constants.SUCCESS.equals(result.getCode());
list.get(0).put("id", "我爱数据库");
result = RequestUtil.post(url, map, token);
assert result != null && Constants.CLIENT_ERROR.equals(result.getCode());
}
@Test
public void testAddFunds() {
init();
String url = Constants.URL_PREFIX + "/buyer/add_funds";
HashMap<String, Object> map = new HashMap<>();
map.put("username", username);
map.put("password", password);
map.put("addValue", 1000);
Result result = RequestUtil.post(url, map, null);
assert result != null && Constants.SUCCESS.equals(result.getCode());
}
@Test
public void testPayment() {
init();
testNewOrder();
testAddFunds();
String url = Constants.URL_PREFIX + "/buyer/order";
Result result = RequestUtil.get(url, null, token);
JSONArray data = (JSONArray) result.getData();
Object[] objects = data.stream().toArray();
url = Constants.URL_PREFIX + "/buyer/payment";
HashMap<String, Object> map = new HashMap<>();
map.put("userId", userId);
map.put("password", password);
for (Object obj : objects) {
JSONObject obj1 = (JSONObject) obj;
map.put("orderId", obj1.getString("orderId"));
result = RequestUtil.post(url, map, null);
assert result != null && Constants.SUCCESS.equals(result.getCode());
}
}
}

+ 10
- 7
src/test/java/cn/edu/ecnu/stu/bookstore/SellerTest.java View File

@ -16,17 +16,17 @@ 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 String storeId;
private final String bookId = "book" + UUID.randomUUID();
private String bookId;
@PostConstruct
public void init() {
if(token != null)
return;
String url = Constants.URL_PREFIX + "/auth/register";
Map<String, Object> map = new HashMap<>();
String username = UUID.randomUUID().toString();
@ -44,11 +44,12 @@ public class SellerTest {
token = data.getString("token");
}
@Order(1)
@Test
public void testCreateStore() {
init();
String url = Constants.URL_PREFIX + "/seller/create_store";
HashMap<String, Object> map = new HashMap<>();
storeId = "store" + UUID.randomUUID();
map.put("storeId", storeId);
Result result = RequestUtil.post(url, map, token);
assert result != null && Constants.SUCCESS.equals(result.getCode());
@ -58,10 +59,11 @@ public class SellerTest {
}
@Order(2)
@Test
public void testAddBook() {
init();
testCreateStore();
bookId = "book" + UUID.randomUUID();
String url = Constants.URL_PREFIX + "/seller/add_book";
String title = "title" + UUID.randomUUID();
String author = "author" + UUID.randomUUID();
@ -71,7 +73,7 @@ public class SellerTest {
String bookIntro = "bookIntro" + UUID.randomUUID();
String content = "content" + UUID.randomUUID();
List<String> tags = Arrays.asList("tag" + UUID.randomUUID(), "tag" + UUID.randomUUID());
List<String> pictures = Arrays.asList(ImageUtil.convertImageToBase64Str("13b2e8c0-c0fd-4d29-b3d6-820019216b2e.png"));
List<String> pictures = Arrays.asList(ImageUtil.convertImageToBase64Str("ff3c65cd-497e-4b17-aa55-5882a38ed2fd.png"));
HashMap<String, Object> map = new HashMap<>();
map.put("storeId", storeId);
map.put("bookId", bookId);
@ -91,6 +93,7 @@ public class SellerTest {
@Test
public void testAddStockLevel() {
init();
testAddBook();
String url = Constants.URL_PREFIX + "/seller/add_stock_level";
HashMap<String, Object> map = new HashMap<>();

Loading…
Cancel
Save