licailing 5 سال پیش
والد
کامیت
c7340b715c
53فایلهای تغییر یافته به همراه1280 افزوده شده و 196 حذف شده
  1. 2 0
      src/main/java/com/izouma/dingdong/config/Constants.java
  2. 5 2
      src/main/java/com/izouma/dingdong/domain/merchant/AutomaticResponse.java
  3. 5 2
      src/main/java/com/izouma/dingdong/domain/merchant/FullReduction.java
  4. 4 4
      src/main/java/com/izouma/dingdong/domain/merchant/Merchant.java
  5. 10 7
      src/main/java/com/izouma/dingdong/domain/merchant/MerchantClassification.java
  6. 3 0
      src/main/java/com/izouma/dingdong/domain/merchant/MerchantSettings.java
  7. 2 0
      src/main/java/com/izouma/dingdong/domain/user/Address.java
  8. 2 2
      src/main/java/com/izouma/dingdong/domain/user/MyCollection.java
  9. 6 1
      src/main/java/com/izouma/dingdong/enums/Identity.java
  10. 7 1
      src/main/java/com/izouma/dingdong/repo/UserRepo.java
  11. 8 0
      src/main/java/com/izouma/dingdong/repo/backstage/BlackListRepo.java
  12. 4 1
      src/main/java/com/izouma/dingdong/repo/merchant/AutomaticResponseRepo.java
  13. 5 2
      src/main/java/com/izouma/dingdong/repo/merchant/FullReductionRepo.java
  14. 2 0
      src/main/java/com/izouma/dingdong/repo/merchant/GoodsSpecificationRepo.java
  15. 4 0
      src/main/java/com/izouma/dingdong/repo/merchant/MerchantClassificationRepo.java
  16. 0 7
      src/main/java/com/izouma/dingdong/repo/merchant/SalesRepo.java
  17. 19 0
      src/main/java/com/izouma/dingdong/repo/user/AddressRepo.java
  18. 30 25
      src/main/java/com/izouma/dingdong/security/Authority.java
  19. 1 1
      src/main/java/com/izouma/dingdong/service/OrderInfoService.java
  20. 21 0
      src/main/java/com/izouma/dingdong/service/UserService.java
  21. 24 0
      src/main/java/com/izouma/dingdong/service/backstage/BlackListService.java
  22. 4 4
      src/main/java/com/izouma/dingdong/service/merchant/FullReductionService.java
  23. 43 12
      src/main/java/com/izouma/dingdong/service/merchant/GoodsService.java
  24. 47 5
      src/main/java/com/izouma/dingdong/service/merchant/MerchantClassificationService.java
  25. 63 32
      src/main/java/com/izouma/dingdong/service/merchant/MerchantService.java
  26. 10 10
      src/main/java/com/izouma/dingdong/service/merchant/SalesService.java
  27. 14 0
      src/main/java/com/izouma/dingdong/service/user/AddressService.java
  28. 32 2
      src/main/java/com/izouma/dingdong/web/AuthenticationController.java
  29. 15 3
      src/main/java/com/izouma/dingdong/web/AuthorityController.java
  30. 28 7
      src/main/java/com/izouma/dingdong/web/UserController.java
  31. 63 0
      src/main/java/com/izouma/dingdong/web/backstage/BlackListController.java
  32. 4 4
      src/main/java/com/izouma/dingdong/web/merchant/AutomaticResponseController.java
  33. 1 1
      src/main/java/com/izouma/dingdong/web/merchant/FullReductionController.java
  34. 3 8
      src/main/java/com/izouma/dingdong/web/merchant/GoodsController.java
  35. 5 4
      src/main/java/com/izouma/dingdong/web/merchant/GoodsSpecificationController.java
  36. 17 1
      src/main/java/com/izouma/dingdong/web/merchant/MerchantClassificationController.java
  37. 68 0
      src/main/java/com/izouma/dingdong/web/user/AddressController.java
  38. 2 2
      src/main/resources/application.yaml
  39. 1 0
      src/main/resources/genjson/Address.json
  40. 1 0
      src/main/resources/genjson/BlackList.json
  41. 33 1
      src/main/vue/src/router.js
  42. 3 3
      src/main/vue/src/views/GoodsEdit.vue
  43. 2 2
      src/main/vue/src/views/GoodsList.vue
  44. 14 8
      src/main/vue/src/views/UserEdit.vue
  45. 1 1
      src/main/vue/src/views/UserList.vue
  46. 100 0
      src/main/vue/src/views/backstage/BlackListEdit.vue
  47. 179 0
      src/main/vue/src/views/backstage/BlackListList.vue
  48. 193 0
      src/main/vue/src/views/backstage/BlackUserEdit.vue
  49. 157 0
      src/main/vue/src/views/backstage/BlackUserList.vue
  50. 10 28
      src/main/vue/src/views/merchant/MerchantEdit.vue
  51. 1 1
      src/main/vue/src/views/merchant/MerchantList.vue
  52. 1 1
      src/main/vue/vue.config.js
  53. 1 1
      src/test/java/com/izouma/dingdong/repo/UserRepoTest.java

+ 2 - 0
src/main/java/com/izouma/dingdong/config/Constants.java

@@ -16,4 +16,6 @@ public interface Constants {
     String SMS_TEMPLATE_CODE_GENERIC = "SMS_175485688";
 
     String CLASSIFICATION_NAME = "好评热销";
+
+    String CLASSIFICATION_NAME2 = "折扣";
 }

+ 5 - 2
src/main/java/com/izouma/dingdong/domain/merchant/AutomaticResponse.java

