Browse Source

Merge branch 'master' of http://git.izouma.com/xiongzhu/9th

panhui 4 years ago
parent
commit
c810f6b6a8
31 changed files with 446 additions and 180 deletions
  1. 5 0
      pom.xml
  2. 6 7
      src/main/java/com/izouma/nineth/config/CacheConfig.java
  3. 5 15
      src/main/java/com/izouma/nineth/domain/UserToken.java
  4. 10 0
      src/main/java/com/izouma/nineth/dto/UserDTO.java
  5. 10 0
      src/main/java/com/izouma/nineth/repo/CollectionRepo.java
  6. 1 1
      src/main/java/com/izouma/nineth/repo/UserRepo.java
  7. 4 6
      src/main/java/com/izouma/nineth/repo/UserTokenRepo.java
  8. 3 13
      src/main/java/com/izouma/nineth/security/Authority.java
  9. 1 3
      src/main/java/com/izouma/nineth/security/JwtAuthorizationTokenFilter.java
  10. 3 3
      src/main/java/com/izouma/nineth/security/JwtTokenUtil.java
  11. 2 3
      src/main/java/com/izouma/nineth/security/JwtUserDetailsService.java
  12. 16 4
      src/main/java/com/izouma/nineth/service/UserService.java
  13. BIN
      src/main/pc-space/src/assets/img/icon-Twitter@3x.png
  14. BIN
      src/main/pc-space/src/assets/img/icon-qq@3x.png
  15. BIN
      src/main/pc-space/src/assets/img/icon-weibo@3x.png
  16. BIN
      src/main/pc-space/src/assets/img/icon-weixin@3x.png
  17. BIN
      src/main/pc-space/src/assets/img/icon-yuyue@3x.png
  18. BIN
      src/main/pc-space/src/assets/img/icon_guanyuwomen@3x.png
  19. BIN
      src/main/pc-space/src/assets/img/icon_lianxiwomen@3x.png
  20. BIN
      src/main/pc-space/src/assets/img/icon_shangwuhezuo@3x.png
  21. BIN
      src/main/pc-space/src/assets/img/icon_yincangtiaokuan@3x.png
  22. 6 1
      src/main/pc-space/src/components/PageHeader.vue
  23. 52 0
      src/main/pc-space/src/components/SearchInfo.vue
  24. 41 30
      src/main/pc-space/src/components/goodsInfo.vue
  25. 16 0
      src/main/pc-space/src/router/index.js
  26. 35 0
      src/main/pc-space/src/views/Blindsbox.vue
  27. 105 0
      src/main/pc-space/src/views/Collection.vue
  28. 96 82
      src/main/pc-space/src/views/Home.vue
  29. 11 12
      src/main/pc-space/src/views/Index.vue
  30. 1 0
      src/main/resources/application.yaml
  31. 17 0
      src/test/java/com/izouma/nineth/service/UserServiceTest.java

+ 5 - 0
pom.xml

@@ -369,6 +369,11 @@
             <groupId>com.fasterxml.jackson.datatype</groupId>
             <groupId>com.fasterxml.jackson.datatype</groupId>
             <artifactId>jackson-datatype-hibernate4</artifactId>
             <artifactId>jackson-datatype-hibernate4</artifactId>
         </dependency>
         </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+        </dependency>
     </dependencies>
     </dependencies>
 
 
 </project>
 </project>

+ 6 - 7
src/main/java/com/izouma/nineth/config/CacheConfig.java

@@ -4,14 +4,12 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import com.fasterxml.jackson.annotation.PropertyAccessor;
 import com.fasterxml.jackson.annotation.PropertyAccessor;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.jsontype.DefaultBaseTypeLimitingValidator;
-import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
+import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
 import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
-import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module;
 import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
 import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
 import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
-import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
@@ -21,12 +19,10 @@ import org.springframework.data.redis.cache.RedisCacheWriter;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
 import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
-import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
 import org.springframework.data.redis.serializer.RedisSerializationContext;
 import org.springframework.data.redis.serializer.RedisSerializationContext;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 
 
-import java.time.Duration;
 
 
 @Configuration
 @Configuration
 @AutoConfigureAfter({RedisAutoConfiguration.class, CacheAutoConfiguration.class})
 @AutoConfigureAfter({RedisAutoConfiguration.class, CacheAutoConfiguration.class})
@@ -47,7 +43,10 @@ public class CacheConfig {
         mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
         mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                 ObjectMapper.DefaultTyping.NON_FINAL,
                 ObjectMapper.DefaultTyping.NON_FINAL,
                 JsonTypeInfo.As.WRAPPER_ARRAY);
                 JsonTypeInfo.As.WRAPPER_ARRAY);
-        mapper.registerModule(new Hibernate5Module());
+        mapper.registerModule(new Hibernate5Module()
+                .enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING));
+        mapper.registerModule(new JavaTimeModule());
+        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
         serializer.setObjectMapper(mapper);
         serializer.setObjectMapper(mapper);
 
 
         template.setValueSerializer(serializer);
         template.setValueSerializer(serializer);

+ 5 - 15
src/main/java/com/izouma/nineth/domain/UserToken.java

@@ -1,30 +1,20 @@
 package com.izouma.nineth.domain;
 package com.izouma.nineth.domain;
 
 
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
-import lombok.Builder;
 import lombok.Data;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.redis.core.RedisHash;
 
 
-import javax.persistence.*;
 
 
 @Data
 @Data
-@Entity
 @AllArgsConstructor
 @AllArgsConstructor
 @NoArgsConstructor
 @NoArgsConstructor
