licailing 5 лет назад
Родитель
Сommit
8999f8f41b
47 измененных файлов с 1145 добавлено и 157 удалено
  1. 5 2
      src/main/java/com/izouma/dingdong/domain/Appraisal.java
  2. 3 0
      src/main/java/com/izouma/dingdong/domain/Coupon.java
  3. 10 0
      src/main/java/com/izouma/dingdong/domain/OrderRefundApply.java
  4. 10 1
      src/main/java/com/izouma/dingdong/domain/backstage/Banner.java
  5. 1 1
      src/main/java/com/izouma/dingdong/domain/backstage/ChatWords.java
  6. 15 6
      src/main/java/com/izouma/dingdong/domain/backstage/Complaint.java
  7. 36 0
      src/main/java/com/izouma/dingdong/domain/backstage/Promote.java
  8. 17 2
      src/main/java/com/izouma/dingdong/domain/backstage/RefundApply.java
  9. 4 0
      src/main/java/com/izouma/dingdong/domain/backstage/Voice.java
  10. 9 5
      src/main/java/com/izouma/dingdong/domain/merchant/Merchant.java
  11. 8 1
      src/main/java/com/izouma/dingdong/domain/user/Address.java
  12. 2 0
      src/main/java/com/izouma/dingdong/domain/user/Feedback.java
  13. 1 0
      src/main/java/com/izouma/dingdong/dto/MerchantDTO.java
  14. 17 0
      src/main/java/com/izouma/dingdong/enums/BannerType.java
  15. 0 17
      src/main/java/com/izouma/dingdong/enums/BusinessNature.java
  16. 13 0
      src/main/java/com/izouma/dingdong/enums/ComplaintType.java
  17. 28 0
      src/main/java/com/izouma/dingdong/enums/Solution.java
  18. 2 0
      src/main/java/com/izouma/dingdong/repo/CouponRepo.java
  19. 16 0
      src/main/java/com/izouma/dingdong/repo/user/FeedbackRepo.java
  20. 2 2
      src/main/java/com/izouma/dingdong/service/UserService.java
  21. 46 1
      src/main/java/com/izouma/dingdong/service/backstage/CategoryService.java
  22. 44 0
      src/main/java/com/izouma/dingdong/service/merchant/MerchantService.java
  23. 32 1
      src/main/java/com/izouma/dingdong/service/merchant/MerchantSettingsService.java
  24. 14 0
      src/main/java/com/izouma/dingdong/service/user/FeedbackService.java
  25. 5 0
      src/main/java/com/izouma/dingdong/web/CouponController.java
  26. 0 2
      src/main/java/com/izouma/dingdong/web/backstage/ComplaintController.java
  27. 9 0
      src/main/java/com/izouma/dingdong/web/backstage/CooperateApplyController.java
  28. 19 4
      src/main/java/com/izouma/dingdong/web/merchant/MerchantController.java
  29. 63 0
      src/main/java/com/izouma/dingdong/web/user/FeedbackController.java
  30. 5 0
      src/main/java/com/izouma/dingdong/web/user/UserCouponController.java
  31. 1 1
      src/main/resources/genjson/Complaint.json
  32. 1 0
      src/main/resources/genjson/Feedback.json
  33. 17 17
      src/main/vue/src/router.js
  34. 2 2
      src/main/vue/src/views/Categories.vue
  35. 118 32
      src/main/vue/src/views/ComplaintEdit.vue
  36. 68 35
      src/main/vue/src/views/ComplaintList.vue
  37. 100 0
      src/main/vue/src/views/FeedbackEdit.vue
  38. 178 0
      src/main/vue/src/views/FeedbackList.vue
  39. 42 1
      src/main/vue/src/views/VoiceEdit.vue
  40. 17 1
      src/main/vue/src/views/VoiceList.vue
  41. 34 13
      src/main/vue/src/views/backstage/CooperateApplyList.vue
  42. 16 4
      src/main/vue/src/views/backstage/OrderRefundApplyEdit.vue
  43. 10 0
      src/main/vue/src/views/backstage/OrderRefundApplyList.vue
  44. 1 1
      src/main/vue/src/views/merchant/MerchantList.vue
  45. 20 0
      src/test/java/com/izouma/dingdong/repo/CouponRepoTest.java
  46. 20 0
      src/test/java/com/izouma/dingdong/service/CategoryServiceTest.java
  47. 64 5
      src/test/java/com/izouma/dingdong/service/MerchantServiceTest.java

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

