Bläddra i källkod

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

panhui 4 år sedan
förälder
incheckning
b37a6f25d0

+ 1 - 1
.env.development

@@ -1,4 +1,4 @@
-VUE_APP_BASE_URL=https://www.raex.vip
+VUE_APP_BASE_URL=https://test.raex.vip
 NODE_ENV=development
 VUE_APP_PUBLIC_PATH=/
 ASSETS_PATH=raex

+ 0 - 11
src/App.vue

@@ -40,17 +40,6 @@ export default {
             });
         }
     },
-    mounted() {
-        // this.$dialog
-        //     .confirm({
-        //         title: '提示',
-        //         message: '您的藏品室有一个新资产哦!',
-        //         confirmButtonText: '立即查看'
-        //     })
-        //     .then(() => {
-        //         this.$router.push('/store');
-        //     });
-    },
     methods: {
         setKeeps(keep = [], isAdd = true) {
             let keeps = [...this.keeps];

BIN
src/assets/icon-sheweitouxiang.png


BIN
src/assets/png-touxiangkuang.png


+ 2 - 2
src/components/level/Level.vue

@@ -66,8 +66,8 @@ export default {
             this.$http.post(
                 '/user/save',
                 {
-                    level: level,
-                    id: this.$store.state.userInfo.id
+                    ...this.$store.state.userInfo,
+                    level: level
                 },
                 { body: 'json' }
             );

+ 38 - 0
src/components/product/ProductBanner.vue

@@ -42,6 +42,11 @@
             </swiper>
 
             <div class="share-content">
+                <div class="setAvatar" @click="setAvatar" v-if="pageType == 'asset' && onlyImg">
+                    <img src="../../assets/icon-sheweitouxiang.png" alt="" />
+                    <span>设为头像</span>
+                </div>
+
                 <like-button v-if="pageType == 'product'" :isLike="info.liked" @click="likeProduct">
                     {{ info.likes }}
                 </like-button>
@@ -117,6 +122,14 @@ export default {
                 this.pageType === 'product' ||
                 (this.info.status === 'NORMAL' && (this.info.publicShow || this.info.consignment))
             );
+        },
+        onlyImg() {
+            if (this.banners.length > 0 && !this.info.model3d) {
+                if (this.banners[0].type.indexOf('image') !== -1) {
+                    return true;
+                }
+            }
+            return false;
         }
     },
     methods: {
@@ -151,6 +164,15 @@ export default {
             this.$nextTick(() => {
                 this.$refs.swiperVideo[0].play();
             });
+        },
+        setAvatar() {
+            this.$toast.loading({
+                message: '加载中...',
+                forbidClick: true
+            });
+            this.updateUser({ avatar: this.banners[0].url, useCollectionPic: true }).then(res => {
+                this.$toast.success('设置成功');
+            });
         }
     }
 };
@@ -243,4 +265,20 @@ export default {
         color: rgba(0, 0, 0, 0.5) !important;
     }
 }
+
+.setAvatar {
+    .flex();
+    img {
+        width: 24px;
+        height: 24px;
+        display: block;
+    }
+
+    span {
+        font-size: 12px;
+        color: #949699;
+        line-height: 24px;
+        margin-left: 3px;
+    }
+}
 </style>

+ 30 - 2
src/main.js

@@ -26,7 +26,7 @@ import calendar from 'dayjs/plugin/calendar';
 import duration from 'dayjs/plugin/duration';
 import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
 import customParseFormat from 'dayjs/plugin/customParseFormat';
-import { Toast } from 'vant';
+import { Toast, Dialog } from 'vant';
 
 Toast.setDefaultOptions('loading', { duration: 0 });
 require('dayjs/locale/zh-cn');
@@ -76,6 +76,7 @@ if (query.code) {
         // document.location.replace(location.origin + '/wx/redirect?redirectUrl=' + location.href);
     }
 }
+store.dispatch('getTime');
 if (query.invitor) {
     store.commit('setInvitor', query.invitor);
 
@@ -109,6 +110,7 @@ const loadSplash = (onload, onerror) =>
             splash.style.opacity = 0;
             setTimeout(() => {
                 document.body.removeChild(splash);
+                showTips();
             }, 800);
             resolve();
         }
@@ -128,9 +130,35 @@ const loadSplash = (onload, onerror) =>
         setTimeout(() => {
             hideSplash();
         }, 5000);
-        splash.src = 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/splash.jpg?ts=' + new Date().getTime();
+        splash.src = 'https://cdn.raex.vip/splash.jpg?ts=' + new Date().getTime();
         document.body.append(splash);
     });
