Browse Source

Merge branch 'dev' into 特权藏品

licailing 4 years ago
parent
commit
a960539bb1

+ 4 - 0
src/main/java/com/izouma/nineth/annotations/Searchable.java

@@ -1,5 +1,7 @@
 package com.izouma.nineth.annotations;
 package com.izouma.nineth.annotations;
 
 
+import com.izouma.nineth.enums.SearchMode;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.RetentionPolicy;
@@ -9,4 +11,6 @@ import java.lang.annotation.Target;
 @Retention(RetentionPolicy.RUNTIME)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Searchable {
 public @interface Searchable {
     boolean value() default true;
     boolean value() default true;
+
+    SearchMode mode() default SearchMode.CONFIG;
 }
 }

+ 1 - 0
src/main/java/com/izouma/nineth/config/CacheConfig.java

@@ -78,6 +78,7 @@ public class CacheConfig {
 //                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
 //                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
 //        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
 //        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
 //    }
 //    }
+
     @Bean
     @Bean
     public RedisCacheManager userRedisCacheManager(RedisTemplate redisTemplate) {
     public RedisCacheManager userRedisCacheManager(RedisTemplate redisTemplate) {
         Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);
         Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);

+ 2 - 0
src/main/java/com/izouma/nineth/config/EventNames.java

@@ -2,4 +2,6 @@ package com.izouma.nineth.config;
 
 
 public class EventNames {
 public class EventNames {
     public final static String SWITCH_ACCOUNT = "switchAccount";
     public final static String SWITCH_ACCOUNT = "switchAccount";
+
+    public final static String CONFIG_CHANGE = "configChange";
 }
 }

+ 31 - 0
src/main/java/com/izouma/nineth/config/RocketMqConfig.java

@@ -0,0 +1,31 @@
+package com.izouma.nineth.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.apache.rocketmq.spring.support.RocketMQMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.converter.CompositeMessageConverter;
+import org.springframework.messaging.converter.MappingJackson2MessageConverter;
+import org.springframework.messaging.converter.MessageConverter;
+
+import java.util.List;
+
+@Configuration
+public class RocketMqConfig {
+
+    @Bean
+    public RocketMQMessageConverter createRocketMQMessageConverter() {
+        RocketMQMessageConverter converter = new RocketMQMessageConverter();
+        CompositeMessageConverter compositeMessageConverter = (CompositeMessageConverter) converter.getMessageConverter();
+        List<MessageConverter> messageConverterList = compositeMessageConverter.getConverters();
+        for (MessageConverter messageConverter : messageConverterList) {
+            if (messageConverter instanceof MappingJackson2MessageConverter) {
+                MappingJackson2MessageConverter jackson2MessageConverter = (MappingJackson2MessageConverter) messageConverter;
+                ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();
+                objectMapper.registerModules(new JavaTimeModule());
+            }
+        }
+        return converter;
+    }
+}

+ 8 - 2
src/main/java/com/izouma/nineth/domain/Collection.java

@@ -24,11 +24,15 @@ import java.util.List;
 @Data
 @Data
 @Entity
 @Entity
 @Table(name = "collection_info", indexes = {
 @Table(name = "collection_info", indexes = {
-        @Index(columnList = "type,source"),
+        @Index(columnList = "type"),
+        @Index(columnList = "source"),
         @Index(columnList = "minterId"),
         @Index(columnList = "minterId"),
         @Index(columnList = "onShelf"),
         @Index(columnList = "onShelf"),
         @Index(columnList = "ownerId"),
         @Index(columnList = "ownerId"),
-        @Index(columnList = "assetId")
+        @Index(columnList = "assetId"),
+        @Index(columnList = "salable"),
+        @Index(columnList = "del"),
+        @Index(columnList = "name")
 })
 })
 @AllArgsConstructor
 @AllArgsConstructor
 @NoArgsConstructor
 @NoArgsConstructor
@@ -189,4 +193,6 @@ public class Collection extends BaseEntity {
     @ApiModelProperty("开启抢白名单")
     @ApiModelProperty("开启抢白名单")
     private Boolean openQuota;
     private Boolean openQuota;
 
 
+    @ApiModelProperty("最低消费")
+    private BigDecimal minimumCharge;
 }
 }

