Răsfoiți Sursa

Merge branch 'dev' of xiongzhu/raex_front into master

panhui 3 ani în urmă
părinte
comite
8038e36540

BIN
public/font/iconfont.ttf


BIN
public/font/iconfont.woff


BIN
public/font/iconfont.woff2


+ 9 - 1
src/App.vue

@@ -1,5 +1,11 @@
 <template>
-    <div class="scroll-wrapper" id="scroll-wrapper" ref="scroll" @scroll="scrollEvent">
+    <div
+        class="scroll-wrapper"
+        :class="{ darkTheme: darkTheme }"
+        id="scroll-wrapper"
+        ref="scroll"
+        @scroll="scrollEvent"
+    >
         <app-bar ref="bar"></app-bar>
         <router-view v-slot="{ Component }">
             <keep-alive :include="keeps">
@@ -14,6 +20,7 @@
 import AppBar from './components/AppBar.vue';
 import { computed } from 'vue';
 import PhoneVer from './components/PhoneVer.vue';
+import { mapState } from 'vuex';
 export default {
     components: { AppBar, PhoneVer },
     name: 'App',
@@ -31,6 +38,7 @@ export default {
     },
     inject: ['barHeight'],
     computed: {
+        ...mapState(['darkTheme']),
         barValue() {
             return this.$refs.bar;
         },

BIN
src/assets/arrow-up.png


BIN
src/assets/box1.png


BIN
src/assets/box2.png


BIN
src/assets/icon1.png


BIN
src/assets/icon2.png


BIN
src/assets/icon3.jpg


BIN
src/assets/info_icon_no1-2.png


BIN
src/assets/info_icon_no2-2.png


BIN
src/assets/info_icon_no3-2.png


BIN
src/assets/png-kapian.png


BIN
src/assets/topbg1.png


+ 132 - 0
src/components/creator/RankInfo.vue

@@ -0,0 +1,132 @@
+<template>
+    <div class="rank" :class="[`rank${index}`]">
+        <div class="rank-icon">
+            <img v-if="index < 3" :src="icons[index]" alt="" />
+            <span v-else>{{ index + 1 }}</span>
+        </div>
+        <div class="content">
+            <van-image round width="42" height="42" :src="info.avatar" />
+            <div class="name van-ellipsis">{{ info.nickname }}</div>
+        </div>
+        <van-button :class="{ follow: info.follow }" @click="follow" type="primary" round size="mini" plain>
+            {{ info.follow ? '已关注' : '关注' }}
+        </van-button>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        index: {
+            type: Number,
+            default: 0
+        },
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {
+            icons: [
+                require('@assets/info_icon_no1-2.png'),
+                require('@assets/info_icon_no2-2.png'),
+                require('@assets/info_icon_no3-2.png')
+            ]
+        };
+    },
+    methods: {
+        follow() {
+            this.checkLogin().then(() => {
+                if (!this.info.follow) {
+                    this.$http.get(`/user/${this.info.id}/follow`).then(res => {
+                        this.$emit('update:info', {
+                            ...this.info,
+                            follow: true
+                        });
+                        this.$toast.success('关注成功');
+                    });
+                } else {
+                    this.$http.get(`/user/${this.info.id}/unfollow`).then(() => {
+                        this.$emit('update:info', {
+                            ...this.info,
+                            follow: false
+                        });
+                        this.$toast.success('取消关注');
+                    });
+                }
+            });
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.rank {
+    .flex();
+    padding: 12px 12px;
+    overflow: hidden;
+    position: relative;
+
+    .rank-icon {
+        width: 38px;
+        height: 38px;
+        flex-shrink: 0;
+        .flex();
+        justify-content: center;
+        img {
+            width: 38px;
+            height: 38px;
+        }
+        span {
+            font-size: 20px;
+            font-family: AlibabaPuHuiTi-Bold, AlibabaPuHuiTi;
+            font-weight: bold;
+            color: var(--text0);
+            line-height: 20px;
+        }
+    }
+
+    .content {
+        .flex();
+        overflow: hidden;
+        flex-grow: 1;
+        margin-left: 14px;
+        .van-image {
+            flex-shrink: 0;
+        }
+
+        .name {
+            font-size: 14px;
+            line-height: 24px;
+            margin-left: 10px;
+            color: var(--text0);
+            font-weight: bold;
+        }
+    }
+
+    .van-button {
+        border: 1px solid var(--prim);
+        --van-button-primary-background-color: var(--prim);
+        --van-button-mini-font-size: 12px;
+        min-width: 60px;
+
+        &.follow {
+            border-color: var(--btnBorderInfo);
+            --van-button-primary-background-color: var(--btnInfo);
+        }
+    }
+
+    &::after {
+        content: '';
+        position: absolute;
+        left: 16px;
+        right: 16px;
+        bottom: 0;
+        height: 1px;
+        background-color: var(--border);
+    }
+}
+</style>

+ 1 - 1
src/components/order/OrderOpen.vue

@@ -7,7 +7,7 @@
                 <img class="img1" src="@assets/box1.png" alt="" />
                 <img class="img2" ref="img2" src="@assets/box2.png" alt="" />
                 <img class="img3" ref="img3" src="@assets/png-kapian.png" alt="" />
-                <img class="guang" src="@assets/png-guang.png" alt="" />
+                <!-- <img class="guang" src="@assets/png-guang.png" alt="" /> -->
             </div>
 
             <div class="product" ref="product">

+ 275 - 0
src/components/product/NewsRecord.vue

@@ -0,0 +1,275 @@
+<template>
+    <router-link
+        :to="{
+            path: '/newsDetail',
+            query: {
+                id: info.id
+            }
+        }"
+        class="news-record"
+        :class="{ isLight: type === 'light' }"
+    >
+        <van-image :src="getImg(info.pic)" :radius="8" width="46" height="46" fit="cover" />
+
+        <div class="content">
+            <div class="name van-ellipsis">{{ info.title }}</div>
+            <!-- <div class="sales-list">
+                <div class="sales">
+                    <span>绿洲头条新闻</span>
+                </div>
+            </div> -->
+            <div class="bottom">
+                <div class="miner">
+                    <span style="margin-left: 0">{{ info.createdAt }}</span>
+                </div>
+            </div>
+        </div>
+        <van-button type="primary" size="mini" round plain>查看</van-button>
+    </router-link>
+</template>
+
+<script>
+import product from '../../mixins/product';
+export default {
+    mixins: [product],
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        },
+        type: {
+            type: String,
+            default: 'dark'
+        }
+    },
+    computed: {
+        time() {
+            if (this.info.startTime) {
+                if (this.dayjs().isSameOrBefore(this.info.startTime, 'YYYY-MM-DD HH:mm:ss')) {
+                    return this.dayjs(this.info.startTime).format('MM月DD日');
+                }
+            }
+
+            return '';
+        }
+    },
+    mounted() {
+        if (this.info.startTime) {
+            var x = this.dayjs(this.info.startTime, 'YYYY-MM-DD HH:mm:ss');
+            var y = this.dayjs();
+            let d = this.dayjs.duration(x.diff(y));
+            let day = parseInt(d.asDays());
+            if (day <= 0) {
+                this.getTime(this.info.startTime);
+            }
+        }
+    },
+    methods: {
+        likeProduct() {
+            if (!this.info.liked) {
+                this.$http.get(`/collection/${this.info.id}/like`).then(() => {
+                    this.$emit('update:info', {
+                        ...this.info,
+                        liked: true,
+                        likes: this.info.likes + 1
+                    });
+                    this.$toast.success('收藏成功');
+                });
+            } else {
+                this.$http.get(`/collection/${this.info.id}/unlike`).then(() => {
+                    this.$emit('update:info', {
+                        ...this.info,
+                        liked: false,
+                        likes: this.info.likes - 1
+                    });
+                    this.$toast.success('取消收藏');
+                });
+            }
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.news-record {
+    position: relative;
+    background-color: var(--bg2);
+    display: inline-block;
+    border-radius: 12px;
+    overflow: hidden;
+    padding: 12px 16px;
+    .flex();
+
+    .bg {
+        position: absolute;
+        width: 92px;
+        height: 116px;
+        right: 0;
+        bottom: 0;
+        z-index: 0;
+    }
+
+    .van-image {
+        flex-shrink: 0;
+    }
+
+    .xianliang {
+        position: absolute;
+        top: 16px;
+        left: 16px;
+        font-size: @font1;
+        color: @prim;
+        display: flex;
+        align-items: center;
+        // border-radius: 13px !important;
+        z-index: 4;
+        padding: 0 10px !important;
+
+        img {
+            width: 18px;
+            height: 18px;
+            margin-right: 3px;
+        }
+    }
+
+    .van-image {
+        display: block;
+        position: relative;
+        z-index: 2;
+    }
+    .content {
+        margin-left: 12px;
+        align-self: stretch;
+        .flex-col();
+        justify-content: space-between;
+        flex-grow: 1;
+        .name {
+            font-size: 14px;
+            font-weight: bold;
+            color: var(--text0);
+            line-height: 24px;
+        }
+
+        .sales-list {
+            margin-top: 8px;
+            .flex();
+        }
+
+        .sales {
+            overflow: hidden;
+            font-size: @font1;
+            border-radius: 4px;
+
+            span {
+                padding: 0 10px;
+                line-height: 20px;
+                height: 20px;
+                display: inline-block;
+                &.sales-fir {
+                    background: @prim;
+                    color: @bg;
+                }
+                background-color: @bg3;
+                color: @prim;
+            }
+        }
+        .sales + .sales {
+            margin-left: 14px;
+        }
+
+        .bottom {
+            display: flex;
+            // margin-top: 14px;
+            align-items: center;
+
+            .miner {
+                display: flex;
+                align-items: center;
+
+                span {
+                    color: @text3;
+                    font-size: @font1;
+                    margin-left: 6px;
+                }
+            }
+
+            .price {
+                font-size: @font4;
+                color: @text0;
+                line-height: 20px;
+                font-family: OSP;
+                img {
+                    width: 8px;
+                    display: inline-block;
+                }
+            }
+        }
+    }
+
+    .text {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+    }
+
+    .top-bg {
+        width: 100%;
+        display: block;
+        position: absolute;
+        z-index: 2;
+        top: 0;
+        left: 0;
+    }
+
+    // &.isLight {
+    //     .content {
+    //         .name {
+    //             color: #000000;
+    //         }
+    //         .bottom {
+    //             .miner {
+    //                 color: #939599;
+    //             }
+    //         }
+    //     }
+    // }
+
+    &:not(:last-child) {
+        &::after {
+            content: '';
+            height: 1px;
+            background-color: var(--border);
+            position: absolute;
+            left: 74px;
+            right: 16px;
+            bottom: 0;
+        }
+    }
+}
+
+.status {
+    font-size: @font2;
+    color: @text0;
+}
+.sold {
+    background-color: @bg2;
+    font-size: @font1;
+    color: @text3;
+    padding: 0 17px;
+    border-radius: 13px;
+    line-height: 24px;
+    position: absolute;
+    top: 16px;
+    left: 16px;
+    z-index: 3;
+}
+.van-button {
+    background: var(--btnplaintBg);
+    border: 1px solid var(--btnplaintBorder);
+    min-width: 68px;
+    font-size: 16px;
+    font-weight: bold;
+}
+</style>

+ 15 - 12
src/components/product/productLarge.vue

@@ -38,7 +38,8 @@
                     </div>
                     <div class="flex1"></div>
                     <div class="price" v-if="info.salable">
-                        <img src="@assets/icon_jiage.png" alt="" />
+                        <!-- <img src="@assets/icon_jiage.png" alt="" /> -->
+                        <van-icon name="icon-icon_jiage" class-prefix="font_family" />
                         <span> {{ info.price }}</span>
                     </div>
                     <div v-else class="status">仅展示</div>
@@ -142,7 +143,7 @@ export default {
     width: calc(100vw - 32px);
     margin: 8px 16px;
     position: relative;
-    background-color: @bg2;
+    background-color: var(--bg2);
     display: inline-block;
     border-radius: 30px;
     overflow: hidden;
@@ -183,9 +184,9 @@ export default {
     .content {
         padding: 10px 16px 18px;
         .name {
-            font-size: @font2;
+            font-size: 16px;
             font-weight: bold;
-            color: @text0;
+            color: var(--text0);
             line-height: 24px;
         }
 
@@ -201,14 +202,14 @@ export default {
 
             span {
                 padding: 0 10px;
-                line-height: 20px;
-                height: 20px;
+                line-height: 18px;
+                height: 18px;
                 display: inline-block;
                 &.sales-fir {
                     background: @prim;
                     color: @bg;
                 }
-                background-color: @bg3;
+                background-color: var(--saleBg);
                 color: @prim;
             }
         }
@@ -234,12 +235,14 @@ export default {
 
             .price {
                 font-size: @font4;
-                color: @text0;
+                color: var(--text0);
                 line-height: 20px;
                 font-family: OSP;
-                img {
-                    width: 8px;
-                    display: inline-block;
+                .flex();
+                .font_family {
+                    font-size: 8px;
+                    line-height: 16px;
+                    margin-top: 3px;
                 }
             }
         }
@@ -263,7 +266,7 @@ export default {
 
 .status {
     font-size: @font2;
-    color: @text0;
+    color: var(--text0);
 }
 .sold {
     background-color: @bg2;

+ 2 - 2
src/components/product/productSmall.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="product" @click="goNext(info)">
-        <van-image width="100%" height="140px" :radius="30" :src="getImg(info.pic)" fit="cover" />
+        <van-image width="100%" height="calc(100vw - 32px)" :src="getImg(info.pic)" fit="cover" />
 
         <!-- <div class="content">
             <div class="name van-ellipsis">
@@ -35,7 +35,7 @@ export default {
     width: 100%;
     background-color: @bg2;
     display: inline-block;
-    border-radius: 30px;
+    // border-radius: 30px;
     overflow: hidden;
 
     .van-image {

+ 3 - 0
src/main.js

@@ -7,6 +7,7 @@ import { ConfigProvider } from 'vant';
 import 'vant/lib/index.css';
 import './styles/app.less';
 import './styles/font.less';
+import './styles/theme.less';
 import http from './plugins/http';
 import colors from './plugins/colors';
 // import ElementUI from 'element-ui';
@@ -151,6 +152,8 @@ if (query.hopeMarket === 'true' || query.hopeMarket === true || sessionStorage.g
 
 store.commit('setPlatform', /iPad|iPhone|iPod/i.test(navigator.userAgent) ? 'ios' : 'android');
 
+store.dispatch('getTheme');
+
 const loadSplash = (onload, onerror) =>
     new Promise((resolve, reject) => {
         let isHide = false;

+ 19 - 1
src/store/index.js

@@ -1,5 +1,6 @@
 import { createStore } from 'vuex';
 import http from '../plugins/http';
+import dayjs from 'dayjs';
 
 export default createStore({
     state: {
@@ -20,7 +21,8 @@ export default createStore({
         showConsole: false,
         bankCard: null,
         showRoomId: null,
-        platform: ''
+        platform: '',
+        darkTheme: false
     },
     mutations: {
         setFinished(state, finished) {
@@ -76,6 +78,9 @@ export default createStore({
         },
         setPlatform(state, platform) {
             state.platform = platform;
+        },
+        setDarkTheme(state, darkTheme) {
+            state.darkTheme = darkTheme;
         }
     },
     actions: {
@@ -113,6 +118,19 @@ export default createStore({
                     context.commit('setBankCard', (res || [])[0]);
                 });
             }
+        },
+        getTheme(context) {
+            let time1 = dayjs().format('YYYY-MM-DD') + ' 06:00:00';
+            let time2 = dayjs().format('YYYY-MM-DD') + ' 18:00:00';
+
+            if (
+                dayjs().isBefore(dayjs(time1, 'YYYY-MM-DD HH:mm:ss')) ||
+                dayjs().isAfter(dayjs(time2, 'YYYY-MM-DD HH:mm:ss'))
+            ) {
+                context.commit('setDarkTheme', true);
+            } else {
+                context.commit('setDarkTheme', false);
+            }
         }
     },
     getters: {

+ 5 - 1
src/styles/font.less

@@ -25,6 +25,10 @@
     -moz-osx-font-smoothing: grayscale;
 }
 
+.font_family-icon-a-iconarrowdown1:before {
+    content: '\e64c';
+}
+
 .icon-png-u-weixuanzhong:before {
     content: '\e640';
 }
@@ -66,7 +70,7 @@
     content: '\e631';
 }
 
-.icon-icon_jiage:before {
+.font_family-icon-icon_jiage:before {
     content: '\e632';
 }
 

+ 45 - 0
src/styles/theme.less

@@ -0,0 +1,45 @@
+:root {
+    --bg: #f5f7fa;
+    --bg2: #fff;
+    --border: #f5f7fa;
+    --btnplaintBg: #f5f7fa;
+    --btnplaintBorder: #f5f7fa;
+    --rankBg: #f5f7fa;
+    --rankBg0: #fff4e5;
+    --rankBg1: #f2f2f2;
+    --rankBg2: #fff8f5;
+    --rankBorder0: #ff7007;
+    --rankBorder1: #808080;
+    --rankBorder2: #e7926c;
+    --rankText0: #f5791d;
+    --rankText2: #e48154;
+    --saleBg: #f5f7fa;
+    --text0: #000;
+    --text1: rgba(0, 0, 0, 0.2);
+    --prim: #3ab200;
+    --btnInfo:#939599;
+    --btnBorderInfo:#C8C9CC;
+}
+
+.darkTheme {
+    --bg: #000000;
+    --bg2: #1c1c1e;
+    --border: #ffffff10;
+    --btnplaintBg: #373b3e;
+    --btnplaintBorder: #43ce00;
+    --rankBg: rgba(0, 0, 0, 0.1);
+    --rankBg0: rgba(0, 0, 0, 0.1);
+    --rankBg1: rgba(0, 0, 0, 0.1);
+    --rankBg2: rgba(0, 0, 0, 0.1);
+    --rankBorder0: #ff9815;
+    --rankBorder1: #929292;
+    --rankBorder2: #e4af98;
+    --rankText0: #ff9815;
+    --rankText2: #e4af98;
+    --saleBg: rgba(255, 255, 255, 0.1);
+    --text0: #fff;
+    --text1: rgba(255, 255, 255, 0.2);
+    --prim: #43ce00;
+    --btnInfo:#939599;
+    --btnBorderInfo:#ffffff10;
+}

+ 303 - 51
src/views/Home.vue

@@ -23,50 +23,120 @@
             ></van-image>
         </div>
 
-        <swiper pagination :space-between="16" class="mySwiper" :autoplay="{ delay: 3500 }" v-if="banners.length > 0">
-            <swiper-slide v-for="item in banners" :key="item.id">
-                <product-small :info="item"></product-small>
-            </swiper-slide>
-        </swiper>
+        <div class="card swiper-card">
+            <swiper
+                pagination
+                :space-between="16"
+                class="mySwiper"
+                :autoplay="{ delay: 3500 }"
+                v-if="banners.length > 0"
+            >
+                <swiper-slide v-for="item in banners" :key="item.id">
+                    <product-small :info="item"></product-small>
+                </swiper-slide>
+            </swiper>
+            <van-grid :column-num="3" :border="false" class="top-grid">
+                <van-grid-item
+                    url="https://yags.raex.vip/h5/home"
+                    :icon="require('@assets/icon2.png')"
+                    text="绿洲电竞链"
+                />
+                <van-grid-item @click="wait" :icon="require('@assets/icon1.png')" text="元宇宙农业" />
+                <van-grid-item
+                    url="https://www.raex.vip/static/download_raex_space.html"
+                    :icon="require('@assets/icon3.jpg')"
+                    text="OASISMETA"
+                />
+            </van-grid>
+            <img src="@assets/topbg1.png" class="swiper-bg" alt="" />
+        </div>
+
+        <div class="card news">
+            <div class="news-title" @click="$router.push('/newsList')">
+                <div class="news-left">
+                    <div class="text1">绿洲头条新闻</div>
+                    <div class="text2">快来了解绿洲宇宙新动态</div>
+                </div>
+                <img class="more" src="@assets/icon_inter.png" alt="" />
+            </div>
+            <news-record
+                v-for="(item, index) in news"
+                :key="index"
+                v-model:info="news[index].obj"
+                type="light"
+            ></news-record>
+        </div>
+
+        <div class="card-list">
+            <div
+                class="card card-hot"
+                :style="{ order: index < 1 ? index + 1 : index + 2 }"
+                v-for="(item, index) in hots"
+                :key="index"
+                @click="goNext(item)"
+            >
+                <van-image :src="item.pic" fit="cover" width="100%" height="110vw" />
+                <div class="hot-top" v-if="index < 2">
+                    <div class="text1">{{ item.name }}</div>
+                    <div class="text2">{{ item.remark }}</div>
+                </div>
+                <div class="hot-bottom" v-else>
+                    <div class="text1">{{ item.name }}</div>
+                    <div class="text2">{{ item.remark }}</div>
+                </div>
+            </div>
+
+            <div class="card news" style="order: 2" v-if="hotUsers.length > 0">
+                <div class="news-title">
+                    <div class="news-left">
+                        <div class="text1">热力IP</div>
+                        <div class="text2">一周最热IP排名</div>
+                    </div>
+                </div>
+                <div class="rank-list">
+                    <swiper
+                        class="rankSwiper"
+                        @reachEnd="reachEnd"
+                        @slidePrevTransitionStart="slidePrevTransitionStart"
+                        direction="vertical"
+                        slides-per-view="auto"
+                        free-mode
+                    >
+                        <swiper-slide v-for="(item, index) in hotUsers" :key="index">
+                            <rank-info :index="index" v-model:info="hotUsers[index]"></rank-info>
+                        </swiper-slide>
+                    </swiper>
+                    <div class="rank-more" :style="{ visibility: hideMore ? 'hidden' : 'visible' }">
+                        <van-icon name="icon-a-iconarrowdown1" class-prefix="font_family" />
+                        <div>上滑显示更多</div>
+                    </div>
+                </div>
+            </div>
+        </div>
 
         <!-- <div class="tabs" v-if="!empty">
             <div class="tab" :class="{ active: active === 0 }" @click="active = 0">数字艺术品</div>
             <div class="tab" :class="{ active: active === 1 }" @click="active = 1">产品新闻端</div>
         </div> -->
 
-        <div class="list-top">
+        <!-- <div class="list-top">
             <van-badge :dot="isNewCollections" :offset="[-35, 15]">
                 <div class="text1" :class="{ active: active === 0 }" @click="changeActive(0)">数字文创</div>
             </van-badge>
             <van-badge :dot="isNewNews" :offset="[-35, 15]">
                 <div class="text1" :class="{ active: active === 1 }" @click="changeActive(1)">绿洲头条</div>
             </van-badge>
+        </div> -->
+        <div class="listSwiper-title">往期数字艺术品</div>
+        <div class="listSwiper">
+            <product-large
+                v-for="(item, index) in products"
+                :key="index"
+                v-model:info="products[index].obj"
+                :type="item.type"
+            >
+            </product-large>
         </div>
-
-        <swiper class="listSwiper" autoHeight @swiper="setSwiperRef" @slideChange="changeSwiper">
-            <swiper-slide>
-                <product-large
-                    v-for="(item, index) in products"
-                    :key="index"
-                    v-model:info="products[index].obj"
-                    :type="item.type"
-                ></product-large
-            ></swiper-slide>
-            <swiper-slide>
-                <news-small
-                    v-for="(item, index) in news"
-                    :key="index"
-                    v-model:info="news[index].obj"
-                    type="light"
-                ></news-small>
-                <!-- <product-large
-                    v-for="(item, index) in news"
-                    :key="index"
-                    v-model:info="news[index].obj"
-                    :type="item.type"
-                ></product-large> -->
-            </swiper-slide>
-        </swiper>
     </van-pull-refresh>
     <van-dialog v-model:show="riskShow" theme="round-button" className="risk">
         <div class="risk-box">
@@ -105,6 +175,8 @@ import ProductSmall from '../components/product/productSmall.vue';
 import { mapState } from 'vuex';
 import NewsInfo from '../components/product/NewsInfo';
 import NewsSmall from '../components/product/NewsSmall.vue';
+import NewsRecord from '../components/product/NewsRecord.vue';
+import RankInfo from '../components/creator/RankInfo.vue';
 
 export default {
     name: 'home',
@@ -115,7 +187,8 @@ export default {
         SwiperSlide,
         ProductLarge,
         ProductSmall,
-        NewsSmall
+        NewsRecord,
+        RankInfo
     },
     computed: {
         ...mapState(['userInfo']),
@@ -147,6 +220,7 @@ export default {
     data() {
         return {
             banners: [],
+            hots: [],
             products: [],
             active: 0,
             news: [],
@@ -157,7 +231,9 @@ export default {
             bgImg: '',
             swiperRef: null,
             scrollTop: 0,
-            riskShow: false
+            riskShow: false,
+            hideMore: false,
+            hotUsers: []
         };
     },
     mounted() {
@@ -169,15 +245,16 @@ export default {
             this.showTips();
         }, 500);
 
+        this.$http.get('/user/topTen').then(res => {
+            this.hotUsers = res;
+        });
+
         this.$nextTick(() => {
             this.$el.parentNode.childNodes[1].className = this.$el.parentNode.childNodes[1].className.replace(
                 / bgBack/,
                 ''
             );
         });
-        // this.$http.get('sysConfig/get/home_bg').then(res => {
-        //     this.bgImg = res.value || '';
-        // });
     },
     methods: {
         changeSwiper() {
@@ -275,9 +352,11 @@ export default {
                     this.products = res.filter(item => {
                         return item.type === 'collection';
                     });
-                    this.news = res.filter(item => {
-                        return item.type === 'news';
-                    });
+                    this.news = res
+                        .filter(item => {
+                            return item.type === 'news';
+                        })
+                        .slice(0, 4);
                 })
             ]).then(() => {
                 this.$toast.clear();
@@ -296,7 +375,7 @@ export default {
                     '/banner/all',
                     {
                         query: {
-                            type: 'HOME',
+                            type: 'HOME,DISCOVER',
                             del: false
                         },
                         sort: 'sort,asc;createdAt,desc'
@@ -304,7 +383,12 @@ export default {
                     { body: 'json' }
                 )
                 .then(res => {
-                    this.banners = res.content;
+                    this.banners = res.content.filter(item => {
+                        return item.type === 'HOME';
+                    });
+                    this.hots = res.content.filter(item => {
+                        return item.type === 'DISCOVER';
+                    });
                     if (this.swiperRef) {
                         this.swiperRef.update();
                     }
@@ -397,6 +481,14 @@ export default {
         changeActive(active) {
             this.active = active;
             this.swiperRef.slideTo(active, 300);
+        },
+        reachEnd() {
+            this.hideMore = true;
+        },
+        slidePrevTransitionStart() {
+            if (this.hideMore) {
+                this.hideMore = false;
+            }
         }
     },
     activated() {
@@ -466,19 +558,19 @@ export default {
     // background-color: @bg3;
     position: relative;
     z-index: 1;
-    background-color: #f5f7fa;
+    background-color: var(--bg);
     padding-top: var(--safe-top);
 }
 
 ::v-deep(.mySwiper) {
     // height: 255px;
-    padding: 16px 0;
-    margin: 0 16px;
+    // padding: 16px 0;
     box-sizing: border-box;
     // padding-bottom: 35px;
+    border-radius: 16px 16px 0 0;
 
     .swiper-pagination {
-        bottom: 30px;
+        bottom: 15px;
     }
 
     .swiper-pagination-bullet {
@@ -509,17 +601,18 @@ export default {
     .left {
         flex-grow: 1;
         .text1 {
-            font-size: 12px;
+            font-size: 14px;
             font-weight: bold;
-            color: @text0;
+            color: #8a8a8e;
             line-height: 24px;
         }
         .text2 {
-            font-size: 24px;
+            font-size: 30px;
             font-weight: bold;
-            color: @text0;
-            line-height: 32px;
-            letter-spacing: 2px;
+            color: var(--text0);
+            line-height: 40px;
+            letter-spacing: 1px;
+            margin-top: 2px;
 
             &.text3 {
                 letter-spacing: 0px;
@@ -662,4 +755,163 @@ export default {
         border-radius: 8px;
     }
 }
+
+.card {
+    background: var(--bg2);
+    box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
+    border-radius: 16px;
+    margin: 16px 16px 0;
+    overflow: hidden;
+    &.news {
+        padding-bottom: 18px;
+    }
+}
+
+.news-title {
+    padding: 14px 14px 16px 16px;
+    .flex();
+    .news-left {
+        flex-grow: 1;
+        .text1 {
+            font-size: 14px;
+            font-weight: bold;
+            color: #8a8a8e;
+            line-height: 24px;
+        }
+
+        .text2 {
+            font-size: 26px;
+            font-weight: bold;
+            color: var(--text0);
+            line-height: 36px;
+        }
+    }
+
+    .more {
+        width: 24px;
+        height: 24px;
+    }
+}
+
+.rankSwiper {
+    height: 320px;
+    .swiper-slide {
+        height: 65px;
+    }
+    // overflow: auto;
+}
+
+.rank-list {
+    .rank-more {
+        .flex-col();
+        align-items: center;
+        padding-top: 10px;
+        .font_family {
+            color: var(--text1);
+        }
+        div {
+            font-size: 12px;
+            color: var(--text1);
+            line-height: 10px;
+            margin-top: 4px;
+        }
+    }
+}
+
+.card-hot {
+    position: relative;
+    .van-image {
+        display: block;
+    }
+    .hot-top {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        .flex-col();
+        flex-direction: column-reverse;
+        padding: 14px 16px;
+        .text1 {
+            font-size: 24px;
+            font-weight: bold;
+            color: #ffffff;
+            line-height: 24px;
+            margin-top: 6px;
+        }
+        .text2 {
+            font-size: 14px;
+            font-weight: bold;
+            color: #ffffff99;
+            line-height: 24px;
+        }
+    }
+    .hot-bottom {
+        position: absolute;
+        top: calc(110vw - 128px);
+        left: 0;
+        right: 0;
+        border-radius: 0 0 16px 16px;
+        overflow: hidden;
+
+        .text2 {
+            line-height: 64px;
+            height: 64px;
+            backdrop-filter: blur(10px);
+            font-size: 14px;
+            color: #ffffff;
+            padding: 0 20px;
+            border-radius: 0 0 16px 16px;
+        }
+
+        .text1 {
+            font-size: 24px;
+            font-weight: bold;
+            color: #ffffff;
+            line-height: 24px;
+            padding: 20px;
+        }
+    }
+}
+.card-list {
+    display: flex;
+    flex-direction: column;
+}
+.listSwiper-title {
+    font-size: 20px;
+    font-weight: bold;
+    color: var(--text0);
+    line-height: 24px;
+    border-top: 1px solid var(--border);
+    padding: 19px 0 8px;
+    margin: 20px 16px 0;
+}
+
+.top-grid {
+    --van-grid-item-icon-size: 56px;
+    --van-grid-item-text-color: var(--text0);
+    --van-grid-item-text-font-size: 12px;
+    --van-grid-item-content-padding: 10px 8px 9px;
+    /deep/.van-grid-item__icon + .van-grid-item__text {
+        margin-top: 6px;
+    }
+    /deep/.van-grid-item__icon {
+        border-radius: 12px;
+        overflow: hidden;
+    }
+}
+.swiper-card {
+    position: relative;
+    .swiper-bg {
+        width: 100%;
+        display: block;
+        position: absolute;
+        left: 0;
+        bottom: 0;
+        z-index: 0;
+    }
+    .van-grid {
+        z-index: 1;
+        position: relative;
+    }
+}
 </style>

+ 7 - 3
src/views/Index.vue

@@ -25,8 +25,10 @@
 </template>
 
 <script>
+import { mapState } from 'vuex';
 export default {
     computed: {
+        ...mapState(['darkTheme']),
         menus() {
             let menus = [
                 {
@@ -79,7 +81,7 @@ export default {
             return menus;
         },
         tabClass() {
-            return this.$route.path === '/home' ? '' : 'bgBack';
+            return this.$route.path === '/home' && !this.darkTheme ? '' : 'bgBack';
         }
     },
     inject: ['keeps'],
@@ -102,6 +104,7 @@ export default {
 
 .index {
     background-color: @bg3;
+    --van-tabbar-item-text-color: #939599;
     .flex-col();
     padding-top: 0 !important;
 }
@@ -111,9 +114,10 @@ export default {
         border: 1px solid @bg3;
     }
     &.bgBack {
-        background-color: #222426;
+        background: rgba(0, 0, 0, 0.5);
+        backdrop-filter: blur(30px);
         &::after {
-            border: 1px solid #222426;
+            border: 1px solid rgba(0, 0, 0, 0.5);
         }
     }
 }