Просмотр исходного кода

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

xuqiang 4 лет назад
Родитель
Сommit
50d51963b6

+ 5 - 0
pom.xml

@@ -369,6 +369,11 @@
             <groupId>com.fasterxml.jackson.datatype</groupId>
             <artifactId>jackson-datatype-hibernate4</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+        </dependency>
     </dependencies>
 
 </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.PropertyAccessor;
 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.datatype.hibernate4.Hibernate4Module;
 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.cache.CacheAutoConfiguration;
-import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
 import org.springframework.context.annotation.Bean;
 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.core.RedisTemplate;
 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.RedisSerializationContext;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 
-import java.time.Duration;
 
 @Configuration
 @AutoConfigureAfter({RedisAutoConfiguration.class, CacheAutoConfiguration.class})
@@ -47,7 +43,10 @@ public class CacheConfig {
         mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                 ObjectMapper.DefaultTyping.NON_FINAL,
                 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);
 
         template.setValueSerializer(serializer);

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

@@ -1,30 +1,20 @@
 package com.izouma.nineth.domain;
 
 import lombok.AllArgsConstructor;
-import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.redis.core.RedisHash;
 
-import javax.persistence.*;
 
 @Data
-@Entity
 @AllArgsConstructor
 @NoArgsConstructor
-@Builder
-@Table(indexes = {@Index(columnList = "userId")})
-public class UserToken extends BaseEntity {
+@RedisHash("UserToken")
+public class UserToken {
 
     @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private Long id;
-
-    private Long userId;
+    private String username;
 
     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
 public class UserDTO extends User {
 
+    private String password;
+
+    private String nftAccount;
+
+    private String kmsId;
+
+    private String publicKey;
+
+    private String tradeCode;
+
     @ApiModelProperty("是否关注")
     private boolean follow;
 

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

@@ -1,11 +1,14 @@
 package com.izouma.nineth.repo;
 
 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.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
+import javax.annotation.Nonnull;
 import javax.transaction.Transactional;
 import java.time.LocalDateTime;
 import java.util.List;
@@ -17,6 +20,9 @@ public interface CollectionRepo extends JpaRepository<Collection, Long>, JpaSpec
     @Transactional
     void softDelete(Long id);
 
+    @Cacheable("collection")
+    Optional<Collection> findById(Long id);
+
     Optional<Collection> findByIdAndDelFalse(Long id);
 
     @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> 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")
     void softDelete(Long id);
 
-    Optional<User> findByUsernameAndDelFalse(String username);
+    User findByUsernameAndDelFalse(String username);
 
     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 org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
 
 import javax.transaction.Transactional;
 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;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.izouma.nineth.enums.AuthorityName;
 import lombok.*;
 
@@ -15,8 +16,9 @@ import java.util.Objects;
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
-@JsonIgnoreProperties(ignoreUnknown = true)
 @EqualsAndHashCode
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(value = {"hibernateLazyInitializer"}, ignoreUnknown = true)
 public class Authority implements Serializable {
 
     public static Authority get(AuthorityName name) {
@@ -47,16 +49,4 @@ public class Authority implements Serializable {
 
         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 JwtTokenUtil       jwtTokenUtil;
     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.jwtTokenUtil = jwtTokenUtil;
         this.tokenHeader = tokenHeader;
-        this.userTokenRepo = userTokenRepo;
     }
 
     @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) {
         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) {
@@ -78,8 +78,8 @@ public class JwtTokenUtil implements Serializable {
         JwtUser jwtUser = (JwtUser) userDetails;
         Map<String, Object> claims = new HashMap<>();
         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;
     }
 

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

@@ -1,7 +1,6 @@
 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 lombok.AllArgsConstructor;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -16,7 +15,7 @@ public class JwtUserDetailsService implements UserDetailsService {
 
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-        User user = userService.findByUsernameAndDelFalse(username).orElse(null);
+        UserDTO user = userService.findByUsernameAndDelFalse(username);
 
         if (user == null) {
             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 FollowRepo     followRepo;
 
-    //    @CacheEvict(value = "user", key = "#user.username")
+    @CacheEvict(value = "user", key = "#user.username")
     public User update(User user) {
         User orig = userRepo.findById(user.getId()).orElseThrow(new BusinessException("无记录"));
         ObjUtils.merge(orig, user);
@@ -73,9 +73,18 @@ public class UserService {
         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) {
@@ -308,6 +317,9 @@ public class UserService {
     public UserDTO toDTO(User user, boolean join) {
         UserDTO userDTO = new UserDTO();
         BeanUtils.copyProperties(user, userDTO);
+        if (user.getAuthorities() != null) {
+            userDTO.setAuthorities(new HashSet<>(user.getAuthorities()));
+        }
         if (join) {
             if (SecurityUtils.getAuthenticatedUser() != null) {
                 userDTO.setFollow(followService.isFollow(SecurityUtils.getAuthenticatedUser().getId(), user.getId()));

+ 8 - 0
src/main/nine-space/src/router/index.js

@@ -221,6 +221,14 @@ const routes = [
             title: '第九空间'
         }
     },
+    {
+        path: '/assetSearch',
+        name: 'assetSearch',
+        component: () => import('../views/asset/Search.vue'),
+        meta: {
+            title: '第九空间'
+        }
+    },
     {
         path: '/submit',
         name: 'submit',

+ 1 - 1
src/main/nine-space/src/styles/app.less

@@ -30,7 +30,7 @@
     --van-uploader-upload-background-color: transparent;
     --van-uploader-file-background-color: transparent;
     --van-active-color: @bg3;
-    --van-image-placeholder-background-color: @bg2;
+    --van-image-placeholder-background-color: @bg3;
     --van-search-background-color: #181818;
     --van-search-content-background-color: #0f0f0f;
     // --van-picker-background-color: @bg;

+ 1 - 1
src/main/nine-space/src/views/Mine.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="mine">
         <div class="userInfo" v-if="isLogin">
-            <van-image width="100%" height="35vw" :src="userInfo.bg" fit="cover" class="top-img" />
+            <van-image width="100%" height="35vw" :src="userInfo.bg" loading-icon="" fit="cover" class="top-img" />
             <div class="userInfo-content">
                 <div class="userInfo-top">
                     <van-image

+ 37 - 32
src/main/nine-space/src/views/Store.vue

@@ -12,9 +12,9 @@
             我卖出的
           </div> -->
                 </div>
-                <!-- <div class="search">
-          <img src="../assets/svgs/search.svg" alt="" />
-        </div> -->
+                <div class="search" v-if="isLogin" @click="$router.push('/assetSearch')">
+                    <img src="../assets/svgs/search.svg" alt="" />
+                </div>
             </div>
 
             <van-tabs
@@ -68,7 +68,6 @@
 <script>
 import AssetInfo from '../components/asset/assetInfo.vue';
 import asset from '../mixins/asset';
-
 export default {
     name: 'discover',
     mixins: [asset],
@@ -80,17 +79,21 @@ export default {
         return {
             active: 'explore',
             stiky: null,
-            type: 'DEFAULT',
+            type: '',
             empty: false,
             list: [],
             typeOptions: [
                 {
-                    label: '藏品类目',
-                    type: 'DEFAULT'
+                    label: '全部',
+                    type: ''
                 },
                 {
-                    label: '盲盒类目',
-                    type: 'BLIND_BOX'
+                    label: '售卖',
+                    type: 'ON_SALE'
+                },
+                {
+                    label: '仅展示',
+                    type: 'NORMAL'
                 }
             ],
             showSelect: false,
@@ -120,29 +123,31 @@ export default {
             this.loading = true;
             this.finished = false;
             this.empty = false;
-            this.$http
-                .post(
-                    '/asset/all',
-                    {
-                        page: this.page,
-                        size: 20,
-                        query: {
-                            userId: this.$store.state.userInfo.id,
-                            type: this.type
-                        },
-                        sort: 'createdAt,desc'
-                    },
-                    { body: 'json' }
-                )
-                .then(res => {
-                    this.list = [...this.list, ...res.content];
-                    this.empty = res.empty;
-                    this.loading = false;
-                    this.finished = res.last;
-                    if (!this.finished) {
-                        this.page = this.page + 1;
-                    }
-                });
+            let form = {
+                page: this.page,
+                size: 20,
+                query: {
+                    userId: this.$store.state.userInfo.id,
+                    status: this.type
+                },
+                sort: 'createdAt,desc'
+            };
+            if (this.type === 'NORMAL') {
+                form.query = {
+                    ...form.query,
+                    publicShow: true
+                };
+            }
+
+            this.$http.post('/asset/all', form, { body: 'json' }).then(res => {
+                this.list = [...this.list, ...res.content];
+                this.empty = res.empty;
+                this.loading = false;
+                this.finished = res.last;
+                if (!this.finished) {
+                    this.page = this.page + 1;
+                }
+            });
         },
         changeActive(active) {
             this.active = active;

+ 0 - 1
src/main/nine-space/src/views/account/Verified.vue

@@ -51,7 +51,6 @@
             </van-field>
 
             <van-field
-                type="digit"
                 label="身份证号"
                 name="身份证号"
                 placeholder="请输入身份证号"

+ 228 - 0
src/main/nine-space/src/views/asset/Search.vue

@@ -0,0 +1,228 @@
+<template>
+    <div class="discover">
+        <van-sticky ref="top" :offset-top="bar.value.show ? 46 : 0">
+            <van-search
+                ref="top"
+                shape="round"
+                v-model="search"
+                placeholder="请输入"
+                show-action
+                autofocus
+                :left-icon="require('../../assets/svgs/icon-sosuo.svg')"
+                @search="getSearch"
+                @cancel="$router.go(-1)"
+            />
+        </van-sticky>
+
+        <van-list
+            class="box-list"
+            v-model:loading="loading"
+            :immediate-check="false"
+            :finished="finished"
+            finished-text=""
+            @load="getData"
+        >
+            <template v-for="(item, index) in list" :key="index">
+                <asset-info :info="item"></asset-info>
+            </template>
+
+            <van-empty v-if="empty" description="您还没有任何藏品哦~" />
+        </van-list>
+    </div>
+</template>
+
+<script>
+import AssetInfo from '../../components/asset/assetInfo.vue';
+import asset from '../../mixins/asset';
+import list from '../../mixins/list';
+export default {
+    name: 'discover',
+    mixins: [asset, list],
+    inject: ['bar'],
+    components: {
+        AssetInfo
+    },
+    data() {
+        return {
+            active: 'explore',
+            stiky: null,
+            type: '',
+            empty: false,
+            list: [],
+            typeOptions: [
+                {
+                    label: '全部',
+                    type: ''
+                },
+                {
+                    label: '售卖',
+                    type: 'ON_SALE'
+                },
+                {
+                    label: '仅展示',
+                    type: 'NORMAL'
+                }
+            ],
+            search: '',
+            url: '/asset/all'
+        };
+    },
+    methods: {
+        beforeData() {
+            return {
+                query: {
+                    userId: this.$store.state.userInfo.id
+                },
+                search: this.search
+            };
+        },
+        getSearch(search) {
+            this.search = search;
+            this.getData(true);
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.top {
+    display: flex;
+    padding: 10px 16px;
+    background-color: @bg;
+    .top-btn {
+        flex-grow: 1;
+        .btn {
+            font-size: 16px;
+            font-family: ZhenyanGB;
+            font-weight: 400;
+            line-height: 26px;
+            display: inline-block;
+            vertical-align: text-bottom;
+
+            &.active {
+                color: @prim;
+                font-size: 20px;
+                font-weight: bold;
+                line-height: 30px;
+            }
+        }
+
+        .btn + .btn {
+            margin-left: 30px;
+        }
+    }
+}
+.select {
+    position: absolute;
+    right: 16px;
+    bottom: 9px;
+    color: #939599 !important;
+    min-width: 96px;
+}
+// /deep/.van-sticky {
+//     position: relative;
+// }
+
+.discover {
+    background-color: @bg3;
+    min-height: 100vh;
+    box-sizing: border-box;
+}
+
+/deep/ .mySwiper {
+    width: calc(100vw - 32px);
+    height: calc(41vw - 13px);
+
+    .swiper-pagination {
+        bottom: 12px;
+    }
+
+    .swiper-pagination-bullet {
+        width: 6px;
+        height: 2px;
+        border-radius: 1px;
+        background: #d7d7d7;
+    }
+
+    .swiper-pagination-bullet-active {
+        background: @prim;
+    }
+}
+
+.swiper-slide {
+    text-align: center;
+    font-size: 18px;
+
+    /* Center slide text vertically */
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-pack: center;
+    -ms-flex-pack: center;
+    -webkit-justify-content: center;
+    justify-content: center;
+    -webkit-box-align: center;
+    -ms-flex-align: center;
+    -webkit-align-items: center;
+    align-items: center;
+}
+
+.swiper-slide img {
+    display: block;
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+    border-radius: 4px;
+}
+.grid-img {
+    display: block;
+}
+.van-grid {
+    margin-top: 12px;
+}
+/deep/ .van-grid-item__content {
+    padding: 14px 20px 16px;
+}
+/deep/ .van-grid-item__text {
+    color: #fff;
+    font-size: 13px;
+    line-height: 18px;
+    margin-top: 4px;
+}
+
+.title {
+    padding: 16px 20px 8px;
+    color: @prim;
+    font-size: 18px;
+    font-weight: bold;
+}
+
+.box-list {
+    // display: flex;
+    // flex-wrap: wrap;
+    padding: 8px 8px 100px;
+}
+
+/deep/.van-tab {
+    color: #fff;
+    flex-grow: 0;
+    padding: 0 0 0 0;
+    margin-right: 30px;
+
+    &.van-tab--active {
+        color: @prim;
+    }
+}
+/deep/.van-tabs__nav {
+    padding-left: 16px;
+}
+
+/deep/ .van-tabs__line {
+    bottom: 20px;
+}
+
+/deep/.van-action-sheet__description::after {
+    border-bottom: 1px solid #f2f2f2;
+}
+</style>

+ 22 - 43
src/main/nine-space/src/views/creator/Search.vue

@@ -9,23 +9,32 @@
                 show-action
                 autofocus
                 :left-icon="require('../../assets/svgs/icon-sosuo.svg')"
-                @search="getList"
+                @search="getSearch"
                 @cancel="$router.go(-1)"
             />
         </van-sticky>
-        <div class="list">
+        <van-list
+            class="list"
+            v-model:loading="loading"
+            :immediate-check="false"
+            :finished="finished"
+            finished-text=""
+            @load="getData"
+        >
             <template v-for="(item, index) in list" :key="index">
                 <creator-info v-model:info="list[index]"></creator-info>
             </template>
             <van-empty v-if="empty" description="没有任何收藏者哦~" />
-        </div>
+        </van-list>
     </div>
 </template>
 
 <script>
 import CreatorInfo from '../../components/creator/CreatorInfo.vue';
+import list from '../../mixins/list';
 export default {
     name: 'Search',
+    mixins: [list],
     components: { CreatorInfo },
     inject: ['bar'],
     data() {
@@ -34,50 +43,20 @@ export default {
             empty: false,
             search: '',
             stiky: null,
-            type: ''
+            type: '',
+            url: '/user/all'
         };
     },
-    beforeRouteLeave(to, from, next) {
-        if (to.name !== 'productDetail') {
-            this.setKeeps([]);
-        }
-        next();
-    },
-    computed: {
-        pageName() {
-            return this.getLabelName(this.type, this.typeOptions);
-        }
-    },
-    mounted() {
-        this.setKeeps(['Search']);
-        if (this.$route.query.type) {
-            this.type = this.$route.query.type;
-        }
-    },
     methods: {
-        getList(search) {
+        beforeData() {
+            return {
+                query: { hasRole: 'ROLE_MINTER' },
+                search: this.search
+            };
+        },
+        getSearch(search) {
             this.search = search;
-            this.$toast.loading({
-                message: '加载中...',
-                forbidClick: true
-            });
-            this.$http
-                .post(
-                    '/user/all',
-                    {
-                        page: 0,
-                        query: { hasRole: 'ROLE_MINTER' },
-                        size: 20,
-                        sort: 'createdAt,desc',
-                        search: this.search
-                    },
-                    { body: 'json' }
-                )
-                .then(res => {
-                    this.list = res.content;
-                    this.empty = res.empty;
-                    this.$toast.clear();
-                });
+            this.getData(true);
         }
     }
 };

+ 27 - 43
src/main/nine-space/src/views/product/Search.vue

@@ -9,27 +9,35 @@
                 show-action
                 autofocus
                 :left-icon="require('../../assets/svgs/icon-sosuo.svg')"
-                @search="getList"
+                @search="getSearch"
                 @cancel="$router.go(-1)"
             />
         </van-sticky>
-        <div class="list">
+        <van-list
+            class="list"
+            v-model:loading="loading"
+            :immediate-check="false"
+            :finished="finished"
+            finished-text=""
+            @load="getData"
+        >
             <template v-for="(item, index) in list" :key="index">
                 <product-info v-model:info="list[index]" @update:info="init"></product-info>
             </template>
             <van-empty v-if="empty" description="没有任何藏品哦~" />
-        </div>
+        </van-list>
     </div>
 </template>
 
 <script>
 import ProductInfo from '../../components/product/productInfo.vue';
 import product from '../../mixins/product';
+import list from '../../mixins/list';
 export default {
     name: 'Search',
     components: { ProductInfo },
     inject: ['bar'],
-    mixins: [product],
+    mixins: [product, list],
     data() {
         return {
             list: [],
@@ -37,62 +45,38 @@ export default {
             search: '',
             stiky: null,
             type: '',
-            minterId: ''
+            minterId: '',
+            url: '/collection/all'
         };
     },
-    beforeRouteLeave(to, from, next) {
-        if (to.name !== 'productDetail') {
-            this.setKeeps([]);
-        }
-        next();
-        // ...
-    },
     computed: {
         pageName() {
             return this.getLabelName(this.type, this.typeOptions);
         }
     },
     mounted() {
-        this.setKeeps(['Search']);
         if (this.$route.query.type) {
             this.type = this.$route.query.type;
         }
         if (this.$route.query.minterId) {
             this.minterId = this.$route.query.minterId;
         }
-        this.$nextTick(() => {
-            this.stiky = this.$refs.top.$el.childNodes[0];
-        });
     },
     methods: {
-        getList(search) {
+        beforeData() {
+            return {
+                query: {
+                    onShelf: true,
+                    type: this.type,
+                    minterId: this.minterId,
+                    del: false
+                },
+                search: this.search
+            };
+        },
+        getSearch(search) {
             this.search = search;
-            this.$toast.loading({
-                message: '加载中...',
-                forbidClick: true
-            });
-            this.$http
-                .post(
-                    '/collection/all',
-                    {
-                        page: 0,
-                        size: 20,
-                        query: {
-                            onShelf: true,
-                            type: this.type,
-                            minterId: this.minterId,
-                            del: false
-                        },
-                        sort: 'createdAt,desc',
-                        search: this.search
-                    },
-                    { body: 'json' }
-                )
-                .then(res => {
-                    this.list = res.content;
-                    this.empty = res.empty;
-                    this.$toast.clear();
-                });
+            this.getData(true);
         }
     }
 };

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

@@ -31,6 +31,7 @@ spring:
     properties:
       hibernate:
         enable_lazy_load_no_trans: true
+    open-in-view: true
   redis:
     host: 118.178.226.110
     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() {
+    }
+}