-@Builder
-@Table(indexes = {@Index(columnList = "userId")})
-public class UserToken extends BaseEntity {
+@RedisHash("UserToken")
+public class UserToken {
 
 
     @Id
     @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private Long id;
-
-    private Long userId;
+    private String username;
 
 
     private String token;
     private String token;
-
-    public UserToken(Long userId, String token) {
-        this.userId = userId;
-        this.token = token;
-    }
 }
 }

+ 10 - 0
src/main/java/com/izouma/nineth/dto/UserDTO.java

@@ -7,6 +7,16 @@ import lombok.Data;
 @Data
 @Data
 public class UserDTO extends User {
 public class UserDTO extends User {
 
 
+    private String password;
+
+    private String nftAccount;
+
+    private String kmsId;
+
+    private String publicKey;
+
+    private String tradeCode;
+
     @ApiModelProperty("是否关注")
     @ApiModelProperty("是否关注")
     private boolean follow;
     private boolean follow;
 
 

+ 10 - 0
src/main/java/com/izouma/nineth/repo/CollectionRepo.java

@@ -1,11 +1,14 @@
 package com.izouma.nineth.repo;
 package com.izouma.nineth.repo;
 
 
 import com.izouma.nineth.domain.Collection;
 import com.izouma.nineth.domain.Collection;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.jpa.repository.Query;
 
 
+import javax.annotation.Nonnull;
 import javax.transaction.Transactional;
 import javax.transaction.Transactional;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
@@ -17,6 +20,9 @@ public interface CollectionRepo extends JpaRepository<Collection, Long>, JpaSpec
     @Transactional
     @Transactional
     void softDelete(Long id);
     void softDelete(Long id);
 
 
+    @Cacheable("collection")
+    Optional<Collection> findById(Long id);
+
     Optional<Collection> findByIdAndDelFalse(Long id);
     Optional<Collection> findByIdAndDelFalse(Long id);
 
 
     @Query("update Collection t set t.likes = t.likes + ?2 where t.id = ?1")
     @Query("update Collection t set t.likes = t.likes + ?2 where t.id = ?1")
@@ -29,4 +35,8 @@ public interface CollectionRepo extends JpaRepository<Collection, Long>, JpaSpec
     List<Collection> userLikes(Long userId);
     List<Collection> userLikes(Long userId);
 
 
     List<Collection> findByScheduleSaleTrueAndOnShelfFalseAndStartTimeBeforeAndDelFalse(LocalDateTime time);
     List<Collection> findByScheduleSaleTrueAndOnShelfFalseAndStartTimeBeforeAndDelFalse(LocalDateTime time);
+
+    @Nonnull
+    @CachePut(value = "collection", key = "#collection.id")
+    Collection save(@Nonnull Collection collection);
 }
 }

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

@@ -18,7 +18,7 @@ public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExe
     @Query("update User u set u.del = true where u.id = ?1")
     @Query("update User u set u.del = true where u.id = ?1")
     void softDelete(Long id);
     void softDelete(Long id);
 
 
-    Optional<User> findByUsernameAndDelFalse(String username);
+    User findByUsernameAndDelFalse(String username);
 
 
     List<User> findAllByAuthoritiesContainsAndDelFalse(Authority authority);
     List<User> findAllByAuthoritiesContainsAndDelFalse(Authority authority);
 
 

+ 4 - 6
src/main/java/com/izouma/nineth/repo/UserTokenRepo.java

@@ -3,14 +3,12 @@ package com.izouma.nineth.repo;
 import com.izouma.nineth.domain.UserToken;
 import com.izouma.nineth.domain.UserToken;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
 
 
 import javax.transaction.Transactional;
 import javax.transaction.Transactional;
 import java.util.Optional;
 import java.util.Optional;
 
 
-public interface UserTokenRepo extends JpaRepository<UserToken, Long> {
-    @Modifying
-    @Transactional
-    int deleteByUserId(Long userId);
-
-    Optional<UserToken> findFirstByToken(String token);
+@Repository
+public interface UserTokenRepo extends CrudRepository<UserToken, String> {
 }
 }

+ 3 - 13
src/main/java/com/izouma/nineth/security/Authority.java

@@ -1,6 +1,7 @@
 package com.izouma.nineth.security;
 package com.izouma.nineth.security;
 
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.izouma.nineth.enums.AuthorityName;
 import com.izouma.nineth.enums.AuthorityName;
 import lombok.*;
 import lombok.*;
 
 
@@ -15,8 +16,9 @@ import java.util.Objects;
 @NoArgsConstructor
 @NoArgsConstructor
 @AllArgsConstructor
 @AllArgsConstructor
 @Builder
 @Builder
