feat: 初始化

This commit is contained in:
George
2025-07-07 15:55:44 +08:00
commit 9b7bfcfe5a
969 changed files with 123036 additions and 0 deletions

View File

@ -0,0 +1,30 @@
.drawer {
position: fixed;
bottom: 0;
left: -300px; /* 隐藏状态 */
width: 300px;
background-color: #fff;
transition: left 0.3s ease;
z-index: 99;
}
.drawer.open {
left: 0; /* 显示状态 */
}
.drawer-content {
z-index: 99;
}
.overlay {
position: fixed;
left: 0;
width: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 80;
}
.overlay.open {
width: 750rpx;
}

View File

@ -0,0 +1,159 @@
.navBarWrapper {
position: sticky;
z-index: 98;
background-color: #fff;
width: 750rpx;
}
.navBarWrapper .navBar {
width: 750rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding-left: 28px;
padding-right: 16px;
height: 44px;
border: 1px solid rgb(236, 236, 236);
border-left-width: 0px;
border-right-width: 0px;
}
.leftDrawer {
z-index: 100;
}
.leftDrawer .submenu {
height: 48px;
padding: 0 48px;
border-bottom: 1px solid #ebeef5;
display: flex;
align-items: center;
}
.leftDrawer .scrollView ::v-deep .uni-scroll-view-content {
height: unset;
padding-bottom: 24px;
}
.leftDrawer .menuItem {
height: 50px;
margin: 0px 28px 0px 16px;
padding: 0px 10px;
display: flex;
flex-direction: row;
align-items: center;
}
.leftDrawer .menuItem.active {
color: #fff;
background-color: #29bbe4;
}
.leftDrawer .menuItem.active .menuText {
color: #fff;
}
.leftDrawer .menuItem .menuText, .leftDrawer .menuItem .value {
font-size: 18px;
}
.leftDrawer .menuItem .menuIcon {
width: 18px;
height: 18px;
}
.leftDrawer .menuItem.userName {
height: 65px;
}
.leftDrawer .menuItem.balance {
height: 65px;
font-size: 12px;
font-weight: 600;
}
.leftDrawer .menuItem.balance .value {
font-size: 24px;
font-weight: 700;
}
.rightDrawer .rightContent {
padding: 0 20px;
}
.rightDrawer .rightContent .noticeItem {
display: flex;
flex-direction: column;
row-gap: 10px;
padding: 20px 0 14px;
border-bottom: 1px solid rgb(236, 236, 236);
}
.rightDrawer .rightContent .noticeItem:last-child {
border-bottom: none;
}
.rightDrawer .rightContent .noticeItem .noticeSubject {
color: rgb(51, 51, 51);
font-size: 16px;
font-weight: 700;
}
.rightDrawer .rightContent .noticeItem .noticeSummary {
color: rgb(102, 102, 102);
font-size: 14px;
line-height: 20px;
}
.popup-content {
width: 726rpx;
height: 100px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 15px;
height: 50px;
background-color: #fff;
}
.popup-height {
height: 100px;
flex: 1;
width: 200px;
}
.detailModal {
flex-direction: row;
position: relative;
width: 726rpx;
background-color: #fff;
}
.detailModal .detailContent {
flex-direction: row;
width: 726rpx;
padding: 32px 30upx 24px;
}
.detailModal .closeIcon {
position: absolute;
z-index: 10;
top: 18px;
right: 21px;
width: 17px;
height: 17px;
}
.detailModal .titleWrapper {
display: flex;
flex-direction: column;
align-items: center;
row-gap: 12px;
color: #333333;
padding: 12px;
margin: 24px 0;
box-shadow: -1px 0 5px 1px rgba(0, 0, 0, 0.1);
}
.detailModal .titleWrapper .title {
margin: 0;
font-size: 24px;
font-weight: 700;
line-height: 34px;
}
.detailModal .titleWrapper .value {
font-size: 36px;
font-weight: 700;
color: #29bbe4;
line-height: 52px;
}
.detailModal .btnsWrapper {
display: flex;
align-items: center;
}
.detailModal .btnsWrapper .delBtn {
background-color: #f56c6c;
}

View File

