From 99b87fbe4bf4e0dc6745336477f35d589c4a725b Mon Sep 17 00:00:00 2001 From: xinsin <2890826955@qq.com> Date: Mon, 24 Apr 2023 21:23:50 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9E=95=20Feat:=20add=20store=20and=20commiss?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 + .../xinsin/controller/AccountController.java | 71 ++++++--- .../controller/AuthorizeController.java | 34 +++-- .../controller/CommissionController.java | 20 +++ .../xinsin/controller/OrderController.java | 102 +++++++++++-- .../controller/PermissionsController.java | 16 +- .../xinsin/controller/RolesController.java | 16 +- .../xinsin/controller/StoreController.java | 20 +++ .../java/top/xinsin/enums/OrderStatus.java | 10 ++ .../java/top/xinsin/enums/SearchType.java | 10 ++ .../java/top/xinsin/mapper/AccountMapper.java | 10 +- .../top/xinsin/mapper/CommissionMapper.java | 18 +++ .../java/top/xinsin/mapper/OrderMapper.java | 12 +- .../top/xinsin/mapper/PermissionsMapper.java | 10 +- .../java/top/xinsin/mapper/RolesMapper.java | 12 +- .../java/top/xinsin/mapper/StoreMapper.java | 18 +++ src/main/java/top/xinsin/pojo/Account.java | 54 ++++--- src/main/java/top/xinsin/pojo/Commission.java | 45 ++++++ src/main/java/top/xinsin/pojo/Order.java | 83 +++++++--- .../java/top/xinsin/pojo/Permissions.java | 80 +++++----- src/main/java/top/xinsin/pojo/Roles.java | 78 +++++----- src/main/java/top/xinsin/pojo/Store.java | 39 +++++ .../top/xinsin/service/AccountService.java | 99 ++++++------ .../top/xinsin/service/CommissionService.java | 18 +++ .../java/top/xinsin/service/OrderService.java | 144 +++++++++++++++++- .../xinsin/service/PermissionsService.java | 12 +- .../java/top/xinsin/service/RolesService.java | 12 +- .../java/top/xinsin/service/StoreService.java | 16 ++ .../java/top/xinsin/util/ExcelParserUtil.java | 103 +++++++++++++ src/main/resources/application.yml | 2 +- src/main/resources/mapper/OrderMapper.xml | 6 +- src/test/java/top/xinsin/CodeGenerator.java | 3 +- template/example.xlsx | Bin 0 -> 9922 bytes 运伦电商软件导图(1).emmx | Bin 0 -> 13127 bytes 34 files changed, 877 insertions(+), 301 deletions(-) create mode 100644 src/main/java/top/xinsin/controller/CommissionController.java create mode 100644 src/main/java/top/xinsin/controller/StoreController.java create mode 100644 src/main/java/top/xinsin/enums/OrderStatus.java create mode 100644 src/main/java/top/xinsin/enums/SearchType.java create mode 100644 src/main/java/top/xinsin/mapper/CommissionMapper.java create mode 100644 src/main/java/top/xinsin/mapper/StoreMapper.java create mode 100644 src/main/java/top/xinsin/pojo/Commission.java create mode 100644 src/main/java/top/xinsin/pojo/Store.java create mode 100644 src/main/java/top/xinsin/service/CommissionService.java create mode 100644 src/main/java/top/xinsin/service/StoreService.java create mode 100644 src/main/java/top/xinsin/util/ExcelParserUtil.java create mode 100644 template/example.xlsx create mode 100644 运伦电商软件导图(1).emmx diff --git a/pom.xml b/pom.xml index d3551c6..0e2a8aa 100644 --- a/pom.xml +++ b/pom.xml @@ -123,5 +123,10 @@ org.freemarker freemarker + + com.alibaba + easyexcel + 3.2.1 + \ No newline at end of file diff --git a/src/main/java/top/xinsin/controller/AccountController.java b/src/main/java/top/xinsin/controller/AccountController.java index 9edb757..b8a7575 100644 --- a/src/main/java/top/xinsin/controller/AccountController.java +++ b/src/main/java/top/xinsin/controller/AccountController.java @@ -1,47 +1,68 @@ package top.xinsin.controller; - import com.alibaba.fastjson2.JSONObject; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import top.xinsin.pojo.Account; import top.xinsin.service.AccountService; -import top.xinsin.util.HttpCodes; import top.xinsin.util.R; /** - *

- * 前端控制器 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:05 + * @version 1.0 */ + @RestController -@RequestMapping("/account") +@RequestMapping({"/account"}) public class AccountController { @Autowired private AccountService accountService; - @RequestMapping(path = "/changeAccount",method = RequestMethod.POST) - public R changeAccount(@RequestBody Account account){ - return accountService.changeAccount(account); + public AccountController() { } - @RequestMapping(path = "/changeStatus",method = RequestMethod.GET) - public R changeStatus(@RequestParam("userId")Integer userId,@RequestParam("status")Boolean status){ - return accountService.changeStatus(userId,status); + + @RequestMapping( + path = {"/changeAccount"}, + method = {RequestMethod.POST} + ) + public R changeAccount(@RequestBody Account account) { + return this.accountService.changeAccount(account); } - @RequestMapping(path = "/changePassword",method = RequestMethod.GET) - public R changePassword(@RequestParam("userId")Integer userId,@RequestParam("oldPassword")String oldPassword,@RequestParam("newPassword") String newPassword){ - return accountService.changePassword(userId,oldPassword,newPassword); + + @RequestMapping( + path = {"/changeStatus"}, + method = {RequestMethod.GET} + ) + public R changeStatus(@RequestParam("userId") Integer userId, @RequestParam("status") Boolean status) { + return this.accountService.changeStatus(userId, status); } - @RequestMapping(path = "/delUser",method = RequestMethod.GET) - public R delUser(@RequestParam("id")Integer id){ - return accountService.delUser(id); + + @RequestMapping( + path = {"/changePassword"}, + method = {RequestMethod.POST} + ) + public R changePassword(@RequestParam("userId") Integer userId, @RequestParam("oldPassword") String oldPassword, @RequestParam("newPassword") String newPassword) { + return this.accountService.changePassword(userId, oldPassword, newPassword); } - @RequestMapping(path = "/getUser",method = RequestMethod.GET) - public R getUser(@RequestParam("page")Integer page,@RequestParam("num")Integer num){ - return accountService.getUser(page,num); + + @RequestMapping( + path = {"/delUser"}, + method = {RequestMethod.GET} + ) + public R delUser(@RequestParam("id") Integer id) { + return this.accountService.delUser(id); + } + + @RequestMapping( + path = {"/getUser"}, + method = {RequestMethod.GET} + ) + public R getUser(@RequestParam("page") Integer page, @RequestParam("num") Integer num) { + return this.accountService.getUser(page, num); } } diff --git a/src/main/java/top/xinsin/controller/AuthorizeController.java b/src/main/java/top/xinsin/controller/AuthorizeController.java index 32b0b5a..84df83e 100644 --- a/src/main/java/top/xinsin/controller/AuthorizeController.java +++ b/src/main/java/top/xinsin/controller/AuthorizeController.java @@ -1,37 +1,41 @@ package top.xinsin.controller; - -import jakarta.validation.constraints.Pattern; -import org.hibernate.validator.constraints.Length; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import top.xinsin.pojo.Account; import top.xinsin.service.AccountService; import top.xinsin.util.R; -import static top.xinsin.util.StringConstant.*; - +/** + * @author xinsin + * Created On 2023/4/24 21:06 + * @version 1.0 + */ @Validated @RestController -@RequestMapping("/api/auth") +@RequestMapping({"/api/auth"}) public class AuthorizeController { - @Autowired private AccountService accountService; - @RequestMapping(path = "/register",method = RequestMethod.POST) - public R register(@Pattern(regexp = USERNAME_REGEX) @Length(min = 3,max = 10) @RequestParam("username") String username, - @Pattern(regexp = REL_NAME_REGEX) @RequestParam("relName") String relName, - @Pattern(regexp = EMAIL_REGEX) @RequestParam("email") String email, - @RequestParam("password") String password, - @Pattern(regexp = ID_REGEX) @RequestParam("roleId") Integer roleId){ + public AuthorizeController() { + } + + @RequestMapping( + path = {"/register"}, + method = {RequestMethod.POST} + ) + public R register(@RequestParam("username") String username, @RequestParam("relName") String relName, @RequestParam("email") String email, @RequestParam("password") String password, @RequestParam("roleId") Integer roleId) { Account account = new Account(); account.setUsername(username); account.setPassword(password); account.setRelName(relName); account.setEmail(email); account.setRoleId(roleId); - return accountService.register(account); + return this.accountService.register(account); } } diff --git a/src/main/java/top/xinsin/controller/CommissionController.java b/src/main/java/top/xinsin/controller/CommissionController.java new file mode 100644 index 0000000..179496a --- /dev/null +++ b/src/main/java/top/xinsin/controller/CommissionController.java @@ -0,0 +1,20 @@ +package top.xinsin.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 前端控制器 + *

+ * + * @author xinsin + * @since 2023-04-24 + */ +@RestController +@RequestMapping("/commission") +public class CommissionController { + +} diff --git a/src/main/java/top/xinsin/controller/OrderController.java b/src/main/java/top/xinsin/controller/OrderController.java index cd7575c..2c22535 100644 --- a/src/main/java/top/xinsin/controller/OrderController.java +++ b/src/main/java/top/xinsin/controller/OrderController.java @@ -1,25 +1,107 @@ package top.xinsin.controller; - +import com.alibaba.fastjson2.JSONObject; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import top.xinsin.enums.OrderStatus; +import top.xinsin.enums.SearchType; +import top.xinsin.pojo.Order; import top.xinsin.service.OrderService; +import top.xinsin.util.R; /** - *

- * 前端控制器 - *

- * * @author xinsin - * @since 2023-04-21 + * Created On 2023/4/24 21:06 + * @version 1.0 */ @RestController -@RequestMapping("/order") +@RequestMapping({"/order"}) public class OrderController { @Autowired private OrderService orderService; + public OrderController() { + } + @RequestMapping( + path = {"/addOrder"}, + method = {RequestMethod.POST} + ) + public R addOrder(@RequestBody Order order) { + return this.orderService.addOrder(order); + } + + @RequestMapping( + path = {"/getOrder"}, + method = {RequestMethod.GET} + ) + public R getOrder(@RequestParam("page") Integer page, @RequestParam("num") Integer num) { + return this.orderService.getOrder(page, num); + } + + @RequestMapping( + path = {"/getOrderUserInfo"}, + method = {RequestMethod.GET} + ) + public R getOrderUserInfo(@RequestParam("content") String content) { + return this.orderService.getOrderUserInfo(content); + } + + @RequestMapping( + path = {"/searchUserOrder"}, + method = {RequestMethod.GET} + ) + public R searchUserOrder(@RequestParam("searchType") SearchType searchType, @RequestParam("searchContent") String searchContent, @RequestParam("batch") Boolean batch, @RequestParam("page") Integer page, @RequestParam("num") Integer num) { + return this.orderService.searchUserOrder(searchType, searchContent, batch, page, num); + } + + @RequestMapping( + path = {"/addOrderFlag"}, + method = {RequestMethod.GET} + ) + public R addOrderFlag(@RequestParam("orderId") Integer orderId, @RequestParam("flagId") Integer flagId, @RequestParam("flagRemark") String flagRemark) { + return this.orderService.addOrderFlag(orderId, flagId, flagRemark); + } + + @RequestMapping( + path = {"/changeOrder"}, + method = {RequestMethod.POST} + ) + public R changeOrder(@RequestBody Order order) { + return this.orderService.changeOrder(order); + } + + @RequestMapping( + path = {"/delOrder"}, + method = {RequestMethod.GET} + ) + public R delOrder(@RequestParam("orderId") Integer orderId) { + return this.orderService.delOrder(orderId); + } + + @RequestMapping( + path = {"/confirm"}, + method = {RequestMethod.GET} + ) + public R confirm(@RequestParam("orderStatus") OrderStatus orderStatus, @RequestParam("orderId") Integer orderId) { + return this.orderService.confirm(orderStatus, orderId); + } + + @RequestMapping( + path = {"/downloadTemplate"}, + method = {RequestMethod.GET} + ) + public void downloadTemplate(HttpServletResponse response) { + this.orderService.downloadTemplate(response); + } + + @RequestMapping( + path = {"/uploadBatch"}, + method = {RequestMethod.POST} + ) + public void uploadBatch(@RequestParam("file") MultipartFile file) { + this.orderService.uploadBatch(file); + } } diff --git a/src/main/java/top/xinsin/controller/PermissionsController.java b/src/main/java/top/xinsin/controller/PermissionsController.java index c6ce729..0d14f1a 100644 --- a/src/main/java/top/xinsin/controller/PermissionsController.java +++ b/src/main/java/top/xinsin/controller/PermissionsController.java @@ -1,20 +1,16 @@ package top.xinsin.controller; - import org.springframework.web.bind.annotation.RequestMapping; - import org.springframework.web.bind.annotation.RestController; /** - *

- * 前端控制器 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:07 + * @version 1.0 */ @RestController -@RequestMapping("/permissions") +@RequestMapping({"/permissions"}) public class PermissionsController { - -} + public PermissionsController() { + } +} \ No newline at end of file diff --git a/src/main/java/top/xinsin/controller/RolesController.java b/src/main/java/top/xinsin/controller/RolesController.java index 17bab9b..cfacac4 100644 --- a/src/main/java/top/xinsin/controller/RolesController.java +++ b/src/main/java/top/xinsin/controller/RolesController.java @@ -1,20 +1,16 @@ package top.xinsin.controller; - import org.springframework.web.bind.annotation.RequestMapping; - import org.springframework.web.bind.annotation.RestController; /** - *

- * 前端控制器 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:07 + * @version 1.0 */ @RestController -@RequestMapping("/roles") +@RequestMapping({"/roles"}) public class RolesController { - -} + public RolesController() { + } +} \ No newline at end of file diff --git a/src/main/java/top/xinsin/controller/StoreController.java b/src/main/java/top/xinsin/controller/StoreController.java new file mode 100644 index 0000000..a1f583d --- /dev/null +++ b/src/main/java/top/xinsin/controller/StoreController.java @@ -0,0 +1,20 @@ +package top.xinsin.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 前端控制器 + *

+ * + * @author xinsin + * @since 2023-04-24 + */ +@RestController +@RequestMapping("/store") +public class StoreController { + +} diff --git a/src/main/java/top/xinsin/enums/OrderStatus.java b/src/main/java/top/xinsin/enums/OrderStatus.java new file mode 100644 index 0000000..bad7218 --- /dev/null +++ b/src/main/java/top/xinsin/enums/OrderStatus.java @@ -0,0 +1,10 @@ +package top.xinsin.enums; + +/** + * @author xinsin + * Created On 2023/4/22 16:40 + * @version 1.0 + */ +public enum OrderStatus { + 商家驳回, 已完成, 已确认等待财务审核, 提交, 新建待提交数据, 财务审核已通过, 财务驳回 +} diff --git a/src/main/java/top/xinsin/enums/SearchType.java b/src/main/java/top/xinsin/enums/SearchType.java new file mode 100644 index 0000000..cf85d39 --- /dev/null +++ b/src/main/java/top/xinsin/enums/SearchType.java @@ -0,0 +1,10 @@ +package top.xinsin.enums; + +/** + * @author xinsin + * Created On 2023/4/22 16:39 + * @version 1.0 + */ +public enum SearchType { + WANG_ID,WECHAT_ID,ALIPAY_ID,PHONE_NUMBER +} diff --git a/src/main/java/top/xinsin/mapper/AccountMapper.java b/src/main/java/top/xinsin/mapper/AccountMapper.java index f225809..02c661c 100644 --- a/src/main/java/top/xinsin/mapper/AccountMapper.java +++ b/src/main/java/top/xinsin/mapper/AccountMapper.java @@ -1,18 +1,14 @@ package top.xinsin.mapper; -import top.xinsin.pojo.Account; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import top.xinsin.pojo.Account; /** - *

- * Mapper 接口 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:08 + * @version 1.0 */ @Mapper public interface AccountMapper extends BaseMapper { - } diff --git a/src/main/java/top/xinsin/mapper/CommissionMapper.java b/src/main/java/top/xinsin/mapper/CommissionMapper.java new file mode 100644 index 0000000..305b517 --- /dev/null +++ b/src/main/java/top/xinsin/mapper/CommissionMapper.java @@ -0,0 +1,18 @@ +package top.xinsin.mapper; + +import top.xinsin.pojo.Commission; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author xinsin + * @since 2023-04-24 + */ +@Mapper +public class CommissionMapper { + +} diff --git a/src/main/java/top/xinsin/mapper/OrderMapper.java b/src/main/java/top/xinsin/mapper/OrderMapper.java index fd6c622..94e376b 100644 --- a/src/main/java/top/xinsin/mapper/OrderMapper.java +++ b/src/main/java/top/xinsin/mapper/OrderMapper.java @@ -1,18 +1,14 @@ package top.xinsin.mapper; -import top.xinsin.pojo.Order; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import top.xinsin.pojo.Order; /** - *

- * Mapper 接口 - *

- * * @author xinsin - * @since 2023-04-21 + * Created On 2023/4/24 21:08 + * @version 1.0 */ @Mapper public interface OrderMapper extends BaseMapper { - -} +} \ No newline at end of file diff --git a/src/main/java/top/xinsin/mapper/PermissionsMapper.java b/src/main/java/top/xinsin/mapper/PermissionsMapper.java index 9a8bb8d..48233e8 100644 --- a/src/main/java/top/xinsin/mapper/PermissionsMapper.java +++ b/src/main/java/top/xinsin/mapper/PermissionsMapper.java @@ -1,18 +1,14 @@ package top.xinsin.mapper; -import top.xinsin.pojo.Permissions; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import top.xinsin.pojo.Permissions; /** - *

- * Mapper 接口 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:09 + * @version 1.0 */ @Mapper public interface PermissionsMapper extends BaseMapper { - } diff --git a/src/main/java/top/xinsin/mapper/RolesMapper.java b/src/main/java/top/xinsin/mapper/RolesMapper.java index 77b8bf3..b097e02 100644 --- a/src/main/java/top/xinsin/mapper/RolesMapper.java +++ b/src/main/java/top/xinsin/mapper/RolesMapper.java @@ -1,18 +1,14 @@ package top.xinsin.mapper; -import top.xinsin.pojo.Roles; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import top.xinsin.pojo.Roles; /** - *

- * Mapper 接口 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:09 + * @version 1.0 */ @Mapper public interface RolesMapper extends BaseMapper { - -} +} \ No newline at end of file diff --git a/src/main/java/top/xinsin/mapper/StoreMapper.java b/src/main/java/top/xinsin/mapper/StoreMapper.java new file mode 100644 index 0000000..97e6fcb --- /dev/null +++ b/src/main/java/top/xinsin/mapper/StoreMapper.java @@ -0,0 +1,18 @@ +package top.xinsin.mapper; + +import top.xinsin.pojo.Store; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author xinsin + * @since 2023-04-24 + */ +@Mapper +public class StoreMapper{ + +} diff --git a/src/main/java/top/xinsin/pojo/Account.java b/src/main/java/top/xinsin/pojo/Account.java index 118f709..e90970a 100644 --- a/src/main/java/top/xinsin/pojo/Account.java +++ b/src/main/java/top/xinsin/pojo/Account.java @@ -4,59 +4,57 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.io.Serializable; -import java.time.LocalDateTime; -import java.util.Date; - import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; +import java.io.Serializable; +import java.util.Date; + /** -*

- * - *

-* -* @author xinsin -* @since 2023-04-12 -*/ + * @author xinsin + * Created On 2023/4/24 21:09 + * @version 1.0 + */ @Data @TableName("account") public class Account implements Serializable { - private static final long serialVersionUID = 1L; - - @TableId(value = "id",type = IdType.AUTO) + @TableId( + value = "id", + type = IdType.AUTO + ) private Integer id; - @TableField("username") private String username; - @TableField("email") private String email; - @TableField("rel_name") private String relName; - @TableField("password") private String password; - @TableField("status") private Boolean status; - @TableField("role_id") private Integer roleId; - @TableField("create_time") - @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) private Date createTime; - - @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) @TableField("update_time") private Date updateTime; - @TableField("del") private Boolean del; -} \ No newline at end of file +} diff --git a/src/main/java/top/xinsin/pojo/Commission.java b/src/main/java/top/xinsin/pojo/Commission.java new file mode 100644 index 0000000..5803470 --- /dev/null +++ b/src/main/java/top/xinsin/pojo/Commission.java @@ -0,0 +1,45 @@ +package top.xinsin.pojo; + + import com.baomidou.mybatisplus.annotation.IdType; + import com.baomidou.mybatisplus.annotation.TableField; + import com.baomidou.mybatisplus.annotation.TableId; + import com.baomidou.mybatisplus.annotation.TableName; + import java.io.Serializable; + import java.sql.Blob; + import java.time.LocalDateTime; + import lombok.Data; + +/** +*

+ * + *

+* +* @author xinsin +* @since 2023-04-24 +*/ + @Data + @TableName("commission") + public class Commission implements Serializable { + + private static final long serialVersionUID = 1L; + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + @TableField("price_min") + private Double priceMin; + @TableField("price_max") + private Double priceMax; + @TableField("commission") + private Double commission; + @TableField("store_id") + private Integer storeId; + @TableField("cteate_time") + private LocalDateTime cteateTime; + @TableField("update_time") + private LocalDateTime updateTime; + @TableField("del") + private Integer del; + @TableField("status") + private Blob status; + + +} \ No newline at end of file diff --git a/src/main/java/top/xinsin/pojo/Order.java b/src/main/java/top/xinsin/pojo/Order.java index 18f6be3..281e873 100644 --- a/src/main/java/top/xinsin/pojo/Order.java +++ b/src/main/java/top/xinsin/pojo/Order.java @@ -1,67 +1,108 @@ package top.xinsin.pojo; - import com.baomidou.mybatisplus.annotation.IdType; - import com.baomidou.mybatisplus.annotation.TableField; - import com.baomidou.mybatisplus.annotation.TableId; - import com.baomidou.mybatisplus.annotation.TableName; - import java.io.Serializable; - import java.time.LocalDateTime; - import lombok.Data; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; /** -*

- * - *

-* -* @author xinsin -* @since 2023-04-21 -*/ + * @author xinsin + * Created On 2023/4/24 21:10 + * @version 1.0 + */ @Data -@TableName("order") +@TableName("shop_order") public class Order implements Serializable { private static final long serialVersionUID = 1L; - @TableId(value = "id", type = IdType.AUTO) + @ExcelIgnore + @TableId( + value = "id", + type = IdType.AUTO + ) private Integer id; + @ExcelProperty({"订单号"}) @TableField("order_no") private String orderNo; + @ExcelProperty({"下单时间"}) @TableField("order_time") - private LocalDateTime orderTime; + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) + private Date orderTime; + @ExcelProperty({"订单状态"}) @TableField("order_status") private String orderStatus; + @ExcelProperty({"旺旺号"}) @TableField("wang_no") private String wangNo; + @ExcelProperty({"微信|qq账号"}) @TableField("wechat_no") private String wechatNo; + @ExcelProperty({"支付宝账号"}) @TableField("alipay_no") private String alipayNo; + @ExcelProperty({"付款金额"}) @TableField("pay_amt") private Double payAmt; - @TableField("shop_town_name") - private String shopTownName; + @ExcelProperty({"店铺名称"}) + @TableField("storeId") + private Integer storeId; + @ExcelProperty({"佣金"}) @TableField("commission") private Double commission; + @ExcelProperty({"支付宝名称"}) @TableField("alipay_name") private String alipayName; + @ExcelProperty({"放单人"}) @TableField("rp_name") private String rpName; + @ExcelProperty({"放单人微信名"}) @TableField("rp_wechat_name") private String rpWechatName; + @ExcelProperty({"备注"}) @TableField("remark") private String remark; + @ExcelProperty({"买家电话"}) @TableField("phone_number") private String phoneNumber; + @ExcelProperty({"银行卡号"}) @TableField("card_no") private String cardNo; + @ExcelProperty({"插旗"}) @TableField("flag") private Integer flag; + @ExcelProperty({"插旗备注"}) @TableField("flag_remark") private String flagRemark; + @ExcelProperty({"付款时间"}) @TableField("pay_time") - private LocalDateTime payTime; + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) + private Date payTime; + @ExcelProperty({"收货地址"}) @TableField("address") private String address; + @ExcelProperty({"商品id"}) @TableField("shop_id") private Integer shopId; + @ExcelProperty({"sku"}) @TableField("sku") private String sku; -} \ No newline at end of file +} diff --git a/src/main/java/top/xinsin/pojo/Permissions.java b/src/main/java/top/xinsin/pojo/Permissions.java index fb0a111..fe50ad3 100644 --- a/src/main/java/top/xinsin/pojo/Permissions.java +++ b/src/main/java/top/xinsin/pojo/Permissions.java @@ -4,47 +4,55 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.io.Serializable; -import java.time.LocalDateTime; - import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; +import java.io.Serializable; +import java.time.LocalDateTime; + /** -*

-* -*

-* -* @author xinsin -* @since 2023-04-12 -*/ + * @author xinsin + * Created On 2023/4/24 21:11 + * @version 1.0 + */ @Data @TableName("permissions") public class Permissions implements Serializable { - -private static final long serialVersionUID = 1L; - -@TableId(value = "id", type = IdType.AUTO) -private Integer id; -@TableField("permission_name") -private String permissionName; -@TableField("permission_code") -private String permissionCode; -@TableField("description") -private String description; -@TableField("account_id") -private Integer accountId; -@TableField("create_time") -@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") -private LocalDateTime createTime; -@TableField("update_time") -@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") -private LocalDateTime updateTime; -@TableField("status") -private Boolean status; -@TableField("del") -private Boolean del; -} \ No newline at end of file + private static final long serialVersionUID = 1L; + @TableId( + value = "id", + type = IdType.AUTO + ) + private Integer id; + @TableField("permission_name") + private String permissionName; + @TableField("permission_code") + private String permissionCode; + @TableField("description") + private String description; + @TableField("account_id") + private Integer accountId; + @TableField("create_time") + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) + private LocalDateTime createTime; + @TableField("update_time") + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) + private LocalDateTime updateTime; + @TableField("status") + private Boolean status; + @TableField("del") + private Boolean del; +} diff --git a/src/main/java/top/xinsin/pojo/Roles.java b/src/main/java/top/xinsin/pojo/Roles.java index e1d6190..d1348a4 100644 --- a/src/main/java/top/xinsin/pojo/Roles.java +++ b/src/main/java/top/xinsin/pojo/Roles.java @@ -4,47 +4,53 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.io.Serializable; -import java.time.LocalDateTime; - import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; +import java.io.Serializable; +import java.time.LocalDateTime; + /** -*

-* -*

-* -* @author xinsin -* @since 2023-04-12 -*/ + * @author xinsin + * Created On 2023/4/24 21:11 + * @version 1.0 + */ @Data @TableName("roles") public class Roles implements Serializable { - -private static final long serialVersionUID = 1L; - -@TableId(value = "id", type = IdType.AUTO) -private Integer id; -@TableField("role_name") -private String roleName; -@TableField("description") -private String description; -@TableField("account_id") -private Integer accountId; -@TableField("create_time") -@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") -private LocalDateTime createTime; -@TableField("update_time") -@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") -private LocalDateTime updateTime; -@TableField("status") -private Boolean status; -@TableField("del") -private Boolean del; - - -} \ No newline at end of file + private static final long serialVersionUID = 1L; + @TableId( + value = "id", + type = IdType.AUTO + ) + private Integer id; + @TableField("role_name") + private String roleName; + @TableField("description") + private String description; + @TableField("account_id") + private Integer accountId; + @TableField("create_time") + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) + private LocalDateTime createTime; + @TableField("update_time") + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss", + timezone = "GMT+8" + ) + private LocalDateTime updateTime; + @TableField("status") + private Boolean status; + @TableField("del") + private Boolean del; +} diff --git a/src/main/java/top/xinsin/pojo/Store.java b/src/main/java/top/xinsin/pojo/Store.java new file mode 100644 index 0000000..466fdd6 --- /dev/null +++ b/src/main/java/top/xinsin/pojo/Store.java @@ -0,0 +1,39 @@ +package top.xinsin.pojo; + + import com.baomidou.mybatisplus.annotation.IdType; + import com.baomidou.mybatisplus.annotation.TableField; + import com.baomidou.mybatisplus.annotation.TableId; + import com.baomidou.mybatisplus.annotation.TableName; + import java.io.Serializable; + import java.sql.Blob; + import java.time.LocalDateTime; + import lombok.Data; + +/** +*