+ 8 - 2
src/main/java/com/izouma/nineth/domain/User.java

@@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.izouma.nineth.JsonView.UserView;
 import com.izouma.nineth.JsonView.UserView;
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.enums.AuthStatus;
 import com.izouma.nineth.enums.AuthStatus;
+import com.izouma.nineth.enums.SearchMode;
 import com.izouma.nineth.security.Authority;
 import com.izouma.nineth.security.Authority;
 import com.izouma.nineth.utils.UserAuthoritySerializer;
 import com.izouma.nineth.utils.UserAuthoritySerializer;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
@@ -33,7 +34,9 @@ import java.util.Set;
         @Index(columnList = "admin"),
         @Index(columnList = "admin"),
         @Index(columnList = "minter"),
         @Index(columnList = "minter"),
         @Index(columnList = "createdAt"),
         @Index(columnList = "createdAt"),
-        @Index(columnList = "settleAccountId")
+        @Index(columnList = "settleAccountId"),
+        @Index(columnList = "nickname"),
+        @Index(columnList = "del"),
 })
 })
 @AllArgsConstructor
 @AllArgsConstructor
 @NoArgsConstructor
 @NoArgsConstructor
@@ -84,7 +87,7 @@ public class User extends BaseEntityNoID implements Serializable {
 
 
     private String country;
     private String country;
 
 
-    @Searchable
+    @Searchable(mode = SearchMode.EXACT)
     private String phone;
     private String phone;
 
 
     private String email;
     private String email;
@@ -159,4 +162,7 @@ public class User extends BaseEntityNoID implements Serializable {
 
 
     @ApiModelProperty(value = "风险提示")
     @ApiModelProperty(value = "风险提示")
     private Boolean riskWarning;
     private Boolean riskWarning;
+
+    @Column(columnDefinition = "int(11) default 0")
+    private boolean canSale = false;
 }
 }

+ 9 - 0
src/main/java/com/izouma/nineth/enums/SearchMode.java

@@ -0,0 +1,9 @@
+package com.izouma.nineth.enums;
+
+public enum SearchMode {
+    PREFIX,
+    SUFFIX,
+    FULL,
+    EXACT,
+    CONFIG
+}

+ 12 - 0
src/main/java/com/izouma/nineth/listener/BroadcastEventListener.java

@@ -3,7 +3,9 @@ package com.izouma.nineth.listener;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.izouma.nineth.config.EventNames;
 import com.izouma.nineth.config.EventNames;
+import com.izouma.nineth.enums.SearchMode;
 import com.izouma.nineth.service.AdapayMerchantService;
 import com.izouma.nineth.service.AdapayMerchantService;
+import com.izouma.nineth.utils.JpaUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.rocketmq.spring.annotation.ConsumeMode;
 import org.apache.rocketmq.spring.annotation.ConsumeMode;
@@ -37,6 +39,16 @@ public class BroadcastEventListener implements RocketMQListener<JSONObject> {
                         log.error("event error", e);
                         log.error("event error", e);
                     }
                     }
                     break;
                     break;
+                case EventNames.CONFIG_CHANGE:
+                    try {
+                        JSONObject data = message.getJSONObject("data");
+                        if ("default_search_mode".equals(data.getString("name"))) {
+                            SearchMode searchMode = SearchMode.valueOf(data.getString("value"));
+                            JpaUtils.setDefaultSearchMode(searchMode);
+                        }
+                    } catch (Exception e) {
+                        log.error("event error", e);
+                    }
             }
             }
         }
         }
     }
     }

+ 2 - 1
src/main/java/com/izouma/nineth/repo/CollectionRepo.java

@@ -14,6 +14,7 @@ import org.springframework.data.jpa.repository.Query;
 
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nonnull;
 import javax.transaction.Transactional;
 import javax.transaction.Transactional;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
@@ -40,7 +41,7 @@ public interface CollectionRepo extends JpaRepository<Collection, Long>, JpaSpec
                 String properties, String model3d, int maxCount, String countId, boolean scanCode,
                 String properties, String model3d, int maxCount, String countId, boolean scanCode,
                 boolean noSoldOut, int assignment, boolean couponPayment, String shareBg, String registerBg,
                 boolean noSoldOut, int assignment, boolean couponPayment, String shareBg, String registerBg,
                 Integer vipQuota, Boolean timeDelay, LocalDateTime saleTime, Integer holdDays, Boolean openQuota,
                 Integer vipQuota, Boolean timeDelay, LocalDateTime saleTime, Integer holdDays, Boolean openQuota,