@@ -40,11 +40,14 @@ public class Appraisal extends BaseEntity {
     @ApiModelProperty(value = "商品评价", name = "goodsAppraise")
     private String goodsAppraise;
 
+    /**
+     * 1-非常差,2-一般,3-超赞
+     */
     @ApiModelProperty(value = "骑手评分", name = "riderScore")
     private Integer riderLike;
 
-    @ApiModelProperty(value = "骑手评分", name = "riderScore")
-    private Integer riderBad;
+//    @ApiModelProperty(value = "骑手评分", name = "riderScore")
+//    private Integer riderBad;
 
     @ApiModelProperty(value = "骑手评价", name = "riderAppraise")
     private String riderAppraise;

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

@@ -59,6 +59,9 @@ public class Coupon extends BaseEntity implements Serializable {
 //    @Convert(converter = LongArrayConverter.class)
 //    private Set<Long> categoryIds = new HashSet<>();
 
+//    @ApiModelProperty(value = "是否过期", name = "isExpired")
+//    private Boolean isExpired;
+
     @Column(nullable = false)
     private Boolean enabled = true;
 }

+ 10 - 0
src/main/java/com/izouma/dingdong/domain/OrderRefundApply.java

@@ -14,6 +14,7 @@ import org.hibernate.annotations.NotFound;
 import org.hibernate.annotations.NotFoundAction;
 
 import javax.persistence.*;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
 @Data
@@ -66,6 +67,15 @@ public class OrderRefundApply extends BaseEntity {
     @ApiModelProperty(value = "沟通结果", name = "context")
     private String context;
 
+    @ApiModelProperty(value = "商家责任", name = "merchantLiability")
+    private BigDecimal merchantLiability;
+
+    @ApiModelProperty(value = "骑手责任", name = "riderLiability")
+    private BigDecimal riderLiability;
+
+    @ApiModelProperty(value = "平台责任", name = "platformLiability")
+    private BigDecimal platformLiability;
+
     //付款流水Id
     //private Long feeId;
 

+ 10 - 1
src/main/java/com/izouma/dingdong/domain/backstage/Banner.java

@@ -1,6 +1,7 @@
 package com.izouma.dingdong.domain.backstage;
 
 import com.izouma.dingdong.domain.BaseEntity;
+import com.izouma.dingdong.enums.BannerType;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -8,9 +9,11 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
 
 @Data
-//@Entity
+@Entity
 @AllArgsConstructor
 @NoArgsConstructor
 @Builder
@@ -23,4 +26,10 @@ public class Banner extends BaseEntity {
 
     @ApiModelProperty(value = "地址", name = "url")
     private String url;
+
+    @Enumerated(EnumType.STRING)
+    @ApiModelProperty(value = "类型", name = "type")
+    private BannerType type;
+
+//    private String address;
 }

+ 1 - 1
src/main/java/com/izouma/dingdong/domain/backstage/ChatWords.java

@@ -18,7 +18,7 @@ import java.io.Serializable;
 @NoArgsConstructor
 @AllArgsConstructor
 @Entity
-@ApiModel(value = "聊天框话术")
+@ApiModel(value = "已知标签内容")
 public class ChatWords extends BaseEntity {
     @ApiModelProperty("内容")
     @Column(length = 10)

+ 15 - 6
src/main/java/com/izouma/dingdong/domain/backstage/Complaint.java

@@ -1,6 +1,8 @@
 package com.izouma.dingdong.domain.backstage;
 
 import com.izouma.dingdong.domain.BaseEntity;
+import com.izouma.dingdong.enums.ComplaintType;
+import com.izouma.dingdong.enums.Solution;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
@@ -9,6 +11,8 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
 import java.time.LocalDateTime;
 
 @Data
@@ -24,20 +28,25 @@ public class Complaint extends BaseEntity {
 
     //商家或骑手
     @ApiModelProperty(value = "投诉目标", name = "target")
-    private String target;
+    private ComplaintType target;
 
-    @ApiModelProperty(value = "投诉类型")
+    @ApiModelProperty(value = "投诉内容", name = "type")
     private String type;
 
     @ApiModelProperty(value = "图片", name = "img")
     private String img;
 
-    @ApiModelProperty(value = "内容", name = "content")
+    @ApiModelProperty(value = "具体内容", name = "content")
     private String content;
 
-    @ApiModelProperty(value = "是否解决",name = "resolve")
-    private Boolean resolve;
+    @ApiModelProperty(value = "是否解决", name = "resolve")
+    private Boolean resolve = false;
 
-    @ApiModelProperty(value = "投诉时间")
+    @ApiModelProperty(value = "投诉时间", name = "time")
     private LocalDateTime time;
+
+    @Enumerated(EnumType.STRING)
+    @ApiModelProperty(value = "解决方式")
+    private Solution solution;
+
 }

+ 36 - 0
src/main/java/com/izouma/dingdong/domain/backstage/Promote.java

@@ -0,0 +1,36 @@
+package com.izouma.dingdong.domain.backstage;
+
+import com.izouma.dingdong.domain.BaseEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import java.time.LocalDateTime;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Builder
+public class Promote extends BaseEntity {
+
+    @ApiModelProperty(value = "商家ID", name = "merchantId")
+    private Long merchantId;
+
+    /**
+     * 推广位 主推广 副推广
+     */
+    @ApiModelProperty(value = "位置", name = "action")
+    private Integer action;
+
+    @ApiModelProperty(value = "推广开始时间",name = "startDateTime")
+    private LocalDateTime startDateTime;
+
+    @ApiModelProperty(value = "推广结束时间",name = "startEndTime")
+    private LocalDateTime endDateTime;
+
+
+}

+ 17 - 2
src/main/java/com/izouma/dingdong/domain/backstage/RefundApply.java

@@ -9,6 +9,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import javax.persistence.Column;
+import javax.persistence.Entity;
 import java.math.BigDecimal;
 
 @Data
@@ -39,10 +40,24 @@ public class RefundApply extends BaseEntity {
     @ApiModelProperty(value = "商家是否同意", name = "isAgree")
     private Boolean isAgree;
 
+    @Builder.Default
     @Column(nullable = false)
     @ApiModelProperty(value = "取消退款", name = "cancel")
-    private Boolean cancel;
+    private Boolean cancel = false;
 
-    @ApiModelProperty(value = "退款是否成功",name = "isPass")
+    @ApiModelProperty(value = "退款是否成功", name = "isPass")
     private Boolean isPass;
+
+    @ApiModelProperty(value = "商家责任", name = "merchantLiability")
+    private BigDecimal merchantLiability;
+
+    @ApiModelProperty(value = "骑手责任", name = "riderLiability")
+    private BigDecimal riderLiability;
+
+    @ApiModelProperty(value = "平台责任", name = "platformLiability")
+    private BigDecimal platformLiability;
+
+    @Builder.Default
+    @Column(nullable = false)
+    private Boolean enabled = true;
 }

+ 4 - 0
src/main/java/com/izouma/dingdong/domain/backstage/Voice.java

@@ -31,6 +31,10 @@ public class Voice extends BaseEntity {
 
     private String url;
 
+    private String enUrl;
+
+    private String thUrl;
+
 /*    @ApiModelProperty(value = "是否开启")
     private Boolean isOpen;*/
 }

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

@@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.izouma.dingdong.annotations.Searchable;
 import com.izouma.dingdong.domain.BaseEntity;
 import com.izouma.dingdong.domain.User;
-import com.izouma.dingdong.domain.Verified;
 import com.izouma.dingdong.enums.ApplyStatus;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -13,7 +12,6 @@ import org.hibernate.annotations.Where;
 
 import javax.persistence.*;
 import java.io.Serializable;
-import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
 @Data
@@ -21,7 +19,7 @@ import java.time.LocalDateTime;
 @AllArgsConstructor
 @NoArgsConstructor
 @Builder
-@JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
+@JsonIgnoreProperties(value = {"hibernateLazyInitializer"})
 @Where(clause = "enabled = true")
 @ApiModel(value = "商户信息", description = "商户信息")
 public class Merchant extends BaseEntity implements Serializable {
@@ -76,7 +74,7 @@ public class Merchant extends BaseEntity implements Serializable {
     private Integer badNum = 0;
 
     @ApiModelProperty(value = "月销", name = "monthSales")
-    private Integer monthSales = 0 ;
+    private Integer monthSales = 0;
 
     @ApiModelProperty(value = "通过", name = "isPass")
     private Boolean isPass;
@@ -91,10 +89,16 @@ public class Merchant extends BaseEntity implements Serializable {
 //    @ApiModelProperty(value = "商家余额",name = "money")
 //    private BigDecimal money;
 
-    @ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.DETACH)
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
     @JoinColumn(name = "userId", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
     private User user;
 
+    @ApiModelProperty(value = "经度", name = "longitude")
+    private Double longitude;
+
+    @ApiModelProperty(value = "纬度",name = "latitude")
+    private Double latitude;
+
 /*    @ApiModelProperty(value = "实名信息ID",name = "verifiedId")
     private Long verifiedId;
 

+ 8 - 1
src/main/java/com/izouma/dingdong/domain/user/Address.java

@@ -9,6 +9,7 @@ import lombok.*;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import java.io.Serializable;
+import java.math.BigDecimal;
 
 @EqualsAndHashCode(callSuper = true)
 @Data
@@ -43,10 +44,16 @@ public class Address extends BaseEntity implements Serializable {
     @ApiModelProperty("是否选为默认地址")
     private Boolean isDefault;
 
+    @ApiModelProperty(value = "经度", name = "longitude")
+    private BigDecimal longitude;
+
+    @ApiModelProperty(value = "纬度",name = "latitude")
+    private BigDecimal latitude;
+
     @Column(nullable = false)
     private Boolean enabled = true;
 
     public String getAddressInfo() {
-        return name + "," + phone + "," + addressName;
+        return name + "," + phone + "," + addressName + number;
     }
 }

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

@@ -1,6 +1,7 @@
 package com.izouma.dingdong.domain.user;
 
 import com.izouma.dingdong.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -17,6 +18,7 @@ import javax.persistence.Entity;
 @NoArgsConstructor
 @Builder
 @Where(clause = "enabled = 1")
+@ApiModel(value = "意见反馈")
 public class Feedback extends BaseEntity {
     @ApiModelProperty(value = "用户Id", name = "userId")
     private Long userId;

+ 1 - 0
src/main/java/com/izouma/dingdong/dto/MerchantDTO.java

@@ -147,6 +147,7 @@ public class MerchantDTO {
     @ApiModelProperty(value = "状态", name = "status")
     private ApplyStatus status;
 
+    @Searchable
     @ApiModelProperty(value = "成立时间", name = "established")
     private LocalDateTime establishTime;
 

+ 17 - 0
src/main/java/com/izouma/dingdong/enums/BannerType.java

@@ -0,0 +1,17 @@
+package com.izouma.dingdong.enums;
+
+public enum BannerType {
+    TOP("顶部"),
+    AREA("优惠专区"),
+    ;
+
+    private String description;
+
+    BannerType(String description) {
+        this.description = description;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

+ 0 - 17
src/main/java/com/izouma/dingdong/enums/BusinessNature.java

@@ -1,17 +0,0 @@
-package com.izouma.dingdong.enums;
-
-public enum BusinessNature {
-    SELF_EMPLOYED("自营"),
-    CHAIN_STORE("连锁"),
-    FRANCHISE("加盟");
-
-    private final String description;
-
-    public String getDescription() {
-        return description;
-    }
-
-    BusinessNature(String description) {
-        this.description = description;
-    }
-}

+ 13 - 0
src/main/java/com/izouma/dingdong/enums/ComplaintType.java

@@ -0,0 +1,13 @@
+package com.izouma.dingdong.enums;
+
+public enum ComplaintType {
+
+    /*
+    商户
+     */
+    MERCHANT,
+    /*
+    骑手
+     */
+    RIDER
+}

+ 28 - 0
src/main/java/com/izouma/dingdong/enums/Solution.java

@@ -0,0 +1,28 @@
+package com.izouma.dingdong.enums;
+
+public enum Solution {
+    /**
+     * 线下沟通
+     */
+    OFFLINE("线下沟通"),
+
+    /**
+     * 退款
+     */
+    REFUND("退款"),
+
+    /**
+     * 发放优惠券
+     */
+    ISSUE_COUPONS("发放优惠券");
+
+    private final String description;
+
+    Solution(String description){
+        this.description=description;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

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

@@ -20,4 +20,6 @@ public interface CouponRepo extends JpaRepository<Coupon, Long>, JpaSpecificatio
     void deleteById(Long id);
 
     List<Coupon> findAllByMerchantIdAndEnabledTrue(Long merchantId);
+
+    List<Coupon> findAllByMerchantIdNullAndEnabledTrue();
 }

+ 16 - 0
src/main/java/com/izouma/dingdong/repo/user/FeedbackRepo.java

@@ -0,0 +1,16 @@
+package com.izouma.dingdong.repo.user;
+
+import com.izouma.dingdong.domain.user.Feedback;
+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 FeedbackRepo extends JpaRepository<Feedback, Long>, JpaSpecificationExecutor<Feedback> {
+    @Query("update Feedback t set t.enabled = false where t.id = ?1")
+    @Modifying
+    @Transactional
+    void deleteById(Long id);
+}

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

@@ -97,13 +97,13 @@ public class UserService {
                     .avatar(Constants.DEFAULT_AVATAR)
                     .build();
 
-        } else {
+        } /*else {
             if (MERCHANT.equals(user.getIdentity())){
                 throw new BusinessException("请使用商户端登陆");
             }else if (RIDER.equals(user.getIdentity())){
                 throw new BusinessException("请使用骑手端登陆");
             }
-        }
+        }*/
 
         return user;
     }

+ 46 - 1
src/main/java/com/izouma/dingdong/service/backstage/CategoryService.java

@@ -15,6 +15,7 @@ import com.izouma.dingdong.repo.merchant.MerchantSettingsRepo;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.List;
 
 
@@ -29,9 +30,51 @@ public class CategoryService {
     /*
     按类别显示商户列表
      */
-    public List<MerchantDTO> categoryMer(Long categoryId) {
+/*    public List<MerchantDTO> categoryMer(Long categoryId) {
         Category category = categoryRepo.findById(categoryId).orElseThrow(new BusinessException("无分类"));
         List<MerchantSettings> settings = merchantSettingsRepo.findAllByCategoryContains(category);
+
+        if (ObjectUtil.isNull(settings)) {
+            return null;
+        }
+        List<MerchantDTO> dtos = CollUtil.newArrayList();
+        settings.forEach(s -> {
+            Merchant merchant = merchantRepo.findById(s.getMerchantId()).orElseThrow(new BusinessException("无商家"));
+            dtos.add(new MerchantDTO(merchant, s));
+        });
+        return dtos;
+    }*/
+
+    public List<MerchantDTO> categoryMer(Long categoryId) {
+        //1级
+        Category category = categoryRepo.findById(categoryId).orElseThrow(new BusinessException("无分类"));
+
+        List<Category> children = category.getChildren();
+
+        //1 子为空 表示是最底层
+        if (CollUtil.isEmpty(children)) {
+            return toDTO(merchantSettingsRepo.findAllByCategoryContains(category));
+        }
+
+        //2级 子不为空
+        List<Category> children2 = new ArrayList<>();
+        //子下面的所有都加入list
+        children.forEach(c -> children2.addAll(c.getChildren()));
+
+        List<MerchantSettings> list = new ArrayList<>();
+
+        if (CollUtil.isEmpty(children2)) {
+            //子下为空,循环children
+            children.forEach(c -> list.addAll(merchantSettingsRepo.findAllByCategoryContains(c)));
+        } else {
+            //3级 子的子不为空 循环子下的子
+            children2.forEach(i -> list.addAll(merchantSettingsRepo.findAllByCategoryContains(i)));
+        }
+        return toDTO(list);
+
+    }
+
+    public List<MerchantDTO> toDTO(List<MerchantSettings> settings) {
         if (ObjectUtil.isNull(settings)) {
             return null;
         }
@@ -42,4 +85,6 @@ public class CategoryService {
         });
         return dtos;
     }
+
+
 }

+ 44 - 0
src/main/java/com/izouma/dingdong/service/merchant/MerchantService.java

@@ -10,6 +10,7 @@ import com.izouma.dingdong.domain.merchant.Merchant;
 import com.izouma.dingdong.domain.merchant.MerchantClassification;
 import com.izouma.dingdong.domain.merchant.MerchantSettings;
 import com.izouma.dingdong.dto.MerchantDTO;
+import com.izouma.dingdong.dto.PageQuery;
 import com.izouma.dingdong.enums.ApplyStatus;
 import com.izouma.dingdong.exception.BusinessException;
 import com.izouma.dingdong.repo.UserRepo;
@@ -22,11 +23,17 @@ import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
+import sun.security.krb5.internal.PAData;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
+
+import static com.izouma.dingdong.web.BaseController.*;
 
 @Service
 @AllArgsConstructor
@@ -200,15 +207,52 @@ public class MerchantService {
      * @return 分页列表
      */
     public Page<MerchantDTO> showAll(Pageable pageable) {
+
+        //所有商家要按距离排序
+
         List<MerchantDTO> merchantDTOS = CollUtil.newArrayList();
         List<Merchant> merchants = merchantRepo.findAll();
         for (Merchant merchant : merchants) {
             MerchantSettings merchantSettings = merchantSettingsRepo.findByMerchantId(merchant.getId()).orElseThrow(new BusinessException("商户不存在"));
+
             merchantDTOS.add(new MerchantDTO(merchant, merchantSettings));
         }
         return new PageImpl<>(merchantDTOS, pageable, merchantDTOS.size());
     }
 
+    public Page<MerchantDTO> showAll(PageQuery pageQuery, Double longitude, Double latitude) {
+
+        //所有商家要按距离排序
+
+        Set<MerchantDTO> merchantDTOS = CollUtil.newHashSet();
+        List<Merchant> merchants = merchantRepo.findAll(toSpecification(pageQuery, Merchant.class));
+
+
+        for (Merchant m : merchants) {
+            MerchantSettings merchantSettings = merchantSettingsRepo.findByMerchantId(m.getId()).orElseThrow(new BusinessException("商户不存在"));
+
+            double lat1 = m.getLatitude() * Math.PI / 180.0;
+            double lat2 = latitude * Math.PI / 180.0;
+
+            double a = lat1 - lat2;
+            double b = m.getLongitude() * Math.PI / 180.0 - longitude * Math.PI / 180.0;
+            double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+                    + Math.cos(lat1)
+                    * Math.cos(lat2)
+                    * Math.pow(Math.sin(b / 2), 2)));
+            s = s * 6378.137 * 1000;
+            s = Math.round(s);
+
+
+            merchantDTOS.add(new MerchantDTO(m, merchantSettings));
+        }
+
+        List<MerchantDTO> dtos = new ArrayList<>(merchantDTOS);
+
+        return new PageImpl<>(dtos, toPageRequest(pageQuery), merchantDTOS.size());
+    }
+
+
     /**
      * 显示个人的商户信息
      *

+ 32 - 1
src/main/java/com/izouma/dingdong/service/merchant/MerchantSettingsService.java

@@ -1,15 +1,21 @@
 package com.izouma.dingdong.service.merchant;
 
+import cn.hutool.core.collection.CollUtil;
 import com.izouma.dingdong.domain.OrderInfo;
+import com.izouma.dingdong.domain.backstage.TimeTag;
+import com.izouma.dingdong.domain.merchant.Merchant;
 import com.izouma.dingdong.domain.merchant.MerchantSettings;
-import com.izouma.dingdong.enums.MerchantStatus;
+import com.izouma.dingdong.dto.MerchantDTO;
 import com.izouma.dingdong.exception.BusinessException;
 import com.izouma.dingdong.repo.OrderInfoRepo;
+import com.izouma.dingdong.repo.backstage.TimeTagRepo;
+import com.izouma.dingdong.repo.merchant.MerchantRepo;
 import com.izouma.dingdong.repo.merchant.MerchantSettingsRepo;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 @AllArgsConstructor
@@ -19,6 +25,11 @@ public class MerchantSettingsService {
 
     private OrderInfoRepo orderInfoRepo;
 
+    private TimeTagRepo timeTagRepo;
+
+    private MerchantRepo merchantRepo;
+
+
     /*
     显示所有订单
      */
@@ -26,6 +37,26 @@ public class MerchantSettingsService {
         return orderInfoRepo.findAllByMerchantId(id);
     }
 
+    /*
+    时间标签类商家列表
+     */
+    public List<MerchantDTO> timeMerchant(Long timeTagId) {
+        TimeTag timeTag = timeTagRepo.findById(timeTagId).orElseThrow(new BusinessException("无时间标签"));
+        List<MerchantSettings> all = merchantSettingsRepo.findAll();
+        List<MerchantSettings> collect = all.stream().filter(a ->
+                //商家开始时间早于结束前的一小时 或者 商家结束时间早于开始后的一小时
+                !a.getStartTime().isAfter(timeTag.getEndTime().minusHours(1)) || !a.getEndTime().isAfter(timeTag.getStartTime().plusHours(1))
+        ).collect(Collectors.toList());
+
+        List<MerchantDTO> list = CollUtil.newArrayList();
+
+        collect.forEach(a -> {
+            Merchant merchant = merchantRepo.findById(a.getMerchantId()).orElseThrow(new BusinessException("无商家"));
+            list.add(new MerchantDTO(merchant, a));
+        });
+
+        return list;
+    }
 
 
 }

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

@@ -0,0 +1,14 @@
+package com.izouma.dingdong.service.user;
+
+import com.izouma.dingdong.domain.user.Feedback;
+import com.izouma.dingdong.repo.user.FeedbackRepo;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class FeedbackService {
+
+    private FeedbackRepo feedbackRepo;
+
+}

+ 5 - 0
src/main/java/com/izouma/dingdong/web/CouponController.java

@@ -70,5 +70,10 @@ public class CouponController extends BaseController {
         Long merchantId = merchantService.findMerchantId(SecurityUtils.getAuthenticatedUser().getId());
         return couponRepo.findAllByMerchantIdAndEnabledTrue(merchantId);
     }
+
+    @GetMapping("/platform")
+    public List<Coupon> platform(){
+        return couponRepo.findAllByMerchantIdNullAndEnabledTrue();
+    }
 }
 

+ 0 - 2
src/main/java/com/izouma/dingdong/web/backstage/ComplaintController.java

@@ -59,7 +59,5 @@ public class ComplaintController extends BaseController {
         List<Complaint> data = all(pageQuery).getContent();
         ExcelUtils.export(response, data);
     }
-
-
 }
 

+ 9 - 0
src/main/java/com/izouma/dingdong/web/backstage/CooperateApplyController.java

@@ -9,6 +9,7 @@ import com.izouma.dingdong.repo.backstage.CooperateApplyRepo;
 import com.izouma.dingdong.utils.ObjUtils;
 import com.izouma.dingdong.utils.excel.ExcelUtils;
 
+import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -59,5 +60,13 @@ public class CooperateApplyController extends BaseController {
         List<CooperateApply> data = all(pageQuery).getContent();
         ExcelUtils.export(response, data);
     }
+
+    @GetMapping("/contact")
+    @ApiOperation("确认已联系")
+    public void contact(Long id){
+        CooperateApply apply = cooperateApplyRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+        apply.setIsPass(true);
+        cooperateApplyRepo.save(apply);
+    }
 }
 

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