+ * + *

+* +* @author xinsin +* @since 2023-04-24 +*/ + @Data + @TableName("store") + public class Store implements Serializable { + + private static final long serialVersionUID = 1L; + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + @TableField("name") + private String name; + @TableField("create_time") + private LocalDateTime createTime; + @TableField("update_time") + private LocalDateTime updateTime; + @TableField("del") + private Integer del; + @TableField("status") + private Blob status; + + +} \ No newline at end of file diff --git a/src/main/java/top/xinsin/service/AccountService.java b/src/main/java/top/xinsin/service/AccountService.java index 4724937..15a5b9f 100644 --- a/src/main/java/top/xinsin/service/AccountService.java +++ b/src/main/java/top/xinsin/service/AccountService.java @@ -1,8 +1,12 @@ package top.xinsin.service; import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; @@ -12,103 +16,92 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import top.xinsin.mapper.AccountMapper; import top.xinsin.pojo.Account; -import com.baomidou.mybatisplus.extension.service.IService; import top.xinsin.util.HttpCodes; import top.xinsin.util.R; import java.util.Date; import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; /** - *

- * 服务类 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:11 + * @version 1.0 */ @Service +@Slf4j public class AccountService implements UserDetailsService { - @Autowired private AccountMapper accountMapper; - BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); - @Override + public AccountService() { + } + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println(username); - if(username == null) throw new UsernameNotFoundException("用户名不能为空"); - Account account = accountMapper.selectOne(new LambdaQueryWrapper() - .eq(Account::getUsername,username) - .or() - .eq(Account::getEmail,username) - .eq(Account::getStatus,true)); - if(account == null) throw new UsernameNotFoundException("用户名或密码错误"); - return User - .withUsername(account.getUsername()) - .password(account.getPassword()) - .roles("role=" + account.getRoleId(),"id=" + account.getId()) - .build(); + if (username == null) { + throw new UsernameNotFoundException("用户名不能为空"); + } else { + Account account = this.accountMapper.selectOne(new LambdaQueryWrapper().eq(Account::getUsername, username).or().eq(Account::getEmail, username).eq(Account::getStatus, true)); + if (account == null) { + throw new UsernameNotFoundException("用户名或密码错误"); + } else { + return User.withUsername(account.getUsername()).password(account.getPassword()).roles(new String[]{"role=" + account.getRoleId(), "id=" + account.getId()}).build(); + } + } } public R register(Account account) { account.setCreateTime(new Date()); account.setStatus(true); - account.setPassword(encoder.encode(account.getPassword())); - int insert = accountMapper.insert(account); - return insert == 1 ? R.success("注册成功") : R.failed(HttpCodes.HTTP_CODES555,"注册失败,您的用户名或者邮箱已经被注册过了"); + account.setPassword(this.encoder.encode(account.getPassword())); + int insert = this.accountMapper.insert(account); + return insert == 1 ? R.success("注册成功") : R.failed(HttpCodes.HTTP_CODES555, "注册失败,您的用户名或者邮箱已经被注册过了"); } + public R changeAccount(Account account) { - if (account.getPassword() != null){ - account.setPassword(encoder.encode(account.getPassword())); + if (account.getPassword() != null) { + account.setPassword(this.encoder.encode(account.getPassword())); } - int update = accountMapper.updateById(account); - return update == 1 ? R.success("修改用户信息成功") : R.failed(HttpCodes.HTTP_CODES555,"修改用户信息失败,请联系服务器管理员"); + + int update = this.accountMapper.updateById(account); + return update == 1 ? R.success("修改用户信息成功") : R.failed(HttpCodes.HTTP_CODES555, "修改用户信息失败,请联系服务器管理员"); } public R changeStatus(Integer userId, Boolean status) { Account account = new Account(); account.setId(userId); account.setStatus(status); - int i = accountMapper.updateById(account); - if (i == 1){ - if (status){ - return R.success("启用该用户成功"); - }else{ - return R.success("禁用该用户成功"); - } - }else{ - return R.failed(HttpCodes.HTTP_CODES555,"修改用户状态失败"); + int i = this.accountMapper.updateById(account); + if (i == 1) { + return status ? R.success("启用该用户成功") : R.success("禁用该用户成功"); + } else { + return R.failed(HttpCodes.HTTP_CODES555, "修改用户状态失败"); } } public R changePassword(Integer userId, String oldPassword, String newPassword) { Account account = new Account(); - account.setPassword(encoder.encode(newPassword)); + account.setPassword(this.encoder.encode(newPassword)); LambdaQueryWrapper accountLambdaQueryWrapper = new LambdaQueryWrapper<>(); - accountLambdaQueryWrapper - .eq(Account::getId,userId) - .eq(Account::getPassword,encoder.encode(oldPassword)); - int update = accountMapper.update(account, accountLambdaQueryWrapper); - return update == 1 ? R.success("修改密码成功") : R.failed(HttpCodes.HTTP_CODES555,"修改密码失败,请联系服务器管理员"); + accountLambdaQueryWrapper.eq(Account::getId, userId).eq(Account::getPassword, this.encoder.encode(oldPassword)); + int update = this.accountMapper.update(account, accountLambdaQueryWrapper); + return update == 1 ? R.success("修改密码成功") : R.failed(HttpCodes.HTTP_CODES555, "修改密码失败,请联系服务器管理员"); } public R getUser(Integer page, Integer num) { - Page accountPage = new Page<>(page,num); - Page accountPage1 = accountMapper.selectPage(accountPage, null); + Page accountPage = new Page<>((long)page, (long)num); + Page accountPage1 = this.accountMapper.selectPage(accountPage, null); JSONObject jsonObject = new JSONObject(); - List collect = accountPage1.getRecords().stream().peek(e -> e.setPassword(null)).toList(); - jsonObject - .fluentPut("info",collect) - .fluentPut("total",accountPage1.getTotal()); + List collect = accountPage1.getRecords().stream().peek((e) -> { + e.setPassword((String)null); + }).toList(); + jsonObject.fluentPut("info", collect).fluentPut("total", accountPage1.getTotal()); return R.success(jsonObject); } public R delUser(Integer id) { - int delete = accountMapper.deleteById(id); - return delete == 1 ? R.success("删除用户成功") : R.failed(HttpCodes.HTTP_CODES555,"删除用户失败,请联系服务器管理员"); + int delete = this.accountMapper.deleteById(id); + return delete == 1 ? R.success("删除用户成功") : R.failed(HttpCodes.HTTP_CODES555, "删除用户失败,请联系服务器管理员"); } } diff --git a/src/main/java/top/xinsin/service/CommissionService.java b/src/main/java/top/xinsin/service/CommissionService.java new file mode 100644 index 0000000..8f299fa --- /dev/null +++ b/src/main/java/top/xinsin/service/CommissionService.java @@ -0,0 +1,18 @@ +package top.xinsin.service; + +import org.springframework.stereotype.Service; +import top.xinsin.pojo.Commission; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author xinsin + * @since 2023-04-24 + */ +@Service +public class CommissionService { + +} diff --git a/src/main/java/top/xinsin/service/OrderService.java b/src/main/java/top/xinsin/service/OrderService.java index d539b03..3c16ed9 100644 --- a/src/main/java/top/xinsin/service/OrderService.java +++ b/src/main/java/top/xinsin/service/OrderService.java @@ -1,21 +1,153 @@ package top.xinsin.service; +import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.servlet.http.HttpServletResponse; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import top.xinsin.enums.OrderStatus; +import top.xinsin.enums.SearchType; import top.xinsin.mapper.OrderMapper; import top.xinsin.pojo.Order; -import com.baomidou.mybatisplus.extension.service.IService; +import top.xinsin.util.ExcelParserUtil; +import top.xinsin.util.HttpCodes; +import top.xinsin.util.R; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.Date; +import java.util.List; /** - *

- * 服务类 - *

- * * @author xinsin - * @since 2023-04-21 + * Created On 2023/4/24 21:12 + * @version 1.0 */ @Service +@Slf4j public class OrderService { @Autowired private OrderMapper orderMapper; + + public R addOrder(Order order) { + order.setOrderTime(new Date()); + int insert = this.orderMapper.insert(order); + return insert == 1 ? R.success("订单添加成功") : R.failed(HttpCodes.HTTP_CODES555, "订单添加失败,请联系服务器管理员"); + } + + public R getOrder(Integer page, Integer num) { + Page orderPage = new Page<>((long)page, (long)num); + Page orderPage1 = this.orderMapper.selectPage(orderPage, null); + JSONObject jsonObject = new JSONObject(); + jsonObject.fluentPut("info", orderPage1.getRecords()).fluentPut("total", orderPage1.getTotal()); + return R.success(jsonObject); + } + + public R getOrderUserInfo(String content) { + LambdaQueryWrapper orderLambdaQueryWrapper = new LambdaQueryWrapper<>(); + orderLambdaQueryWrapper.eq(Order::getWechatNo, content).or().eq(Order::getWangNo, content).or().eq(Order::getAlipayNo, content).or().eq(Order::getPhoneNumber, content).or().eq(Order::getAlipayName, content); + List orders = this.orderMapper.selectList(orderLambdaQueryWrapper); + return orders.size() == 0 ? R.success(false) : R.success(true); + } + + public R searchUserOrder(SearchType searchType, String searchContent, Boolean batch, Integer page, Integer num) { + LambdaQueryWrapper orderLambdaQueryWrapper = new LambdaQueryWrapper<>(); + if (batch) { + String[] split = searchContent.split(","); + String[] var8 = split; + int var9 = split.length; + + for(int var10 = 0; var10 < var9; ++var10) { + String s = var8[var10]; + this.searchForWhereOne(searchType, orderLambdaQueryWrapper, s); + } + } else { + this.searchForWhereOne(searchType, orderLambdaQueryWrapper, searchContent); + } + + Page orderPage = new Page<>((long)page, (long)num); + Page orderPage1 = this.orderMapper.selectPage(orderPage, orderLambdaQueryWrapper); + JSONObject jsonObject = new JSONObject(); + jsonObject.fluentPut("info", orderPage1.getRecords()).fluentPut("total", orderPage1.getTotal()); + return R.success(jsonObject); + } + + private void searchForWhereOne(SearchType searchType, LambdaQueryWrapper orderLambdaQueryWrapper, String searchContent) { + switch (searchType) { + case WANG_ID -> orderLambdaQueryWrapper.like(Order::getWangNo, searchContent); + case ALIPAY_ID -> orderLambdaQueryWrapper.like(Order::getAlipayNo, searchContent); + case WECHAT_ID -> orderLambdaQueryWrapper.like(Order::getWechatNo, searchContent); + case PHONE_NUMBER -> orderLambdaQueryWrapper.like(Order::getPhoneNumber, searchContent); + } + + } + + public R addOrderFlag(Integer orderId, Integer flagId, String flagRemark) { + Order order = new Order(); + order.setId(orderId); + order.setFlag(flagId); + order.setFlagRemark(flagRemark); + int update = this.orderMapper.updateById(order); + return update == 1 ? R.success("订单插旗成功," + flagId + "号旗") : R.failed(HttpCodes.HTTP_CODES555, "订单插旗失败,请联系服务器管理员"); + } + + public R changeOrder(Order order) { + int update = this.orderMapper.updateById(order); + return update == 1 ? R.success("订单修改成功") : R.failed(HttpCodes.HTTP_CODES555, "订单修改失败,请联系服务器管理员"); + } + + public R delOrder(Integer orderId) { + int delete = this.orderMapper.deleteById(orderId); + return delete == 1 ? R.success("删除订单成功") : R.failed(HttpCodes.HTTP_CODES555, "删除订单失败,请联系服务器管理员"); + } + + public R confirm(OrderStatus orderStatus, Integer orderId) { + Order order = new Order(); + order.setId(orderId); + order.setOrderStatus(orderStatus.name()); + int update = this.orderMapper.updateById(order); + return update == 1 ? R.success("订单确认成功,当前状态:" + orderStatus.name()) : R.failed(HttpCodes.HTTP_CODES555, "订单确认失败,请联系服务器管理员"); + } + + @SneakyThrows + public void downloadTemplate(HttpServletResponse response) { + try { + File file = new File("template/example.xlsx"); + FileInputStream fileInputStream = new FileInputStream(file); + BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); + byte[] bytes = new byte[bufferedInputStream.available()]; + bufferedInputStream.read(bytes); + bufferedInputStream.close(); + response.reset(); + response.setCharacterEncoding("utf-8"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.addHeader("Content-disposition", "attachment;filename*=utf-8''example.xlsx"); + response.addHeader("Content-Length", "" + file.length()); + BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(response.getOutputStream()); + response.setContentType("application/octet-stream"); + bufferedOutputStream.write(bytes); + bufferedOutputStream.flush(); + } catch (Throwable var7) { + throw var7; + } + } + + @SneakyThrows + public void uploadBatch(MultipartFile file) { + try { + EasyExcel.read(file.getInputStream(), Order.class, new ExcelParserUtil(this.orderMapper)).sheet().doRead(); + } catch (Throwable var3) { + throw var3; + } + } } diff --git a/src/main/java/top/xinsin/service/PermissionsService.java b/src/main/java/top/xinsin/service/PermissionsService.java index 63c917b..87702b6 100644 --- a/src/main/java/top/xinsin/service/PermissionsService.java +++ b/src/main/java/top/xinsin/service/PermissionsService.java @@ -1,18 +1,14 @@ package top.xinsin.service; import org.springframework.stereotype.Service; -import top.xinsin.pojo.Permissions; -import com.baomidou.mybatisplus.extension.service.IService; /** - *

- * 服务类 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:13 + * @version 1.0 */ @Service public class PermissionsService { - + public PermissionsService() { + } } diff --git a/src/main/java/top/xinsin/service/RolesService.java b/src/main/java/top/xinsin/service/RolesService.java index e44ed52..d2c86d5 100644 --- a/src/main/java/top/xinsin/service/RolesService.java +++ b/src/main/java/top/xinsin/service/RolesService.java @@ -1,18 +1,14 @@ package top.xinsin.service; import org.springframework.stereotype.Service; -import top.xinsin.pojo.Roles; -import com.baomidou.mybatisplus.extension.service.IService; /** - *

- * 服务类 - *

- * * @author xinsin - * @since 2023-04-12 + * Created On 2023/4/24 21:13 + * @version 1.0 */ @Service public class RolesService { - + public RolesService() { + } } diff --git a/src/main/java/top/xinsin/service/StoreService.java b/src/main/java/top/xinsin/service/StoreService.java new file mode 100644 index 0000000..641784f --- /dev/null +++ b/src/main/java/top/xinsin/service/StoreService.java @@ -0,0 +1,16 @@ +package top.xinsin.service; + +import top.xinsin.pojo.Store; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author xinsin + * @since 2023-04-24 + */ +public interface StoreService extends IService { + +} diff --git a/src/main/java/top/xinsin/util/ExcelParserUtil.java b/src/main/java/top/xinsin/util/ExcelParserUtil.java new file mode 100644 index 0000000..38dd61c --- /dev/null +++ b/src/main/java/top/xinsin/util/ExcelParserUtil.java @@ -0,0 +1,103 @@ +package top.xinsin.util; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelDataConvertException; +import com.alibaba.excel.read.processor.AnalysisEventProcessor; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import top.xinsin.mapper.OrderMapper; +import top.xinsin.pojo.Order; +import top.xinsin.service.OrderService; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author xinsin + * Created On 2023/4/22 22:44 + * @version 1.0 + */ +@Slf4j +public class ExcelParserUtil extends AnalysisEventListener { + /** + * 每次读取的最大数据条数 + */ + private static final int MAX_BATCH_COUNT = 100; + + /** + * 泛型bean属性 + */ + private OrderMapper dynamicService; + + /** + * 可接收任何参数的泛型List集合 + */ + List list = new ArrayList<>(); + + List total = new ArrayList<>(); + + + /** + * 构造函数注入bean(根据传入的bean动态注入) + * + * @param dynamicService + */ + public ExcelParserUtil(OrderMapper dynamicService) { + this.dynamicService = dynamicService; + } + + @Override + public void invoke(Order data, AnalysisContext analysisContext) { + log.info(" ==> 解析一条数据: {}", JSONObject.toJSONString(data)); + list.add(data); + if (list.size() > MAX_BATCH_COUNT) { + // 保存数据 + saveData(); + // 清空list + list.clear(); + } + } + /** + * 所有数据解析完成后,会来调用一次 + * 作用: 避免最后集合中小于 MAX_BATCH_COUNT 条的数据没有被保存 + * + * @param context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + saveData(); + log.info(" ==> 数据解析完成 <=="); + } + /** + * 保存数据 + */ + private void saveData() { + log.info(" ==> 数据保存开始: {}", list.size()); + ArrayList ts = new ArrayList<>(); + list.forEach(order -> { + if (order.getOrderNo() != null && order.getOrderTime() != null && order.getWangNo() != null && order.getPayAmt() != null && order.getShopId() != null && order.getAddress() != null){ + ts.add(order); + } + }); + ts.forEach(dynamicService::insert); + log.info(" ==> 数据保存结束 <=="); + } + + /** + * 在转换异常 获取其他异常下会调用本接口。我们如果捕捉并手动抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。 + * + * @param exception + * @param context + * @throws Exception + */ + @Override + public void onException(Exception exception, AnalysisContext context) throws Exception { + log.error(" ==> 数据解析失败,但是继续读取下一行:{}", exception.getMessage()); + // 如果是某一个单元格的转换异常 能获取到具体行号 + if (exception instanceof ExcelDataConvertException) { + ExcelDataConvertException convertException = (ExcelDataConvertException) exception; + log.error("第{}行,第{}列数据解析异常", convertException.getRowIndex(), convertException.getColumnIndex()); + } + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 84f06c1..e2a2c04 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,7 +4,7 @@ spring: datasource: username: commerce_system password: Jix656dzD6St4YCn - url: jdbc:mysql://wzpmc.cn:3306/commerce_system?serverTimezone=UTC-8 + url: jdbc:mysql://www.wzpmc.cn:3306/commerce_system?serverTimezone=UTC-8 driver-class-name: com.mysql.cj.jdbc.Driver # druid配置 type: com.alibaba.druid.pool.DruidDataSource diff --git a/src/main/resources/mapper/OrderMapper.xml b/src/main/resources/mapper/OrderMapper.xml index 71b2ea9..c315879 100644 --- a/src/main/resources/mapper/OrderMapper.xml +++ b/src/main/resources/mapper/OrderMapper.xml @@ -10,11 +10,11 @@ - + - + - + diff --git a/src/test/java/top/xinsin/CodeGenerator.java b/src/test/java/top/xinsin/CodeGenerator.java index 03f7d94..4886dbd 100644 --- a/src/test/java/top/xinsin/CodeGenerator.java +++ b/src/test/java/top/xinsin/CodeGenerator.java @@ -14,7 +14,8 @@ import java.util.function.Consumer; public class CodeGenerator { public static void main(String[] args) { List tables = new ArrayList<>(); - tables.add("order"); + tables.add("store"); + tables.add("commission"); FastAutoGenerator.create("jdbc:mysql://wzpmc.cn:3306/commerce_system?serverTimezone=UTC-8","commerce_system","Jix656dzD6St4YCn") .globalConfig(builder -> { diff --git a/template/example.xlsx b/template/example.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ee9c302f4d2acc005ec3cfe495044c3e94e9e29b GIT binary patch literal 9922 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 literal 0 HcmV?d00001