-@JsonIgnoreProperties(ignoreUnknown = true)
 @EqualsAndHashCode
 @EqualsAndHashCode
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(value = {"hibernateLazyInitializer"}, ignoreUnknown = true)
 public class Authority implements Serializable {
 public class Authority implements Serializable {
 
 
     public static Authority get(AuthorityName name) {
     public static Authority get(AuthorityName name) {
@@ -47,16 +49,4 @@ public class Authority implements Serializable {
 
 
         return Objects.equals(name, authority.name);
         return Objects.equals(name, authority.name);
     }
     }
-
-    @Override
-    public int hashCode() {
-        return name != null ? name.hashCode() : 0;
-    }
-
-    @Override
-    public String toString() {
-        return "Authority{" +
-                "name='" + name + '\'' +
-                "}";
-    }
 }
 }

+ 1 - 3
src/main/java/com/izouma/nineth/security/JwtAuthorizationTokenFilter.java

@@ -27,13 +27,11 @@ public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
     private final UserDetailsService userDetailsService;
     private final UserDetailsService userDetailsService;
     private final JwtTokenUtil       jwtTokenUtil;
     private final JwtTokenUtil       jwtTokenUtil;
     private final String             tokenHeader;
     private final String             tokenHeader;
-    private final UserTokenRepo      userTokenRepo;
 
 
-    public JwtAuthorizationTokenFilter(@Qualifier("jwtUserDetailsService") UserDetailsService userDetailsService, JwtTokenUtil jwtTokenUtil, @Value("${jwt.header}") String tokenHeader, UserTokenRepo userTokenRepo) {
+    public JwtAuthorizationTokenFilter(@Qualifier("jwtUserDetailsService") UserDetailsService userDetailsService, JwtTokenUtil jwtTokenUtil, @Value("${jwt.header}") String tokenHeader) {
         this.userDetailsService = userDetailsService;
         this.userDetailsService = userDetailsService;
         this.jwtTokenUtil = jwtTokenUtil;
         this.jwtTokenUtil = jwtTokenUtil;
         this.tokenHeader = tokenHeader;
         this.tokenHeader = tokenHeader;
-        this.userTokenRepo = userTokenRepo;
     }
     }
 
 
     @Override
     @Override

+ 3 - 3
src/main/java/com/izouma/nineth/security/JwtTokenUtil.java

@@ -62,7 +62,7 @@ public class JwtTokenUtil implements Serializable {
 
 
     private Boolean isTokenExpired(String token) {
     private Boolean isTokenExpired(String token) {
         final Date expiration = getExpirationDateFromToken(token);
         final Date expiration = getExpirationDateFromToken(token);
-        return expiration.before(clock.now()) || !userTokenRepo.findFirstByToken(token).isPresent();
+        return expiration.before(clock.now()) || !userTokenRepo.findById(getUsernameFromToken(token)).isPresent();
     }
     }
 
 
     private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
     private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
@@ -78,8 +78,8 @@ public class JwtTokenUtil implements Serializable {
         JwtUser jwtUser = (JwtUser) userDetails;
         JwtUser jwtUser = (JwtUser) userDetails;
         Map<String, Object> claims = new HashMap<>();
         Map<String, Object> claims = new HashMap<>();
         String token = doGenerateToken(claims, userDetails.getUsername());
         String token = doGenerateToken(claims, userDetails.getUsername());
-        userTokenRepo.deleteByUserId(jwtUser.getUser().getId());
-        userTokenRepo.save(new UserToken(jwtUser.getUser().getId(), token));
+        userTokenRepo.deleteById(jwtUser.getUser().getUsername());
+        userTokenRepo.save(new UserToken(jwtUser.getUser().getUsername(), token));
         return token;
         return token;
     }
     }
 
 

+ 2 - 3
src/main/java/com/izouma/nineth/security/JwtUserDetailsService.java

@@ -1,7 +1,6 @@
 package com.izouma.nineth.security;
 package com.izouma.nineth.security;
 
 
-import com.izouma.nineth.domain.User;
-import com.izouma.nineth.repo.UserRepo;
+import com.izouma.nineth.dto.UserDTO;
 import com.izouma.nineth.service.UserService;
 import com.izouma.nineth.service.UserService;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -16,7 +15,7 @@ public class JwtUserDetailsService implements UserDetailsService {
 
 
     @Override
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-        User user = userService.findByUsernameAndDelFalse(username).orElse(null);
+        UserDTO user = userService.findByUsernameAndDelFalse(username);
 
 
         if (user == null) {
         if (user == null) {
             throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
             throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));

+ 16 - 4
src/main/java/com/izouma/nineth/service/UserService.java

@@ -61,7 +61,7 @@ public class UserService {
     private FollowService  followService;
     private FollowService  followService;
     private FollowRepo     followRepo;
     private FollowRepo     followRepo;
 
 
-    //    @CacheEvict(value = "user", key = "#user.username")
+    @CacheEvict(value = "user", key = "#user.username")
     public User update(User user) {
     public User update(User user) {
         User orig = userRepo.findById(user.getId()).orElseThrow(new BusinessException("无记录"));
         User orig = userRepo.findById(user.getId()).orElseThrow(new BusinessException("无记录"));
         ObjUtils.merge(orig, user);
         ObjUtils.merge(orig, user);
@@ -73,9 +73,18 @@ public class UserService {
         return orig;
         return orig;
     }
     }
 
 
-    //    @Cacheable("user")
-    public Optional<User> findByUsernameAndDelFalse(String username) {
-        return userRepo.findByUsernameAndDelFalse(username);
+    @Cacheable("user")
+    public UserDTO findByUsernameAndDelFalse(String username) {
+        User user = userRepo.findByUsernameAndDelFalse(username);
+        if (user != null) {
+            UserDTO dto = new UserDTO();
+            BeanUtils.copyProperties(user, dto);
+            if (user.getAuthorities() != null) {
+                dto.setAuthorities(new HashSet<>(user.getAuthorities()));
+            }
+            return dto;
+        }
+        return null;
     }
     }
 
 
     public Page<User> all(PageQuery pageQuery) {
     public Page<User> all(PageQuery pageQuery) {
@@ -308,6 +317,9 @@ public class UserService {
     public UserDTO toDTO(User user, boolean join) {
     public UserDTO toDTO(User user, boolean join) {
         UserDTO userDTO = new UserDTO();
         UserDTO userDTO = new UserDTO();
         BeanUtils.copyProperties(user, userDTO);
         BeanUtils.copyProperties(user, userDTO);
+        if (user.getAuthorities() != null) {
+            userDTO.setAuthorities(new HashSet<>(user.getAuthorities()));
+        }
         if (join) {
         if (join) {
             if (SecurityUtils.getAuthenticatedUser() != null) {
             if (SecurityUtils.getAuthenticatedUser() != null) {
                 userDTO.setFollow(followService.isFollow(SecurityUtils.getAuthenticatedUser().getId(), user.getId()));
                 userDTO.setFollow(followService.isFollow(SecurityUtils.getAuthenticatedUser().getId(), user.getId()));

BIN
src/main/pc-space/src/assets/img/icon-Twitter@3x.png


BIN
src/main/pc-space/src/assets/img/icon-qq@3x.png


BIN
src/main/pc-space/src/assets/img/icon-weibo@3x.png


BIN
src/main/pc-space/src/assets/img/icon-weixin@3x.png


BIN
src/main/pc-space/src/assets/img/icon-yuyue@3x.png


BIN
src/main/pc-space/src/assets/img/icon_guanyuwomen@3x.png


BIN
src/main/pc-space/src/assets/img/icon_lianxiwomen@3x.png


BIN
src/main/pc-space/src/assets/img/icon_shangwuhezuo@3x.png


BIN
src/main/pc-space/src/assets/img/icon_yincangtiaokuan@3x.png


+ 6 - 1
src/main/pc-space/src/components/PageHeader.vue

@@ -34,6 +34,10 @@ export default {
             this.active = item;
             this.active = item;
             if (item === '铸造者') {
             if (item === '铸造者') {
                 this.$router.push('/casting');
                 this.$router.push('/casting');
+            } else if (item === '收藏探索') {
+                this.$router.push('/collection');
+            } else if (item === '数字盲盒') {
+                this.$router.push('/blindbox?flag=' + 1);
             }
             }
         }
         }
     }
     }
@@ -46,10 +50,11 @@ export default {
     .header {
     .header {
         display: flex;
         display: flex;
         align-items: center;
         align-items: center;
+        justify-content: space-between;
         .logo {
         .logo {
             width: 170px;
             width: 170px;
             height: 60px;
             height: 60px;
-            padding: 15px 538px 15px 30px;
+            padding: 15px 0px 15px 30px;
         }
         }
         .content {
         .content {
             display: flex;
             display: flex;

+ 52 - 0
src/main/pc-space/src/components/SearchInfo.vue

@@ -0,0 +1,52 @@
+<template>
+    <div class="search">
+        <el-input prefix-icon="el-icon-zoom-out" placeholder="请输入内容" v-model="input" clearable> </el-input>
+        <el-dropdown @command="onCommand">
+            <el-button type="primary"> 综合排序<i class="el-icon-arrow-down el-icon--right"></i> </el-button>
+            <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item>黄金糕</el-dropdown-item>
+                <el-dropdown-item>狮子头</el-dropdown-item>
+                <el-dropdown-item>螺蛳粉</el-dropdown-item>
+            </el-dropdown-menu>
+        </el-dropdown>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            input: ''
+        };
+    },
+    methods: {
+        onCommand(command) {}
+    }
+};
+</script>
+<style lang="less" scoped>
+.search {
+    height: 124px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    /deep/ .el-input__inner {
+        background: #0f1111;
+        width: 280px;
+        height: 42px;
+        color: #fff;
+        border-radius: 8px;
+        border: 1px solid #898989;
+    }
+    /deep/ .el-button {
+        background: #0f1111;
+        width: 120px;
+        height: 42px;
+        color: #fff;
+        border-radius: 8px;
+        border: 1px solid #898989;
+    }
+    /deep/ .el-dropdown-menu {
+        background: #fff;
+    }
+}
+</style>

+ 41 - 30
src/main/pc-space/src/components/goodsInfo.vue

@@ -7,6 +7,10 @@
                 <div class="price">
                 <div class="price">
                     <img class="img1" src="../assets/img/icon_jiage@3x.png" alt="" />
                     <img class="img1" src="../assets/img/icon_jiage@3x.png" alt="" />
                     <div class="num">{{ item.price }}</div>
                     <div class="num">{{ item.price }}</div>
+                    <div class="time" v-if="flagId == 1">
+                        <div class="time1">抢购倒计时</div>
+                        <div class="time2">1天 01:35:06</div>
+                    </div>
                 </div>
                 </div>
                 <div class="border"></div>
                 <div class="border"></div>
                 <div class="fans">
                 <div class="fans">
@@ -15,25 +19,24 @@
                             <img class="text2" src="../assets/img/888.jpg" alt="" />
                             <img class="text2" src="../assets/img/888.jpg" alt="" />
                             <div class="text3">铸造者</div>
                             <div class="text3">铸造者</div>
                         </div>
                         </div>
-                        <div class="text1">
+                        <div class="text1" v-if="flagId !== '1'">
                             <img class="text2" src="../assets/img/888.jpg" alt="" />
                             <img class="text2" src="../assets/img/888.jpg" alt="" />
                             <div class="text3">持有者</div>
                             <div class="text3">持有者</div>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="text">
                     <div class="text">
-                        <div class="text1">
+                        <div class="text1" v-if="flagId !== '1'">
                             <img class="text2 text4" src="../assets/img/icon-dianzan@3x.png" alt="" />
                             <img class="text2 text4" src="../assets/img/icon-dianzan@3x.png" alt="" />
                             <div class="text3">16</div>
                             <div class="text3">16</div>
                         </div>
                         </div>
+                        <div class="text1" v-else>
+                            <img class="text2 text4" src="../assets/img/icon-yuyue@3x.png" alt="" />
+                            <div class="text3">预约</div>
+                        </div>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        <div class="all">
-            <img class="img1" src="../assets/img/icon_inter@3x.png" alt="" />
-            <div class="name">查看更多</div>
-            <img class="img1" src="../assets/img/icon_inter@3x (3).png" alt="" />
-        </div>
     </div>
     </div>
 </template>
 </template>
 <script>
 <script>
@@ -47,23 +50,29 @@ export default {
                 { name: '游戏《百分之一》精美皮肤-恶…', price: '320' }
                 { name: '游戏《百分之一》精美皮肤-恶…', price: '320' }
             ]
             ]
         };
         };
-    }
+    },
+    computed: {
+        flagId() {
+            return this.$route.query.flag;
+        }
+    },
+    mounted() {
+        console.log(this.$route.query.flag);
+    },
+    methods: {}
 };
 };
 </script>
 </script>
 <style lang="less" scoped>
 <style lang="less" scoped>
 .box {
 .box {
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
-    justify-content: center;
-    padding-left: 10px;
+    justify-content: space-between;
     .content {
     .content {
         width: 276px;
         width: 276px;
         height: 416px;
         height: 416px;
         background: #1c1e26;
         background: #1c1e26;
-        margin-bottom: 32px;
-
+        margin-bottom: 40px;
         border: 1px solid;
         border: 1px solid;
-        margin-right: 32px;
         border-image: linear-gradient(135deg, rgba(0, 255, 203, 1), rgba(0, 110, 255, 1)) 1 1;
         border-image: linear-gradient(135deg, rgba(0, 255, 203, 1), rgba(0, 110, 255, 1)) 1 1;
         .imgBox {
         .imgBox {
             height: 266px;
             height: 266px;
@@ -80,7 +89,8 @@ export default {
         .price {
         .price {
             display: flex;
             display: flex;
             align-items: center;
             align-items: center;
-            padding: 0 0 16px 16px;
+            // justify-content: space-between;
+            padding: 0 16px 16px;
             .img1 {
             .img1 {
                 width: 10px;
                 width: 10px;
                 height: 11px;
                 height: 11px;
@@ -93,6 +103,23 @@ export default {
                 color: #00ffcb;
                 color: #00ffcb;
                 line-height: 30px;
                 line-height: 30px;
             }
             }
+            .time {
+                display: flex;
+                margin-left: 24px;
+                .time1 {
+                    font-size: 14px;
+                    font-weight: 400;
+                    color: #939599;
+                    line-height: 24px;
+                }
+                .time2 {
+                    font-size: 14px;
+                    font-weight: 400;
+                    color: #00ffcb;
+                    line-height: 24px;
+                    margin-left: 6px;
+                }
+            }
         }
         }
         .border {
         .border {
             height: 1px;
             height: 1px;
@@ -135,20 +162,4 @@ export default {
         }
         }
     }
     }
 }
 }
-.all {
-    display: flex;
-    align-content: center;
-    justify-content: center;
-    .img1 {
-        width: 32px;
-        height: 24px;
-    }
-    .name {
-        font-size: 16px;
-        font-weight: 400;
-        color: #ffffff;
-        line-height: 24px;
-        margin: 0 10px;
-    }
-}
 </style>
 </style>

+ 16 - 0
src/main/pc-space/src/router/index.js

@@ -31,6 +31,22 @@ const routes = [
                 meta: {
                 meta: {
                     title: '铸造'
                     title: '铸造'
                 }
                 }
+            },
+            {
+                path: '/collection',
+                name: 'collection',
+                component: () => import('../views/Collection.vue'),
+                meta: {
+                    title: '收藏探索'
+                }
+            },
+            {
+                path: '/blindbox',
+                name: 'blindbox',
+                component: () => import('../views/Blindsbox.vue'),
+                meta: {
+                    title: '数字盲盒'
+                }
             }
             }
         ]
         ]
     }
     }

+ 35 - 0
src/main/pc-space/src/views/Blindsbox.vue

@@ -0,0 +1,35 @@
+<template>
+    <div class="container">
+        <div class="title">欢迎来到 NFT 盲盒市场</div>
+        <search-info></search-info>
+        <goods-info></goods-info>
+    </div>
+</template>
+<script>
+import GoodsInfo from '../components/GoodsInfo.vue';
+import SearchInfo from '../components/SearchInfo.vue';
+export default {
+    components: { GoodsInfo, SearchInfo },
+    data() {
+        return {
+            currentPage4: 4
+        };
+    },
+    methods: {}
+};
+</script>
+<style lang="less" scoped>
+.container {
+    padding: 0 200px;
+
+    .title {
+        height: 42px;
+        font-size: 32px;
+        font-weight: 400;
+        color: #ffffff;
+        line-height: 42px;
+        padding: 60px 0 30px;
+        text-align: left;
+    }
+}
+</style>

+ 105 - 0
src/main/pc-space/src/views/Collection.vue

@@ -0,0 +1,105 @@
+<template>
+    <div class="container">
+        <div class="title">欢迎来到 NFT 市场</div>
+        <div class="tabs">
+            <div
+                class="tab"
+                :class="{ active: active === item }"
+                v-for="(item, index) in tabs"
+                :key="index"
+                @click="tab(item)"
+            >
+                {{ item }}
+            </div>
+        </div>
+        <div class="border"></div>
+        <search-info></search-info>
+        <goods-info></goods-info>
+        <!-- <div>
+            <el-pagination
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="currentPage4"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="100"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="400"
+            >
+            </el-pagination>
+        </div> -->
+    </div>
+</template>
+<script>
+import GoodsInfo from '../components/GoodsInfo.vue';
+import SearchInfo from '../components/SearchInfo.vue';
+export default {
+    components: { GoodsInfo, SearchInfo },
+    data() {
+        return {
+            tabs: ['全部', '新品', '转让', '拍卖'],
+            active: '全部',
+            currentPage4: 4
+        };
+    },
+    methods: {
+        tab(item) {
+            this.active = item;
+        },
+        handleSizeChange(val) {
+            console.log(`每页 ${val} 条`);
+        },
+        handleCurrentChange(val) {
+            console.log(`当前页: ${val}`);
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.container {
+    padding: 0 200px;
+
+    .title {
+        height: 42px;
+        font-size: 32px;
+        font-weight: 400;
+        color: #ffffff;
+        line-height: 42px;
+        padding: 60px 0;
+        text-align: left;
+    }
+    .tabs {
+        display: flex;
+        align-items: center;
+        padding-bottom: 30px;
+        text-align: center;
+        .tab {
+            width: 140px;
+            border: 1px solid #939599;
+            height: 42px;
+            font-size: 18px;
+            font-weight: bold;
+            color: #949699;
+            line-height: 42px;
+            &.active {
+                color: #ffffff;
+                background: linear-gradient(46deg, #00ffcb 0%, #006eff 100%);
+            }
+            &:first-child {
+                border-radius: 8px 0px 0px 8px;
+            }
+            &:last-child {
+                border-radius: 0px 8px 8px 0px;
+            }
+        }
+    }
+    .border {
+        height: 1px;
+        background: #494a4d;
+        border-radius: 1px;
+    }
+
+    // .footer {
+    //     flex-shrink: 0;
+    // }
+}
+</style>

+ 96 - 82
src/main/pc-space/src/views/Home.vue

@@ -4,97 +4,106 @@
             <div class="title">游戏数字资产的链上开创者们</div>
             <div class="title">游戏数字资产的链上开创者们</div>
             <div class="title2">全球领先的游戏数字藏品NFT集结地</div>
             <div class="title2">全球领先的游戏数字藏品NFT集结地</div>
             <div class="btn">立即探索</div>
             <div class="btn">立即探索</div>
-        </div>
-        <div class="introduce">
-            <div class="introduce2">
-                <img class="img1" src="../assets/img/888.jpg" alt="" />
-                <div>
-                    <div class="name">本期推荐:创作者姓名</div>
-                    <div class="name name1">作者简介</div>
-                    <div class="name2">
-                        介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍…
+            <div class="introduce">
+                <div class="introduce2">
+                    <img class="img1" src="../assets/img/888.jpg" alt="" />
+                    <div>
+                        <div class="name">本期推荐:创作者姓名</div>
+                        <div class="name name1">作者简介</div>
+                        <div class="name2">
+                            介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍…
+                        </div>
                     </div>
                     </div>
                 </div>
                 </div>
+                <img class="img2" src="../assets/img/888.jpg" alt="" />
+                <img class="img2" src="../assets/img/888.jpg" alt="" />
+                <img class="img2" src="../assets/img/888.jpg" alt="" />
             </div>
             </div>
-            <img class="img2" src="../assets/img/888.jpg" alt="" />
-            <img class="img2" src="../assets/img/888.jpg" alt="" />
-            <img class="img2" src="../assets/img/888.jpg" alt="" />
-        </div>
-        <div class="hot">最HOT收藏品</div>
-        <goods-info></goods-info>
-        <div class="hot">官方活动</div>
-        <div class="imgBox">
-            <img class="imgBox1" src="../assets/img/888.jpg" alt="" />
-            <img class="imgBox1" src="../assets/img/888.jpg" alt="" />
-        </div>
-        <div class="all">
-            <img class="img1" src="../assets/img/icon_inter@3x.png" alt="" />
-            <div class="name">查看更多</div>
-            <img class="img1" src="../assets/img/icon_inter@3x (3).png" alt="" />
-        </div>
-        <!-- <div> -->
-        <div class="describe">
-            <div class="box">
-                <div class="box1">
-                    <div class="text1">发现</div>
-                    <div class="text2">和你一起探索,全球最有才华的开发者铸造开创性NFT数字游戏藏品</div>
-                </div>
+            <div class="hot">最HOT收藏品</div>
+            <goods-info></goods-info>
+            <div class="all all1">
+                <img class="img1" src="../assets/img/icon_inter@3x.png" alt="" />
+                <div class="name">查看更多</div>
+                <img class="img1" src="../assets/img/icon_inter@3x (3).png" alt="" />
             </div>
             </div>
-            <div class="box">
-                <div class="box1">
-                    <div class="text1">交易</div>
-                    <div class="text2">方便快捷-无需数字钱包,人民币支付即可购买和出售游戏资产收藏品</div>
-                </div>
+            <div class="hot">官方活动</div>
+            <div class="imgBox">
+                <img class="imgBox1" src="../assets/img/888.jpg" alt="" />
+                <img class="imgBox1" src="../assets/img/888.jpg" alt="" />
             </div>
             </div>
-        </div>
-        <div class="describe">
-            <div class="box">
-                <div class="box1">
-                    <div class="text1">收集</div>
-                    <div class="text2">用稀有和独特的数字宝藏增加库存,成为全球首批游戏数字资产收藏家</div>
-                </div>
+            <div class="all">
+                <img class="img1" src="../assets/img/icon_inter@3x.png" alt="" />
+                <div class="name">查看更多</div>
+                <img class="img1" src="../assets/img/icon_inter@3x (3).png" alt="" />
             </div>
             </div>
-            <div class="box">
-                <div class="box1">
-                    <div class="text1">使命</div>
-                    <div class="text2">让每个游戏资产都能获得“电子身份证”,让每位收藏家都能获得区块链“数字指纹”</div>
+            <!-- <div> -->
+            <div class="describe">
+                <div class="box">
+                    <div class="box1">
+                        <div class="text1">发现</div>
+                        <div class="text2">和你一起探索,全球最有才华的开发者铸造开创性NFT数字游戏藏品</div>
+                    </div>
+                </div>
+                <div class="box">
+                    <div class="box1">
+                        <div class="text1">交易</div>
+                        <div class="text2">方便快捷-无需数字钱包,人民币支付即可购买和出售游戏资产收藏品</div>
+                    </div>
                 </div>
                 </div>
             </div>
             </div>
-        </div>
-        <!-- </div> -->
-        <div class="space">为什么叫第九空间</div>
-        <div class="space2">一切数据皆可复制的时代,第九空间NFT让你拥有一份独家数字藏品,让你拥有一份唯一游戏权益</div>
-        <div class="th">
-            <div>
-                <div class="words1">我们始终坚信</div>
-                <div class="words2">未来的虚拟世界将演变成同具价值的数字世界</div>
-            </div>
-            <div class="border"></div>
-            <div>
-                <div class="words1">我们始终坚信</div>
-                <div class="words2">未来的虚拟世界将演变成同具价值的数字世界</div>
+            <div class="describe">
+                <div class="box">
+                    <div class="box1">
+                        <div class="text1">收集</div>
+                        <div class="text2">用稀有和独特的数字宝藏增加库存,成为全球首批游戏数字资产收藏家</div>
+                    </div>
+                </div>
+                <div class="box">
+                    <div class="box1">
+                        <div class="text1">使命</div>
+                        <div class="text2">
+                            让每个游戏资产都能获得“电子身份证”,让每位收藏家都能获得区块链“数字指纹”
+                        </div>
+                    </div>
+                </div>
             </div>
             </div>
-            <div class="border"></div>
-            <div>
-                <div class="words1">我们始终坚信</div>
-                <div class="words2">未来的虚拟世界将演变成同具价值的数字世界</div>
+            <!-- </div> -->
+            <div class="space">为什么叫第九空间</div>
+            <div class="space2">
+                一切数据皆可复制的时代,第九空间NFT让你拥有一份独家数字藏品,让你拥有一份唯一游戏权益
             </div>
             </div>
-            <div class="border"></div>
-            <div>
-                <div class="words1">我们始终坚信</div>
-                <div class="all">
-                    <img class="img1" src="../assets/img/icon_inter@3x.png" alt="" />
-                    <div class="name">了解更多</div>
-                    <img class="img1" src="../assets/img/icon_inter@3x (3).png" alt="" />
+            <div class="th">
+                <div>
+                    <div class="words1">我们始终坚信</div>
+                    <div class="words2">未来的虚拟世界将演变成同具价值的数字世界</div>
+                </div>
+                <div class="border"></div>
+                <div>
+                    <div class="words1">我们始终坚信</div>
+                    <div class="words2">未来的虚拟世界将演变成同具价值的数字世界</div>
+                </div>
+                <div class="border"></div>
+                <div>
+                    <div class="words1">我们始终坚信</div>
+                    <div class="words2">未来的虚拟世界将演变成同具价值的数字世界</div>
+                </div>
+                <div class="border"></div>
+                <div>
+                    <div class="words1 words3">我们始终坚信</div>
+                    <div class="all">
+                        <img class="img1" src="../assets/img/icon_inter@3x.png" alt="" />
+                        <div class="name">了解更多</div>
+                        <img class="img1" src="../assets/img/icon_inter@3x (3).png" alt="" />
+                    </div>
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
 <script>
 <script>
-import goodsInfo from '../components/goodsInfo.vue';
+import GoodsInfo from '../components/GoodsInfo.vue';
 export default {
 export default {
-    components: { goodsInfo },
+    components: { GoodsInfo },
     data() {
     data() {
         return {};
         return {};
     },
     },
@@ -103,7 +112,7 @@ export default {
 </script>
 </script>
 <style lang="less" scoped>
 <style lang="less" scoped>
 .container {
 .container {
-    padding-left: 17.5%;
+    padding: 0 200px;
     .title {
     .title {
         height: 42px;
         height: 42px;
         font-size: 32px;
         font-size: 32px;
@@ -135,7 +144,7 @@ export default {
 .introduce {
 .introduce {
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
-    justify-content: center;
+    justify-content: space-between;
     .introduce2 {
     .introduce2 {
         display: flex;
         display: flex;
         align-items: center;
         align-items: center;
@@ -184,12 +193,11 @@ export default {
 .imgBox {
 .imgBox {
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
-    justify-content: center;
+    justify-content: space-between;
     .imgBox1 {
     .imgBox1 {
         width: 585px;
         width: 585px;
         height: 260px;
         height: 260px;
         border-radius: 8px;
         border-radius: 8px;
-        margin-right: 30px;
     }
     }
 }
 }
 .all {
 .all {
@@ -197,6 +205,9 @@ export default {
     align-content: center;
     align-content: center;
     justify-content: center;
     justify-content: center;
     margin: 40px 0 60px;
     margin: 40px 0 60px;
+    &.all1 {
+        margin: 0;
+    }
     .img1 {
     .img1 {
         width: 32px;
         width: 32px;
         height: 24px;
         height: 24px;
@@ -212,17 +223,16 @@ export default {
 .describe {
 .describe {
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
-    justify-content: center;
+    justify-content: space-between;
     .box {
     .box {
         width: 580px;
         width: 580px;
         height: 114px;
         height: 114px;
         background: #0f1111;
         background: #0f1111;
         border-radius: 8px;
         border-radius: 8px;
         border: 1px solid;
         border: 1px solid;
-        margin-right: 30px;
         margin-bottom: 30px;
         margin-bottom: 30px;
         border-image: linear-gradient(
         border-image: linear-gradient(
-                174deg,
+                143deg,
                 rgba(0, 255, 203, 0.6),
                 rgba(0, 255, 203, 0.6),
                 rgba(0, 209, 220, 0.1),
                 rgba(0, 209, 220, 0.1),
                 rgba(0, 151, 240, 0.1),
                 rgba(0, 151, 240, 0.1),
@@ -266,7 +276,8 @@ export default {
 }
 }
 .th {
 .th {
     display: flex;
     display: flex;
-    justify-content: center;
+    justify-content: space-between;
+    padding: 0 50px;
     .border {
     .border {
         width: 1px;
         width: 1px;
         height: 115px;
         height: 115px;
@@ -279,6 +290,9 @@ export default {
         color: #ffffff;
         color: #ffffff;
         line-height: 25px;
         line-height: 25px;
         margin: 12px 0;
         margin: 12px 0;
+        &.words3 {
+            text-align: center;
+        }
     }
     }
     .words2 {
     .words2 {
         width: 240px;
         width: 240px;

+ 11 - 12
src/main/pc-space/src/views/Index.vue

@@ -19,27 +19,27 @@
                     </div>
                     </div>
                     <div class="footer-r">
                     <div class="footer-r">
                         <div class="slogan">
                         <div class="slogan">
-                            <img class="logo1" src="../assets/img/copy_icon@3x.png" alt="" />
-                            <img class="logo1" src="../assets/img/copy_icon@3x.png" alt="" />
-                            <img class="logo1" src="../assets/img/copy_icon@3x.png" alt="" />
-                            <img class="logo1" src="../assets/img/copy_icon@3x.png" alt="" />
+                            <img class="logo1" src="../assets/img/icon-weixin@3x.png" alt="" />
+                            <img class="logo1" src="../assets/img/icon-weixin@3x.png" alt="" />
+                            <img class="logo1" src="../assets/img/icon-qq@3x.png" alt="" />
+                            <img class="logo1" src="../assets/img/icon-Twitter@3x.png" alt="" />
                         </div>
                         </div>
                         <div class="content">
                         <div class="content">
                             <div class="content1">
                             <div class="content1">
-                                <img class="logo2" src="../assets/img/copy_icon@3x.png" alt="" />
+                                <img class="logo2" src="../assets/img/icon_lianxiwomen@3x.png" alt="" />
                                 <div class="name">联系我们</div>
                                 <div class="name">联系我们</div>
                             </div>
                             </div>
                             <div class="content1">
                             <div class="content1">
-                                <img class="logo2" src="../assets/img/copy_icon@3x.png" alt="" />
-                                <div class="name">联系我们</div>
+                                <img class="logo2" src="../assets/img/icon_guanyuwomen@3x.png" alt="" />
+                                <div class="name">关于我们</div>
                             </div>
                             </div>
                             <div class="content1">
                             <div class="content1">
-                                <img class="logo2" src="../assets/img/copy_icon@3x.png" alt="" />
-                                <div class="name">联系我们</div>
+                                <img class="logo2" src="../assets/img/icon_shangwuhezuo@3x.png" alt="" />
+                                <div class="name">商务合作</div>
                             </div>
                             </div>
                             <div class="content1">
                             <div class="content1">
-                                <img class="logo2" src="../assets/img/copy_icon@3x.png" alt="" />
-                                <div class="name">联系我们</div>
+                                <img class="logo2" src="../assets/img/icon_yincangtiaokuan@3x.png" alt="" />
+                                <div class="name">隐私条款</div>
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
@@ -62,7 +62,6 @@ export default {
 .el-main {
 .el-main {
     min-height: 1000px;
     min-height: 1000px;
     background: #0f1111;
     background: #0f1111;
-    // padding-left: 200px;
 }
 }
 .el-footer {
 .el-footer {
     position: relative;
     position: relative;

+ 1 - 0
src/main/resources/application.yaml

@@ -31,6 +31,7 @@ spring:
     properties:
     properties:
       hibernate:
       hibernate:
         enable_lazy_load_no_trans: true
         enable_lazy_load_no_trans: true
+    open-in-view: true
   redis:
   redis:
     host: 118.178.226.110
     host: 118.178.226.110
     port: 6379
     port: 6379

+ 17 - 0
src/test/java/com/izouma/nineth/service/UserServiceTest.java

@@ -0,0 +1,17 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.ApplicationTests;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.junit.Assert.*;
+
+public class UserServiceTest extends ApplicationTests {
+
+    @Autowired
+    private UserService userService;
+
+    @Test
+    public void findByUsernameAndDelFalse1() {
+    }
+}