@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.List;
 
 @RestController
@@ -66,11 +67,11 @@ public class MerchantController extends BaseController {
         ExcelUtils.export(response, data);
     }
 
-    @GetMapping("/showAll")
+/*    @GetMapping("/showAll")
     @ApiOperation("商家所有信息")
     public Page<MerchantDTO> showAll(PageQuery pageQuery) {
-        return merchantService.showAll(toPageRequest(pageQuery));
-    }
+        return merchantService.showAll(pageQuery);
+    }*/
 
     @GetMapping("/my")
     public MerchantDTO my() {
@@ -98,9 +99,23 @@ public class MerchantController extends BaseController {
 
     @GetMapping("/closeMer")
     @ApiOperation("停止营业/开始营业")
-    public void closeMer(){
+    public void closeMer() {
         Long merchantId = merchantService.findMerchantId(SecurityUtils.getAuthenticatedUser().getId());
         merchantService.closeMer(merchantId);
     }
+
+    @GetMapping("/showAll")
+    @ApiOperation("商家所有信息")
+    public Page<MerchantDTO> showAll(PageQuery pageQuery, BigDecimal longitude, BigDecimal latitude) {
+
+
+
+
+
+
+/*        return merchantService.showAll(pageQuery);*/
+        return null;
+    }
+
 }
 

+ 63 - 0
src/main/java/com/izouma/dingdong/web/user/FeedbackController.java

@@ -0,0 +1,63 @@
+package com.izouma.dingdong.web.user;
+
+import com.izouma.dingdong.web.BaseController;
+import com.izouma.dingdong.domain.user.Feedback;
+import com.izouma.dingdong.service.user.FeedbackService;
+import com.izouma.dingdong.dto.PageQuery;
+import com.izouma.dingdong.exception.BusinessException;
+import com.izouma.dingdong.repo.user.FeedbackRepo;
+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("/feedback")
+@AllArgsConstructor
+public class FeedbackController extends BaseController {
+    private FeedbackService feedbackService;
+    private FeedbackRepo feedbackRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public Feedback save(@RequestBody Feedback record) {
+        if (record.getId() != null) {
+            Feedback orig = feedbackRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return feedbackRepo.save(orig);
+        }
+        return feedbackRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @GetMapping("/all")
+    public Page<Feedback> all(PageQuery pageQuery) {
+        return feedbackRepo.findAll(toSpecification(pageQuery,Feedback.class), toPageRequest(pageQuery));
+    }
+
+    @GetMapping("/get/{id}")
+    public Feedback get(@PathVariable Long id) {
+        return feedbackRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        feedbackRepo.deleteById(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<Feedback> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

+ 5 - 0
src/main/java/com/izouma/dingdong/web/user/UserCouponController.java

@@ -77,5 +77,10 @@ public class UserCouponController extends BaseController {
             userCouponRepo.save(build);
         });
     }
+
+    @GetMapping("/my")
+    public Page<UserCoupon> my(PageQuery pageQuery){
+        return null;
+    }
 }
 

+ 1 - 1
src/main/resources/genjson/Complaint.json

@@ -1 +1 @@
-{"tableName":"Complaint","className":"Complaint","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":"orderId","modelName":"orderId","remark":"订单ID","showInList":true,"showInForm":true,"formType":"number"},{"name":"target","modelName":"target","remark":"投诉目标","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"type","modelName":"type","remark":"投诉类型","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"img","modelName":"img","remark":"图片","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"content","modelName":"content","remark":"内容","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"resolve","modelName":"resolve","remark":"是否解决","showInList":true,"showInForm":true,"formType":"switch"},{"name":"time","modelName":"time","remark":"投诉时间","showInList":true,"showInForm":true,"formType":"datetime"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.dingdong","tablePackage":"com.izouma.dingdong.domain.backstage.Complaint","genPackage":"backstage"}
+{"tableName":"Complaint","className":"Complaint","remark":"投诉","genTable":true,"genClass":true,"genList":true,"genForm":true,"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":"orderId","modelName":"orderId","remark":"订单ID","showInList":true,"showInForm":true,"formType":"number"},{"name":"target","modelName":"target","remark":"投诉目标","showInList":true,"showInForm":true,"formType":"select","apiFlag":"1","optionsValue":"[{\"label\":\"商家\",\"value\":\"MERCHANT\"},{\"label\":\"骑手\",\"value\":\"RIDER\"}]"},{"name":"type","modelName":"type","remark":"投诉类型","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"img","modelName":"img","remark":"图片","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"content","modelName":"content","remark":"内容","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"resolve","modelName":"resolve","remark":"是否解决","showInList":true,"showInForm":true,"formType":"switch"},{"name":"time","modelName":"time","remark":"投诉时间","showInList":true,"showInForm":true,"formType":"datetime"},{"name":"solution","modelName":"solution","remark":"解决方式","showInList":true,"showInForm":true,"formType":"select","apiFlag":"1","optionsValue":"[{\"label\":\"线下沟通\",\"value\":\"OFFLINE\"},{\"label\":\"退款\",\"value\":\"REFUND\"},{\"label\":\"发放优惠券\",\"value\":\"ISSUE_COUPONS\"}]"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.dingdong","tablePackage":"com.izouma.dingdong.domain.backstage.Complaint","genPackage":"backstage"}

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

@@ -0,0 +1 @@
+{"tableName":"Feedback","className":"Feedback","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":"content","modelName":"content","remark":"内容","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"img","modelName":"img","remark":"图片","showInList":true,"showInForm":true,"formType":"multiImage"},{"name":"name","modelName":"name","remark":"联系人","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"phone","modelName":"phone","remark":"电话","showInList":true,"showInForm":true,"formType":"singleLineText"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.dingdong","tablePackage":"com.izouma.dingdong.domain.user.Feedback","genPackage":"user"}

+ 17 - 17
src/main/vue/src/router.js

@@ -350,7 +350,23 @@ const router = new Router({
                     meta: {
                        title: '合作申请',
                     },
-               }
+               },
+                {
+                    path: '/feedbackEdit',
+                    name: 'FeedbackEdit',
+                    component: () => import(/* webpackChunkName: "feedbackEdit" */ '@/views/FeedbackEdit.vue'),
+                    meta: {
+                       title: '意见反馈编辑',
+                    },
+                },
+                {
+                    path: '/feedbackList',
+                    name: 'FeedbackList',
+                    component: () => import(/* webpackChunkName: "feedbackList" */ '@/views/FeedbackList.vue'),
+                    meta: {
+                       title: '意见反馈',
+                    },
+               },
                 /**INSERT_LOCATION**/,
                 {
                     path: '/categories',
@@ -392,22 +408,6 @@ const router = new Router({
                         title: '退款申请',
                     },
                 },
-                {
-                    path: '/withdrawApplyEdit',
-                    name: 'WithdrawApplyEdit',
-                    component: () => import(/* webpackChunkName: "withdrawalsRecordEdit" */ '@/views/backstage/WithdrawApplyEdit.vue'),
-                    meta: {
-                        title: '退款申请编辑',
-                    },
-                },
-                {
-                    path: '/withdrawApplyList',
-                    name: 'WithdrawApplyList',
-                    component: () => import(/* webpackChunkName: "withdrawalsRecordList" */ '@/views/backstage/WithdrawApplyList.vue'),
-                    meta: {
-                        title: '退款申请',
-                    },
-                },
             ],
         },
         {

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

@@ -346,13 +346,13 @@
             color: #999;
         }
         .opt {
-            opacity: 1;
+            opacity: 0;
         }
     }
 
     .custom-tree-node:hover {
         .opt {
-            opacity: 0;
+            opacity: 1;
         }
     }
 

+ 118 - 32
src/main/vue/src/views/ComplaintEdit.vue

@@ -2,41 +2,84 @@
     <div class="edit-view">
         <el-form :model="formData" :rules="rules" ref="form" label-width="80px" label-position="right" size="small"
                  style="max-width: 500px;">
-                <el-form-item prop="orderId" label="订单ID">
-                            <el-input-number type="number" v-model="formData.orderId"></el-input-number>
-                </el-form-item>
-                <el-form-item prop="target" label="投诉目标">
-                            <el-input v-model="formData.target"></el-input>
-                </el-form-item>
-                <el-form-item prop="type" label="投诉类型">
-                            <el-input v-model="formData.type"></el-input>
-                </el-form-item>
-                <el-form-item prop="img" label="图片">
-                            <el-input v-model="formData.img"></el-input>
-                </el-form-item>
-                <el-form-item prop="content" label="内容">
-                            <el-input v-model="formData.content"></el-input>
-                </el-form-item>
-                <el-form-item prop="resolve" label="是否解决">
-                            <el-switch v-model="formData.resolve"></el-switch>
-                </el-form-item>
-                <el-form-item prop="time" label="投诉时间">
-                            <el-date-picker
-                                    v-model="formData.time"
-                                    type="datetime"
-                                    value-format="yyyy-MM-dd HH:mm:ss"
-                                    placeholder="选择日期时间">
-                            </el-date-picker>
-                </el-form-item>
+            <el-form-item prop="orderId" label="订单ID">
+                <el-input-number type="number" v-model="formData.orderId"></el-input-number>
+            </el-form-item>
+            <el-form-item prop="target" label="投诉目标">
+                <el-select v-model="formData.target" clearable filterable placeholder="请选择">
+                    <el-option
+                            v-for="item in targetOptions"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value">
+                    </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item prop="type" label="投诉类型">
+                <el-input v-model="formData.type"></el-input>
+            </el-form-item>
+            <el-form-item prop="img" label="图片">
+                <multi-upload v-model="formData.img"></multi-upload>
+            </el-form-item>
+            <el-form-item prop="content" label="内容">
+                <el-input type="textarea" v-model="formData.content"></el-input>
+            </el-form-item>
+            <el-form-item prop="resolve" label="是否解决">
+                <el-switch v-model="formData.resolve"></el-switch>
+            </el-form-item>
+            <el-form-item prop="time" label="投诉时间">
+                <el-date-picker
+                        v-model="formData.time"
+                        type="datetime"
+                        value-format="yyyy-MM-dd HH:mm:ss"
+                        placeholder="选择日期时间">
+                </el-date-picker>
+            </el-form-item>
+            <el-form-item prop="solution" label="解决方式">
+                <el-select v-model="formData.solution" clearable filterable placeholder="请选择">
+                    <el-option
+                            v-for="item in solutionOptions"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value">
+                    </el-option>
+                </el-select>
+                <el-button class="left" type="warning" v-if="formData.solution==='ISSUE_COUPONS'" size="mini"
+                           @click="showCoupon">发放优惠券
+                </el-button>
+                <el-button class="left" type="warning" v-if="formData.solution==='REFUND'" size="mini">退款</el-button>
+            </el-form-item>
             <el-form-item>
                 <el-button @click="onSave" :loading="saving"
-                           type="primary">保存</el-button>
+                           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>
+
+        <el-dialog
+                title="优惠券列表"
+                center
+                :visible.sync="dislogTableCoupon"
+        >
+            <el-table :data="coupons" ref="table">
+                <el-table-column align="center" type="selection"
+                                 width="50">
+                </el-table-column>
+                <el-table-column prop="name" label="优惠券名称"></el-table-column>
+                <el-table-column prop="amount" label="金额"></el-table-column>
+                <el-table-column prop="fullAmount" label="限制"></el-table-column>
+                <el-table-column prop="endDate" label="结束时间"></el-table-column>
+            </el-table>
+            <div class="pagination-wrapper">
+                <el-button @click="operation1">确定</el-button>
+            </div>
+        </el-dialog>
+
     </div>
 </template>
 <script>
@@ -45,7 +88,7 @@
         created() {
             if (this.$route.query.id) {
                 this.$http
-                    .get('complaint/get/'+this.$route.query.id)
+                    .get('complaint/get/' + this.$route.query.id)
                     .then(res => {
                         this.formData = res;
                     })
@@ -58,10 +101,15 @@
         data() {
             return {
                 saving: false,
-                formData: {
-                },
-                rules: {
-                },
+                formData: {},
+                rules: {},
+                targetOptions: [{"label": "商家", "value": "MERCHANT"}, {"label": "骑手", "value": "RIDER"}],
+                solutionOptions: [{"label": "线下沟通", "value": "OFFLINE"}, {
+                    "label": "退款",
+                    "value": "REFUND"
+                }, {"label": "发放优惠券", "value": "ISSUE_COUPONS"}],
+                dislogTableCoupon: false,
+                coupons: [],
             }
         },
         methods: {
@@ -78,6 +126,7 @@
                 let data = {...this.formData};
 
                 this.saving = true;
+                data.img = data.img.join(',');
                 this.$http
                     .post('/complaint/save', data, {body: 'json'})
                     .then(res => {
@@ -104,8 +153,45 @@
                     }
                 })
             },
+            operation1() {
+                /*this.$notify({
+                    title: '发放',
+                    message: this.selection
+                });*/
+                this.$http
+                    .post("/userCoupon/issue", {
+                            userId: this.formData.id,
+                            couponId: this.selection.toString(),
+
+                        },
+                    )
+                    .then(res => {
+                        this.$message.success("发放成功");
+                        //this.showSetLogistics = false;
+                        this.$router.go(0);
+                    })
+                    .catch(e => {
+                        console.log(e);
+                        this.$message.error(e.error || '发放失败');
+                    });
+            },
+            showCoupon() {
+                this.dislogTableCoupon = true;
+                this.$http
+                    .get('/coupon/platform')
+                    .then(res => {
+                        this.coupons = res.content;
+                        //console.log(this.coupons)
+                    })
+                    .catch(e => {
+                        console.log(e);
+                    });
+            },
         }
     }
 </script>
 <style lang="less" scoped>
+    .left {
+        margin: 0 0 0 10px;
+    }
 </style>

+ 68 - 35
src/main/vue/src/views/ComplaintList.vue

@@ -1,5 +1,5 @@
 <template>
-    <div  class="list-view">
+    <div class="list-view">
         <div class="filters-container">
             <el-input placeholder="输入关键字" v-model="search" clearable
                       class="filter-item"></el-input>
@@ -9,9 +9,6 @@
             <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"
@@ -23,31 +20,41 @@
             </el-table-column>
             <el-table-column prop="id" label="ID" width="100">
             </el-table-column>
-                                <el-table-column prop="orderId" label="订单ID"
->
-                    </el-table-column>
-                    <el-table-column prop="target" label="投诉目标"
->
-                    </el-table-column>
-                    <el-table-column prop="type" label="投诉类型"
->
-                    </el-table-column>
-                    <el-table-column prop="img" label="图片"
->
-                    </el-table-column>
-                    <el-table-column prop="content" label="内容"
->
-                    </el-table-column>
-                    <el-table-column prop="resolve" label="是否解决"
->
-                            <template slot-scope="{row}">
-                                <el-tag :type="row.resolve?'':'info'">{{row.resolve}}</el-tag>
-                            </template>
-                    </el-table-column>
-                    <el-table-column prop="time" label="投诉时间"
-                            :formatter="datetimeFormatter"
->
-                    </el-table-column>
+            <el-table-column prop="orderId" label="订单ID"
+            >
+            </el-table-column>
+            <el-table-column prop="target" label="投诉目标"
+                             :formatter="targetFormatter"
+            >
+            </el-table-column>
+            <el-table-column prop="type" label="投诉类型"
+            >
+            </el-table-column>
+            <el-table-column prop="img" label="图片"
+            >
+                <template slot-scope="{row}">
+                    <el-image style="width: 30px; height: 30px"
+                              :src="picList(row.img)[0]" fit="cover"
+                              :preview-src-list="picList(row.img)?picList(row.img):[]"></el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="content" label="内容"
+            >
+            </el-table-column>
+            <el-table-column prop="resolve" label="是否解决"
+            >
+                <template slot-scope="{row}">
+                    <el-tag :type="row.resolve?'':'info'">{{row.resolve}}</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column prop="time" label="投诉时间"
+                             :formatter="datetimeFormatter"
+            >
+            </el-table-column>
+            <el-table-column prop="solution" label="解决方式"
+                             :formatter="solutionFormatter"
+            >
+            </el-table-column>
             <el-table-column
                     label="操作"
                     align="center"
@@ -79,7 +86,7 @@
     </div>
 </template>
 <script>
-    import { mapState } from "vuex";
+    import {mapState} from "vuex";
     import pageableTable from "@/mixins/pageableTable";
 
     export default {
@@ -94,6 +101,11 @@
                 search: "",
                 url: "/complaint/all",
                 downloading: false,
+                targetOptions: [{"label": "商家", "value": "MERCHANT"}, {"label": "骑手", "value": "RIDER"}],
+                solutionOptions: [{"label": "线下沟通", "value": "OFFLINE"}, {
+                    "label": "退款",
+                    "value": "REFUND"
+                }, {"label": "发放优惠券", "value": "ISSUE_COUPONS"}],
             }
         },
         computed: {
@@ -102,9 +114,30 @@
             }
         },
         methods: {
+            picList(row) {
+                if (row) {
+                    return row.split(",");
+                } else {
+                    return "";
+                }
+            },
+            targetFormatter(row, column, cellValue, index) {
+                let selectedOption = this.targetOptions.find(i => i.value === cellValue);
+                if (selectedOption) {
+                    return selectedOption.label;
+                }
+                return '';
+            },
+            solutionFormatter(row, column, cellValue, index) {
+                let selectedOption = this.solutionOptions.find(i => i.value === cellValue);
+                if (selectedOption) {
+                    return selectedOption.label;
+                }
+                return '';
+            },
             beforeGetData() {
                 if (this.search) {
-                    return { search: this.search };
+                    return {search: this.search};
                 }
             },
             toggleMultipleMode(multipleMode) {
@@ -117,7 +150,7 @@
                 this.$router.push({
                     path: "/complaintEdit",
                     query: {
-                    ...this.$route.query
+                        ...this.$route.query
                     }
                 });
             },
@@ -125,16 +158,16 @@
                 this.$router.push({
                     path: "/complaintEdit",
                     query: {
-                    id: row.id
+                        id: row.id
                     }
                 });
             },
             download() {
                 this.downloading = true;
                 this.$axios
-                    .get("/complaint/excel", { 
+                    .get("/complaint/excel", {
                         responseType: "blob",
-                        params: { size: 10000 }
+                        params: {size: 10000}
                     })
                     .then(res => {
                         console.log(res);

+ 100 - 0
src/main/vue/src/views/FeedbackEdit.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="content" label="内容">
+                            <el-input v-model="formData.content"></el-input>
+                </el-form-item>
+                <el-form-item prop="img" label="图片">
+                            <multi-upload v-model="formData.img"></multi-upload>
+                </el-form-item>
+                <el-form-item prop="name" label="联系人">
+                            <el-input v-model="formData.name"></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>
+                <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: 'FeedbackEdit',
+        created() {
+            if (this.$route.query.id) {
+                this.$http
+                    .get('feedback/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('/feedback/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(`/feedback/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>

+ 178 - 0
src/main/vue/src/views/FeedbackList.vue

@@ -0,0 +1,178 @@
+<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>
+                    </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="content" label="内容"
+>
+                    </el-table-column>
+                    <el-table-column prop="img" label="图片"
+>
+                            <template slot-scope="{row}">
+                                <el-image style="width: 30px; height: 30px"
+                                          :src="row.img[0]" fit="cover"
+                                          :preview-src-list="row.img"></el-image>
+                            </template>
+                    </el-table-column>
+                    <el-table-column prop="name" label="联系人"
+>
+                    </el-table-column>
+                    <el-table-column prop="phone" label="电话"
+>
+                    </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: 'FeedbackList',
+        mixins: [pageableTable],
+        created() {
+            this.getData();
+        },
+        data() {
+            return {
+                multipleMode: false,
+                search: "",
+                url: "/feedback/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: "/feedbackEdit",
+                    query: {
+                    ...this.$route.query
+                    }
+                });
+            },
+            editRow(row) {
+                this.$router.push({
+                    path: "/feedbackEdit",
+                    query: {
+                    id: row.id
+                    }
+                });
+            },
+            download() {
+                this.downloading = true;
+                this.$axios
+                    .get("/feedback/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(`/feedback/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>

+ 42 - 1
src/main/vue/src/views/VoiceEdit.vue

@@ -5,7 +5,7 @@
             <el-form-item prop="content" label="内容">
                 <el-input v-model="formData.content"></el-input>
             </el-form-item>
-            <el-form-item prop="url" label="文件">
+            <el-form-item prop="url" label="中文文件">
                 <el-upload
                         class="avatar-uploader"
                         :action="uploadUrl"
@@ -19,6 +19,34 @@
                 <!--<file-upload v-model="formData.url">
                 </file-upload>-->
             </el-form-item>
+            <el-form-item prop="enUrl" label="英文文件">
+                <el-upload
+                        class="avatar-uploader"
+                        :action="uploadUrl"
+                        :limit="1"
+                        :show-file-list="true"
+                        :on-success="onSuccess2"
+                        v-model="formData.enUrl"
+                        :beforeUpload="beforeAvatarUpload">
+                    <el-button size="small" type="primary">点击上传</el-button>
+                </el-upload>
+                <!--<file-upload v-model="formData.url">
+                </file-upload>-->
+            </el-form-item>
+            <el-form-item prop="thUrl" label="泰文文件">
+                <el-upload
+                        class="avatar-uploader"
+                        :action="uploadUrl"
+                        :limit="1"
+                        :show-file-list="true"
+                        :on-success="onSuccess3"
+                        v-model="formData.thUrl"
+                        :beforeUpload="beforeAvatarUpload">
+                    <el-button size="small" type="primary">点击上传</el-button>
+                </el-upload>
+                <!--<file-upload v-model="formData.url">
+                </file-upload>-->
+            </el-form-item>
             <el-form-item>
                 <el-button @click="onSave" :loading="saving"
                            type="primary">保存
@@ -106,6 +134,19 @@
 
                 this.$message.success('上传成功');
             },
+            onSuccess2(res, file) {
+                this.uploadLoading = false;
+                this.formData.enUrl = res;
+
+                this.$message.success('上传成功');
+            },
+            onSuccess3(res, file) {
+                this.uploadLoading = false;
+                this.formData.thUrl = res
+
+                this.$message.success('上传成功');
+            },
+
             beforeAvatarUpload(file) {
                 this.uploadLoading = true;
                 var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)

+ 17 - 1
src/main/vue/src/views/VoiceList.vue

@@ -26,7 +26,7 @@
             <el-table-column prop="content" label="内容"
             >
             </el-table-column>
-            <el-table-column prop="url" label="文件"
+            <el-table-column prop="url" label="中文文件"
             >
                 <template slot-scope="{row}">
                     <video controls v-if="row.url!=null">
@@ -34,6 +34,22 @@
                     </video>
                 </template>
             </el-table-column>
+            <el-table-column prop="enUrl" label="英文文件"
+            >
+                <template slot-scope="{row}">
+                    <video controls v-if="row.enUrl!=null">
+                        <source :src="row.enUrl" type="audio/mpeg">
+                    </video>
+                </template>
+            </el-table-column>
+            <el-table-column prop="thUrl" label="泰文文件"
+            >
+                <template slot-scope="{row}">
+                    <video controls v-if="row.thUrl!=null">
+                        <source :src="row.thUrl" type="audio/mpeg">
+                    </video>
+                </template>
+            </el-table-column>
             <el-table-column
                     label="操作"
                     align="center"

+ 34 - 13
src/main/vue/src/views/backstage/CooperateApplyList.vue

@@ -12,11 +12,11 @@
             <el-button @click="download" type="primary" icon="el-icon-download"
                        :loading="downloading" class="filter-item">导出EXCEL
             </el-button>
-<!--            <el-checkbox-group v-model="checkTypes">
-                <el-checkbox v-for="item in types" :key="item.value" :label="item.label" :value="item.value"
-                             class="cb" border size="mini" @change="change"
-                ></el-checkbox>
-            </el-checkbox-group>-->
+            <!--            <el-checkbox-group v-model="checkTypes">
+                            <el-checkbox v-for="item in types" :key="item.value" :label="item.label" :value="item.value"
+                                         class="cb" border size="mini" @change="change"
+                            ></el-checkbox>
+                        </el-checkbox-group>-->
             <el-select
                     v-model="checkType"
                     class="filter-item"
@@ -47,7 +47,7 @@
             <el-table-column prop="userId" label="用户ID"
             >
             </el-table-column>
-            <el-table-column prop="type" label="类型"
+            <el-table-column prop="type" label="类型" :formatter="typesFormatter"
             >
             </el-table-column>
             <el-table-column prop="name" label="联系人"
@@ -80,7 +80,8 @@
                     fixed="right"
                     min-width="150">
                 <template slot-scope="{row}">
-                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
+                    <!-- <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>-->
+                    <el-button @click="contactRow(row)" type="primary" size="mini" plain>已联系</el-button>
                     <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
                 </template>
             </el-table-column>
@@ -132,14 +133,21 @@
             }
         },
         methods: {
+            typesFormatter(row, column, cellValue, index) {
+                let selectedOption = this.types.find(i => i.value === cellValue);
+                if (selectedOption) {
+                    return selectedOption.label;
+                }
+                return '';
+            },
             beforeGetData() {
                 if (this.search) {
                     return {search: this.search};
                 }
-                if (this.checkType){
+                if (this.checkType) {
                     return {
                         query: {
-                            type : this.checkType
+                            type: this.checkType
                         }
                     }
                 }
@@ -216,16 +224,29 @@
                     }
                 })
             },
+            contactRow(row) {
+                this.$alert('确认已联系?', '提示').then(() => {
+                    return this.$http.get('/cooperateApply/contact/', {
+                        id: row.id
+                    })
+                }).then(() => {
+                    this.$message.success('确认成功');
+                    this.getData();
+                }).catch(action => {
+                    if (action === 'cancel') {
+                        this.$message.info('取消确认');
+                    } else {
+                        this.$message.error('确认失败');
+                    }
+                })
+            },
 
-            change(){
-                console.log(this.checkTypes)
-            }
         }
     }
 </script>
 <style lang="less" scoped>
 
-    .cb{
+    .cb {
         margin: 2px;
     }
 </style>

+ 16 - 4
src/main/vue/src/views/backstage/OrderRefundApplyEdit.vue

@@ -3,7 +3,7 @@
         <el-form :model="formData" :rules="rules" ref="form" label-width="80px" label-position="right" size="small"
                  style="max-width: 500px;">
             <el-form-item prop="orderId" label="订单ID">
-                <el-input  v-model="formData.orderId"></el-input>
+                <el-input v-model="formData.orderId"></el-input>
             </el-form-item>
             <el-form-item prop="reason" label="理由">
                 <el-select v-model="formData.reason" clearable filterable placeholder="请选择">
@@ -55,6 +55,15 @@
             <el-form-item prop="refundId" label="退款单号">
                 <el-input v-model="formData.refundId"></el-input>
             </el-form-item>
+            <el-form-item prop="merchantLiability" label="商家承担">
+                <el-input v-model="formData.merchantLiability"></el-input>
+            </el-form-item>
+            <el-form-item prop="riderLiability" label="骑手承担">
+                <el-input v-model="formData.riderLiability"></el-input>
+            </el-form-item>
+            <el-form-item prop="platformLiability" label="平台承担">
+                <el-input v-model="formData.platformLiability"></el-input>
+            </el-form-item>
             <el-form-item>
                 <el-button @click="onSave" :loading="saving"
                            type="primary">保存
@@ -86,8 +95,11 @@
         data() {
             return {
                 saving: false,
-                formData: {},
-                rules: {},
+                formData: {
+
+                },
+                rules: {
+                },
                 statusOptions: [
                     {"label": "待处理", "value": "PENDING"},
                     /*{"label": "退款中","value": "REFUNDING"},*/
@@ -116,7 +128,7 @@
 
                 this.saving = true;
                 this.$http
-                    .post('/orderRefundApply/add', data, {body: 'json'})
+                    .post('/orderRefundApply/save', data, {body: 'json'})
                     .then(res => {
                         this.saving = false;
                         this.$message.success('成功');

+ 10 - 0
src/main/vue/src/views/backstage/OrderRefundApplyList.vue

@@ -82,6 +82,15 @@
             <el-table-column prop="refundId" label="退款单号"
             >
             </el-table-column>
+            <el-table-column prop="merchantLiability" label="商家承担"
+            >
+            </el-table-column>
+            <el-table-column prop="riderLiability" label="骑手承担"
+            >
+            </el-table-column>
+            <el-table-column prop="platformLiability" label="平台承担"
+            >
+            </el-table-column>
             <!--            <el-table-column
                                 label="操作"
                                 align="center"
@@ -94,6 +103,7 @@
                         </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
                             v-if="row.status === 'PENDING'"
                             :loading="row.loading"

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

@@ -355,7 +355,7 @@
                     data.search = this.search;
                 }
                 if (this.dateRange && this.dateRange.length > 0) {
-                    data.query.startTime = this.dateRange[0] + ',' + this.dateRange[1];
+                    data.query.establishTime = this.dateRange[0] + ',' + this.dateRange[1];
                 }
 
                 return data;

+ 20 - 0
src/test/java/com/izouma/dingdong/repo/CouponRepoTest.java

@@ -0,0 +1,20 @@
+package com.izouma.dingdong.repo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class CouponRepoTest {
+    @Autowired
+    private CouponRepo couponRepo;
+
+    @Test
+    public void test(){
+        System.out.println(couponRepo.findAllByMerchantIdNullAndEnabledTrue().size());
+    }
+
+}

+ 20 - 0
src/test/java/com/izouma/dingdong/service/CategoryServiceTest.java

@@ -0,0 +1,20 @@
+package com.izouma.dingdong.service;
+
+import com.izouma.dingdong.service.backstage.CategoryService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class CategoryServiceTest {
+    @Autowired
+    private CategoryService categoryService;
+
+    @Test
+    public void test(){
+        System.out.println("---------->"+categoryService.categoryMer(0L).size());
+    }
+}

+ 64 - 5
src/test/java/com/izouma/dingdong/service/MerchantServiceTest.java

@@ -6,6 +6,7 @@ import com.izouma.dingdong.dto.PageQuery;
 import com.izouma.dingdong.repo.backstage.CategoryRepo;
 import com.izouma.dingdong.repo.merchant.MerchantRepo;
 import com.izouma.dingdong.service.merchant.MerchantService;
+import com.izouma.dingdong.service.merchant.MerchantSettingsService;
 import com.izouma.dingdong.web.merchant.MerchantController;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -31,8 +32,11 @@ public class MerchantServiceTest {
     @Autowired
     private CategoryRepo categoryRepo;
 
+    @Autowired
+    private MerchantSettingsService merchantSettingsService;
+
     @Test
-    public void testChange(){
+    public void testChange() {
         MerchantDTO merchantDTO = MerchantDTO.builder()
                 .mid(189L)
                 .automaticOrder(true)
@@ -41,24 +45,79 @@ public class MerchantServiceTest {
     }
 
     @Test
-    public void testAll(){
+    public void testAll() {
         PageQuery pageQuery = new PageQuery();
         pageQuery.setPage(0);
         pageQuery.setSize(50);
         pageQuery.setSearch(null);
         pageQuery.setSort("");
-        Map<String,Object> map = new HashMap<>();
-        map.put("startTime","2020-05-14 13:49:11,2020-5-30 23:59:59");
+        Map<String, Object> map = new HashMap<>();
+        map.put("startTime", "2020-05-14 13:49:11,2020-5-30 23:59:59");
         pageQuery.setQuery(map);
         System.out.println(merchantController.all(pageQuery));
     }
 
     @Test
-    public void saveDTO(){
+    public void saveDTO() {
         MerchantDTO dto = new MerchantDTO();
         dto.setMid(752L);
         Category category = categoryRepo.findById(733L).orElse(null);
         dto.setCategory(Collections.singleton(category));
         System.out.println(merchantController.saveDTO(dto));
     }
+
+    @Test
+    public void testTag() {
+        System.out.println("--------------->" + merchantSettingsService.timeMerchant(145L).size());
+    }
+
+    @Test
+    public void test() {
+        //广告园
+        double lat3 = 118.735194;
+        double lon3 = 31.982256;
+
+        //康润园
+        double lat4 = 118.754795;
+        double lon4 = 31.990671;
+
+        //六合
+        double lat5 = 118.83;
+        double lon5 = 32.36;
+
+
+/*        double mulLat1 = lat5 * Math.PI / 180.0;
+        double mulLat2 = lat3 * Math.PI / 180.0;
+
+        double a = mulLat1 - mulLat2;
+        double b = lon5 * Math.PI / 180.0 - lon3 * Math.PI / 180.0;
+        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+                + Math.cos(mulLat1)
+                * Math.cos(mulLat2)
+                * Math.pow(Math.sin(b / 2), 2)));
+
+        System.out.println(s);
+
+        //6378.137地球半径
+        s = s * 6378.137 * 1000;
+
+        System.out.println(s);
+
+        //向上取整
+        s = Math.round(s);
+
+        System.out.println(s);*/
+
+        double radLat1 = lat3 * Math.PI / 180.0;
+        double radLat2 = lat5 * Math.PI / 180.0;
+        double a = radLat1 - radLat2;
+        double b = lon3 * Math.PI / 180.0 - lon5 * Math.PI / 180.0;
+
+        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
+                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
+        s = s * 6378.137;
+        s = Math.round(s * 1000);
+        System.out.println(s);
+
+    }
 }