-                Integer totalQuota);
+                Integer totalQuota, BigDecimal minimumCharge);
 
 
     @Cacheable("collection")
     @Cacheable("collection")
     Optional<Collection> findById(@Nonnull Long id);
     Optional<Collection> findById(@Nonnull Long id);

+ 1 - 39
src/main/java/com/izouma/nineth/service/CollectionService.java

@@ -156,7 +156,7 @@ public class CollectionService {
                 record.getMaxCount(), record.getCountId(), record.isScanCode(), record.isNoSoldOut(),
                 record.getMaxCount(), record.getCountId(), record.isScanCode(), record.isNoSoldOut(),
                 record.getAssignment(), record.isCouponPayment(), record.getShareBg(), record.getRegisterBg(),
                 record.getAssignment(), record.isCouponPayment(), record.getShareBg(), record.getRegisterBg(),
                 record.getVipQuota(), record.getTimeDelay(), record.getSaleTime(), record.getHoldDays(),
                 record.getVipQuota(), record.getTimeDelay(), record.getSaleTime(), record.getHoldDays(),
-                record.getOpenQuota(), record.getTotalQuota());
+                record.getOpenQuota(), record.getTotalQuota(), record.getMinimumCharge());
 
 
         record = collectionRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
         record = collectionRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
         onShelfTask(record);
         onShelfTask(record);
@@ -542,44 +542,6 @@ public class CollectionService {
         log.info("邀请实名认证人量:{}", collect2.size());
         log.info("邀请实名认证人量:{}", collect2.size());
 //        log.info("sql: update user set vip_point = 1 where id in ({})", longArrayConverter.convertToDatabaseColumn(collect2));
 //        log.info("sql: update user set vip_point = 1 where id in ({})", longArrayConverter.convertToDatabaseColumn(collect2));
 
 
-        //只留库存数量
-//        List<PointDTO> result = dtos.stream()
-//                .sorted(Comparator.comparing(PointDTO::getCreatedAt))
-//                .collect(Collectors.toList());
-//        List<Long> userIds = result.stream().map(PointDTO::getId).collect(Collectors.toList());
-//        Map<Long, User> resultMap = userRepo.findAllById(userIds)
-//                .stream()
-//                .collect(Collectors.toMap(User::getId, user -> user));
-//
-//        List<PointDTO> result2 = new ArrayList<>();
-//        List<PointDTO> result3 = new ArrayList<>();
-//        result.forEach(dto -> {
-//            if (dto.getIdentitySum() > 0) {
-//                result2.add(dto);
-//            } else {
-//                result3.add(dto);
-//            }
-//        });
-//
-//        result2.addAll(result3);
-
-
-        //加积分,存记录
-//        result.forEach(pointDTO -> {
-//            User user = resultMap.get(pointDTO.getId());
-//            if (user.getVipPoint() <= 0) {
-//                user.setVipPoint(1);
-//                userRepo.save(user);
-//                pointRecordRepo.save(PointRecord.builder()
-//                        .collectionId(collectionId)
-//                        .userId(pointDTO.getId())
-//                        .type("VIP_POINT")
-//                        .point(1)
-//                        .build());
-//            }
-//
-//        });
-
         return dtos;
         return dtos;
     }
     }
 }
 }

+ 14 - 1
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -214,6 +214,15 @@ public class OrderService {
                     throw new BusinessException("限购" + collection.getMaxCount() + "件");
                     throw new BusinessException("限购" + collection.getMaxCount() + "件");
                 }
                 }
             }
             }
+            User user = null;
+            if (ObjectUtils.isNotEmpty(collection.getMinimumCharge()) && collection.getMinimumCharge()
+                    .compareTo(BigDecimal.ZERO) > 0) {
+                user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
+                if (!user.isCanSale()) {
+                    throw new BusinessException("绿洲石不足");
+                }
+            }
+
 
 
             //查询是否有拉新任务,只算官方购买
             //查询是否有拉新任务,只算官方购买
             if (collection.getSource() != CollectionSource.TRANSFER && collection.getAssignment() > 0) {
             if (collection.getSource() != CollectionSource.TRANSFER && collection.getAssignment() > 0) {
@@ -223,7 +232,11 @@ public class OrderService {
                         throw new BusinessException("当前还未开售");
                         throw new BusinessException("当前还未开售");
                     }
                     }
                 }
                 }
