Browse Source

vip页面

panhui 2 years ago
parent
commit
433b111a2c

+ 2 - 2
.env.development

@@ -1,7 +1,7 @@
 # Glob API URL
-VITE_GLOB_API_URL=http://localhost:3000/api
+VITE_GLOB_API_URL=https://chillgpt.raexmeta.com/api
 
-VITE_APP_API_BASE_URL=http://localhost:3000/api
+VITE_APP_API_BASE_URL=https://chillgpt.raexmeta.com/api
 
 # Whether long replies are supported, which may result in higher API fees
 VITE_GLOB_OPEN_LONG_REPLY=false

BIN
src/assets/bg_share_card.png


BIN
src/assets/huihua.png


BIN
src/assets/qiye.png


+ 30 - 10
src/components/common/ShareModal.vue

@@ -1,15 +1,22 @@
 <template>
     <n-modal v-model:show="showModal" transform-origin="center">
         <div class="share-box">
-            <img :src="imgUrl" v-if="imgUrl" alt="" class="shareImgUrl" />
-            <div class="share-img" v-else ref="postRef">
+            <img :src="imgUrl" v-if="imgUrl" alt="" class="shareImgUrl w-5/6 max-w-md" />
+            <div class="share-img w-5/6 relative max-w-md" v-else ref="postRef">
                 <img src="@/assets/bg_share_card.png" class="bg" alt="" />
-                <div class="qrcode">
-                    <qrcode-vue :value="shareUrl" :size="124" level="H" />
+                <!-- <div class="absolute inset-x-0 top-0">
+                    <user-avatar avatarType="small" onlyAvatar />
+                </div> -->
+                <div class="qrcode flex items-center justify-center">
+                    <qrcode-vue :value="shareUrl" :size="300" renderAs="svg" level="H" />
                 </div>
             </div>
 
-            <div class="tips">长按保存图片</div>
+            <div class="tips" v-if="isMobile">长按保存图片</div>
+            <div class="mt-16" v-else>
+                <n-button type="primary" @click="down">点击保存图片</n-button>
+            </div>
+
             <n-button text class="cancel" @click.stop="showModal = false"> 取消 </n-button>
         </div>
     </n-modal>
@@ -22,6 +29,8 @@ import QrcodeVue from 'qrcode.vue'
 import html2canvas from 'html2canvas'
 import resolveUrl from 'resolve-url'
 import { useUserStore } from '@/store'
+import { UserAvatar } from '@/components/common'
+import { useBasicLayout } from '@/hooks/useBasicLayout'
 import { Ref } from 'vue'
 const showModal = ref(false)
 
@@ -32,6 +41,9 @@ const userStore = useUserStore()
 const shareUrl = computed(() => {
     return resolveUrl(baseURL, '#/login?invitor=' + userStore.userInfo.id)
 })