@@ -20,8 +20,11 @@ import java.io.Serializable;
 @ApiModel(value = "自动回复设置")
 public class AutomaticResponse extends BaseEntity implements Serializable {
 
-    @ApiModelProperty(value = "商户ID")
-    private Long merchantId;
+//    @ApiModelProperty(value = "商户ID")
+//    private Long merchantId;
+
+    @ApiModelProperty(value = "用户ID")
+    private Long userId;
 
     @ApiModelProperty(value = "自动回复内容")
     private String context;

+ 5 - 2
src/main/java/com/izouma/dingdong/domain/merchant/FullReduction.java

@@ -19,8 +19,11 @@ import java.math.BigDecimal;
 @Builder
 @ApiModel(value = "满减表", description = "满减表")
 public class FullReduction extends BaseEntity implements Serializable {
-    @ApiModelProperty(value = "商户ID",name = "merchantSettingsId")
-    private Long merchantId;
+//    @ApiModelProperty(value = "商户ID",name = "merchantSettingsId")
+//    private Long merchantId;
+
+    @ApiModelProperty(value = "用户ID")
+    private Long userId;
 
     @ApiModelProperty(value = "满额", name = "fullAmount")
     private BigDecimal fullAmount;

+ 4 - 4
src/main/java/com/izouma/dingdong/domain/merchant/Merchant.java

@@ -63,13 +63,13 @@ public class Merchant extends BaseEntity implements Serializable {
     private String aliAccount;
 
     @ApiModelProperty(value = "总好评数量", name = "goodNum")
-    private Integer goodNum = 0;
+    private Integer goodNum;
 
     @ApiModelProperty(value = "差评数量", name = "badNum")
-    private Integer badNum = 0;
+    private Integer badNum;
 
     @ApiModelProperty(value = "月销", name = "monthSales")
-    private Integer monthSales = 0;
+    private Integer monthSales;
 
     @ApiModelProperty(value = "通过", name = "isPass")
     private Boolean isPass;
@@ -81,6 +81,6 @@ public class Merchant extends BaseEntity implements Serializable {
     @ApiModelProperty(value = "成立时间", name = "established")
     private LocalDateTime establishTime;
 
-    @ApiModelProperty(value = "自动接单",name = "automaticOrder")
+    @ApiModelProperty(value = "自动接单", name = "automaticOrder")
     private Boolean automaticOrder;
 }

+ 10 - 7
src/main/java/com/izouma/dingdong/domain/merchant/MerchantClassification.java

@@ -1,19 +1,16 @@
 package com.izouma.dingdong.domain.merchant;
 
+
 import com.izouma.dingdong.domain.BaseEntity;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.hibernate.annotations.BatchSize;
+import lombok.*;
+
 
 import javax.persistence.*;
 import javax.validation.constraints.Size;
 import java.io.Serializable;
-import java.util.List;
-import java.util.Set;
+
 
 @Data
 @AllArgsConstructor
@@ -22,6 +19,9 @@ import java.util.Set;
 @Builder
 @ApiModel(value = "商家自定义分类")
 public class MerchantClassification extends BaseEntity implements Serializable {
+
+    //private Long userId;
+
     @ApiModelProperty(value = "名称", name = "name")
     @Column(length = 50)
     @Size(max = 50)
@@ -47,4 +47,7 @@ public class MerchantClassification extends BaseEntity implements Serializable {
     @ApiModelProperty(value = "是否开启", name = "isOpen")
     private Boolean isOpen;
 
+    @ApiModelProperty(value = "是否显示", name = "isShow")
+    private Boolean isShow;
+
 }

+ 3 - 0
src/main/java/com/izouma/dingdong/domain/merchant/MerchantSettings.java

@@ -25,6 +25,9 @@ import java.util.Set;
 @Where(clause = "enabled = true")
 @ApiModel(value = "商户设置", description = "商户设置")
 public class MerchantSettings extends BaseEntity {
+    @ApiModelProperty(value = "用户ID")
+    private Long merUserId;
+
     @ApiModelProperty(value = "商户ID", name = "merchantId")
     private Long merchantId;
 

+ 2 - 0
src/main/java/com/izouma/dingdong/domain/user/Address.java

@@ -29,5 +29,7 @@ public class Address extends BaseEntity {
     private String address;
 
     @ApiModelProperty("是否选为默认地址")
+    private Boolean isDefault;
+
     private Boolean enabled ;
 }

+ 2 - 2
src/main/java/com/izouma/dingdong/domain/user/MyCollection.java

@@ -22,6 +22,6 @@ public class MyCollection extends BaseEntity {
     @ApiModelProperty(value = "商户ID",name = "merchantId")
     private Long merchantId;
 
-    @ApiModelProperty(value = "商户简介",name = "merchantProfile")
-    private String merchantProfile;
+//    @ApiModelProperty(value = "商户简介",name = "merchantProfile")
+//    private String merchantProfile;
 }

+ 6 - 1
src/main/java/com/izouma/dingdong/enums/Identity.java

@@ -12,5 +12,10 @@ public enum Identity {
     /*
     骑手
      */
-    RIDER;
+    RIDER,
+    /*
+    管理员
+     */
+    ADMIN
+
 }

+ 7 - 1
src/main/java/com/izouma/dingdong/repo/UserRepo.java

@@ -1,19 +1,21 @@
 package com.izouma.dingdong.repo;
 
 import com.izouma.dingdong.domain.User;
+import com.izouma.dingdong.enums.Identity;
 import com.izouma.dingdong.security.Authority;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
+
 import javax.transaction.Transactional;
 import java.util.List;
 
 public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
     User findByUsername(String username);
 
-    List<User> findAllByAuthoritiesContains(Authority authority);
+    List<User> findAllByAuthoritiesNotContains(Authority authority);
 
     User findByOpenId(String openId);
 
@@ -23,4 +25,8 @@ public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExe
     @Modifying
     @Transactional
     void deleteById(Long id);
+
+    List<User> findAllByIdentityAndAuthoritiesContains(Identity identity, Authority authority);
+
+    List<User> findAllByIdentity(Identity identity);
 }

+ 8 - 0
src/main/java/com/izouma/dingdong/repo/backstage/BlackListRepo.java

@@ -0,0 +1,8 @@
+package com.izouma.dingdong.repo.backstage;
+
+import com.izouma.dingdong.domain.backstage.BlackList;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+public interface BlackListRepo extends JpaRepository<BlackList, Long>, JpaSpecificationExecutor<BlackList> {
+}

+ 4 - 1
src/main/java/com/izouma/dingdong/repo/merchant/AutomaticResponseRepo.java

@@ -9,5 +9,8 @@ import java.util.List;
 public interface AutomaticResponseRepo extends JpaRepository<AutomaticResponse, Long>, JpaSpecificationExecutor<AutomaticResponse> {
 
     //查找商户下的所有自动回复
-    List<AutomaticResponse> findAllByMerchantId(Long merchantId);
+   // List<AutomaticResponse> findAllByMerchantId(Long merchantId);
+
+    //查找商户下的所有自动回复
+    List<AutomaticResponse> findAllByUserId(Long userId);
 }

+ 5 - 2
src/main/java/com/izouma/dingdong/repo/merchant/FullReductionRepo.java

@@ -8,6 +8,9 @@ import java.util.List;
 
 public interface FullReductionRepo extends JpaRepository<FullReduction, Long>, JpaSpecificationExecutor<FullReduction> {
 
-    //查找商户下的所有商品
-    List<FullReduction> findAllByMerchantId(Long merchantId);
+    //查找商户下的所有满减
+    //List<FullReduction> findAllByMerchantId(Long merchantId);
+
+    //查找商户下的所有满减
+    List<FullReduction> findAllByUserId(Long userId);
 }

+ 2 - 0
src/main/java/com/izouma/dingdong/repo/merchant/GoodsSpecificationRepo.java

@@ -9,4 +9,6 @@ import java.util.List;
 public interface GoodsSpecificationRepo extends JpaRepository<GoodsSpecification, Long>, JpaSpecificationExecutor<GoodsSpecification> {
     //按商品ID查询
     List<GoodsSpecification> findAllByGoodsId(Long goodsId);
+
+    void deleteByGoodsId(Long goodsId);
 }

+ 4 - 0
src/main/java/com/izouma/dingdong/repo/merchant/MerchantClassificationRepo.java

@@ -9,6 +9,10 @@ import java.util.List;
 public interface MerchantClassificationRepo extends JpaRepository<MerchantClassification, Long>, JpaSpecificationExecutor<MerchantClassification> {
     List<MerchantClassification> findAllByMerchantId(Long merchantId);
 
+    //List<MerchantClassification> findAllByUserId(Long userId);
+
     MerchantClassification findByMerchantIdAndName(Long merchantId, String Name);
 
+    //MerchantClassification findByUserIdAndName(Long merchantId, String Name);
+
 }

+ 0 - 7
src/main/java/com/izouma/dingdong/repo/merchant/SalesRepo.java

@@ -9,13 +9,6 @@ import java.util.List;
 
 public interface SalesRepo extends JpaRepository<Sales, Long>, JpaSpecificationExecutor<Sales> {
 
-//    List<Sales> findByGoodsIdAndPopularityGreaterThanEqual(Long goodsId, Integer num);
-
-    //人气商品,前一天起连续五天,每天销量>50
-//    List<Sales> findByGoodsIdAndDayAndPopularityGreaterThanEqual(Long goodsId, LocalDate day, Integer num);
-
-    //好评商品,前一天起连续五天,每天销量>10,点赞数量在增加
-//    Sales findByGoodsIdAndDayAndPraiseGreaterThanEqual(Long goodsId, LocalDate day, Integer num);
 
     List<Sales> findAllByGoodsId(Long goodsId);
 

+ 19 - 0
src/main/java/com/izouma/dingdong/repo/user/AddressRepo.java

@@ -0,0 +1,19 @@
+package com.izouma.dingdong.repo.user;
+
+import com.izouma.dingdong.domain.user.Address;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import javax.transaction.Transactional;
+
+public interface AddressRepo extends JpaRepository<Address, Long>, JpaSpecificationExecutor<Address> {
+    @Query("update Address t set t.enabled = false where t.id = ?1")
+    @Modifying
+    @Transactional
+    void deleteById(Long id);
+
+    @Query("update Address t set t.isDefault = 0 where t.id<>?1 and t.userId=?2")
+    Address updateIsDefault(Long id, Long userId);
+}

+ 30 - 25
src/main/java/com/izouma/dingdong/security/Authority.java

@@ -20,31 +20,34 @@ import java.util.Objects;
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class Authority implements Serializable {
     public enum NAMES {
-        /*
-        普通用户
-         */
-        ROLE_USER,
-        ROLE_DEV,
-        /*
-        超级管理员
-         */
-        ROLE_ADMIN,
-        /*
-        行业管理员
-         */
-        ROLE_INDUSTRY,
-        /*
-        本地化
-         */
-        ROLE_LOCALIZATION,
-        /*
-        财务
-         */
-        ROLE_FINANCE,
-        /*
-        客服
-         */
-        ROLE_CUSTOMER
+
+        ROLE_USER("普通用户"),
+
+        ROLE_DEV("开发者"),
+
+        ROLE_ADMIN("超级管理员"),
+
+        ROLE_INDUSTRY("行业管理员"),
+
+        ROLE_LOCALIZATION("本地化"),
+
+        ROLE_FINANCE("财务"),
+
+        ROLE_CUSTOMER("客服");
+
+        public final String description;
+
+        NAMES(String description) {
+            this.description = description;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+    }
+
+    public static Authority getInstance(NAMES name) {
+        return new Authority(name.name(), name.getDescription());
     }
 
     @Id
@@ -53,6 +56,8 @@ public class Authority implements Serializable {
     @Column(length = 50)
     private String name;
 
+    private String description;
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {

+ 1 - 1
src/main/java/com/izouma/dingdong/service/OrderInfoService.java

@@ -115,7 +115,7 @@ public class OrderInfoService {
         BigDecimal goodsAmount = orderInfo.getTotalAmount();
         if (type == CouponType.REDUCTION) {
             if (goodsAmount.compareTo(coupon.getFullAmount()) >= 0) {
-                goodsAmount.subtract(coupon.getAmount());
+                goodsAmount = goodsAmount.subtract(coupon.getAmount());
             }
 
         }

+ 21 - 0
src/main/java/com/izouma/dingdong/service/UserService.java

@@ -3,6 +3,7 @@ package com.izouma.dingdong.service;
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
+import cn.hutool.core.util.ObjectUtil;
 import com.izouma.dingdong.config.Constants;
 import com.izouma.dingdong.domain.User;
 import com.izouma.dingdong.exception.BusinessException;
@@ -36,6 +37,26 @@ public class UserService {
     private StorageService storageService;
     private JwtTokenUtil   jwtTokenUtil;
 
+
+    /*
+    创建User
+     */
+    public User register(String phone, String password) {
+        //用于商家登录
+        User user = userRepo.findByPhone(phone);
+        if (ObjectUtil.isNull(user)) {
+            user = User.builder().username(phone)
+                    .password(new BCryptPasswordEncoder().encode(password))
+                    .blacklist(false)
+                    .enabled(true)
+                    .phone(phone)
+                    .authorities(Collections.singleton(Authority.getInstance(Authority.NAMES.ROLE_USER)))
+                    .build();
+            userRepo.save(user);
+        }
+        return user;
+    }
+
     public User loginByPhone(String phone) {
         return userRepo.findByPhone(phone);
     }

+ 24 - 0
src/main/java/com/izouma/dingdong/service/backstage/BlackListService.java

@@ -0,0 +1,24 @@
+package com.izouma.dingdong.service.backstage;
+
+import com.izouma.dingdong.domain.backstage.BlackList;
+import com.izouma.dingdong.repo.backstage.BlackListRepo;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class BlackListService {
+
+    private BlackListRepo blackListRepo;
+
+
+    /*
+    加入黑名单
+     */
+
+
+    /*
+    移出黑名单
+     */
+
+}

+ 4 - 4
src/main/java/com/izouma/dingdong/service/merchant/FullReductionService.java

@@ -27,24 +27,24 @@ public class FullReductionService {
     添加
      */
     public void add(Long userId, List<FullReductionDTO> fullReductionDTOS) {
-        Long merchantId = merchantService.findMerchantId(userId);
+       // Long merchantId = merchantService.findMerchantId(userId);
 
         for (FullReductionDTO dto : fullReductionDTOS) {
-            toDTO(merchantId, dto);
+            toDTO(userId, dto);
         }
     }
 
     /*
     DTO转实体
      */
-    private void toDTO(Long merchantId, FullReductionDTO dto) {
+    private void toDTO(Long userId, FullReductionDTO dto) {
         if (dto.getFullAmount().compareTo(dto.getMinusAmount()) <= 0) {
             throw new BusinessException("减的金额不能大于等于满的金额");
         }
         FullReduction fullReduction = new FullReduction();
         fullReduction.setFullAmount(dto.getFullAmount());
         fullReduction.setMinusAmount(dto.getMinusAmount());
-        fullReduction.setMerchantId(merchantId);
+        fullReduction.setUserId(userId);
         fullReductionRepo.save(fullReduction);
     }
 }

+ 43 - 12
src/main/java/com/izouma/dingdong/service/merchant/GoodsService.java

@@ -1,17 +1,20 @@
 package com.izouma.dingdong.service.merchant;
 
 import cn.hutool.core.util.ObjectUtil;
+import com.izouma.dingdong.config.Constants;
 import com.izouma.dingdong.domain.merchant.Goods;
+import com.izouma.dingdong.domain.merchant.MerchantClassification;
 import com.izouma.dingdong.exception.BusinessException;
 import com.izouma.dingdong.repo.merchant.GoodsRepo;
+import com.izouma.dingdong.repo.merchant.MerchantClassificationRepo;
 import com.izouma.dingdong.repo.merchant.MerchantRepo;
 import com.izouma.dingdong.repo.merchant.SalesRepo;
+import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.util.List;
+
 
 @Service
 @AllArgsConstructor
@@ -25,27 +28,55 @@ public class GoodsService {
 
     private SalesRepo salesRepo;
 
+    private MerchantClassificationRepo merchantClassificationRepo;
+
+    private MerchantClassificationService merchantClassificationService;
+
     /*
-    添加商品
+    添加修改商品
      */
-    public Goods add(Goods goods) {
+    public Goods save(Goods goods) {
         if (ObjectUtil.isNull(goods.getMerchantId())) {
-            throw new BusinessException("商家出错");
+            throw new BusinessException("缺少商家");
         }
         merchantRepo.findById(goods.getMerchantId()).orElseThrow(new BusinessException("商家不存在"));
         if (goods.getInventory() < 1) {
             throw new BusinessException("商品供应数量不足");
         }
         if (BigDecimal.ZERO.compareTo(goods.getAmount()) >= 0) {
-            throw new BusinessException("价格不得小于0");
+            throw new BusinessException("价格不得小于等于0");
+        }
+        if (BigDecimal.ZERO.compareTo(goods.getDiscountAmount()) >= 0) {
+            throw new BusinessException("折扣价不得小于等于0");
+        }
+
+        int i = goods.getAmount().compareTo(goods.getDiscountAmount());
+        if (i < 0) {
+            throw new BusinessException("折扣价不得大于原价");
         }
-        goods.setLikes(0);
-        goods.setBad(0);
-        goods.setTotalSales(0);
-        goods.setTakeOff(false);
-        goods.setSignboard(false);
 
-        return goodsRepo.save(goods);
+        if (goods.getId() == null) {
+            goods.setLikes(0);
+            goods.setBad(0);
+            goods.setTotalSales(0);
+            goods.setTakeOff(false);
+            goods.setSignboard(false);
+            goods.setEnabled(true);
+        }
+
+        goods = goodsRepo.save(goods);
+
+        if (i > 0) {
+            //如果有折扣价,自动加入折扣分类
+            MerchantClassification classification = merchantClassificationRepo.findByMerchantIdAndName(goods.getMerchantId(), Constants.CLASSIFICATION_NAME2);
+            if (!classification.getIsShow() || ObjectUtil.isNull(classification.getIsShow())) {
+                classification.setIsShow(true);
+                merchantClassificationRepo.save(classification);
+            }
+            merchantClassificationService.saveOneGoods(classification.getId(), goods.getId());
+        }
+
+        return goods;
     }
 
 

+ 47 - 5
src/main/java/com/izouma/dingdong/service/merchant/MerchantClassificationService.java

@@ -1,6 +1,8 @@
 package com.izouma.dingdong.service.merchant;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import com.izouma.dingdong.converter.StringArrayConverter;
 import com.izouma.dingdong.domain.merchant.Goods;
 import com.izouma.dingdong.domain.merchant.MerchantClassification;
@@ -8,6 +10,7 @@ import com.izouma.dingdong.exception.BusinessException;
 import com.izouma.dingdong.repo.merchant.GoodsRepo;
 import com.izouma.dingdong.repo.merchant.MerchantClassificationRepo;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -27,15 +30,20 @@ public class MerchantClassificationService {
     添加商家自定义分类
      */
     public MerchantClassification add(Long id, MerchantClassification classification) {
+        Long merchantId = merchantService.findMerchantId(id);
+        if (ObjectUtil.isNotNull(merchantClassificationRepo.findByMerchantIdAndName(merchantId, classification.getName()))){
+            throw new BusinessException("该分类已存在");
+        }
 
         MerchantClassification build = MerchantClassification.builder()
                 .name(classification.getName())
                 .goodsIds(classification.getGoodsIds())
+                .sort(classification.getSort())
                 .build();
 
         //根据用户ID设置商户ID
-        build.setMerchantId(merchantService.findMerchantId(id));
-        if (classification.getIsOpen() == null) {
+        build.setMerchantId(merchantId);
+        if (ObjectUtil.isNull(classification.getIsOpen())) {
             build.setIsOpen(true);
         } else {
             build.setIsOpen(classification.getIsOpen());
@@ -61,8 +69,9 @@ public class MerchantClassificationService {
 
     /**
      * 分类下添加商品
+     *
      * @param classificationId 分类Id
-     * @param string 拼接好的goodsId字符串
+     * @param string           拼接好的goodsId字符串
      * @return 分类
      */
     public MerchantClassification saveGoods(Long classificationId, String string) {
@@ -72,19 +81,52 @@ public class MerchantClassificationService {
         StringArrayConverter converter = new StringArrayConverter();
         String string = converter.convertToDatabaseColumn(goodId);*/
 
+
         String goodsIds = merchantClassification.getGoodsIds();
 
-        //保存
-        merchantClassification.setGoodsIds(goodsIds + "," + string);
+//        StringArrayConverter converter = new StringArrayConverter();
+//        List<String> strings1 = converter.convertToEntityAttribute(string);
+//        List<String> strings = converter.convertToEntityAttribute(goodsIds);
+//        strings1.forEach(strings::contains);
+
+        if (StrUtil.isBlank(goodsIds)) {
+            merchantClassification.setGoodsIds(string);
+        } else {
+            //保存
+            merchantClassification.setGoodsIds(goodsIds + "," + string);
+        }
         return merchantClassificationRepo.save(merchantClassification);
     }
 
+    /*
+    分类下一个个添加商品
+     */
+    public void saveOneGoods(Long classificationId, Long goodsId) {
+        //查找分类
+        MerchantClassification merchantClassification = merchantClassificationRepo.findById(classificationId).orElseThrow(new BusinessException("无分类"));
+        String goodsIds = merchantClassification.getGoodsIds();
+
+        StringArrayConverter converter = new StringArrayConverter();
+        List<String> strings = converter.convertToEntityAttribute(goodsIds);
+
+        if (!strings.contains(goodsId.toString())) {
+            if (StrUtil.isBlank(goodsIds)) {
+                merchantClassification.setGoodsIds(goodsId.toString());
+            } else {
+                //保存
+                merchantClassification.setGoodsIds(goodsIds + "," + goodsId);
+            }
+            merchantClassificationRepo.save(merchantClassification);
+        }
+    }
+
     /*
     分类下删除商品
      */
     public void delGoods(Long classificationId, Long goodId) {
         //查找分类
         MerchantClassification merchantClassification = merchantClassificationRepo.findById(classificationId).orElseThrow(new BusinessException("无分类"));
+
         //替换
         String replaceAll = merchantClassification.getGoodsIds().replaceAll(",|''" + goodId.toString() + "''|,", "");
         //保存

+ 63 - 32
src/main/java/com/izouma/dingdong/service/merchant/MerchantService.java

@@ -17,6 +17,8 @@ import com.izouma.dingdong.repo.merchant.MerchantClassificationRepo;
 import com.izouma.dingdong.repo.merchant.MerchantRepo;
 import com.izouma.dingdong.repo.merchant.MerchantSettingsRepo;
 import com.izouma.dingdong.security.Authority;
+import com.izouma.dingdong.service.UserService;
+import com.izouma.dingdong.utils.ObjUtils;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
@@ -25,6 +27,8 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 
 import javax.transaction.Transactional;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -40,36 +44,16 @@ public class MerchantService {
 
     private MerchantClassificationRepo merchantClassificationRepo;
 
+    private UserService userService;
 
-    /*
-    创建User
-     */
-    public User reg(){
-        return null;
-    }
 
     /*
     商户注册申请
      */
     @Transactional
     public MerchantDTO registerApply(MerchantDTO merchantDTO) {
-        //用于商家登录
-        User user = userRepo.findByPhone(merchantDTO.getPhone());
-        if (ObjectUtil.isNull(user)) {
-            user = User.builder().username(merchantDTO.getPhone())
-                    .password(new BCryptPasswordEncoder().encode(merchantDTO.getPassword()))
-                    .blacklist(false)
-                    .enabled(true)
-                    .identity(Identity.MERCHANT)
-                    .phone(merchantDTO.getPhone())
-                    .nickname(merchantDTO.getShowName())
-                    .avatar(merchantDTO.getLogo())
-                    .authorities(Collections.singleton(new Authority(Authority.NAMES.ROLE_USER.name())))
-                    .build();
-        } else {
-            user.setPassword(new BCryptPasswordEncoder().encode(merchantDTO.getPassword()));
-        }
-        user = userRepo.save(user);
+        //注册商家用户
+        User user = userService.register(merchantDTO.getPhone(), merchantDTO.getPassword());
 
         //查看商家是否已存在
         Merchant merchant1 = merchantRepo.findByPhone(merchantDTO.getPhone());
@@ -83,6 +67,31 @@ public class MerchantService {
             }
         }
 
+
+        user.setAvatar(merchantDTO.getLogo());
+        user.setNickname(merchantDTO.getShowName());
+        user.setIdentity(Identity.MERCHANT);
+        userRepo.save(user);
+
+//        //用于商家登录
+//        User user = userRepo.findByPhone(merchantDTO.getPhone());
+//        if (ObjectUtil.isNull(user)) {
+//            user = User.builder().username(merchantDTO.getPhone())
+//                    .password(new BCryptPasswordEncoder().encode(merchantDTO.getPassword()))
+//                    .blacklist(false)
+//                    .enabled(true)
+//                    .identity(Identity.MERCHANT)
+//                    .phone(merchantDTO.getPhone())
+//                    .nickname(merchantDTO.getShowName())
+//                    .avatar(merchantDTO.getLogo())
+//                    .authorities(Collections.singleton(new Authority(Authority.NAMES.ROLE_USER.name())))
+//                    .build();
+//        } else {
+//            user.setPassword(new BCryptPasswordEncoder().encode(merchantDTO.getPassword()));
+//        }
+//        user = userRepo.save(user);
+
+
 /*        if (ObjectUtil.isEmpty(merchantDTO.getBusinessNature())) {
             throw new BusinessException("商家性质未填");
         }*/
@@ -95,9 +104,9 @@ public class MerchantService {
         BeanUtil.copyProperties(merchantDTO, merchant);
         merchant.setUserId(user.getId());
         merchant.setStatus(ApplyStatus.PENDING);
-//        merchant.setGoodNum(0);
-//        merchant.setBadNum(0);
-//        merchant.setMonthSales(0);
+        merchant.setGoodNum(0);
+        merchant.setBadNum(0);
+        merchant.setMonthSales(0);
         merchant.setEnabled(true);
         merchant.setBlacklist(false);
         merchant = merchantRepo.save(merchant);
@@ -113,16 +122,23 @@ public class MerchantService {
 
     /**
      * 商户修改信息
+     *
      * @param merchantDTO 修改的信息
      * @return 修改
      */
     public MerchantDTO change(MerchantDTO merchantDTO) {
+        if (merchantDTO.getMid() == null) {
+            return registerApply(merchantDTO);
+        }
         Merchant merchant = merchantRepo.findById(merchantDTO.getMid()).orElseThrow(new BusinessException("商户不存在"));
         MerchantSettings merchantSettings = merchantSettingsRepo.findByMerchantId(merchantDTO.getMid()).orElseThrow(new BusinessException("商户不存在"));
 
+        MerchantDTO dto = new MerchantDTO(merchant, merchantSettings);
+        ObjUtils.merge(dto, merchantDTO);
+
         //dto转实体
-        BeanUtil.copyProperties(merchantDTO, merchant);
-        BeanUtil.copyProperties(merchantDTO, merchantSettings);
+        BeanUtil.copyProperties(dto, merchant);
+        BeanUtil.copyProperties(dto, merchantSettings);
         merchantRepo.save(merchant);
         merchantSettingsRepo.save(merchantSettings);
         return merchantDTO;
@@ -130,21 +146,34 @@ public class MerchantService {
 
     /**
      * 商家过审
+     *
      * @param merchantId 商户ID
-     * @param pass 是否过审
+     * @param pass       是否过审
      */
     public void audit(Long merchantId, Boolean pass) {
         Merchant merchant = merchantRepo.findById(merchantId).orElseThrow(new BusinessException("商户不存在"));
         if (pass) {
             merchant.setStatus(ApplyStatus.PASS);
             merchant.setIsPass(true);
-            //新建一好评热销分类
+            merchant.setEstablishTime(LocalDateTime.now());
+
+            //新建 系统预制分类:好评热销
             merchantClassificationRepo.save(MerchantClassification.builder()
                     .merchantId(merchantId)
                     .name(Constants.CLASSIFICATION_NAME)
                     .sort(1)
                     .isOpen(false)
+                    .isShow(true)
                     .build());
+            merchantClassificationRepo.save(MerchantClassification.builder()
+                    .merchantId(merchantId)
+                    .name(Constants.CLASSIFICATION_NAME2)
+                    .sort(2)
+                    .isOpen(true)
+                    .isShow(false)
+                    .build());
+
+
         } else {
             merchant.setStatus(ApplyStatus.DENY);
             merchant.setIsPass(false);
@@ -155,6 +184,7 @@ public class MerchantService {
 
     /**
      * 显示所有商家信息
+     *
      * @param pageable 分页
      * @return 分页列表
      */
@@ -170,6 +200,7 @@ public class MerchantService {
 
     /**
      * 显示个人的商户信息
+     *
      * @param userId 用户的ID
      * @return 个人的商户信息
      */
@@ -181,14 +212,14 @@ public class MerchantService {
 
     /**
      * 用户查找商家
+     *
      * @param userId 用户ID
      * @return 商家ID
      */
-    public Long findMerchantId(Long userId){
+    public Long findMerchantId(Long userId) {
         Merchant merchant = merchantRepo.findByUserId(userId).orElseThrow(new BusinessException("商户不存在"));
         return merchant.getId();
     }
 
 
-
 }

+ 10 - 10
src/main/java/com/izouma/dingdong/service/merchant/SalesService.java

@@ -1,11 +1,9 @@
 package com.izouma.dingdong.service.merchant;
 
-import cn.hutool.core.collection.CollUtil;
 import com.izouma.dingdong.config.Constants;
 import com.izouma.dingdong.domain.Appraisal;
 import com.izouma.dingdong.domain.OrderGoodsSpec;
 import com.izouma.dingdong.domain.OrderInfo;
-import com.izouma.dingdong.domain.merchant.Goods;
 import com.izouma.dingdong.domain.merchant.MerchantClassification;
 import com.izouma.dingdong.domain.merchant.Sales;
 import com.izouma.dingdong.exception.BusinessException;
@@ -19,7 +17,6 @@ import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
 import java.util.List;
-import java.util.Set;
 
 @Service
 @AllArgsConstructor
@@ -35,6 +32,8 @@ public class SalesService {
 
     private GoodsRepo goodsRepo;
 
+    private MerchantClassificationService merchantClassificationService;
+
     /*
     订单插入销量
      */
@@ -127,8 +126,8 @@ public class SalesService {
         List<Sales> praises = salesRepo.findAllByDayAndPraiseGreaterThanEqual(LocalDate.now(), 5);
 
         //插入
-        popularities.forEach(popularity -> into(popularity, Constants.CLASSIFICATION_NAME));
-        praises.forEach(praise -> into(praise, Constants.CLASSIFICATION_NAME));
+        popularities.forEach(this::into);
+        praises.forEach(this::into);
 
 
     }
@@ -137,9 +136,9 @@ public class SalesService {
     /*
     插入到商家自定义分类
      */
-    private void into(Sales sales, String name) {
+    private void into(Sales sales) {
         //查找好评热销
-        MerchantClassification merchantClass = merchantClassificationRepo.findByMerchantIdAndName(sales.getId(), name);
+        MerchantClassification merchantClass = merchantClassificationRepo.findByMerchantIdAndName(sales.getId(), Constants.CLASSIFICATION_NAME);
         if (!merchantClass.getIsOpen()) {
             return;
         }
@@ -147,10 +146,11 @@ public class SalesService {
 //        goodsList.add(sales.getGoods());
 //        merchantClass.setGoodsList(goodsList);
 
-        String goodsId = merchantClass.getGoodsIds();
-        goodsId = goodsId + "," + sales.getGoodsId();
-        merchantClass.setGoodsIds(goodsId);
+        merchantClassificationService.saveOneGoods(merchantClass.getId(), sales.getGoodsId());
 
+//        String goodsId = merchantClass.getGoodsIds();
+//        goodsId = goodsId + "," + sales.getGoodsId();
+//        merchantClass.setGoodsIds(goodsId);
     }
 
 }

+ 14 - 0
src/main/java/com/izouma/dingdong/service/user/AddressService.java

@@ -0,0 +1,14 @@
+package com.izouma.dingdong.service.user;
+
+import com.izouma.dingdong.domain.user.Address;
+import com.izouma.dingdong.repo.user.AddressRepo;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class AddressService {
+
+    private AddressRepo addressRepo;
+
+}

+ 32 - 2
src/main/java/com/izouma/dingdong/web/AuthenticationController.java

@@ -1,14 +1,17 @@
 package com.izouma.dingdong.web;
 
 import com.izouma.dingdong.domain.User;
+import com.izouma.dingdong.dto.MerchantDTO;
 import com.izouma.dingdong.exception.AuthenticationException;
 import com.izouma.dingdong.security.JwtTokenUtil;
 import com.izouma.dingdong.security.JwtUserDetailsService;
 import com.izouma.dingdong.security.JwtUserFactory;
 import com.izouma.dingdong.service.UserService;
+import com.izouma.dingdong.service.merchant.MerchantService;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.access.method.P;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.DisabledException;
@@ -26,9 +29,11 @@ import java.util.Objects;
 @RequestMapping("/auth")
 public class AuthenticationController {
     private AuthenticationManager authenticationManager;
-    private JwtTokenUtil          jwtTokenUtil;
+    private JwtTokenUtil jwtTokenUtil;
     private JwtUserDetailsService userDetailsService;
-    private UserService           userService;
+    private UserService userService;
+
+    private MerchantService merchantService;
 
     @PostMapping("/login")
     public String loginByUserPwd(String username, String password, Integer expiration) {
@@ -93,6 +98,31 @@ public class AuthenticationController {
         }
     }
 
+    @PostMapping("/loginByRegister")
+    @ApiOperation("注册登录")
+    public String loginByRegister(String phone, String password) {
+        try {
+            User user = userService.register(phone, password);
+            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
+        } catch (Exception e) {
+            log.error("loginByRegister", e);
+            throw new AuthenticationException("登录错误", e);
+        }
+    }
+
+    @PostMapping("/merchantRegister")
+    @ApiOperation("注册登录")
+    public String registerMerchant(MerchantDTO merchantDTO) {
+        try {
+            User user = userService.register(merchantDTO.getPhone(),merchantDTO.getPassword());
+            //商家信息
+            merchantService.registerApply(merchantDTO);
+            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
+        } catch (Exception e) {
+            log.error("loginByRegister", e);
+            throw new AuthenticationException("登录错误", e);
+        }
+    }
 
 
 }

+ 15 - 3
src/main/java/com/izouma/dingdong/web/AuthorityController.java

@@ -21,6 +21,14 @@ public class AuthorityController extends BaseController {
         return authorityRepo.findAll();
     }
 
+    @PreAuthorize("hasRole('ADMIN')")
+    @GetMapping("/allAdmin")
+    public List<Authority> allAdmin(){
+        List<Authority> all = authorityRepo.findAll();
+        all.remove(Authority.getInstance(Authority.NAMES.ROLE_USER));
+        return all;
+    }
+
     @PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     public Authority save(Authority authority) {
@@ -29,8 +37,12 @@ public class AuthorityController extends BaseController {
 
     @PostConstruct
     public void init() {
-        authorityRepo.save(new Authority(Authority.NAMES.ROLE_ADMIN.name()));
-        authorityRepo.save(new Authority(Authority.NAMES.ROLE_USER.name()));
-        authorityRepo.save(new Authority(Authority.NAMES.ROLE_DEV.name()));
+        authorityRepo.save(Authority.getInstance(Authority.NAMES.ROLE_ADMIN));
+        authorityRepo.save(Authority.getInstance(Authority.NAMES.ROLE_USER));
+        authorityRepo.save(Authority.getInstance(Authority.NAMES.ROLE_DEV));
+        authorityRepo.save(Authority.getInstance(Authority.NAMES.ROLE_CUSTOMER));
+        authorityRepo.save(Authority.getInstance(Authority.NAMES.ROLE_FINANCE));
+        authorityRepo.save(Authority.getInstance(Authority.NAMES.ROLE_INDUSTRY));
+        authorityRepo.save(Authority.getInstance(Authority.NAMES.ROLE_LOCALIZATION));
     }
 }

+ 28 - 7
src/main/java/com/izouma/dingdong/web/UserController.java

@@ -2,6 +2,7 @@ package com.izouma.dingdong.web;
 
 import com.izouma.dingdong.domain.User;
 import com.izouma.dingdong.dto.PageQuery;
+import com.izouma.dingdong.enums.Identity;
 import com.izouma.dingdong.exception.BusinessException;
 import com.izouma.dingdong.repo.UserRepo;
 import com.izouma.dingdong.security.Authority;
@@ -12,6 +13,7 @@ import com.izouma.dingdong.utils.excel.ExcelUtils;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.web.bind.annotation.*;
@@ -25,19 +27,20 @@ import java.util.List;
 @RestController
 @RequestMapping("/user")
 public class UserController extends BaseController {
-    private UserRepo    userRepo;
+    private UserRepo userRepo;
     private UserService userService;
 
     @PostMapping("/register")
     public User register(@RequestParam String username,
                          @RequestParam String password) {
         User user = User.builder()
-                        .username(username)
-                        .nickname(username)
-                        .password(new BCryptPasswordEncoder().encode(password))
-                        .enabled(true)
-                        .authorities(Collections.singleton(new Authority(Authority.NAMES.ROLE_USER.name())))
-                        .build();
+                .username(username)
+                .nickname(username)
+                .password(new BCryptPasswordEncoder().encode(password))
+                .enabled(true)
+                .authorities(Collections.singleton(Authority.getInstance(Authority.NAMES.ROLE_USER)))
+                .identity(Identity.USER)
+                .build();
         return userRepo.save(user);
     }
 
@@ -49,6 +52,10 @@ public class UserController extends BaseController {
             ObjUtils.merge(orig, user);
             return userRepo.save(orig);
         }
+        if (user.getAuthorities() == null) {
+            user.setAuthorities(Collections.singleton(Authority.getInstance(Authority.NAMES.ROLE_USER)));
+            user.setIdentity(Identity.USER);
+        }
         return userRepo.save(user);
     }
 
@@ -91,4 +98,18 @@ public class UserController extends BaseController {
     public String setPasswordAdmin(@RequestParam Long userId, @RequestParam String password) {
         return userService.setPassword(userId, password);
     }
+
+    @GetMapping("/allUser")
+    public Page<User> allUser(PageQuery pageQuery) {
+        //List<User> users = userRepo.findAllByIdentityAndAuthoritiesContains(Identity.USER, Authority.getInstance(Authority.NAMES.ROLE_USER));
+        List<User> users = userRepo.findAllByIdentity(Identity.USER);
+        return new PageImpl<>(users, toPageRequest(pageQuery), pageQuery.getPage());
+    }
+
+    @GetMapping("/allAdmin")
+    public Page<User> allAdmin(PageQuery pageQuery) {
+        //List<User> users = userRepo.findAllByAuthoritiesNotContains(Authority.getInstance(Authority.NAMES.ROLE_USER));
+        List<User> users = userRepo.findAllByIdentity(Identity.ADMIN);
+        return new PageImpl<>(users, toPageRequest(pageQuery), pageQuery.getPage());
+    }
 }

+ 63 - 0
src/main/java/com/izouma/dingdong/web/backstage/BlackListController.java

@@ -0,0 +1,63 @@
+package com.izouma.dingdong.web.backstage;
+
+import com.izouma.dingdong.web.BaseController;
+import com.izouma.dingdong.domain.backstage.BlackList;
+import com.izouma.dingdong.service.backstage.BlackListService;
+import com.izouma.dingdong.dto.PageQuery;
+import com.izouma.dingdong.exception.BusinessException;
+import com.izouma.dingdong.repo.backstage.BlackListRepo;
+import com.izouma.dingdong.utils.ObjUtils;
+import com.izouma.dingdong.utils.excel.ExcelUtils;
+
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/blackList")
+@AllArgsConstructor
+public class BlackListController extends BaseController {
+    private BlackListService blackListService;
+    private BlackListRepo blackListRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public BlackList save(@RequestBody BlackList record) {
+        if (record.getId() != null) {
+            BlackList orig = blackListRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return blackListRepo.save(orig);
+        }
+        return blackListRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @GetMapping("/all")
+    public Page<BlackList> all(PageQuery pageQuery) {
+        return blackListRepo.findAll(toSpecification(pageQuery,BlackList.class), toPageRequest(pageQuery));
+    }
+
+    @GetMapping("/get/{id}")
+    public BlackList get(@PathVariable Long id) {
+        return blackListRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        blackListRepo.deleteById(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<BlackList> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

+ 4 - 4
src/main/java/com/izouma/dingdong/web/merchant/AutomaticResponseController.java

@@ -34,11 +34,11 @@ public class AutomaticResponseController extends BaseController {
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     public AutomaticResponse save(@RequestBody AutomaticResponse record) {
-        if (record.getMerchantId() == null) {
+        if (record.getUserId() == null) {
             //如果商家ID为空
-            record.setMerchantId(merchantService.findMerchantId(SecurityUtils.getAuthenticatedUser().getId()));
+            record.setUserId((SecurityUtils.getAuthenticatedUser().getId()));
         }
-        merchantRepo.findById(record.getMerchantId()).orElseThrow(new BusinessException("商家不存在"));
+        merchantRepo.findByUserId(record.getUserId()).orElseThrow(new BusinessException("商家不存在"));
         if (record.getId() != null) {
             AutomaticResponse orig = automaticResponseRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
             ObjUtils.merge(orig, record);
@@ -74,7 +74,7 @@ public class AutomaticResponseController extends BaseController {
     @ApiOperation("商家下的所有自动回复")
     @GetMapping("/my")
     public List<AutomaticResponse> my() {
-        return automaticResponseRepo.findAllByMerchantId(merchantService.findMerchantId(SecurityUtils.getAuthenticatedUser().getId()));
+        return automaticResponseRepo.findAllByUserId(SecurityUtils.getAuthenticatedUser().getId());
     }
 }
 

+ 1 - 1
src/main/java/com/izouma/dingdong/web/merchant/FullReductionController.java

@@ -72,7 +72,7 @@ public class FullReductionController extends BaseController {
     @GetMapping("/my")
     @ApiOperation("商户下的满减")
     public List<FullReduction> my(){
-        return fullReductionRepo.findAllByMerchantId(merchantService.findMerchantId(SecurityUtils.getAuthenticatedUser().getId()));
+        return fullReductionRepo.findAllByUserId(SecurityUtils.getAuthenticatedUser().getId());
     }
 }
 

+ 3 - 8
src/main/java/com/izouma/dingdong/web/merchant/GoodsController.java

@@ -36,18 +36,12 @@ public class GoodsController extends BaseController {
     @PostMapping("/save")
     @ApiOperation("添加修改商品")
     public Goods save(@RequestBody Goods record) {
-        if (record.getInventory() < 1) {
-            throw new BusinessException("商品供应数量不足");
-        }
-        if (BigDecimal.ZERO.compareTo(record.getAmount()) >= 0) {
-            throw new BusinessException("价格不得小于0");
-        }
         if (record.getId() != null) {
             Goods orig = goodsRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
             ObjUtils.merge(orig, record);
-            return goodsRepo.save(orig);
+            return goodsService.save(orig);
         }
-        return goodsRepo.save(record);
+        return goodsService.save(record);
     }
 
 
@@ -64,6 +58,7 @@ public class GoodsController extends BaseController {
 
     @PostMapping("/del/{id}")
     public void del(@PathVariable Long id) {
+
         goodsRepo.deleteById(id);
     }
 

+ 5 - 4
src/main/java/com/izouma/dingdong/web/merchant/GoodsSpecificationController.java

@@ -33,13 +33,14 @@ public class GoodsSpecificationController extends BaseController {
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     @ApiOperation("商品规格添加修改")
-    public GoodsSpecification save(/*@RequestBody*/ GoodsSpecification record) {
-        goodsRepo.findById(record.getGoodsId()).orElseThrow(new BusinessException("商品不存在"));
+    public GoodsSpecification save(@RequestBody GoodsSpecification record) {
         if (record.getId() != null) {
             GoodsSpecification orig = goodsSpecificationRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
             ObjUtils.merge(orig, record);
+            goodsRepo.findById(orig.getGoodsId()).orElseThrow(new BusinessException("商品不存在"));
             return goodsSpecificationRepo.save(orig);
         }
+        goodsRepo.findById(record.getGoodsId()).orElseThrow(new BusinessException("商品不存在"));
         return goodsSpecificationRepo.save(record);
     }
 
@@ -47,7 +48,7 @@ public class GoodsSpecificationController extends BaseController {
     //@PreAuthorize("hasRole('ADMIN')")
     @GetMapping("/all")
     public Page<GoodsSpecification> all(PageQuery pageQuery) {
-        return goodsSpecificationRepo.findAll(toSpecification(pageQuery,GoodsSpecification.class), toPageRequest(pageQuery));
+        return goodsSpecificationRepo.findAll(toSpecification(pageQuery, GoodsSpecification.class), toPageRequest(pageQuery));
     }
 
     @GetMapping("/get/{id}")
@@ -69,7 +70,7 @@ public class GoodsSpecificationController extends BaseController {
 
     @GetMapping("/byGoodsId")
     @ApiOperation("按商品ID查询")
-    public List<GoodsSpecification> byGoodsId(Long goodsId){
+    public List<GoodsSpecification> byGoodsId(Long goodsId) {
         return goodsSpecificationRepo.findAllByGoodsId(goodsId);
     }
 }

+ 17 - 1
src/main/java/com/izouma/dingdong/web/merchant/MerchantClassificationController.java

@@ -1,5 +1,7 @@
 package com.izouma.dingdong.web.merchant;
 
+import cn.hutool.core.util.ObjectUtil;
+import com.izouma.dingdong.domain.merchant.Goods;
 import com.izouma.dingdong.service.merchant.MerchantService;
 import com.izouma.dingdong.utils.SecurityUtils;
 import com.izouma.dingdong.web.BaseController;
@@ -23,7 +25,7 @@ import java.util.Comparator;
 import java.util.List;
 
 @RestController
-@RequestMapping("/merchantClassification")
+@RequestMapping("/classification")
 @AllArgsConstructor
 public class MerchantClassificationController extends BaseController {
     private MerchantClassificationService merchantClassificationService;
@@ -38,6 +40,9 @@ public class MerchantClassificationController extends BaseController {
         if (record.getId() != null) {
             MerchantClassification orig = merchantClassificationRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
             ObjUtils.merge(orig, record);
+            if (ObjectUtil.isNotNull(merchantClassificationRepo.findByMerchantIdAndName(orig.getMerchantId(), orig.getName()))){
+                throw new BusinessException("该分类已存在");
+            }
             return merchantClassificationRepo.save(orig);
         }
         //添加
@@ -89,6 +94,17 @@ public class MerchantClassificationController extends BaseController {
         merchantClassificationService.delGoods(classificationId, goodId);
     }
 
+    @GetMapping("/saveOneGoods")
+    @ApiOperation("分类下添加一个商品")
+    public void saveOneGoods(Long classificationId, Long goodId) {
+        merchantClassificationService.saveOneGoods(classificationId, goodId);
+    }
+
+    @GetMapping("/allGoods")
+    @ApiOperation("分类下的所有商品")
+    public List<Goods> allGoods(Long classificationId) {
+        return merchantClassificationService.showGoods(classificationId);
+    }
 
 }
 

+ 68 - 0
src/main/java/com/izouma/dingdong/web/user/AddressController.java

@@ -0,0 +1,68 @@
+package com.izouma.dingdong.web.user;
+
+import com.izouma.dingdong.web.BaseController;
+import com.izouma.dingdong.domain.user.Address;
+import com.izouma.dingdong.service.user.AddressService;
+import com.izouma.dingdong.dto.PageQuery;
+import com.izouma.dingdong.exception.BusinessException;
+import com.izouma.dingdong.repo.user.AddressRepo;
+import com.izouma.dingdong.utils.ObjUtils;
+import com.izouma.dingdong.utils.excel.ExcelUtils;
+
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/address")
+@AllArgsConstructor
+public class AddressController extends BaseController {
+    private AddressService addressService;
+    private AddressRepo addressRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public Address save(@RequestBody Address record) {
+        if (record.getId() != null) {
+            Address orig = addressRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            record = addressRepo.save(orig);
+        } else {
+            record = addressRepo.save(record);
+        }
+        if (record.getIsDefault()) {
+            addressRepo.updateIsDefault(record.getId(), record.getUserId());
+        }
+        return record;
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @GetMapping("/all")
+    public Page<Address> all(PageQuery pageQuery) {
+        return addressRepo.findAll(toSpecification(pageQuery, Address.class), toPageRequest(pageQuery));
+    }
+
+    @GetMapping("/get/{id}")
+    public Address get(@PathVariable Long id) {
+        return addressRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        addressRepo.deleteById(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<Address> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

+ 2 - 2
src/main/resources/application.yaml

@@ -70,8 +70,8 @@ aliyun:
     access-key-id: PXzJyah5rZfWHIIH
     access-key-secret: e1MS6j0wypXJrw8CM0hObZu8qKbfah
     oss-end-point: oss-cn-hangzhou.aliyuncs.com
-    oss-bucket-name: dingdong
-    oss-domain: https://dingdong.oss-cn-hangzhou.aliyuncs.com
+    oss-bucket-name: idingdong
+    oss-domain: https://idingdong.oss-cn-hangzhou.aliyuncs.com
 general:
     host: http://dingdong.izouma.com
 ---

+ 1 - 0
src/main/resources/genjson/Address.json

@@ -0,0 +1 @@
+{"tableName":"Address","className":"Address","remark":"用户地址","genTable":true,"genClass":true,"genList":false,"genForm":false,"genRouter":false,"javaPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/java/com/izouma/dingdong","viewPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/vue/src/views","routerPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/vue/src","resourcesPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"userId","modelName":"userId","remark":"用户Id","showInList":true,"showInForm":true,"formType":"number"},{"name":"name","modelName":"name","remark":"收件人姓名","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"phone","modelName":"phone","remark":"收件人电话","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"address","modelName":"address","remark":"详细地址","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"enabled","modelName":"enabled","remark":"默认地址","showInList":true,"showInForm":true,"formType":"switch"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.dingdong","tablePackage":"com.izouma.dingdong.domain.user.Address","genPackage":"user"}

+ 1 - 0
src/main/resources/genjson/BlackList.json

@@ -0,0 +1 @@
+{"tableName":"BlackList","className":"BlackList","remark":"黑名单表","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/java/com/izouma/dingdong","viewPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/vue/src/views","routerPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/vue/src","resourcesPath":"/Users/qiufangchao/Desktop/project/dingdong/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"userId","modelName":"userId","remark":"用户ID","showInList":true,"showInForm":true,"formType":"number"},{"name":"otherId","modelName":"otherId","remark":"其他ID","showInList":true,"showInForm":true,"formType":"number"},{"name":"identity","modelName":"identity","remark":"身份","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"reason","modelName":"reason","remark":"缘由","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"remove","modelName":"remove","remark":"移除","showInList":true,"showInForm":true,"formType":"switch"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.dingdong","tablePackage":"com.izouma.dingdong.domain.backstage.BlackList","genPackage":"backstage"}

+ 33 - 1
src/main/vue/src/router.js

@@ -130,7 +130,7 @@ const router = new Router({
                 {
                     path: '/cateEdit',
                     name: 'cateEdit',
-                    component: () => import(/* webpackChunkName: "cateEdit" */ '@/views/TagEdit.vue'),
+                    component: () => import(/* webpackChunkName: "tagEdit" */ '@/views/TagEdit.vue'),
                     meta: {
                        title: '标签编辑',
                     },
@@ -190,6 +190,22 @@ const router = new Router({
                     meta: {
                        title: '评价表',
                     },
+               },
+                {
+                    path: '/blackListEdit',
+                    name: 'BlackListEdit',
+                    component: () => import(/* webpackChunkName: "blackListEdit" */ '@/views/backstage/BlackListEdit.vue'),
+                    meta: {
+                       title: '黑名单表编辑',
+                    },
+                },
+                {
+                    path: '/blackListList',
+                    name: 'BlackListList',
+                    component: () => import(/* webpackChunkName: "blackListList" */ '@/views/backstage/BlackListList.vue'),
+                    meta: {
+                       title: '黑名单表',
+                    },
                }
                 /**INSERT_LOCATION**/,
                 {
@@ -199,6 +215,22 @@ const router = new Router({
                     meta: {
                         title: '分类',
                     },
+                },
+                {
+                    path: '/blackUserEdit',
+                    name: 'BlackUserEdit',
+                    component: () => import(/* webpackChunkName: "blackUserEdit" */ '@/views/backstage/BlackUserEdit.vue'),
+                    meta: {
+                        title: '管理员编辑',
+                    },
+                },
+                {
+                    path: '/blackUserList',
+                    name: 'BlackUserList',
+                    component: () => import(/* webpackChunkName: "blackUserList" */ '@/views/backstage/BlackUserList.vue'),
+                    meta: {
+                        title: '管理员列表',
+                    },
                 }
             ],
         },

+ 3 - 3
src/main/vue/src/views/GoodsEdit.vue

@@ -38,9 +38,9 @@
             <!--<el-form-item prop="takeOff" label="下架">
                 <el-switch v-model="formData.takeOff"></el-switch>
             </el-form-item>-->
-            <el-form-item prop="sort" label="排布">
-                <el-input-number type="number" v-model="formData.sort"></el-input-number>
-            </el-form-item>
+<!--            <el-form-item prop="sort" label="排布">-->
+<!--                <el-input-number type="number" v-model="formData.sort"></el-input-number>-->
+<!--            </el-form-item>-->
             <el-form-item prop="isFullReduction" label="满减">
                 <el-switch v-model="formData.isFullReduction"></el-switch>
             </el-form-item>

+ 2 - 2
src/main/vue/src/views/GoodsList.vue

@@ -70,9 +70,9 @@
                     <el-tag :type="row.takeOff?'':'info'">{{row.takeOff}}</el-tag>
                 </template>
             </el-table-column>
-            <el-table-column prop="sort" label="排布"
+<!--            <el-table-column prop="sort" label="排布"
             >
-            </el-table-column>
+            </el-table-column>-->
             <el-table-column prop="isFullReduction" label="满减"
             >
                 <template slot-scope="{row}">

+ 14 - 8
src/main/vue/src/views/UserEdit.vue

@@ -21,14 +21,14 @@
             <el-form-item prop="phone" label="手机">
                 <el-input v-model="formData.phone"></el-input>
             </el-form-item>
-            <el-form-item prop="authorities" label="角色">
+<!--            <el-form-item prop="authorities" label="角色">
                 <el-select v-model="formData.authorities" multiple
                            placeholder="请选择" value-key="name">
                     <el-option v-for="item in authorities" :key="item.name"
                                :label="item.name" :value="item">
                     </el-option>
                 </el-select>
-            </el-form-item>
+            </el-form-item>-->
             <el-form-item>
                 <el-button @click="onSave" :loading="$store.state.fetchingData"
                            type="primary">保存</el-button>
@@ -54,14 +54,14 @@ export default {
                     this.$message.error(e.error);
                 });
         }
-        this.$http
+/*        this.$http
             .get('/authority/all')
             .then(res => {
                 this.authorities = res;
             })
             .catch(e => {
                 console.log(e);
-            });
+            });*/
     },
     data() {
         return {
@@ -95,11 +95,11 @@ export default {
                         trigger: 'blur',
                     },
                 ],
-                authorities: [
+/*                authorities: [
                     { required: true, message: '请选择角色', trigger: 'blur' },
-                ],
+                ],*/
             },
-            authorities: [],
+            // authorities: [],
         };
     },
     methods: {
@@ -114,7 +114,13 @@ export default {
         },
         submit() {
             this.$http
-                .post('/user/save', this.formData, { body: 'json' })
+                .post({
+                    url: '/user/save',
+                    data: {
+                        identity: 'USER'
+                    }
+
+                }, this.formData, { body: 'json' })
                 .then(res => {
                     this.$message.success('成功');
                     this.formData = res;

+ 1 - 1
src/main/vue/src/views/UserList.vue

@@ -70,7 +70,7 @@ export default {
         return {
             multipleMode: false,
             search: "",
-            url: "/user/all",
+            url: "/user/allUser",
             downloading: false
         };
     },

+ 100 - 0
src/main/vue/src/views/backstage/BlackListEdit.vue

@@ -0,0 +1,100 @@
+<template>
+    <div class="edit-view">
+        <el-form :model="formData" :rules="rules" ref="form" label-width="66px" label-position="right" size="small"
+                 style="max-width: 500px;">
+                <el-form-item prop="userId" label="用户ID">
+                            <el-input-number type="number" v-model="formData.userId"></el-input-number>
+                </el-form-item>
+                <el-form-item prop="otherId" label="其他ID">
+                            <el-input-number type="number" v-model="formData.otherId"></el-input-number>
+                </el-form-item>
+                <el-form-item prop="identity" label="身份">
+                            <el-input v-model="formData.identity"></el-input>
+                </el-form-item>
+                <el-form-item prop="reason" label="缘由">
+                            <el-input v-model="formData.reason"></el-input>
+                </el-form-item>
+                <el-form-item prop="remove" label="移除">
+                            <el-switch v-model="formData.remove"></el-switch>
+                </el-form-item>
+            <el-form-item>
+                <el-button @click="onSave" :loading="saving"
+                           type="primary">保存</el-button>
+                <el-button @click="onDelete" :loading="saving"
+                           type="danger" v-if="formData.id">删除
+                </el-button>
+                <el-button @click="$router.go(-1)">取消</el-button>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+<script>
+    export default {
+        name: 'BlackListEdit',
+        created() {
+            if (this.$route.query.id) {
+                this.$http
+                    .get('blackList/get/'+this.$route.query.id)
+                    .then(res => {
+                        this.formData = res;
+                    })
+                    .catch(e => {
+                        console.log(e);
+                        this.$message.error(e.error);
+                    });
+            }
+        },
+        data() {
+            return {
+                saving: false,
+                formData: {
+                },
+                rules: {
+                },
+            }
+        },
+        methods: {
+            onSave() {
+                this.$refs.form.validate((valid) => {
+                    if (valid) {
+                        this.submit();
+                    } else {
+                        return false;
+                    }
+                });
+            },
+            submit() {
+                let data = {...this.formData};
+
+                this.saving = true;
+                this.$http
+                    .post('/blackList/save', data, {body: 'json'})
+                    .then(res => {
+                        this.saving = false;
+                        this.$message.success('成功');
+                        this.$router.go(-1);
+                    })
+                    .catch(e => {
+                        console.log(e);
+                        this.saving = false;
+                        this.$message.error(e.error);
+                    });
+            },
+            onDelete() {
+                this.$alert('删除将无法恢复,确认要删除么?', '警告', {type: 'error'}).then(() => {
+                    return this.$http.post(`/blackList/del/${this.formData.id}`)
+                }).then(() => {
+                    this.$message.success('删除成功');
+                    this.$router.go(-1);
+                }).catch(e => {
+                    if (e !== 'cancel') {
+                        console.log(e);
+                        this.$message.error(e.error);
+                    }
+                })
+            },
+        }
+    }
+</script>
+<style lang="less" scoped>
+</style>

+ 179 - 0
src/main/vue/src/views/backstage/BlackListList.vue

@@ -0,0 +1,179 @@
+<template>
+    <div  class="list-view">
+        <div class="filters-container">
+            <el-input placeholder="输入关键字" v-model="search" clearable
+                      class="filter-item"></el-input>
+            <el-button @click="getData" type="primary" icon="el-icon-search"
+                       class="filter-item">搜索
+            </el-button>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus"
+                       class="filter-item">添加
+            </el-button>
+            <el-button @click="download" type="primary" icon="el-icon-download"
+                       :loading="downloading" class="filter-item">导出EXCEL
+            </el-button>
+        </div>
+        <el-table :data="tableData" row-key="id" ref="table"
+                  header-row-class-name="table-header-row"
+                  header-cell-class-name="table-header-cell"
+                  row-class-name="table-row" cell-class-name="table-cell"
+                  :height="tableHeight">
+            <el-table-column v-if="multipleMode" align="center" type="selection"
+                             width="50">
+            </el-table-column>
+            <el-table-column prop="id" label="ID" width="100">
+            </el-table-column>
+                                <el-table-column prop="userId" label="用户ID"
+>
+                    </el-table-column>
+                    <el-table-column prop="otherId" label="其他ID"
+>
+                    </el-table-column>
+                    <el-table-column prop="identity" label="身份"
+>
+                    </el-table-column>
+                    <el-table-column prop="reason" label="缘由"
+>
+                    </el-table-column>
+                    <el-table-column prop="remove" label="移除"
+>
+                            <template slot-scope="{row}">
+                                <el-tag :type="row.remove?'':'info'">{{row.remove}}</el-tag>
+                            </template>
+                    </el-table-column>
+            <el-table-column
+                    label="操作"
+                    align="center"
+                    fixed="right"
+                    min-width="150">
+                <template slot-scope="{row}">
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
+                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <!-- <div class="multiple-mode-wrapper">
+                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
+                <el-button-group v-else>
+                    <el-button @click="operation1">批量操作1</el-button>
+                    <el-button @click="operation2">批量操作2</el-button>
+                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
+                </el-button-group>
+            </div> -->
+            <el-pagination background @size-change="onSizeChange"
+                           @current-change="onCurrentChange" :current-page="page"
+                           :page-sizes="[10, 20, 30, 40, 50]" :page-size="pageSize"
+                           layout="total, sizes, prev, pager, next, jumper"
+                           :total="totalElements">
+            </el-pagination>
+        </div>
+
+    </div>
+</template>
+<script>
+    import { mapState } from "vuex";
+    import pageableTable from "@/mixins/pageableTable";
+
+    export default {
+        name: 'BlackListList',
+        mixins: [pageableTable],
+        created() {
+            this.getData();
+        },
+        data() {
+            return {
+                multipleMode: false,
+                search: "",
+                url: "/blackList/all",
+                downloading: false,
+            }
+        },
+        computed: {
+            selection() {
+                return this.$refs.table.selection.map(i => i.id);
+            }
+        },
+        methods: {
+            beforeGetData() {
+                if (this.search) {
+                    return { search: this.search };
+                }
+            },
+            toggleMultipleMode(multipleMode) {
+                this.multipleMode = multipleMode;
+                if (!multipleMode) {
+                    this.$refs.table.clearSelection();
+                }
+            },
+            addRow() {
+                this.$router.push({
+                    path: "/blackListEdit",
+                    query: {
+                    ...this.$route.query
+                    }
+                });
+            },
+            editRow(row) {
+                this.$router.push({
+                    path: "/blackListEdit",
+                    query: {
+                    id: row.id
+                    }
+                });
+            },
+            download() {
+                this.downloading = true;
+                this.$axios
+                    .get("/blackList/excel", { 
+                        responseType: "blob",
+                        params: { size: 10000 }
+                    })
+                    .then(res => {
+                        console.log(res);
+                        this.downloading = false;
+                        const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                        const link = document.createElement("a");
+                        link.href = downloadUrl;
+                        link.setAttribute(
+                            "download",
+                            res.headers["content-disposition"].split("filename=")[1]
+                        );
+                        document.body.appendChild(link);
+                        link.click();
+                        link.remove();
+                    })
+                    .catch(e => {
+                        console.log(e);
+                        this.downloading = false;
+                        this.$message.error(e.error);
+                    });
+            },
+            operation1() {
+                this.$notify({
+                    title: '提示',
+                    message: this.selection
+                });
+            },
+            operation2() {
+                this.$message('操作2');
+            },
+            deleteRow(row) {
+                this.$alert('删除将无法恢复,确认要删除么?', '警告', {type: 'error'}).then(() => {
+                    return this.$http.post(`/blackList/del/${row.id}`)
+                }).then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                }).catch(action => {
+                    if (action === 'cancel') {
+                        this.$message.info('删除取消');
+                    } else {
+                        this.$message.error('删除失败');
+                    }
+                })
+            },
+        }
+    }
+</script>
+<style lang="less" scoped>
+</style>

+ 193 - 0
src/main/vue/src/views/backstage/BlackUserEdit.vue

@@ -0,0 +1,193 @@
+<template>
+    <div class="edit-view">
+        <el-form :model="formData" :rules="rules" ref="form" label-width="80px"
+                 label-position="right" style="max-width: 500px;">
+            <el-form-item prop="avatar" label="头像">
+                <crop-upload v-model="formData.avatar"></crop-upload>
+            </el-form-item>
+            <el-form-item prop="username" label="用户名">
+                <el-input v-model="formData.username"></el-input>
+            </el-form-item>
+            <el-form-item prop="nickname" label="昵称">
+                <el-input v-model="formData.nickname"></el-input>
+            </el-form-item>
+            <el-form-item v-if="formData.id" label="密码">
+                <el-button type="primary" plain @click="resetPassword">重置
+                </el-button>
+            </el-form-item>
+            <el-form-item v-else prop="password" label="密码">
+                <el-input v-model="formData.password"></el-input>
+            </el-form-item>
+            <el-form-item prop="phone" label="手机">
+                <el-input v-model="formData.phone"></el-input>
+            </el-form-item>
+            <el-form-item prop="authorities" label="角色">
+                <el-select v-model="formData.authorities" multiple
+                           placeholder="请选择" value-key="name">
+                    <el-option v-for="item in authorities" :key="item.name"
+                               :label="item.description" :value="item">
+                    </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item prop="identity" label="身份">
+                <el-select v-model="formData.identity"
+                           placeholder="请选择" >
+                    <el-option key="ADMIN"
+                               label="ADMIN" value="ADMIN">
+                    </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item>
+                <el-button @click="onSave" :loading="$store.state.fetchingData"
+                           type="primary">保存</el-button>
+                <el-button @click="del" :loading="$store.state.fetchingData"
+                           type="danger" v-if="formData.id">删除
+                </el-button>
+                <el-button @click="$router.go(-1)">取消</el-button>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+<script>
+export default {
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get(`/user/get/${this.$route.query.id}`)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+        this.$http
+            .get('/authority/allAdmin')
+            .then(res => {
+                this.authorities = res;
+            })
+            .catch(e => {
+                console.log(e);
+            });
+    },
+    data() {
+        return {
+            saving: false,
+            formData: {
+                avatar:
+                    'https://zhumj.oss-cn-hangzhou.aliyuncs.com/image/user.jpg',
+            },
+            rules: {
+                avatar: [
+                    {
+                        required: true,
+                        regexp: /^[_.@A-Za-z0-9-]*$/,
+                        message: '请上传头像',
+                        trigger: 'blur',
+                    },
+                ],
+                username: [
+                    { required: true, message: '请输入昵称', trigger: 'blur' },
+                ],
+                nickname: [
+                    { required: true, message: '请输入昵称', trigger: 'blur' },
+                ],
+                password: [
+                    { required: true, message: '请输入密码', trigger: 'blur' },
+                ],
+                phone: [
+                    {
+                        regexp: /^1[3-9]\d{9}$/,
+                        message: '请输入正确的手机号',
+                        trigger: 'blur',
+                    },
+                ],
+                authorities: [
+                    { required: true, message: '请选择角色', trigger: 'blur' },
+                ],
+                identity: [
+                    { required: true, message: '请选择身份', trigger: 'blur' },
+                ],
+            },
+            authorities: [],
+            identity:[],
+        };
+    },
+    methods: {
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            this.$http
+                .post('/user/save', this.formData, { body: 'json' })
+                .then(res => {
+                    this.$message.success('成功');
+                    this.formData = res;
+                    this.$router.replace({
+                        query: {
+                            id: res.id
+                        },
+                    });
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        },
+        del() {
+            this.$confirm('确认删除吗?', '提示', { type: 'warning' })
+                .then(() => {
+                    this.$http
+                        .post({
+                            url: '/userInfo/del',
+                            data: {
+                                id: this.formData.id,
+                            },
+                        })
+                        .then(res => {
+                            if (res.success) {
+                                this.$message.success('成功');
+                                this.$router.go(-1);
+                            } else {
+                                this.$message.warning('失败');
+                            }
+                        });
+                })
+                .catch(() => {});
+        },
+        resetPassword() {
+            this.$prompt('请输入新密码', '重置密码', { inputType: 'password' })
+                .then(res => {
+                    console.log(res);
+                    if (res.value) {
+                        this.$alert('确定重置密码?', '提示', {
+                            showCancelButton: true
+                        })
+                            .then(() => {
+                                return this.$http.post('/user/setPasswordAdmin', {
+                                    userId: this.formData.id,
+                                    password: res.value
+                                });
+                            })
+                            .then(res => {
+                                this.$message.success('密码重置成功');
+                            })
+                            .catch(() => {
+                                this.$message.error(res.error || '重置密码失败');
+                            });
+                    }
+                })
+                .catch(() => {});
+        }
+    },
+};
+</script>
+<style lang="less" scoped>
+</style>

+ 157 - 0
src/main/vue/src/views/backstage/BlackUserList.vue

@@ -0,0 +1,157 @@
+<template>
+    <div class="list-view">
+        <div class="filters-container">
+            <el-input placeholder="输入关键字" v-model="search" clearable
+                class="filter-item"></el-input>
+            <el-button @click="getData" type="primary" icon="el-icon-search"
+                class="filter-item">搜索
+            </el-button>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus"
+                class="filter-item">添加
+            </el-button>
+            <el-button @click="download" type="primary" icon="el-icon-download"
+                :loading="downloading" class="filter-item">导出EXCEL
+            </el-button>
+        </div>
+        <el-table :data="tableData" row-key="id" ref="table"
+            height="tableHeight" header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row" cell-class-name="table-cell">
+            <el-table-column v-if="multipleMode" align="center" type="selection"
+                width="50">
+            </el-table-column>
+            <el-table-column prop="id" label="ID" width="100">
+                <template slot="header" slot-scope="{column}">
+                    <sortable-header :column="column" :current-sort="sort"
+                        @changeSort="changeSort">
+                    </sortable-header>
+                </template>
+            </el-table-column>
+            <el-table-column prop="username" label="用户名" min-width="100">
+                <template slot="header" slot-scope="{column}">
+                    <sortable-header :column="column" :current-sort="sort"
+                        @changeSort="changeSort">
+                    </sortable-header>
+                </template>
+            </el-table-column>
+            <el-table-column prop="nickname" label="昵称" min-width="100">
+            </el-table-column>
+            <el-table-column label="头像" min-width="300">
+                <template slot-scope="{row}">
+                    <el-image style="width: 30px; height: 30px"
+                        :src="row.avatar" fit="cover"
+                        :preview-src-list="[row.avatar]"></el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="authorities" label="权限" min-width="100" >
+                <template slot-scope="{ row }" >
+                    <el-tag  v-for="item in row.authorities"
+                             :key="item.name"
+                             >{{ item.description }}</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" min-width="120">
+                <template slot-scope="{row}">
+                    <el-button @click="editRow(row)" type="primary" size="mini"
+                        plain>编辑</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <el-pagination background @size-change="onSizeChange"
+                @current-change="onCurrentChange" :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]" :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements">
+            </el-pagination>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from "vuex";
+import pageableTable from "@/mixins/pageableTable";
+
+export default {
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: "",
+            url: "/user/allAdmin",
+            downloading: false
+        };
+    },
+    computed: {
+        ...mapState([]),
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        beforeGetData() {
+            if (this.search) {
+                return { search: this.search };
+            }
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: "/blackUserEdit",
+                query: {
+                    ...this.$route.query,
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: "/blackUserEdit",
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get("/user/excel", { responseType: "blob" })
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(
+                        new Blob([res.data])
+                    );
+                    const link = document.createElement("a");
+                    link.href = downloadUrl;
+                    link.setAttribute(
+                        "download",
+                        res.headers["content-disposition"].split("filename=")[1]
+                    );
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: "提示",
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message("操作2");
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+</style>

+ 10 - 28
src/main/vue/src/views/merchant/MerchantEdit.vue

@@ -47,13 +47,13 @@
             <el-form-item prop="week" label="周几" id="week">
                 <el-select v-model="formData.week" multiple
                            placeholder="请选择" value-key="value">
-                    <el-option value="周一">周一</el-option>
-                    <el-option value="周二">周二</el-option>
-                    <el-option value="周三">周三</el-option>
-                    <el-option value="周四">周四</el-option>
-                    <el-option value="周五">周五</el-option>
-                    <el-option value="周六">周六</el-option>
-                    <el-option value="周日">周日</el-option>
+                    <el-option value="MONDAY">MONDAY</el-option>
+                    <el-option value="TUESDAY">TUESDAY</el-option>
+                    <el-option value="WEDNESDAY">WEDNESDAY</el-option>
+                    <el-option value="THURSDAY">THURSDAY</el-option>
+                    <el-option value="FRIDAY">FRIDAY</el-option>
+                    <el-option value="SATURDAY">SATURDAY</el-option>
+                    <el-option value="SUNDAY">SUNDAY</el-option>
                 </el-select>
             </el-form-item>
             <el-form-item prop="startTime" label="营业时间">
@@ -169,31 +169,13 @@
         },
         methods: {
             onSave() {
-                /*this.$refs.form.validate((valid) => {
+                this.$refs.form.validate((valid) => {
                     if (valid) {
                         this.submit();
                     } else {
                         return false;
                     }
-                });*/
-                let data = {...this.formData};
-                data.img = data.img.join(",");
-                data.qualification = data.qualification.join(",");
-                data.week = data.week.join(",")
-
-                this.saving = true;
-                this.$http
-                    .post('/merchant/saveDTO', data, {body: 'json'})
-                    .then(res => {
-                        this.saving = false;
-                        this.$message.success('成功');
-                        this.$router.go(-1);
-                    })
-                    .catch(e => {
-                        console.log(e);
-                        this.saving = false;
-                        this.$message.error(e.error);
-                    });
+                });
             },
             submit() {
                 let data = {...this.formData};
@@ -203,7 +185,7 @@
 
                 this.saving = true;
                 this.$http
-                    .post('/merchant/reg', data, {body: 'json'})
+                    .post('/merchant/saveDTO', data, {body: 'json'})
                     .then(res => {
                         this.saving = false;
                         this.$message.success('成功');

+ 1 - 1
src/main/vue/src/views/merchant/MerchantList.vue

@@ -207,7 +207,7 @@
                 url: "/merchant/showAll",
                 downloading: false,
                 statusOptions: [{"label": "待处理", "value": "PENDING"}, {
-                    "label": "成功", "value": "SUCCESS"
+                    "label": "成功", "value": "PASS"
                 }, {"label": "失败", "value": "FAIL"}],
                 status: '',
                 drawer: false,

+ 1 - 1
src/main/vue/vue.config.js

@@ -1,7 +1,7 @@
 const path = require('path');
 module.exports = {
     publicPath: process.env.NODE_ENV === 'production' ? '/admin/' : '/',
-    outputDir: '/var/www/zmj_admin',
+    outputDir: '/var/www/dingdong_admin',
     devServer: {
         port: 8081,
     },

+ 1 - 1
src/test/java/com/izouma/dingdong/repo/UserRepoTest.java

@@ -42,7 +42,7 @@ public class UserRepoTest {
 
     @Test
     public void findAllByAuthoritiesContains() {
-        List<User> list = userRepo.findAllByAuthoritiesContains(Authority.builder().name("ROLE_ADMIN").build());
+        List<User> list = userRepo.findAllByAuthoritiesNotContains(Authority.builder().name("ROLE_ADMIN").build());
         System.out.println(list);
     }
 }