-                User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
+
+                if (user == null) {
+                    user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
+                }
+
                 if (vip) {
                 if (vip) {
                     int purchase = orderRepo.countByUserIdAndCollectionIdAndVipTrueAndStatusIn(userId, collectionId, Arrays.asList(OrderStatus.FINISH, OrderStatus.NOT_PAID, OrderStatus.PROCESSING));
                     int purchase = orderRepo.countByUserIdAndCollectionIdAndVipTrueAndStatusIn(userId, collectionId, Arrays.asList(OrderStatus.FINISH, OrderStatus.NOT_PAID, OrderStatus.PROCESSING));
                     if (user.getVipPurchase() - purchase <= 0) {
                     if (user.getVipPurchase() - purchase <= 0) {

+ 15 - 4
src/main/java/com/izouma/nineth/service/SysConfigService.java

@@ -2,6 +2,7 @@ package com.izouma.nineth.service;
 
 
 import com.izouma.nineth.domain.SysConfig;
 import com.izouma.nineth.domain.SysConfig;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.SearchMode;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.SysConfigRepo;
 import com.izouma.nineth.repo.SysConfigRepo;
 import com.izouma.nineth.utils.JpaUtils;
 import com.izouma.nineth.utils.JpaUtils;
@@ -49,7 +50,7 @@ public class SysConfigService {
 
 
     @PostConstruct
     @PostConstruct
     public void init() {
     public void init() {
-        if (!sysConfigRepo.findByName("gift_gas_fee").isPresent()) {
+        if (sysConfigRepo.findByName("gift_gas_fee").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
             sysConfigRepo.save(SysConfig.builder()
                     .name("gift_gas_fee")
                     .name("gift_gas_fee")
                     .desc("转赠gas费")
                     .desc("转赠gas费")
@@ -57,7 +58,7 @@ public class SysConfigService {
                     .value("1")
                     .value("1")
                     .build());
                     .build());
         }
         }
-        if (!sysConfigRepo.findByName("enable_wx_pub").isPresent()) {
+        if (sysConfigRepo.findByName("enable_wx_pub").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
             sysConfigRepo.save(SysConfig.builder()
                     .name("enable_wx_pub")
                     .name("enable_wx_pub")
                     .desc("使用公众号支付")
                     .desc("使用公众号支付")
@@ -65,7 +66,7 @@ public class SysConfigService {
                     .value("FALSE")
                     .value("FALSE")
                     .build());
                     .build());
         }
         }
-        if (!sysConfigRepo.findByName("enable_wx_lite").isPresent()) {
+        if (sysConfigRepo.findByName("enable_wx_lite").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
             sysConfigRepo.save(SysConfig.builder()
                     .name("enable_wx_lite")
                     .name("enable_wx_lite")
                     .desc("使用小程序支付")
                     .desc("使用小程序支付")
@@ -73,7 +74,7 @@ public class SysConfigService {
                     .value("FALSE")
                     .value("FALSE")
                     .build());
                     .build());
         }
         }
-        if (!sysConfigRepo.findByName("hold_days").isPresent()) {
+        if (sysConfigRepo.findByName("hold_days").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
             sysConfigRepo.save(SysConfig.builder()
                     .name("hold_days")
                     .name("hold_days")
                     .desc("持有满几天可销售")
                     .desc("持有满几天可销售")
@@ -81,5 +82,15 @@ public class SysConfigService {
                     .value("5")
                     .value("5")
                     .build());
                     .build());
         }
         }
+        if (sysConfigRepo.findByName("default_search_mode").isEmpty()) {
+            sysConfigRepo.save(SysConfig.builder()
+                    .name("default_search_mode")
+                    .desc("默认搜索方式")
+                    .type(SysConfig.ValueType.STRING)
+                    .value("FULL")
+                    .build());
+        }
+        SearchMode searchMode = SearchMode.valueOf(sysConfigRepo.findByName("default_search_mode").get().getValue());
+        JpaUtils.setDefaultSearchMode(searchMode);
     }
     }
 }
 }

+ 29 - 2
src/main/java/com/izouma/nineth/utils/JpaUtils.java

@@ -3,11 +3,13 @@ package com.izouma.nineth.utils;
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.annotations.SearchableOne;
 import com.izouma.nineth.annotations.SearchableOne;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.SearchMode;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Component;
 
 
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.CriteriaQuery;
@@ -23,7 +25,15 @@ import java.util.regex.Pattern;
 
 
 @Slf4j
 @Slf4j
 @SuppressWarnings("ALL")
 @SuppressWarnings("ALL")
+@Component
 public class JpaUtils {
 public class JpaUtils {
+
+    private static SearchMode defaultSearchMode = SearchMode.PREFIX;
+
+    public static void setDefaultSearchMode(SearchMode defaultSearchMode) {
+        JpaUtils.defaultSearchMode = defaultSearchMode;
+    }
+
     public static PageRequest toPageRequest(PageQuery pageQuery) {
     public static PageRequest toPageRequest(PageQuery pageQuery) {
         PageRequest pageRequest;
         PageRequest pageRequest;
         if (StringUtils.isNotEmpty(pageQuery.getSort())) {
         if (StringUtils.isNotEmpty(pageQuery.getSort())) {
@@ -145,7 +155,7 @@ public class JpaUtils {
             } else if (String.class == fieldType) {
             } else if (String.class == fieldType) {
                 SearchableOne annotation = field.getAnnotation(SearchableOne.class);
                 SearchableOne annotation = field.getAnnotation(SearchableOne.class);
                 if (annotation != null && annotation.value()) {
                 if (annotation != null && annotation.value()) {
-                    and.add(criteriaBuilder.like(root.get(field.getName()), "%" + value + "%"));
+                    and.add(criteriaBuilder.like(root.get(field.getName()), value + "%"));
                 } else {
                 } else {
                     and.add(criteriaBuilder.and(criteriaBuilder.equal(root.get(property), value)));
                     and.add(criteriaBuilder.and(criteriaBuilder.equal(root.get(property), value)));
                 }
                 }
@@ -171,8 +181,25 @@ public class JpaUtils {
                     continue;
                     continue;
                 }
                 }
 
 
+                SearchMode searchMode = annotation.mode();
+                if (searchMode == SearchMode.CONFIG) {
+                    searchMode = defaultSearchMode;
+                }
                 if (field.getType() == String.class) {
                 if (field.getType() == String.class) {
-                    or.add(criteriaBuilder.like(root.get(field.getName()), "%" + pageQuery.getSearch() + "%"));
+                    switch (searchMode) {
+                        case PREFIX:
+                            or.add(criteriaBuilder.like(root.get(field.getName()), pageQuery.getSearch() + "%"));
+                            break;
+                        case SUFFIX:
+                            or.add(criteriaBuilder.like(root.get(field.getName()), "%" + pageQuery.getSearch()));
+                            break;
+                        case FULL:
+                            or.add(criteriaBuilder.like(root.get(field.getName()), "%" + pageQuery.getSearch() + "%"));
+                            break;
+                        case EXACT:
+                            or.add(criteriaBuilder.equal(root.get(field.getName()), pageQuery.getSearch()));
+                            break;
+                    }
                 } else if (field.getType() == Long.class || field.getType() == long.class) {
                 } else if (field.getType() == Long.class || field.getType() == long.class) {
                     try {
                     try {
                         or.add(criteriaBuilder.equal(root.get(field.getName()), Long.parseLong(pageQuery.getSearch())));
                         or.add(criteriaBuilder.equal(root.get(field.getName()), Long.parseLong(pageQuery.getSearch())));

+ 2 - 0
src/main/java/com/izouma/nineth/web/RecommendController.java

@@ -9,6 +9,7 @@ import com.izouma.nineth.service.RecommendService;
 import com.izouma.nineth.utils.ObjUtils;
 import com.izouma.nineth.utils.ObjUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
@@ -51,6 +52,7 @@ public class RecommendController extends BaseController {
         return recommendRepo.findById(id).orElseThrow(new BusinessException("无记录"));
         return recommendRepo.findById(id).orElseThrow(new BusinessException("无记录"));
     }
     }
 
 
+    @CacheEvict(value = "recommend", key = "#id")
     @PostMapping("/del/{id}")
     @PostMapping("/del/{id}")
     public void del(@PathVariable Long id) {
     public void del(@PathVariable Long id) {
         recommendRepo.deleteById(id);
         recommendRepo.deleteById(id);

+ 19 - 3
src/main/java/com/izouma/nineth/web/SysConfigController.java

@@ -1,5 +1,8 @@
 package com.izouma.nineth.web;
 package com.izouma.nineth.web;
 
 
+import com.alibaba.fastjson.JSONObject;
+import com.izouma.nineth.config.EventNames;
+import com.izouma.nineth.config.GeneralProperties;
 import com.izouma.nineth.domain.SysConfig;
 import com.izouma.nineth.domain.SysConfig;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.exception.BusinessException;
@@ -7,6 +10,7 @@ import com.izouma.nineth.repo.SysConfigRepo;
 import com.izouma.nineth.service.SysConfigService;
 import com.izouma.nineth.service.SysConfigService;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -21,14 +25,26 @@ import java.util.List;
 @RequestMapping("/sysConfig")
 @RequestMapping("/sysConfig")
 @AllArgsConstructor
 @AllArgsConstructor
 public class SysConfigController extends BaseController {
 public class SysConfigController extends BaseController {
-    private SysConfigService sysConfigService;
-    private SysConfigRepo    sysConfigRepo;
+    private SysConfigService  sysConfigService;
+    private SysConfigRepo     sysConfigRepo;
+    private RocketMQTemplate  rocketMQTemplate;
+    private GeneralProperties generalProperties;
 
 
     @PreAuthorize("hasRole('ADMIN')")
     @PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     @PostMapping("/save")
     @CacheEvict(value = {"SysConfigServiceGetBigDecimal", "SysConfigServiceGetTime", "SysConfigServiceGetBoolean", "SysConfigServiceGetInt"}, allEntries = true)
     @CacheEvict(value = {"SysConfigServiceGetBigDecimal", "SysConfigServiceGetTime", "SysConfigServiceGetBoolean", "SysConfigServiceGetInt"}, allEntries = true)
     public SysConfig save(@RequestBody SysConfig record) {
     public SysConfig save(@RequestBody SysConfig record) {
-        return sysConfigRepo.save(record);
+        record = sysConfigRepo.save(record);
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("name", EventNames.CONFIG_CHANGE);
+        JSONObject data = new JSONObject();
+        data.put("name", record.getName());
+        data.put("value", record.getValue());
+        jsonObject.put("data", data);
+        rocketMQTemplate.convertAndSend(generalProperties.getBroadcastEventTopic(), jsonObject);
+
+        return record;
     }
     }
 
 
 
 

+ 3 - 1
src/main/vue/src/views/BannerEdit.vue

@@ -54,6 +54,7 @@
                     </el-form-item>
                     </el-form-item>
                     <el-form-item prop="linkContent" label="跳转内容" v-if="formData.link">
                     <el-form-item prop="linkContent" label="跳转内容" v-if="formData.link">
                         <el-input v-if="formData.linkType === 'collections'" v-model="formData.linkContent" placeholder="输入藏品名称"></el-input>
                         <el-input v-if="formData.linkType === 'collections'" v-model="formData.linkContent" placeholder="输入藏品名称"></el-input>
+                        <el-input v-else-if="formData.linkType === 'hyperlink'" v-model="formData.linkContent" placeholder="输入链接"></el-input>
                         <el-input v-else v-model="formData.linkContent" placeholder="输入ID"></el-input>
                         <el-input v-else v-model="formData.linkContent" placeholder="输入ID"></el-input>
                     </el-form-item>
                     </el-form-item>
                     <el-form-item class="form-submit">
                     <el-form-item class="form-submit">
@@ -141,7 +142,8 @@ export default {
                 { label: '藏品/盲盒', value: 'collection' },
                 { label: '藏品/盲盒', value: 'collection' },
                 { label: '铸造者', value: 'user' },
                 { label: '铸造者', value: 'user' },
                 { label: '活动', value: 'activity' },
                 { label: '活动', value: 'activity' },
-                { label: '多个藏品', value: 'collections' }
+                { label: '多个藏品', value: 'collections' },
+                { label: '指定链接', value: 'hyperlink' }
             ]
             ]
         };
         };
     },
     },

+ 2 - 1
src/main/vue/src/views/BannerList.vue

@@ -120,7 +120,8 @@ export default {
                 { label: '藏品/盲盒', value: 'collection' },
                 { label: '藏品/盲盒', value: 'collection' },
                 { label: '铸造者', value: 'user' },
                 { label: '铸造者', value: 'user' },
                 { label: '活动', value: 'activity' },
                 { label: '活动', value: 'activity' },
-                { label: '多个藏品', value: 'collections' }
+                { label: '多个藏品', value: 'collections' },
+                { label: '指定链接', value: 'hyperlink' }
             ]
             ]
         };
         };
     },
     },

+ 14 - 1
src/main/vue/src/views/BlindBoxEdit.vue

@@ -191,9 +191,22 @@
                     </el-form-item>
                     </el-form-item>
 
 
                     <el-form-item prop="holdDays" label="持有天数">
                     <el-form-item prop="holdDays" label="持有天数">
-                        <el-input-number type="number" :min="0" :step="1" :max="2147483647" v-model="formData.holdDays" style="width: 180px"></el-input-number>
+                        <el-input-number
+                            type="number"
+                            :min="0"
+                            :step="1"
+                            :max="2147483647"
+                            v-model="formData.holdDays"
+                            style="width: 180px"
+                        ></el-input-number>
                         <div class="tip">持有多少天可转赠/转让。为空时,按系统设置天数</div>
                         <div class="tip">持有多少天可转赠/转让。为空时,按系统设置天数</div>
                     </el-form-item>
                     </el-form-item>
+
+                    <el-form-item prop="minimumCharge" label="最低消费">
+                        <el-input-number type="number" :min="0" v-model="formData.minimumCharge" style="width: 180px">
+                        </el-input-number>
+                    </el-form-item>
+
                     <el-form-item prop="noSoldOut" label="售罄">
                     <el-form-item prop="noSoldOut" label="售罄">
                         <el-radio v-model="formData.noSoldOut" :label="false">是</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="false">是</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="true">否</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="true">否</el-radio>

+ 9 - 3
src/main/vue/src/views/CollectionEdit.vue

@@ -238,6 +238,12 @@
                         ></el-input-number>
                         ></el-input-number>
                         <div class="tip">持有多少天可转赠/转让。为空时,按系统设置天数。</div>
                         <div class="tip">持有多少天可转赠/转让。为空时,按系统设置天数。</div>
                     </el-form-item>
                     </el-form-item>
+
+                    <el-form-item prop="minimumCharge" label="最低消费">
+                        <el-input-number type="number" :min="0" v-model="formData.minimumCharge" style="width: 180px">
+                        </el-input-number>
+                    </el-form-item>
+
                     <el-form-item prop="noSoldOut" label="售罄">
                     <el-form-item prop="noSoldOut" label="售罄">
                         <el-radio v-model="formData.noSoldOut" :label="false">是</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="false">是</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="true">否</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="true">否</el-radio>
@@ -248,13 +254,13 @@
                             <el-radio :label="false">支付宝/微信</el-radio>
                             <el-radio :label="false">支付宝/微信</el-radio>
                         </el-radio-group>
                         </el-radio-group>
                     </el-form-item>
                     </el-form-item>
-                    
-                    <el-form-item prop="vip" label="享有特权">
+
+                    <!-- <el-form-item prop="vip" label="享有特权">
                         <el-radio-group v-model="formData.vip">
                         <el-radio-group v-model="formData.vip">
                             <el-radio :label="true">白名单权利</el-radio>
                             <el-radio :label="true">白名单权利</el-radio>
                             <el-radio :label="false">无特权</el-radio>
                             <el-radio :label="false">无特权</el-radio>
                         </el-radio-group>
                         </el-radio-group>
-                    </el-form-item>
+                    </el-form-item> -->
 
 
                     <div class="inline-wrapper">
                     <div class="inline-wrapper">
                         <el-form-item prop="assignment" label="拉新任务指标">
                         <el-form-item prop="assignment" label="拉新任务指标">