+
+function showTips() {
+    let inApp = /#cordova#/i.test(navigator.userAgent);
+    let inIos = /iPhone|iPad|iPod/i.test(navigator.userAgent);
+    if (!window.localStorage.getItem('AppTips') && !inIos && inApp) {
+        Dialog.confirm({
+            title: '绿洲服务协议和隐私政策',
+            message:
+                '在您使用我的各项服务之前,请务必审慎阅读、充分理解<a href="/agreement?page=service">《用户隐私协议》</a>、<a href="/agreement">《隐私政策》</a>的条款。并且我们会申请获取您的设备信息,以向您提供安全风控服务。同时您应特别注意前述协议中免除或者限制我们责任的条款、对您权利进行限制的条款。如您已详细阅读并同意绿洲用户协议、隐私政策,请点击【同意并继续】开始使用我们的服务。',
+            confirmButtonText: '同意并继续',
+            allowHtml: true
+        })
+            .then(() => {
+                return Dialog.confirm({
+                    title: '温馨提示',
+                    message:
+                        '收集个人信息为我们向您提供服务所必须哦。我们仅会将您的个人信息用于为您提供服务,若不同意此协议,我们将无法为您提供服务并退出应用。',
+                    confirmButtonText: '同意'
+                });
+            })
+            .then(() => {
+                window.localStorage.setItem('AppTips', '1');
+            });
+    }
+}
+
 if (navigator.userAgent.includes('#cordova#')) {
     document.addEventListener(
         'deviceready',

+ 1 - 1
src/mixins/banner.js

@@ -1,6 +1,6 @@
 export default {
     methods: {
-        goNext(info, props) {
+        goNext(info, props = '') {
             if (info.link && info.linkType === 'collection') {
                 this.$router.push(`/productDetail?id=${info.linkContent}${props}`);
             } else if (info.link && info.linkType === 'user') {

+ 20 - 20
src/mixins/level.js

@@ -7,8 +7,8 @@ export default {
                     end: 9,
                     color1: '#717171',
                     color: '#3B445D',
-                    vicon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/v.png',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV0-1-icon.png',
+                    vicon: 'https://cdn.raex.vip/medals/v.png',
+                    icon: 'https://cdn.raex.vip/medals/LV0-1-icon.png',
                     hide: true,
                     textColor: '#ffffff',
                     startColor: '#A5AEC9',
@@ -20,8 +20,8 @@ export default {
                     color: '#557595',
                     startColor: '#AAD4FF',
                     endColor: '#C5E2FF',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV10-19-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V10-19.png'
+                    icon: 'https://cdn.raex.vip/medals/LV10-19-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V10-19.png'
                 },
                 {
                     start: 20,
@@ -29,8 +29,8 @@ export default {
                     color: '#A65F3B',
                     startColor: '#fec391',
                     endColor: '#fde9cb',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV20-29-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V20-29.png'
+                    icon: 'https://cdn.raex.vip/medals/LV20-29-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V20-29.png'
                 },
                 {
                     start: 30,
@@ -38,8 +38,8 @@ export default {
                     color: '#3C62FF',
                     startColor: '#B6C2FF',
                     endColor: '#A8B7FF',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV30-39-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V30-39.png'
+                    icon: 'https://cdn.raex.vip/medals/LV30-39-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V30-39.png'
                 },
                 {
                     start: 40,
@@ -47,8 +47,8 @@ export default {
                     color: '#663FA7',
                     startColor: '#CEAFFF',
                     endColor: '#C19AFF',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV40-49-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V40-49.png'
+                    icon: 'https://cdn.raex.vip/medals/LV40-49-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V40-49.png'
                 },
                 {
                     start: 50,
@@ -56,8 +56,8 @@ export default {
                     color: '#1076E1',
                     startColor: '#B3EAFF',
                     endColor: '#7CDAFF',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV50-59-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V50-59.png'
+                    icon: 'https://cdn.raex.vip/medals/LV50-59-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V50-59.png'
                 },
                 {
                     start: 60,
@@ -65,8 +65,8 @@ export default {
                     color: '#DB31CA',
                     startColor: '#FFBEF8',
                     endColor: '#FF8DF5',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV60-69-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V60-69.png'
+                    icon: 'https://cdn.raex.vip/medals/LV60-69-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V60-69.png'
                 },
                 {
                     start: 70,
@@ -74,8 +74,8 @@ export default {
                     color: '#3D26D2',
                     startColor: '#B6AAFC',
                     endColor: '#9F8EFF',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV70-79-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V70-79.png'
+                    icon: 'https://cdn.raex.vip/medals/LV70-79-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V70-79.png'
                 },
                 {
                     start: 80,
@@ -83,8 +83,8 @@ export default {
                     color: '#DF1637',
                     startColor: '#FFB2B9',
                     endColor: '#F89BA3',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV80-89-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V80-89.png'
+                    icon: 'https://cdn.raex.vip/medals/LV80-89-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V80-89.png'
                 },
                 {
                     start: 90,
@@ -92,8 +92,8 @@ export default {
                     color: '#FA6802',
                     startColor: '#FFE3BB',
                     endColor: '#FFCF8C',
-                    icon: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/LV90-99-icon.png',
-                    bg: 'https://raex-meta.oss-cn-shenzhen.aliyuncs.com/medals/V90-99.png'
+                    icon: 'https://cdn.raex.vip/medals/LV90-99-icon.png',
+                    bg: 'https://cdn.raex.vip/medals/V90-99.png'
                 }
             ],
             levels: [],

+ 26 - 10
src/mixins/product.js

@@ -39,7 +39,9 @@ export default {
                 最HOT收藏品: 'soldOut;likes,desc;sort,desc;createdAt,desc',
                 更多藏品: 'soldOut;source,asc;sale,desc;likes,desc'
             },
-            timer: null
+            startTimetimer: null,
+            saleTimetimer: null,
+            saleTime: ''
         };
     },
     computed: {
@@ -56,6 +58,13 @@ export default {
                 return false;
             }
         },
+        isSale() {
+            if (this.info.saleTime) {
+                return this.dayjs().isBefore(this.dayjs(this.info.saleTime));
+            } else {
+                return false;
+            }
+        },
         isSold() {
             return this.info && this.info.soldOut && this.info.salable;
         },
@@ -85,40 +94,47 @@ export default {
             n = n + '';
             return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
         },
-        getTime(startTime) {
+        getTime(startTime, key = 'startTime') {
             if (!startTime) {
                 return;
             }
-            if (!this.isAppointment) {
+            if (key == 'startTime' && !this.isAppointment) {
                 return;
             }
 
+            if (key == 'saleTime' && !this.isSale) {
+                return;
+            }
+
+            let subTime = parseInt(this.$store.state.netTime / 1000);
+
             let seconds = this.dayjs(startTime, 'YYYY-MM-DD HH:mm:ss').diff(this.dayjs(), 'second');
+            seconds = seconds - subTime;
             let str = '';
             let d = Math.floor(seconds / 24 / 3600);
             if (abs(d) > 0) {
                 str += d + '天 ';
             }
 
-            this.startTime =
+            this[key] =
                 str +
                 this.pad(parseInt(seconds / 3600) % 24, 2) +
                 ':' +
                 this.pad(parseInt(seconds / 60) % 60, 2) +
                 ':' +
                 this.pad(seconds % 60, 2);
-            if (this.timer) {
-                clearTimeout(this.timer);
-                this.timer = null;
+            if (this[key + 'timer']) {
+                clearTimeout(this[key + 'timer']);
+                this[key + 'timer'] = null;
             }
             if (!this.dayjs().isBefore(this.dayjs(startTime, 'YYYY-MM-DD HH:mm:ss'))) {
                 if (this.getProduct) {
                     this.getProduct();
                 }
-                this.startTime = '';
+                this[key] = '';
             } else {
-                this.timer = setTimeout(() => {
-                    this.getTime(startTime);
+                this[key + 'timer'] = setTimeout(() => {
+                    this.getTime(startTime, key);
                 }, 1000);
             }
         },

+ 9 - 0
src/router/index.js

@@ -344,6 +344,15 @@ const routes = [
             title: '第九空间'
         }
     },
+    {
+        path: '/consignmentAgreement',
+        name: 'consignmentAgreement',
+        component: () => import('../views/asset/Agreement.vue'),
+        meta: {
+            pageType: Page.Every,
+            title: '第九空间'
+        }
+    },
     {
         path: '/assetSearch',
         name: 'assetSearch',

+ 38 - 6
src/styles/app.less

@@ -202,20 +202,21 @@ input:-webkit-autofill {
 }
 
 .page-detail img {
-    width: 100%;
+    width: 100% !important;
+    height: auto !important;
 }
 
 .filter-bg {
-    position: absolute;
+    position: fixed;
     z-index: -1;
     top: 0;
     left: 0;
     right: 0;
     bottom: 0;
-    filter: blur(20px);
-    background-position: center;
-    background-size: cover;
-    background-attachment: fixed;
+    filter: blur(5px);
+    // background-position: center;
+    // background-size: content;
+    // background-attachment: fixed;
 }
 .van-key--blue {
     background-color: @prim!important;
@@ -234,3 +235,34 @@ input:-webkit-autofill {
     opacity: 1;
     transition: opacity 0.8s ease-in-out;
 }
+
+.activeAvatar {
+    overflow: initial !important;
+    img {
+        border-radius: 100px;
+        // border: 4px solid;
+        // border-image: linear-gradient(
+        //         140deg,
+        //         rgba(78, 251, 30, 1),
+        //         rgba(239, 255, 236, 1),
+        //         rgba(79, 251, 31, 1),
+        //         rgba(232, 255, 230, 1),
+        //         rgba(78, 251, 30, 1)
+        //     )
+        //     4 4;
+        box-sizing: border-box;
+        // box-shadow: 0px 0px 6px 0px rgba(38, 245, 13, 0.6);
+    }
+    position: relative;
+    &::after {
+        content: '';
+        background-image: url(https://cdn.raex.vip/png-touxiangkuang.png);
+        background-size: 100% 100%;
+        position: absolute;
+        left: 50%;
+        top: 47%;
+        transform: translate(-50%, -50%);
+        width: 126%;
+        height: 126%;
+    }
+}

+ 3 - 3
src/styles/font.less

@@ -5,16 +5,16 @@
 
 @font-face {
   font-family: 'OSP';
-  src: url(https://zhirongip.oss-cn-hangzhou.aliyuncs.com/fonts/OSP-DIN.ttf);
+  src: url(https://cdn.raex.vip/font/OSP-DIN.ttf);
 }
 
 @font-face {
   font-family: 'DIN';
-  src: url(https://zhirongip.oss-cn-hangzhou.aliyuncs.com/fonts/OSP-DIN.ttf);
+  src: url(https://cdn.raex.vip/font/OSP-DIN.ttf);
 }
 @font-face {
   font-family: 'SourceHanSans-Medium';
-  src: url(https://raex-meta.oss-cn-shenzhen.aliyuncs.com/font/SourceHanSans-Medium.otf);
+  src: url(https://cdn.raex.vip/font/SourceHanSans-Medium.otf);
 }
 
 

+ 1 - 1
src/views/Discover.vue

@@ -104,7 +104,7 @@
         <div class="box">
             <page-title title="更多藏品" :isLink="false"></page-title>
             <van-list
-                style="padding-bottom: 100px;"
+                style="padding-bottom: 100px"
                 class="box-list"
                 v-model:loading="loading"
                 :finished="finished"

+ 1 - 1
src/views/DiscoverPre.vue

@@ -142,7 +142,7 @@ export default {
                 .post(
                     '/collection/all',
                     {
-                        page: 0,
+                        page: this.page,
                         size: 20,
                         query: {
                             onShelf: true,

+ 99 - 15
src/views/Home.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="home">
-        <div class="filter-bg"></div>
+        <div class="filter-bg" :style="{ backgroundImage: `url(${bgImg})` }"></div>
         <div class="welcom">
             <div class="left">
                 <div class="text1">WELCOME</div>
@@ -10,6 +10,7 @@
                 width="38"
                 height="38"
                 :radius="32"
+                :class="{ activeAvatar: isLogin && userInfo.useCollectionPic }"
                 :src="isLogin ? userInfo.avatar : require('@assets/img_default_photo.png')"
             ></van-image>
         </div>
@@ -27,17 +28,28 @@
             </swiper-slide>
         </swiper>
 
-        <div class="list">
+        <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" v-if="active == 0">
             <product-large
                 v-for="(item, index) in products"
                 :key="index"
                 v-model:info="products[index]"
             ></product-large>
         </div>
+        <template v-else>
+            <van-list v-model:loading="loading" :finished="finished" finished-text="" @load="getNews">
+                <news-info v-for="item in news" :key="item.id" :info="item"></news-info>
+            </van-list>
+        </template>
     </div>
 </template>
 
 <script>
+import product from '../mixins/product';
 import { Swiper, SwiperSlide } from 'swiper/vue';
 
 import 'swiper/swiper.min.css';
@@ -52,16 +64,18 @@ import banner from '../mixins/banner';
 import ProductLarge from '../components/product/productLarge.vue';
 import ProductSmall from '../components/product/productSmall.vue';
 import { mapState } from 'vuex';
+import NewsInfo from '../components/product/NewsInfo';
 
 export default {
     name: 'home',
     inject: ['bar'],
-    mixins: [banner],
+    mixins: [banner, product],
     components: {
         Swiper,
         SwiperSlide,
         ProductLarge,
-        ProductSmall
+        ProductSmall,
+        NewsInfo
     },
     computed: {
         ...mapState(['userInfo'])
@@ -69,7 +83,14 @@ export default {
     data() {
         return {
             banners: [],
-            products: []
+            products: [],
+            active: 0,
+            news: [],
+            loading: false,
+            finished: false,
+            page: 0,
+            empty: false,
+            bgImg: ''
         };
     },
     mounted() {
@@ -78,6 +99,9 @@ export default {
             StatusBar.styleDefault();
         }
         this.getInit();
+        // this.$http.get('sysConfig/get/home_bg').then(res => {
+        //     this.bgImg = res.value || '';
+        // });
     },
     methods: {
         getInit() {
@@ -89,6 +113,7 @@ export default {
             this.getProduct('LIST').then(res => {
                 this.products = res;
             });
+            this.getNews();
         },
         getProduct(type = 'BANNER') {
             return this.$http
@@ -105,7 +130,8 @@ export default {
                     '/banner/all',
                     {
                         query: {
-                            type: 'HOME'
+                            type: 'HOME',
+                            del: false
                         },
                         sort: 'sort,asc;createdAt,desc'
                     },
@@ -120,9 +146,6 @@ export default {
             if (this.page === 0) {
                 this.list = [];
             }
-            this.loading = true;
-            this.finished = false;
-            this.empty = false;
             this.$http
                 .post(
                     '/collection/all',
@@ -139,9 +162,6 @@ export default {
                 )
                 .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;
                     }
@@ -163,12 +183,45 @@ export default {
                     this.miners = res.content;
                     // console.log(this.miners);
                 });
+        },
+        getNews() {
+            if (this.page === 0) {
+                this.news = [];
+            }
+            this.loading = true;
+            this.finished = false;
+            this.empty = false;
+            this.$http
+                .post(
+                    '/news/all',
+                    {
+                        page: this.page,
+                        size: 20,
+                        query: {
+                            del: false
+                        },
+                        sort: 'sort,asc;createdAt,desc'
+                    },
+                    { body: 'json' }
+                )
+                .then(res => {
+                    this.news = [...this.news, ...res.content];
+                    this.empty = res.empty;
+                    this.loading = false;
+                    this.finished = res.last;
+                    if (!this.finished) {
+                        this.page = this.page + 1;
+                    }
+                });
         }
     }
 };
 </script>
 
 <style lang="less" scoped>
+.darkBg {
+    background-color: #181818;
+}
 .top {
     display: flex;
     padding: 9px 16px;
@@ -225,7 +278,7 @@ export default {
     }
 
     .swiper-pagination-bullet-active {
-        background: @prim;
+        background: #fff;
     }
 }
 .swiper-slide {
@@ -245,13 +298,13 @@ export default {
         .text1 {
             font-size: 12px;
             font-weight: bold;
-            color: #939599;
+            color: @text0;
             line-height: 24px;
         }
         .text2 {
             font-size: 24px;
             font-weight: bold;
-            color: #0a0a0a;
+            color: @text0;
             line-height: 32px;
             letter-spacing: 2px;
 
@@ -263,4 +316,35 @@ export default {
         }
     }
 }
+
+.tabs {
+    .flex();
+    font-size: 14px;
+    color: fade(@text0, 60%);
+    line-height: 24px;
+    padding: 0 16px;
+
+    .tab + .tab {
+        margin-left: 20px;
+    }
+
+    .tab {
+        position: relative;
+        &.active {
+            font-weight: bold;
+            color: @text0;
+
+            &::after {
+                content: '';
+                height: 2px;
+                background-color: #fff;
+                width: 18px;
+                position: absolute;
+                bottom: -2px;
+                left: 50%;
+                transform: translateX(-50%);
+            }
+        }
+    }
+}
 </style>

+ 1 - 0
src/views/Mine.vue

@@ -17,6 +17,7 @@
                         height="78"
                         :src="userInfo.avatar || require('@assets/img_default_photo.png')"
                         fit="cover"
+                        :class="{ activeAvatar: isLogin && userInfo.useCollectionPic }"
                         @click="$router.push('/setting')"
                     />
                     <div class="text">

+ 1 - 1
src/views/Submit.vue

@@ -295,7 +295,7 @@ export default {
                 collectionId: this.$route.query.id,
                 qty: 1,
                 couponId: (this.couponInfo || {}).id || '',
-                invitor: sessionStorage.getItem('invitor'),
+                invitor: this.$store.state.invitor || '',
                 vip: this.$store.state.userInfo.vipPurchase > 0 ? true : false
             };
             params.sign = encryptUtil.encrypt(qs.stringify({ ...params, ts: new Date().getTime() }));

+ 1 - 1
src/views/account/Setting.vue

@@ -85,7 +85,7 @@ export default {
                 forbidClick: true
             });
             this.updateFile(e, 500).then(img => {
-                this.updateUser({ avatar: img }).then(res => {
+                this.updateUser({ avatar: img, useCollectionPic: false }).then(res => {
                     this.$toast.clear();
                 });
             });

+ 2 - 3
src/views/activity/List1.vue

@@ -62,8 +62,7 @@ export default {
         beforeData() {
             return {
                 query: {
-                    del: false,
-                    onShelf: false
+                    del: false
                 }
             };
         }
@@ -79,7 +78,7 @@ export default {
     position: relative;
     .filter-bg {
         background-position: top;
-        background-size: 100% 500px;
+        // background-size: 100% 500px;
         background-repeat: no-repeat;
         top: 50px;
     }

+ 205 - 0
src/views/asset/Agreement.vue

@@ -0,0 +1,205 @@
+<template>
+    <van-overlay :show="show" @click="show = false" :lock-scroll="false" z-index="99">
+        <div class="content" ref="content" @click.stop="">
+            <div>
+                <div class="align-center">RAEX绿洲宇宙华储艺术品中心委托拍卖协议</div>
+                <h4>委托方(以下简称“甲方”):{{ identityAuthInfo.realName }}</h4>
+                <h3>身份证号:{{ identityAuthInfo.idNo }}</h3>
+                <h3>联系电话:{{ identityAuthInfo.phone }}</h3>
+                <h4>拍卖方 (以下简称“乙方”):华储艺术品中心(深圳)有限公司</h4>
+                <h5>鉴于:</h5>
+                <p>
+                    1、甲方系本协议约定拍卖品的所有人或受所有人全权委托而签署和履行本协议。<br />
+                    2、乙方系具有合法拍卖资质和拍卖经验的拍卖企业,愿意接受委托进行拍卖。<br />
+                    3、本协议构成甲乙双方之间委托拍卖合同关系。<br />
+                    为此,甲乙双方依照《拍卖法》、《民法典》等法律法规的规定,于本协议网络签署日在深圳市福田区达成协议如下:
+                </p>
+                <h5>一、委托关系</h5>
+                <p>
+                    1、乙方系接受甲方委托按照乙方的拍卖程序,通过RAEX绿洲宇宙APP对外公开拍卖,但乙方对拍卖成交不承担保证责任,也不对竞买人的支付能力承担担保责任。<br />
+                    2、甲方知晓并认可乙方的拍卖程序,并愿意按照乙方的拍卖程序进行拍卖和拍卖交割,由其对拍卖交易的后果承担全部法律责任。
+                </p>
+                <h5>二、拍卖品</h5>
+                <p>
+                    1、甲方委托乙方拍卖的标的:本数字艺术作品。<br />
+                    2、甲方保证其对拍卖标的拥有完全所有权及处分权或者得到了所有权人的完全授权。<br />
+                    3、甲方就拍卖品的合法性向乙方承诺:<br />
+                    (1)拍卖品来源合法,非盗抢等赃物、非走私物等其他非法物品。<br />
+                    (2)拍卖品不存在权属争议,也未设定抵押或质押或留置等负担。<br />
+                    (3)拍卖品不存在侵犯他人版权、肖像权等合法权利的情形。<br />
+                    4、甲方承诺:根据乙方的要求提供拍卖标的的有关证明和资料,说明知道或应当知道的拍卖标的瑕疵;如参与竞买人对拍卖品提出疑问或异议,甲方应及时予以说明或澄清;甲方对于前述提供的证明、资料及相关说明、澄清等,均保证其真实性,不得弄虚作假。
+                </p>
+                <h5>三、拍卖安排</h5>
+                <h5>1、拍卖前的评估、鉴定:</h5>
+                <p>
+                    (1)甲方应合理对标的拍卖商品进行合理评估,不得恶意炒作,不得恶意哄抬价格,不得故意进行“托价”行为。<br />
+                    (2)竞买人拍得拍卖品后,如委托评估或鉴定机构进行价值评估或相应鉴定,或者其评估、鉴定结论与甲方在拍卖前进行的评估或鉴定结论不符,由甲方与竞买人协商或按照法律规定处理,乙方与此无关,若因此造成乙方损失,甲方负责赔偿。
+                </p>
+                <h5>2、拍卖期限、地点:</h5>
+                <p>
+                    双方确认:拍卖品通过乙方自有APP或网站,以网络方式向竞买人拍卖。拍卖时间为立即拍卖或由双方另行协商确认,或乙方按其相关安排自主确定拍卖时间。
+                </p>
+                <h5>3、拍卖价格:</h5>
+                <p>
+                    (1)保留价:拍卖品的保留价由甲方在拍卖前确定,乙方可对保留价的确定提供相关意见。<br />
+                    (2)竞买人的最高应价未达到保留价时,乙方不得确认成交。<br />
+                    (3)甲方可自行设置拍卖标的拍卖一口价,同时,甲方授权乙方随时调整拍卖标的的最高可售价格而无需另行取得甲方同意。
+                </p>
+                <h5>4、拍卖品的产权转移:</h5>
+                <p>
+                    (1)拍卖一旦成交,视为甲方对拍卖结果及拍卖价格无异议。<br />
+                    (2)拍卖成交后,拍卖标的将由RAEX绿洲宇宙APP自动转移至买受人。<br />
+                    (3)拍卖成交后,拍卖所得款项在扣除乙方及RAEX绿洲宇宙APP应得款项后,在T+1个工作日支付至甲方指定的银行账户内。
+                </p>
+                <h5>5、特别承诺:</h5>
+                <p>
+                    (1)甲方承诺:自己不参与竞买,也不委托他人代为参与竞买拍卖品。<br />
+                    (2)任何一方不得擅自变更拍卖品的保留价,乙方也不得低于保留价拍卖。<br />
+                    (3)乙方不得转委托而将拍卖品委托其他人进行拍卖。
+                </p>
+                <h5>6、拍卖的佣金与费用:</h5>
+                <p>
+                    双方确认,拍卖佣金为拍卖成交价的2.5%的佣金。该佣金在甲方向RAEX绿洲宇宙APP支付的5%的平台服务费中扣除。
+                </p>
+                <h5>7、拍卖品的撤回与撤除:</h5>
+                <p>
+                    (1)甲方在拍卖开始前可以在RAEX绿洲宇宙APP上取消对拍卖品的拍卖委托并撤回拍卖品。但若因此造成乙方或他方损失的,乙方应承担全部赔偿责任。<br />
+                    (2)乙方有确切证据证明拍卖标的存在下列情况之一的,有权单方解除本协议,撤销对拍卖品的拍卖,并不承担由此产生的法律责任:<br />
+                    ① 拍卖品的来源不合法或与甲方承诺不符。<br />
+                    ② 拍卖品权属存在争议或权属状况与甲方声明不一致的。<br />
+                    ③ 拍卖品非真品或存在甲方未声明的重大瑕疵的。
+                </p>
+                <h5>8、终止委托:</h5>
+                <p>
+                    (1)本合同本协议因下列情形之一,终止委托且本合同本协议终止,但如有违约责任或未结清事项,则应在合同终止前承担违约责任或结清相关事项。<br />
+                    ① 流拍。<br />
+                    ② 拍卖成交。 <br />
+                    ③ 甲方撤销委托、撤回拍卖品。<br />
+                    ④ 乙方认为本次委托无效或因本合同本协议被依法或依约解除。<br />
+                    (2)因流拍致使拍卖标的未能售出的,本合同本协议终止;如甲乙双方愿意再次拍卖,则另行续签合同。
+                </p>
+                <h5>四、其他事项:</h5>
+                <p>
+                    1、违约责任:<br />
+                    (1)甲乙双方在本协议执行过程中,任何一方不履行协议、违反本协议条约内容,即为违约,且应承担违约责任。<br />
+                    (2)甲方隐瞒拍卖品的瑕疵或拍卖品的权属瑕疵,应赔偿由此给乙方造成的损失。<br />
+                    (3)甲方参与竞买或委托他人代为竞买自己委托的拍卖品的、甲方故意恶意炒作价格的、甲方进行“托价”行为的,乙方有权制止甲方的相应行为或向有关行政机关举报,并解除合同;甲方对乙方由此受到的损失应承担赔偿责任。<br />
+                    2、争议解决:双方因本协议的解释或履行发生争议,应先由双方协商解决。如协商不成,双方任何一方可向乙方所在地人民法院提起诉讼。<br />
+                    3、本协议为电子方式签署。自甲方点击“我已阅读且同意签署”按钮即视为协议生效。<br />
+                    4、甲方联络方式为其在乙方RAEX绿洲宇宙APP上所确认之联系方式,若甲方变更联络方式的,应及时通过乙方RAEX绿洲宇宙APP修改或变更。
+                </p>
+
+                <h4>甲方(签章):{{ identityAuthInfo.realName }}</h4>
+                <h3>签订日期:{{ date }}</h3>
+                <h4>乙方(签章):华储艺术品中心(深圳)有限公司</h4>
+                <h3>签订日期:{{ date }}</h3>
+                <h3>签约地点:中国深圳福田区</h3>
+
+                <h5>
+                    本人自愿委托华储进行《{{ info.name }}》,<span v-if="info.number">编号{{ info.number }}</span
+                    >的拍卖。
+                </h5>
+
+                <div class="btn">
+                    <van-button type="primary" round block @click="sure">我已阅读且完全理解</van-button>
+                </div>
+            </div>
+        </div>
+    </van-overlay>
+</template>
+
+<script>
+import { mapState } from 'vuex';
+export default {
+    computed: {
+        ...mapState(['userInfo'])
+    },
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {
+            identityAuthInfo: {},
+            date: '',
+            show: false
+        };
+    },
+    mounted() {
+        this.$http
+            .post(
+                '/identityAuth/all',
+                {
+                    query: {
+                        userId: this.userInfo.id
+                    }
+                },
+                { body: 'json' }
+            )
+            .then(res => {
+                if (!res.empty) {
+                    this.identityAuthInfo = res.content[0];
+                }
+            });
+        this.date = this.dayjs().format('YYYY年MM月DD日');
+    },
+    methods: {
+        sure() {
+            this.show = false;
+            this.$emit('agree');
+        },
+        init() {
+            this.show = true;
+            this.$refs.content.scrollTop = 0;
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.content {
+    background: @bg;
+    border-radius: 8px;
+    padding: 16px;
+    width: 80vw;
+    height: 60vh;
+    overflow: auto;
+    z-index: 100;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    -webkit-overflow-scrolling: touch;
+    .align-center {
+        font-size: @font3;
+        font-weight: bold;
+        text-align: center;
+        margin: 0;
+        padding-bottom: 10px;
+    }
+    p {
+        font-size: @font2;
+        margin: 6px 0 0;
+        color: @text3;
+    }
+
+    h4,
+    h5,
+    h6 {
+        font-size: @font2;
+        margin: 20px 0 0;
+    }
+    h3 {
+        font-size: @font2;
+        margin: 0 0 0;
+    }
+}
+
+.btn {
+    margin: 10px 20px 20px;
+}
+</style>

+ 28 - 10
src/views/asset/Consignment.vue

@@ -7,7 +7,7 @@
             </div>
             <div class="border border1"></div>
             <div class="content">
-                <div class="title">寄售价格(元)<span>最高定价20000.00</span></div>
+                <div class="title">寄售价格(元)<span>最高定价100000.00(超过20000的需要签署委托协议)</span></div>
                 <!-- <van-field type="number" input-align="center" placeholder="请输入价格" v-model="price" /> -->
                 <van-stepper
                     v-model="price"
@@ -16,9 +16,10 @@
                     :show-minus="false"
                     :decimal-length="2"
                     allow-empty
-                    max="20000"
                     min="0"
+                    max="100000"
                     placeholder="请输入价格"
+                    @change="agreement = false"
                 />
                 <div class="title">预计收入(元)</div>
                 <div class="info-item">
@@ -76,12 +77,15 @@
             </div>
         </div>
         <div class="border"></div>
+        <agreement ref="agree" :info="info" @agree="agree"></agreement>
     </div>
 </template>
 
 <script>
 import { mapState } from 'vuex';
+import Agreement from '../asset/Agreement.vue';
 export default {
+    components: { Agreement },
     name: 'Top',
     inject: ['changeScroll'],
     data() {
@@ -107,7 +111,8 @@ export default {
                     title: '5. 因电子支付通道限制,单笔限额20000元'
                 }
             ],
-            info: {}
+            info: {},
+            agreement: false
         };
     },
     computed: {
@@ -154,8 +159,14 @@ export default {
                     this.sets = res.set;
                 });
         },
+        agree() {
+            this.agreement = true;
+            this.submit();
+        },
         submit() {
-            if (Number(this.price)) {
+            if (Number(this.price) > 20000 && !this.agreement) {
+                this.$refs.agree.init();
+            } else if (Number(this.price)) {
                 this.$dialog
                     .confirm({
                         title: '寄售',
@@ -167,8 +178,15 @@ export default {
                             message: '加载中...',
                             forbidClick: true
                         });
-                        return this.$http.post('/user/verifyTradeCode', {
-                            tradeCode: this.password
+                        return new Promise((resolve, reject) => {
+                            this.$http
+                                .post('/user/verifyTradeCode', {
+                                    tradeCode: this.password
+                                })
+                                .then(_ => resolve())
+                                .catch(e => {
+                                    reject({ error: '密码错误' });
+                                });
                         });
                     })
                     .then(() => {
@@ -178,8 +196,8 @@ export default {
                         });
                     })
                     .catch(e => {
-                        if (e && e.error) {
-                            this.$toast('密码错误');
+                        if (e.error) {
+                            this.$toast(e.error || '出现错误,请稍后再试');
                         }
                         return Promise.reject('cancel');
                     })
@@ -291,9 +309,9 @@ export default {
     .title {
         font-size: 14px;
         color: @text0;
-        line-height: 30px;
+        // line-height: 30px;
         margin-top: 5px;
-        padding-left: 16px;
+        padding: 5px 16px 5px;
     }
     .name {
         padding-left: 16px;

+ 28 - 2
src/views/product/Detail.vue

@@ -256,22 +256,44 @@
                             <span>{{ startTime }}</span>
                         </div>
                     </van-button>
+
                     <!-- <van-button class="no-btn" v-else-if="isSold" block round>已售罄</van-button> -->
                     <van-button class="no-btn" v-else-if="isSolded" block round>已售罄</van-button>
                     <van-button class="no-btn" v-else-if="isSold" block round>即将售罄</van-button>
                     <van-button class="no-btn" v-else-if="limit.limit > 0 && limit.count >= limit.limit" block round>
                         限购{{ limit.limit }}件
                     </van-button>
-                    <template v-else-if="assignment && assignments.length < assignment">
+                    <template v-else-if="assignment && ((isLogin && userInfo.vipPoint < 1) || !isLogin)">
                         <div class="btn-assignments" v-if="isLogin && userInfo.vipPurchase">
                             <van-button @click="vipAssignment" class="vip" type="danger" block round>
                                 vip通道
                             </van-button>
-                            <van-button @click="share" type="primary" block round>邀请获取 </van-button>
+                            <van-button style="font-size: 12px" class="no-btn" v-if="info.vipQuota < 1" block round>
+                                名额为空
+                            </van-button>
+                            <van-button @click="share" v-else type="primary" block round>邀请获取 </van-button>
                         </div>
+                        <van-button
+                            style="font-size: 12px"
+                            class="no-btn"
+                            v-if="info.vipQuota < 1 || assignments.length >= assignment"
+                            block
+                            round
+                        >
+                            活动名额已被抢光
+                        </van-button>
                         <van-button @click="share" v-else type="primary" block round>邀请获取白名单 </van-button>
                     </template>
 
+                    <template v-else-if="assignment && isSale && info.timeDelay">
+                        <van-button class="no-btn" block round>
+                            <div class="appoint">
+                                <span style="font-size: 12px">任务完成,即将抢购</span>
+                                <span>{{ saleTime }}</span>
+                            </div>
+                        </van-button>
+                    </template>
+
                     <van-button v-else type="primary" block round @click="buy">
                         {{ info.couponPayment ? '立即兑换' : '立即购买' }}
                     </van-button>
@@ -362,6 +384,7 @@ export default {
     mounted() {
         this.$store.dispatch('getUsedBuy');
         this.$store.dispatch('getTime');
+        this.$store.dispatch('getUserInfo');
         this.getProduct();
         this.$http.get('/order/checkLimit', { collectionId: this.$route.query.id }).then(res => {
             this.limit = res;
@@ -453,6 +476,9 @@ export default {
                         });
                     }
                     this.getTime(res.startTime);
+                    if (res.saleTime) {
+                        this.getTime(res.saleTime, 'saleTime');
+                    }
                     this.$nextTick(() => {
                         if (this.isBuy) {
                             this.btn = this.$refs.btn;

+ 2 - 1
src/views/product/List.vue

@@ -193,7 +193,8 @@ export default {
                     '/banner/all',
                     {
                         query: {
-                            type: 'MARKET'
+                            type: 'MARKET',
+                            del: false
                         },
                         sort: 'sort,asc;createdAt,desc'
                     },

+ 3 - 5
vue.config.js

@@ -7,10 +7,10 @@ switch (process.env.NODE_ENV) {
         publicPath = '/';
         break;
     case 'production':
-        publicPath = `https://raex-meta.oss-cn-shenzhen.aliyuncs.com/www/` + new Date().getTime();
+        publicPath = `https://cdn.raex.vip/www/` + new Date().getTime();
         break;
     case 'test':
-        publicPath = `https://raex-meta.oss-cn-shenzhen.aliyuncs.com/www_test/` + new Date().getTime();
+        publicPath = `https://cdn.raex.vip/www_test/` + new Date().getTime();
         break;
 }
 module.exports = {
@@ -27,9 +27,7 @@ module.exports = {
     },
     chainWebpack: config => {
         if (process.env.NODE_ENV === 'production') {
-            config
-                .plugin('upload')
-                .use(new UploadPlugin(publicPath.replace('https://raex-meta.oss-cn-shenzhen.aliyuncs.com/', '')));
+            config.plugin('upload').use(new UploadPlugin(publicPath.replace('https://cdn.raex.vip/', '')));
         }
         config.output.filename('[name].[hash].js').end();
         config.resolve.alias.set('@assets', path.resolve(__dirname, 'src', 'assets'));