@ -0,0 +1,323 @@
<template>
<page-meta :page-style="`overflow:${show ? 'visible' : 'hidden'};height:100%;font-family:${fontFamily};`"></page-meta>
<view :style="{'width': '750rpx','margin-top': safeTop}"></view>
<view class="navBarWrapper">
<view class="navBar">
<image src="/static/menu.png" mode="aspectFit" style="width: 16px; height: 13px" @click="toggleLeftDrawerVisible"></image>
<image src="/static/logo.png" alt="" style="width: 86px; height: 31px" @click="redirectToTarget('/pages/home/index')" />
<!-- <image src="/static/notification.png" mode="aspectFit" alt="" style="width: 17px; height: 19px; margin-right: 6px" @click="toggleRightDrawerVisible" /> -->
<view></view>
</view>
<uni-popup ref="alertDialog" :isMaskClick="false">
<view class="detailModal">
<uni-icons type="closeempty" size="17" class="closeIcon" @click="closeDialog"></uni-icons>
<view class="detailContent">
<view class="notice-content" v-html="currentNotice.content"></view>
</view>
</view>
</uni-popup>
</view>
<view :class="['overlay', { 'open': isOpen }]" @click="toggleLeftDrawerVisible" :style="{'height': contentHeight}" ></view>
<view :class="['leftDrawer', 'drawer', { 'open': isOpen }]" :style="{'height': contentHeight}" >
<view class="drawer-content" :style="{'height': contentHeight}">
<scroll-view class="scrollView" :scroll-y="true" :style="{'height': contentHeight}" >
<view>
<view class="menuItem userName" @click="toPersonalInfoPage">
<image style="width: 18px; height: 18px;margin-right: 10px;" src="/static/avatar.png" mode="aspectFit"></image>
<text class="menuText" >{{ userInfo?.name }}</text>
</view>
<view class="menuItem balance" v-if="isIb">
<image style="width: 18px; height: 18px;margin-right: 10px;" src="/static/wallet.png" mode="aspectFit"></image>
<view style="flex-direction: row;align-items: center;">
<text class="value">{{ ibFund?.amount }}</text>
USD
</view>
</view>
<uni-collapse accordion @change="change">
<view :class="['menuItem', isActived('/pages/home/index') ? 'active' : '']" @tap="goToTarget('/pages/home/index')">
<image
style="width: 18px; height: 18px;margin-right: 10px;"
:src="`/static/${isActived('/pages/home/index') ? 'myAccountActived' : 'myAccount'}.png`"
mode="aspectFit"
></image>
<text class="value">{{ t('menu.myAccount') }}</text>
</view>
<view v-for="menu in menuListData" :key="menu.route_key">
<view :class="['menuItem', isActived(menuLinks[menu.route_key]) ? 'active' : '']" @tap="goToTarget(menuLinks[menu.route_key])">
<image style="margin-right: 10px;" class="menuIcon" :src="`/static/nvue/${menu.route_key}${isActived(menuLinks[menu.route_key]) ? 'Active' : ''}.png`" mode="aspectFit"></image>
<text class="menuText">{{ t(`menu.${menu.route_key}`) }}</text>
</view>
</view>
<view style="border-top: 1px solid #ececec; margin-top: 8px">
<MenuLanguageSelector />
</view>
<view class="menuItem" style="min-height: 24px" @click="handleLogout">
<image style="width: 18px; height: 18px;margin-right: 10px;" src="/static/nvue/logout.png" mode="aspectFit"></image>
<text class="value">{{ t('menu.logOut') }}</text>
</view>
</uni-collapse>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import { useUserStore } from '@/stores/user.ts';
import MenuLanguageSelector from '@/components/nvue/menuLanguageSelector/index.vue';
import { getToken } from '@/utils/const.ts';
import { queryMenuList, getNotice, setNoticeReadStatus } from '@/services/home/home';
import { logout } from '@/services/user/loginAndRegister';
import { UserLanguage } from '@/utils/const';
import { i18n } from '@/locale/index.ts';
export default {
data() {
return {
safeTop: uni.getSystemInfoSync().statusBarHeight + 'px',
bodyHeight: (uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight) + 'px',
contentHeight: (uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44) + 'px',
fontFamily: 'SourceHanSans',
type: 'center',
msgType: 'success',
messageText: '这是一条成功提示',
value: '',
show: true,
showDl: true,
userInfo: {},
isIb: false,
ibFund: {},
currentPage: '',
menuListData: [],
menuLinks: {
partner: '/pages/partner/index',
capital: '/pages/capital/index',
activity: '/pages/activity/index',
download: '/pages/download/index',
contact: '/pages/contact/index',
news: '/pages/news/index',
fts: '/pages/fts/index',
pamm: '/pages/pamm/index',
tools: '/pages/toolsAndReport/index'
},
noticeList: [],
currentNotice: {},
windowScrollY: 0,
contentSize: 0,
t: i18n.global.t,
isOpen: false
}
},
emits: ["navLeft", "navRight"],
computed: {
paddingTop: () => {
const { safeAreaInsets } = uni.getSystemInfoSync();
return safeAreaInsets?.top + 'px';
},
token: () => {
return getToken();
}
},
methods: {
initData() {
const userStore = useUserStore();
this.userInfo = Object.assign(this.userInfo, userStore.userInfo);
this.ibFund = Object.assign(this.ibFund, userStore.ibFund);
this.isIb = Number(userStore.userInfo.user_type) === 1;
},
isActived(path) {
return path.includes(this.currentPage)
},
showDialog(notice = {}) {
if (notice.content.length) {
notice.content = `<div style="zoom:${this.contentSize};">`+notice.content+'</div>'
}
this.currentNotice = notice;
this.show = false;
this.toggleRightDrawerVisible();
if (notice.status === '0') {
setNoticeReadStatus({ id: notice.id });
}
this.showDl = true;
this.$refs.alertDialog.open();
},
closeDialog() {
this.show = true;
this.toggleRightDrawerVisible();
this.showDl = false;
this.$refs.alertDialog.close();
},
goToTarget(target) {
const pages = getCurrentPages();
if (!target.endsWith(pages[pages.length - 1].route)) {
uni.navigateTo({
url: target
});
this.show = true;
this.isOpen = false;
}
},
toPersonalInfoPage() {
this.$refs.showLeft.close();
uni.navigateTo({ url: '/pages/user/index' });
},
redirectToTarget(target) {
uni.redirectTo({
url: target
});
},
async handleLogout() {
this.$cusModal.showModal({
type: 'confirm',
contentText: t('modal.logoutContent'),
closeAfterConfirm: true,
onConfirm: async () => {
try {
const res = await logout();
if (res && res.code === 0) {
const userStore = useUserStore();
userStore.clear();
uni.removeStorageSync('access_token');
uni.redirectTo({
url: '/pages/login/index'
});
}
} catch (e) {
console.log('e===>', e);
}
}
});
},
async getMenuListData() {
const res = await queryMenuList();
if (res && res.code === 0) {
for (var i = 0; i < res.data.length; i++) {
const { route_key } = res.data[i]
if (route_key == 'capital') {
res.data[i].rank = 2
} else if (route_key == 'partner') {
res.data[i].rank = 3
} else if (route_key == 'download') {
res.data[i].rank = 8
} else if (route_key == 'pamm') {
res.data[i].rank = 7
} else if (route_key == 'tools') {
res.data[i].rank = 5
} else if (route_key == 'fts') {
res.data[i].rank = 6
} else if (route_key == 'news') {
res.data[i].rank = 9
} else if (route_key == 'activity') {
res.data[i].rank = 4
} else if (route_key == 'contact') {
res.data[i].rank = 10
}
}
res.data.sort((a, b) => a.rank - b.rank)
this.menuListData = res.data;
}
},
async getNoticeList() {
const res = await getNotice();
if (res && res.code === 0) {
this.noticeList = res.data;
}
},
recordWindowScrollY() {
// #ifdef H5
this.windowScrollY = window.scrollY;
// #endif
},
windowScrollByRecord() {
// #ifdef H5
setTimeout(() => {
window.scroll(0, this.windowScrollY);
}, 0);
// #endif
},
handleLeftDrawerChange(e) {
if (!e) {
this.show = true;
this.windowScrollByRecord();
}
this.$emit('navLeft', e || this.showDl)
},
toggleLeftDrawerVisible() {
if (this.isOpen) {
this.show = true;
this.windowScrollByRecord();
this.isOpen = false;
} else {
this.initData();
this.show = false;
this.recordWindowScrollY();
this.isOpen = true;
//如果接口出错没请求到数据,则打开侧边栏的时候再请求一次
if (!this.menuListData.length) {
this.getMenuListData();
}
}
},
handleRightDrawerChange(e) {
if (!e) {
this.show = true;
this.windowScrollByRecord();
}
this.$emit('navRight', e || this.showDl)
},
toggleRightDrawerVisible() {
if (this.$refs.showRight.visibleSync) {
this.show = true;
this.windowScrollByRecord();
this.$refs.showRight.close();
} else {
this.getNoticeList();
this.show = false;
this.recordWindowScrollY();
this.$refs.showRight.open();
}
},
open() {
// 通过组件定义的ref调用uni-popup方法 ,如果传入参数 type 属性将失效 ,仅支持 ['top','left','bottom','right','center']
this.$refs.popup.open('top');
},
toggle(type) {
this.type = type;
// open 方法传入参数 等同在 uni-popup 组件上绑定 type属性
this.$refs.popup.open(type);
},
change(e) {
console.log('popup_change', e);
}
},
created() {
const domModule = weex.requireModule('dom')
domModule.addRule('fontFace', {
'fontFamily': "SourceHanSans",
'src': "url('../../../static/fonts/SourceHanSansCN-Regular.otf')"
});
const pages = getCurrentPages();
this.currentPage = pages[pages.length - 1].route;
const locale = uni.getLocale();
if (['zh-CN', 'zh-TW'].includes(locale)) {
this.fontFamily = 'SourceHanSans';
} else {
this.fontFamily = 'Arial';
}
},
async mounted() {
if (getToken()) {
this.getMenuListData();
}
this.$cusModal.register(this.$refs.cusModal);
this.contentSize = uni.upx2px(666) / 800
},
components: {
MenuLanguageSelector
}
}
</script>
<style scoped>
@import './index.css';
@import './drawer.css';
</style>