+const userInfo = computed(() => {
+    return userStore.userInfo
+})
 
 const postRef: Ref<HTMLElement | null> = ref(null)
 function init() {
@@ -53,38 +65,46 @@ function down() {
     const tempLink = document.createElement('a')
     tempLink.style.display = 'none'
     tempLink.href = imgUrl.value
-    tempLink.setAttribute('download', 'chat-shot.png')
+    tempLink.setAttribute('download', 'chat-share.png')
     if (typeof tempLink.download === 'undefined') tempLink.setAttribute('target', '_blank')
 
     document.body.appendChild(tempLink)
     tempLink.click()
     document.body.removeChild(tempLink)
     window.URL.revokeObjectURL(imgUrl.value)
+    showModal.value = false
 }
 
+const { isMobile } = useBasicLayout()
+
 defineExpose({ init })
 </script>
 
 <style lang="less" scoped>
 .share-img {
     .bg {
-        width: 300px;
         display: block;
     }
 
     .qrcode {
         position: absolute;
-        top: 167px;
-        left: 85px;
+        top: 48%;
+        left: 30%;
         background-color: #fff;
         box-shadow: 0px 0px 4px 0px rgba(163, 121, 255, 0.5);
         padding: 6px;
         border-radius: 8px;
+        width: 40%;
+        height: 29%;
+        :deep(svg) {
+            width: 100%;
+            height: 100%;
+        }
     }
 }
 
 .shareImgUrl {
-    width: 300px;
+    // width: 300px;
     display: block;
 }
 

+ 1 - 12
src/components/common/UserAvatar.vue

@@ -23,7 +23,7 @@ const props = defineProps({
 
 <template>
     <div class="flex items-center overflow-hidden">
-        <div class="w-10 h-10 overflow-hidden rounded-full shrink-0" :class="[avatarType]">
+        <div class="w-10 h-10 overflow-hidden rounded-full shrink-0 flex items-center justify-center">
             <template v-if="isString(userInfo.avatar) && userInfo.avatar.length > 0">
                 <NAvatar :size="avatarType" round :src="userInfo.avatar" :fallback-src="defaultAvatar" />
             </template>
@@ -43,17 +43,6 @@ const props = defineProps({
 </template>
 
 <style lang="less" scoped>
-// .small {
-//     width: 24px;
-//     height: 24px;
-//     --n-avatar-size-override: 24px;
-// }
-
-// .large {
-//     width: 50px;
-//     height: 50px;
-//     --n-avatar-size-override: 50px;
-// }
 
 .large-text {
     h2 {

+ 70 - 0
src/components/common/UserAvatar/index.vue

@@ -0,0 +1,70 @@
+<script setup lang="ts">
+import { computed } from 'vue'
+import { NAvatar, avatarProps } from 'naive-ui'
+import { useUserStore } from '@/store'
+import defaultAvatar from '@/assets/avatar.png'
+import { isString } from '@/utils/is'
+
+const userStore = useUserStore()
+
+const userInfo = computed(() => userStore.userInfo)
+
+const props = defineProps({
+    avatarType: {
+        type: avatarProps.size,
+        default: 'large'
+    },
+    onlyAvatar: {
+        type: Boolean,
+        default: false
+    }
+})
+</script>
+
+<template>
+    <div class="flex items-center overflow-hidden">
+        <div class="w-10 h-10 overflow-hidden rounded-full shrink-0">
+            <template v-if="isString(userInfo.avatar) && userInfo.avatar.length > 0">
+                <NAvatar :size="avatarType" round :src="userInfo.avatar" :fallback-src="defaultAvatar" />
+            </template>
+            <template v-else>
+                <NAvatar :size="avatarType" round :src="defaultAvatar" />
+            </template>
+        </div>
+        <div class="flex-1 min-w-0 ml-2" v-if="!onlyAvatar" :class="[avatarType + '-text']">
+            <h2 class="overflow-hidden font-bold text-md text-ellipsis whitespace-nowrap">
+                {{ userInfo.name ?? 'ChenZhaoYu' }}
+            </h2>
+            <p class="overflow-hidden text-xs text-ellipsis whitespace-nowrap">
+                <span>2023年05月01日到期</span>
+            </p>
+        </div>
+    </div>
+</template>
+
+<style lang="less" scoped>
+// .small {
+//     width: 24px;
+//     height: 24px;
+//     --n-avatar-size-override: 24px;
+// }
+
+// .large {
+//     width: 50px;
+//     height: 50px;
+//     --n-avatar-size-override: 50px;
+// }
+
+.large-text {
+    h2 {
+        font-size: 16px;
+    }
+    p {
+        margin-top: 4px;
+    }
+}
+
+h2 {
+    color: var(--n-text-color);
+}
+</style>

+ 1 - 0
src/components/common/VipCard.vue

@@ -71,6 +71,7 @@ function goVip() {
         .btn {
             position: relative;
             width: 82px;
+            cursor: pointer;
             img {
                 width: 82px;
                 height: 29px;

+ 123 - 0
src/components/common/VipPannel.vue

@@ -0,0 +1,123 @@
+<template>
+    <div class="page h-full">
+        <n-card :bordered="false">
+            <vip-card pageType="vip"></vip-card>
+        </n-card>
+
+        <n-card title="专属权益" :bordered="false">
+            <n-grid cols="4" responsive="screen" class="backdrop-blur-lg">
+                <n-grid-item v-for="item in items" :key="item.name">
+                    <div class="flex flex-col items-center pt-5 pb-7">
+                        <img class="w-10 h-10" :src="item.img" alt="" />
+                        <div class="text text-xs mt-2 text-center">
+                            <div>{{ item.name }}</div>
+                            <div class="mt-0.5">{{ item.desc }}</div>
+                        </div>
+                    </div>
+                </n-grid-item>
+            </n-grid>
+        </n-card>
+
+        <div class="btn-list flex items-align px-5 overflow-x-auto pt-5">
+            <div
+                class="choose-btn w-2/5 flex-shrink-0 flex-col items-center text-center pb-5 pt-4 border rounded-lg"
+                v-for="i in 3"
+                :key="i"
+            >
+                <div class="text-black dark:text-white text-base">3个月</div>
+                <div class="text-3xl font-medium"><span class="text-base">¥</span>399</div>
+            </div>
+        </div>
+
+        <div class="px-6 py-10">
+            <n-button type="primary" size="large" round block>¥399 立即开通</n-button>
+        </div>
+    </div>
+</template>
+<script setup lang="ts">
+import { VipCard } from '@/components/common'
+import { NCard, NEl, NPageHeader, NRow, NCol, NGrid, NGridItem, NButton, NIcon } from 'naive-ui'
+import { useRouter } from 'vue-router'
+import imgItem01 from '@/assets/png-01.png'
+import imgQiye from '@/assets/qiye.png'
+import imgHuihua from '@/assets/huihua.png'
+import imgItem02 from '@/assets/png-02.png'
+import imgItem03 from '@/assets/png-03.png'
+import imgItem05 from '@/assets/png-05.png'
+import imgItem06 from '@/assets/png-06.png'
+import imgItem07 from '@/assets/png-07.png'
+
+const router = useRouter()
+function handleBack() {
+    router.back()
+}
+
+const items = [
+    {
+        name: '无限对话',
+        desc: '畅快聊天',
+        img: imgItem01
+    },
+    {
+        name: '独立会话',
+        desc: '上下文精准约束',
+        img: imgQiye
+    },
+    {
+        name: '企业链路',
+        desc: '高效稳定',
+        img: imgHuihua
+    },
+    {
+        name: '推荐奖励',
+        desc: '一级经销商权限',
+        img: imgItem02
+    },
+    {
+        name: '空投福利',
+        desc: '高价值数字藏品',
+        img: imgItem03
+    },
+    {
+        name: '测试白名单',
+        desc: '第一优先级',
+        img: imgItem05
+    },
+    {
+        name: 'Chillgpt Pix',
+        desc: '六个月免费会员',
+        img: imgItem06
+    },
+    {
+        name: '可申请Chillg',
+        desc: '城市级节点权限',
+        img: imgItem07
+    }
+]
+</script>
+
+<style lang="less" scoped>
+:deep(.n-page-header) {
+    height: 50px;
+    padding: 0 22px;
+    .n-page-header__main {
+        flex-grow: 1;
+        .n-page-header__title {
+            flex-grow: 1;
+            text-align: center;
+        }
+    }
+}
+
+.n-card {
+    --n-padding-left: 20px !important;
+    --n-padding-bottom: 10px !important;
+    background-color: transparent;
+}
+.choose-btn + .choose-btn {
+    margin-left: 23px;
+}
+::-webkit-scrollbar {
+    // display: none;
+}
+</style>

+ 3 - 1
src/components/common/index.ts

@@ -7,5 +7,7 @@ import Share from './ShareModal.vue'
 import Setting from './Setting/SettingIndex.vue'
 import PromptStore from './PromptStore.vue'
 import LoginForm from './LoginForm.vue'
+import MinePannel from './minePannel.vue'
+import VipPannel from './VipPannel.vue'
 
-export { HoverButton, NaiveProvider, SvgIcon, UserAvatar, Setting, PromptStore, VipCard, Share, LoginForm }
+export { HoverButton, NaiveProvider, SvgIcon, UserAvatar, Setting, PromptStore, VipCard, Share, LoginForm, MinePannel,VipPannel }

+ 179 - 0
src/components/common/minePannel.vue

@@ -0,0 +1,179 @@
+<template>
+    <div class="page h-full flex flex-col">
+        <!-- <n-page-header title="个人中心" @back="handleBack"> </n-page-header> -->
+        <n-card :bordered="false">
+            <UserAvatar avatarType="large" />
+        </n-card>
+        <n-card :bordered="false">
+            <vip-card @goVip="goVip"></vip-card>
+        </n-card>
+        <n-card :bordered="false">
+            <n-row gutter="12">
+                <n-col :span="12">
+                    <div class="share-btn" @click="shareEvent">
+                        <div class="share-text">
+                            <div class="text1">邀请好友</div>
+                            <div class="text2">一起赚钱</div>
+                        </div>
+                        <img src="@/assets/png--anniu.png" alt="" />
+                    </div>
+                </n-col>
+                <n-col :span="12">
+                    <div class="share-btn">
+                        <div class="share-text">
+                            <div class="text1">我的收益</div>
+                            <div class="text2">余额:888.00</div>
+                        </div>
+                        <img src="@/assets/png-shouyi.png" alt="" />
+                    </div>
+                </n-col>
+            </n-row>
+        </n-card>
+
+        <div class="flex-1"></div>
+
+        <div class="logout">
+            <n-button @click="logout" quaternary type="primary" block round size="large"> 退出登录 </n-button>
+        </div>
+
+        <share ref="shareRef" />
+
+        <n-modal
+            v-model:show="showVip"
+            :block-scroll="false"
+            transform-origin="center"
+            class="max-w-xl"
+            style="width: 75%"
+        >
+            <n-card :border="false" content-style="padding:0" class="bg-white dark:bg-black rounded-lg">
+                <vip-pannel></vip-pannel
+            ></n-card>
+        </n-modal>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { UserAvatar, VipCard, Share, VipPannel } from '@/components/common'
+import { NCard, NEl, NPageHeader, NRow, NCol, useMessage, NButton, useDialog, NModal } from 'naive-ui'
+import { useRouter } from 'vue-router'
+import { ref } from 'vue'
+import { useUserStore } from '@/store'
+import { useBasicLayout } from '@/hooks/useBasicLayout'
+
+const router = useRouter()
+function handleBack() {
+    router.back()
+}
+
+const message = useMessage()
+
+const { isMobile } = useBasicLayout()
+function goVip() {
+    if (isMobile.value) {
+        router.push({
+            name: 'vip'
+        })
+    } else {
+        showVip.value = true
+    }
+}
+
+const shareRef: any = ref(null)
+function shareEvent() {
+    shareRef.value.init()
+}
+
+const dialog = useDialog()
+const userStore = useUserStore()
+function logout() {
+    dialog.create({
+        title: '提示',
+        content: '确认要退出登录吗?',
+        positiveText: '退出登录',
+        negativeText: '取消',
+        maskClosable: false,
+        onPositiveClick: () => {
+            userStore.logout()
+            message.success('退出登录成功')
+            router.replace('/home')
+        }
+    })
+}
+
+const showVip = ref(false)
+</script>
+
+<style lang="less" scoped>
+.page {
+    color: var(--n-text-color);
+}
+
+.n-card {
+    --n-padding-left: 20px !important;
+    --n-padding-bottom: 10px !important;
+    background-color: transparent;
+}
+
+:deep(.n-page-header) {
+    height: 50px;
+    padding: 0 22px;
+    .n-page-header__main {
+        flex-grow: 1;
+        .n-page-header__title {
+            flex-grow: 1;
+            text-align: center;
+        }
+    }
+}
+.page-top {
+    .f();
+    height: 50px;
+    position: relative;
+    justify-content: center;
+
+    img {
+        width: 24px;
+        height: 24px;
+        position: absolute;
+        top: 13px;
+        left: 22px;
+    }
+
+    .title {
+        font-size: 16px;
+        font-weight: bold;
+        color: #ffffff;
+        line-height: 24px;
+        text-align: center;
+    }
+}
+
+.share-btn {
+    background: var(--bg2);
+    border-radius: 8px;
+    .f();
+    img {
+        width: 45%;
+        max-width: 70px;
+        display: block;
+    }
+
+    .share-text {
+        flex-grow: 1;
+        padding: 12px 0 12px 12px;
+
+        .text1 {
+            font-size: 16px;
+            font-weight: 500;
+            line-height: 24px;
+        }
+
+        .text2 {
+            font-size: 12px;
+            color: var(--n-text-color);
+            opacity: 0.5;
+            line-height: 24px;
+        }
+    }
+}
+</style>

+ 3 - 2
src/store/modules/app/helper.ts

@@ -10,15 +10,16 @@ export interface AppState {
     siderCollapsed: boolean
     theme: Theme
     language: Language
+    minePannel: boolean
 }
 
 export function defaultSetting(): AppState {
-    return { siderCollapsed: false, theme: 'auto', language: 'zh-CN' }
+    return { siderCollapsed: false, theme: 'auto', language: 'zh-CN', minePannel: false }
 }
 
 export function getLocalSetting(): AppState {
     const localSetting: AppState | undefined = ss.get(LOCAL_NAME)
-    return { ...defaultSetting(), ...localSetting }
+    return { ...defaultSetting(), ...localSetting, minePannel: false }
 }
 
 export function setLocalSetting(setting: AppState): void {

+ 12 - 2
src/store/modules/app/index.ts

@@ -2,17 +2,27 @@ import { defineStore } from 'pinia'
 import type { AppState, Language, Theme } from './helper'
 import { useStorage } from '@vueuse/core'
 
-const appState = useStorage<AppState>('appState', { siderCollapsed: false, theme: 'auto', language: 'zh-CN' })
+const appState = useStorage<AppState>('appState', {
+    siderCollapsed: false,
+    minePannel: false,
+    theme: 'auto',
+    language: 'zh-CN'
+})
 
 export const useAppStore = defineStore('app-store', {
     state: (): AppState => appState.value,
-    
+
     actions: {
         setSiderCollapsed(collapsed: boolean) {
             appState.value.siderCollapsed = collapsed
             this.$state.siderCollapsed = collapsed
         },
 
+        setMinePannel(pannelShow: boolean) {
+            appState.value.minePannel = pannelShow
+            this.$state.minePannel = pannelShow
+        },
+
         setTheme(theme: Theme) {
             appState.value.theme = theme
             this.$state.theme = theme

+ 4 - 11
src/styles/global.less

@@ -17,22 +17,15 @@ body {
     --bg2: linear-gradient(136deg, #34354f 0%, #20223c 100%);
 }
 
-// .n-button--primary-type {
-//     background: #26f50d linear-gradient(307deg, #c072ff 0%, #f9d6ff 45%, #dfffff 89%, #f5ffff 100%);
-//     font-weight: bold !important;
-//     .n-button__border {
-//         border-width: 0 !important;
-//     }
-//     .n-button__state-border {
-//         border-width: 0 !important;
-//     }
-// }
-
 @font-face {
     font-family: 'AlimamaShuHeiTi';
     src: url(https://cdn.raex.vip/font/2023-03-24-10-09-25HtghnVXP.ttf);
 }
 
+.alimamaShuHeiTi {
+    font-family: 'AlimamaShuHeiTi';
+}
+
 .text-color-1 {
     color: var(--text-color-1);
 }

+ 2 - 9
src/views/chat/components/Header/index.vue

@@ -2,8 +2,6 @@
 import { computed, nextTick } from 'vue'
 import { HoverButton, SvgIcon, UserAvatar } from '@/components/common'
 import { useAppStore, useChatStore } from '@/store'
-import { useRouter } from 'vue-router'
-import { useBasicLayout } from '@/hooks/useBasicLayout'
 
 interface Props {
     usingContext: boolean
@@ -42,14 +40,9 @@ function toggleUsingContext() {
     emit('toggleUsingContext')
 }
 
-const { isMobile } = useBasicLayout()
-const router = useRouter()
+
 function goMine() {
-    if (isMobile.value) {
-        router.push({
-            name: 'mine'
-        })
-    }
+    emit('goMine')
 }
 </script>
 

+ 32 - 5
src/views/chat/index.vue

@@ -1,9 +1,9 @@
 <script setup lang="ts">
 import type { Ref } from 'vue'
-import { computed, onMounted, onUnmounted, ref } from 'vue'
+import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 import { storeToRefs } from 'pinia'
-import { NAutoComplete, NButton, NInput, useDialog, useMessage } from 'naive-ui'
+import { NAutoComplete, NButton, NInput, useDialog, useMessage, NModal, NConfigProvider } from 'naive-ui'
 import html2canvas from 'html2canvas'
 import { Message } from './components'
 import { useScroll } from './hooks/useScroll'
@@ -11,9 +11,9 @@ import { useChat } from './hooks/useChat'
 import { useCopyCode } from './hooks/useCopyCode'
 import { useUsingContext } from './hooks/useUsingContext'
 import HeaderComponent from './components/Header/index.vue'
-import { HoverButton, SvgIcon } from '@/components/common'
+import { HoverButton, SvgIcon, MinePannel } from '@/components/common'
 import { useBasicLayout } from '@/hooks/useBasicLayout'
-import { useChatStore, usePromptStore, useAuthStore, AuthState } from '@/store'
+import { useChatStore, useAppStore, usePromptStore, useAuthStore, AuthState } from '@/store'
 import { fetchChatAPIProcess } from '@/api'
 import { t } from '@/locales'
 
@@ -419,11 +419,28 @@ onMounted(() => {
 
 onUnmounted(() => {
     if (loading.value) controller.abort()
+    appStore.setMinePannel(false)
 })
 
+const appStore = useAppStore()
+const showMine = computed(() => appStore.minePannel)
 function goMine() {
-    
+    if (isMobile.value) {
+        router.push({
+            name: 'mine'
+        })
+    } else {
+        appStore.setMinePannel(true)
+    }
+}
+
+function onMask() {
+    appStore.setMinePannel(false)
 }
+
+watch(isMobile, val => {
+    appStore.setMinePannel(false)
+})
 </script>
 
 <template>
@@ -520,5 +537,15 @@ function goMine() {
                 </div>
             </div>
         </footer>
+
+        <n-modal
+            v-model:show="showMine"
+            transform-origin="center"
+            class="max-w-xl p-3"
+            style="width: 75%"
+            :on-mask-click="onMask"
+        >
+            <n-card :border="false" class="bg-white dark:bg-black rounded-lg"> <mine-pannel></mine-pannel> </n-card>
+        </n-modal>
     </div>
 </template>

+ 5 - 0
src/views/chat/layout/sider/Footer.vue

@@ -3,6 +3,7 @@ import { defineAsyncComponent, ref } from 'vue'
 import { HoverButton, SvgIcon, UserAvatar } from '@/components/common'
 import { useRouter } from 'vue-router'
 import { useBasicLayout } from '@/hooks/useBasicLayout'
+import { useAppStore } from '@/store'
 
 const Setting = defineAsyncComponent(() => import('@/components/common/Setting/SettingIndex.vue.js'))
 
@@ -10,11 +11,15 @@ const show = ref(false)
 
 const { isMobile } = useBasicLayout()
 const router = useRouter()
+const appStore = useAppStore()
 function goMine() {
     if (isMobile.value) {
         router.push({
             name: 'mine'
         })
+    } else {
+        console.log('e99')
+        appStore.setMinePannel(true)
     }
 }
 </script>

+ 25 - 17
src/views/page/HomeView.vue

@@ -6,20 +6,20 @@
         <n-page-header>
             <template #title>
                 <div class="flex items-center py-3 lg:py-8 pl-4 lg:pl-52">
-                    <img style="width: 34px" :src="logo" />
-                    <span class="ml-3 text-white text-sm lg:text-lg">CHILLGPT </span>
+                    <n-avatar :size="isMobile ? 'small' : 'large'" :src="logo"></n-avatar>
+                    <span class="ml-3 text-white text-base lg:text-lg alimamaShuHeiTi">CHILLGPT </span>
                 </div>
             </template>
             <template #extra>
                 <div class="flex items-center py-3 lg:py-8 pr-4 lg:pr-52">
                     <template v-if="isLogin">
                         <n-button text v-if="isMobile" @click="goMine">
-                            <user-avatar avatarType="medium" onlyAvatar />
+                            <user-avatar avatarType="small" onlyAvatar />
                         </n-button>
                         <n-popover placement="bottom" trigger="click" v-else>
                             <template #trigger>
                                 <n-button text>
-                                    <user-avatar :avatarType="isMobile ? 'medium' : 'large'" onlyAvatar />
+                                    <user-avatar :avatarType="isMobile ? 'small' : 'large'" onlyAvatar />
                                 </n-button>
                             </template>
                             <n-button size="small" @click="logout" text>退出登录</n-button>
@@ -35,9 +35,9 @@
         </n-page-header>
 
         <div class="flex flex-col items-center content-center flex-1 pt-4 pb-24 lg:py-32 page-content">
-            <img src="@/assets/brand.png" class="w-4/5 max-w-3xl" alt="" />
+            <img src="@/assets/brand.png" class="w-3/4 max-w-3xl" alt="" />
 
-            <div class="text-sm lg:text-lg text-white text-center mt-4 w-8/12 max-w-4xl">
+            <div class="text-sm lg:text-lg text-white text-center mt-4 w-5/6 max-w-4xl">
                 ChillGPT是人工智能技术驱动的自然语言处理工具,它能够通过理解和学习人类的语言来进行对话,还能根据聊天的上下文进行互动,真正像人类一样来聊天交流,甚至能完成撰写邮件、视频脚本、文案、翻译、代码,写论文等任务。
             </div>
 
@@ -61,12 +61,12 @@
                     }"
                 >
                     <div
-                        class="flex items-center justify-center h-11 text-lg text-white"
+                        class="flex items-center justify-center h-11 text-lg text-white backdrop-blur-sm"
                         style="font-family: AlimamaShuHeiTi"
                     >
                         会员权益
                     </div>
-                    <n-grid cols="2 s:5 m:7" responsive="screen" class="backdrop-blur-lg">
+                    <n-grid cols="2 s:4 m:8" responsive="screen" class="backdrop-blur-lg">
                         <n-grid-item v-for="item in items" :key="item.name">
                             <div class="flex flex-col items-center pt-5 pb-7">
                                 <img class="w-11 h-11" :src="item.img" alt="" />
@@ -128,9 +128,8 @@ import {
     darkTheme,
     NEl,
     NPopover,
-    useMessage,
-    useDialog,
-    avatarProps
+    useMessage, 
+    useDialog
 } from 'naive-ui'
 import h5Bg from '@/assets/bg_mobile.jpg'
 import pcBg from '@/assets/bg_desktop.jpg'
@@ -141,9 +140,10 @@ import { ref, computed } from 'vue'
 import { UserAvatar, LoginForm } from '@/components/common'
 import { useBasicLayout } from '@/hooks/useBasicLayout'
 import imgItem01 from '@/assets/png-01.png'
+import imgQiye from '@/assets/qiye.png'
+import imgHuihua from '@/assets/huihua.png'
 import imgItem02 from '@/assets/png-02.png'
 import imgItem03 from '@/assets/png-03.png'
-import imgItem04 from '@/assets/png-04.png'
 import imgItem05 from '@/assets/png-05.png'
 import imgItem06 from '@/assets/png-06.png'
 import imgItem07 from '@/assets/png-07.png'
@@ -158,6 +158,15 @@ const items = [
         name: '无限对话',
         desc: '畅快聊天',
         img: imgItem01
+    },{
+        name: '独立会话',
+        desc: '上下文精准约束',
+        img: imgQiye
+    },
+    {
+        name: '企业链路',
+        desc: '高效稳定',
+        img: imgHuihua
     },
     {
         name: '推荐奖励',
@@ -169,11 +178,6 @@ const items = [
         desc: '高价值数字藏品',
         img: imgItem03
     },
-    {
-        name: '全线3折购',
-        desc: 'Chillgpt生态',
-        img: imgItem04
-    },
     {
         name: '测试白名单',
         desc: '第一优先级',
@@ -241,4 +245,8 @@ function logout() {
     top: 0;
     z-index: 20;
 }
+
+:deep(.n-avatar) {
+    --n-merged-color: transparent;
+}
 </style>

+ 3 - 68
src/views/page/MineView.vue

@@ -1,84 +1,19 @@
 <template>
     <div class="page h-full flex flex-col">
         <n-page-header title="个人中心" @back="handleBack"> </n-page-header>
-        <n-card :bordered="false">
-            <UserAvatar avatarType="large" />
-        </n-card>
-        <n-card :bordered="false">
-            <vip-card @goVip="goVip"></vip-card>
-        </n-card>
-        <n-card :bordered="false">
-            <n-row gutter="12">
-                <n-col :span="12">
-                    <div class="share-btn" @click="shareEvent">
-                        <div class="share-text">
-                            <div class="text1">邀请好友</div>
-                            <div class="text2">一起赚钱</div>
-                        </div>
-                        <img src="@/assets/png--anniu.png" alt="" />
-                    </div>
-                </n-col>
-                <n-col :span="12">
-                    <div class="share-btn">
-                        <div class="share-text">
-                            <div class="text1">我的收益</div>
-                            <div class="text2">余额:888.00</div>
-                        </div>
-                        <img src="@/assets/png-shouyi.png" alt="" />
-                    </div>
-                </n-col>
-            </n-row>
-        </n-card>
-
-        <div class="flex-1"></div>
-
-        <div class="logout">
-            <n-button @click="logout" quaternary type="primary" block round size="large"> 退出登录 </n-button>
-        </div>
-
-        <share ref="shareRef" />
+        <mine-pannel></mine-pannel>
     </div>
 </template>
 
 <script setup lang="ts">
-import { UserAvatar, VipCard, Share } from '@/components/common'
-import { NCard, NEl, NPageHeader, NRow, NCol, useMessage, NButton, useDialog } from 'naive-ui'
+import { MinePannel } from '@/components/common'
+import { NPageHeader } from 'naive-ui'
 import { useRouter } from 'vue-router'
-import { ref } from 'vue'
-import { useUserStore } from '@/store'
 
 const router = useRouter()
 function handleBack() {
     router.back()
 }
-
-const message = useMessage()
-function goVip() {
-    message.info('暂未开放')
-    // router.push('/vip')
-}
-
-const shareRef: any = ref(null)
-function shareEvent() {
-    shareRef.value.init()
-}
-
-const dialog = useDialog()
-const userStore = useUserStore()
-function logout() {
-    dialog.create({
-        title: '提示',
-        content: '确认要退出登录吗?',
-        positiveText: '退出登录',
-        negativeText: '取消',
-        maskClosable: false,
-        onPositiveClick: () => {
-            userStore.logout()
-            message.success('退出登录成功')
-            router.replace('/home')
-        }
-    })
-}
 </script>
 
 <style lang="less" scoped>

+ 9 - 8
src/views/page/VipView.vue

@@ -2,14 +2,12 @@
     <div class="page h-full">
         <n-page-header title="开通会员" @back="handleBack"> </n-page-header>
 
-        <n-card :bordered="false">
-            <vip-card pageType="vip"></vip-card>
-        </n-card>
+        <vip-pannel></vip-pannel>
     </div>
 </template>
 <script setup lang="ts">
-import { VipCard } from '@/components/common'
-import { NCard, NEl, NPageHeader, NRow, NCol } from 'naive-ui'
+import { VipPannel } from '@/components/common'
+import { NCard, NEl, NPageHeader, NRow, NCol, NGrid, NGridItem, NButton, NIcon } from 'naive-ui'
 import { useRouter } from 'vue-router'
 
 const router = useRouter()
@@ -19,9 +17,6 @@ function handleBack() {
 </script>
 
 <style lang="less" scoped>
-.page {
-    background-color: #000033;
-}
 :deep(.n-page-header) {
     height: 50px;
     padding: 0 22px;
@@ -39,4 +34,10 @@ function handleBack() {
     --n-padding-bottom: 10px !important;
     background-color: transparent;
 }
+.choose-btn + .choose-btn {
+    margin-left: 23px;
+}
+::-webkit-scrollbar {
+    display: none;
+}
 </style>