Browse Source

注册tab组件到登录页

wangyi/feature-20251022162725-启动页登录注册
Ethereal 1 month ago
parent
commit
b678f207e8
  1. 192
      components/footerBar-cn.vue
  2. 2
      components/footerBar.vue
  3. 184
      pages/deepMate/deepMate.vue
  4. 9
      pages/start/Registration/Registration.vue
  5. 29
      pages/start/login/login.vue

192
components/footerBar-cn.vue

@ -0,0 +1,192 @@
<template>
<view class="static-footer-bar" :style="{ 'padding-bottom': safeAreaInsets.bottom + 'px' }">
<view class="static-footer-li" @click="tabChange(1)">
<image src="../static/footBar-image/home.png" class="static-footer-li-icon" v-if="type != 'home'"></image>
<image src="../static/footBar-image/home-selected.png" class="static-footer-li-icon" v-if="type == 'home'"></image>
<view :class="type == 'home' ? 'static-footer-li-title1' : 'static-footer-li-title'">
首页</view>
</view>
<view class="static-footer-li" @click="tabChange(2)">
<image src="../static/footBar-image/marketSituation.png" class="static-footer-li-icon" v-if="type != 'marketSituation'">
</image>
<image src="../static/footBar-image/marketSituation-selected.png" class="static-footer-li-icon"
v-if="type == 'marketSituation'"></image>
<view :class="type == 'marketSituation' ? 'static-footer-li-title1' : 'static-footer-li-title'">
行情</view>
</view>
<view class="static-footer-li static-footer-li-special" @click="tabChange(3)">
<image src="../static/footBar-image/deepMate.png" class="static-footer-li-icon static-footer-li-icon-special" v-if="type != 'deepMate'"></image>
<image src="../static/footBar-image/deepMate-selected.png" class="static-footer-li-icon static-footer-li-icon-special" v-if="type == 'deepMate'">
</image>
<view :class="type == 'deepMate' ? 'static-footer-li-title1' : 'static-footer-li-title'">
DeepMate</view>
</view>
<view class="static-footer-li" @click="tabChange(4)">
<image src="../static/footBar-image/deepExploration.png" class="static-footer-li-icon" v-if="type != 'deepExploration'">
</image>
<image src="../static/footBar-image/deepExploration-selected.png" class="static-footer-li-icon"
v-if="type == 'deepExploration'"></image>
<view :class="type == 'deepExploration' ? 'static-footer-li-title1' : 'static-footer-li-title'">
深度探索</view>
</view>
<view class="static-footer-li" @click="tabChange(5)">
<image src="../static/footBar-image/member.png" class="static-footer-li-icon" v-if="type != 'member'"></image>
<image src="../static/footBar-image/member-selected.png" class="static-footer-li-icon" v-if="type == 'member'"></image>
<view :class="type == 'member' ? 'static-footer-li-title1' : 'static-footer-li-title'">
我的</view>
</view>
</view>
</template>
<script setup>
import { computed, onMounted } from 'vue'
// props
const props = defineProps({
type: {
type: String,
default: ''
}
})
//
const safeAreaInsets = computed(() => {
//
const systemInfo = uni.getSystemInfoSync()
return {
bottom: systemInfo.safeAreaInsets?.bottom || 0
}
})
//
const tabChange = (value) => {
// console.log(value)
if (value == 1) { //
uni.redirectTo({
url: '/pages/home/home',
animationType: 'fade-in'
})
} else if (value == 2) { //
uni.redirectTo({
url: '/pages/home/marketSituation',
animationType: 'fade-in'
})
} else if (value == 3) { //DeepMate
uni.redirectTo({
url: '/pages/deepMate/deepMate',
animationType: 'fade-in'
})
} else if (value == 4) { //
if (props.type == 'deepExploration') return;
uni.redirectTo({
url: '/pages/home/deepExploration',
animationType: 'fade-in'
})
} else if (value == 5) { //
if (props.type == 'member') return;
uni.redirectTo({
url: '/pages/home/member',
animationType: 'fade-in'
})
}
}
//
onMounted(() => {
//
})
</script>
<style scoped>
.static-footer-bar {
width: 100%;
height: 120rpx;
border-top: 1px solid #E2E2E2;
background: #fff;
position: relative;
}
.static-footer-li {
display: inline-block;
width: 20%;
height: 100%;
text-align: center;
position: relative;
transform: translateY(-12rpx);
}
.static-footer-li-icon {
width: 46rpx;
height: 46rpx;
margin: 12rpx 0;
}
/* 中间导航项的特殊样式 */
.static-footer-li-special {
position: relative;
z-index: 10;
}
.static-footer-li-icon-special {
width: 95rpx !important;
height: 95rpx !important;
margin: 0rpx 0 !important;
border-radius: 50rpx;
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.2);
transform: translateY(-12rpx);
transition: all 0.3s ease;
}
.static-footer-li-title {
width: 100%;
height: 40rpx;
line-height: 40rpx;
font-size: 24rpx;
text-align: center;
margin-top: -20rpx;
color: gray;
}
.static-footer-li-title1 {
width: 100%;
height: 40rpx;
line-height: 40rpx;
font-size: 24rpx;
text-align: center;
margin-top: -20rpx;
color: black;
}
.unreadNum {
position: absolute;
right: 15%;
background-color: #f00;
color: #fff;
font-size: 24rpx;
padding: 0 6rpx;
height: 36rpx;
line-height: 36rpx;
min-width: 36rpx;
border-radius: 18rpx;
z-index: 9;
}
.taskNew {
position: absolute;
right: 15%;
height: 30rpx;
z-index: 9;
}
.homeWorkUnRead {
position: absolute;
right: 30%;
top: 10%;
background-color: #f00;
color: #fff;
height: 12rpx;
width: 12rpx;
border-radius: 6rpx;
z-index: 9;
}
</style>

2
components/footerBar.vue

@ -73,7 +73,7 @@ const tabChange = (value) => {
})
} else if (value == 3) { //DeepMate
uni.redirectTo({
url: '/pages/home/deepMate',
url: '/pages/deepMate/deepMate',
animationType: 'fade-in'
})
} else if (value == 4) { //

184
pages/deepMate/deepMate.vue

@ -3,14 +3,23 @@
<!-- 顶部导航栏 -->
<view class="header" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="header-left">
<image src="https://d31zlh4on95l9h.cloudfront.net/images/f91e09b5987802185e7679055dafd272.svg" class="icon"></image>
<image
src="https://d31zlh4on95l9h.cloudfront.net/images/f91e09b5987802185e7679055dafd272.svg"
class="icon"
></image>
</view>
<view class="header-center">
<text class="title">DeepMate</text>
</view>
<view class="header-right">
<image src="https://d31zlh4on95l9h.cloudfront.net/images/d7c4e74201213a25dd9574e908233928.svg" class="icon"></image>
<image src="https://d31zlh4on95l9h.cloudfront.net/images/099903c4aabf5713488b5cb60815e3f7.svg" class="icon"></image>
<image
src="https://d31zlh4on95l9h.cloudfront.net/images/d7c4e74201213a25dd9574e908233928.svg"
class="icon"
></image>
<image
src="https://d31zlh4on95l9h.cloudfront.net/images/099903c4aabf5713488b5cb60815e3f7.svg"
class="icon"
></image>
<!-- 新增新会话按钮
<button class="new-chat-button" @click="newChat">
<text class="new-chat-text">新会话</text>
@ -21,50 +30,69 @@
<!-- 主要内容区域 -->
<view class="main-content">
<view class="banner-panel" v-if="messages.length === 0">
<image src="https://d31zlh4on95l9h.cloudfront.net/images/42e18bd7fe97d4f4f37aa70439a0990b.svg" class="pray-banner" mode="aspectFill" ></image>
<view class="contain">
<!-- 机器人头像和欢迎语 -->
<view class="robot-container" v-if="messages.length === 0">
<image src="https://d31zlh4on95l9h.cloudfront.net/images/61fa384381c88ad80be28f41827fe0e5.svg" class="robot-avatar"></image>
<view class="welcome-message">
<text class="greeting">Hi, 我是您的股市随身顾问~</text>
<text class="description">个股诊断市场情绪解读都可以找我</text>
</view>
</view>
<image
src="https://d31zlh4on95l9h.cloudfront.net/images/42e18bd7fe97d4f4f37aa70439a0990b.svg"
class="pray-banner"
mode="aspectFill"
></image>
<view class="contain">
<!-- 机器人头像和欢迎语 -->
<view class="robot-container" v-if="messages.length === 0">
<image
src="https://d31zlh4on95l9h.cloudfront.net/images/61fa384381c88ad80be28f41827fe0e5.svg"
class="robot-avatar"
></image>
<view class="welcome-message">
<text class="greeting">Hi, 我是您的股市随身顾问~</text>
<text class="description"
>个股诊断市场情绪解读都可以找我</text
>
</view>
</view>
<!-- 功能标签栏 -->
<view class="function-tabs" v-if="messages.length === 0" scroll-x="true" show-scrollbar="false">
<view class="tab-item ">个股诊断</view>
<view class="tab-item">市场情绪温度计</view>
<view class="tab-item">买卖时机提示</view>
<view class="tab-item">个股</view>
</view>
<!-- 功能标签栏 -->
<view
class="function-tabs"
v-if="messages.length === 0"
scroll-x="true"
show-scrollbar="false"
>
<view class="tab-item">个股诊断</view>
<view class="tab-item">市场情绪温度计</view>
<view class="tab-item">买卖时机提示</view>
<view class="tab-item">个股</view>
</view>
<!-- 特斯拉推荐卡片 -->
<view class="recommend-card" v-if="messages.length === 0">
<view class="arrow" v-if="messages.length === 0"></view>
<view class="card-content">
<image src="../../static/images/tesla-logo.png" class="logo"></image>
<view class="card-text">
<text class="main-question">当前特斯拉该如何布局</text>
<text class="stock-code">TSLA</text>
<!-- 特斯拉推荐卡片 -->
<view class="recommend-card" v-if="messages.length === 0">
<view class="arrow" v-if="messages.length === 0"></view>
<view class="card-content">
<image
src="../../static/images/tesla-logo.png"
class="logo"
></image>
<view class="card-text">
<text class="main-question">当前特斯拉该如何布局</text>
<text class="stock-code">TSLA</text>
</view>
<image
src="https://d31zlh4on95l9h.cloudfront.net/images/40d94054644f6e3f1c366751f07f0010.svg"
class="arrow-icon"
@click="goBlank"
></image>
</view>
</view>
<image src="https://d31zlh4on95l9h.cloudfront.net/images/40d94054644f6e3f1c366751f07f0010.svg" class="arrow-icon" @click="goBlank"></image>
</view>
</view>
</view>
</view>
<!-- 可能感兴趣的话题 -->
<view v-if="messages.length === 0" class="interest-section">
<text class="section-title">- 您可能感兴趣 -</text>
<view class="topics-list">
<view class="topic-item" v-for="topic in hotTopics" :key="topic.id">
<image
:src="topic.icon"
class="tag-icon"
></image>
<text class="topic-text" @click="sendMessageList(topic.text)">{{ topic.text }}</text>
<image :src="topic.icon" class="tag-icon"></image>
<text class="topic-text" @click="sendMessageList(topic.text)">{{
topic.text
}}</text>
</view>
</view>
</view>
@ -128,7 +156,12 @@
>
</view>
<image class="back-to-top" src="https://d31zlh4on95l9h.cloudfront.net/images/ba357635d2bb480241952bb1cabacd73.svg" @click="scrollToTop"></image>
<image
class="back-to-top"
src="https://d31zlh4on95l9h.cloudfront.net/images/ba357635d2bb480241952bb1cabacd73.svg"
@click="scrollToTop"
></image>
<footerBar class="static-footer" :type="type"></footerBar>
</view>
</template>
@ -136,7 +169,10 @@
const { safeAreaInsets } = uni.getSystemInfoSync();
import { ref, onMounted, nextTick } from "vue";
import footerBar from "../../components/footerBar-cn.vue";
const type = ref('member')
const inputMessage = ref("");
const isSending = ref(false);
const uuid = ref("");
@ -144,24 +180,24 @@ const messages = ref([]);
const hotTopics = ref([
{
id: 1,
text: '英伟达(NVDA)股票情绪温度?',
icon: 'https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg'
text: "英伟达(NVDA)股票情绪温度?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
{
id: 2,
text: '博通(AVGO)明天还能涨吗?',
icon: 'https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg'
text: "博通(AVGO)明天还能涨吗?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
{
id: 3,
text: '为什么Fluence Energy(FLNC)会暴涨?',
icon: 'https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg'
text: "为什么Fluence Energy(FLNC)会暴涨?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
{
id: 4,
text: '为什么Fluence Energy(FLNC)会暴涨?',
icon: 'https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg'
}
text: "为什么Fluence Energy(FLNC)会暴涨?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
]);
//
@ -177,19 +213,19 @@ onMounted(() => {
// UUID
const initUUID = () => {
let storedUUID = uni.getStorageSync('user_uuid');
let storedUUID = uni.getStorageSync("user_uuid");
if (!storedUUID) {
storedUUID = generateUUID();
uni.setStorageSync('user_uuid', storedUUID);
uni.setStorageSync("user_uuid", storedUUID);
}
uuid.value = storedUUID;
};
// UUID
const generateUUID = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};
@ -197,14 +233,14 @@ const generateUUID = () => {
//
const newChat = () => {
messages.value = [];
uni.removeStorageSync('user_uuid');
uni.removeStorageSync("user_uuid");
initUUID();
};
//
const goBlank = () => {
uni.navigateTo({
url: '/pages/blank/blank'
url: "/pages/blank/blank",
});
};
@ -216,7 +252,7 @@ const sendMessage = () => {
content: inputMessage.value,
isUser: true,
isThinking: false,
isTyping: false
isTyping: false,
};
messages.value.push(userMessage);
@ -231,18 +267,15 @@ const sendMessage = () => {
simulateBotResponse(userMessage.content);
};
//
const sendMessageList = (listMessage) => {
console.log(listMessage);
const userMessage = {
content: listMessage,
isUser: true,
isThinking: false,
isTyping: false
isTyping: false,
};
messages.value.push(userMessage);
@ -266,7 +299,7 @@ const simulateBotResponse = (userMessage) => {
content: "",
isUser: false,
isTyping: true,
isThinking: false
isThinking: false,
};
messages.value.push(botMsg);
@ -301,14 +334,14 @@ const simulateBotResponse = (userMessage) => {
//
const scrollToBottom = () => {
const query = uni.createSelectorQuery();
query.select('#messageList').boundingClientRect();
query.select("#messageList").boundingClientRect();
query.selectViewport().scrollOffset();
query.exec((res) => {
if (res[0] && res[1]) {
uni.pageScrollTo({
scrollTop: res[0].height,
duration: 100
duration: 100,
});
}
});
@ -349,8 +382,6 @@ const scrollToTop = () => {
}
.header-center .title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
@ -434,7 +465,7 @@ const scrollToTop = () => {
}
.recommend-card {
background: url('https://d31zlh4on95l9h.cloudfront.net/images/4da1d629a55c307c3605ca15bf15189a.svg');
background: url("https://d31zlh4on95l9h.cloudfront.net/images/4da1d629a55c307c3605ca15bf15189a.svg");
background-repeat: no-repeat;
/* border-radius: 20rpx; */
padding: 40rpx;
@ -483,14 +514,13 @@ const scrollToTop = () => {
}
.arrow-icon {
background: url('https://d31zlh4on95l9h.cloudfront.net/images/40d94054644f6e3f1c366751f07f0010.svg');
background-repeat: no-repeat;
left: 0.5rem;
top: 1.8rem;
background-size: 100% 100%;
width: 60rpx;
height: 60rpx;
background: url("https://d31zlh4on95l9h.cloudfront.net/images/40d94054644f6e3f1c366751f07f0010.svg");
background-repeat: no-repeat;
left: 0.5rem;
top: 1.8rem;
background-size: 100% 100%;
width: 60rpx;
height: 60rpx;
}
.interest-section {
@ -661,7 +691,7 @@ height: 60rpx;
padding: 15rpx 20rpx;
background-color: rgb(220, 31, 29);
border-radius: 100rpx;
display: flex;
display: flex;
align-items: center;
justify-content: center;
@ -693,7 +723,7 @@ height: 60rpx;
}
.send-button {
background: url('https://d31zlh4on95l9h.cloudfront.net/images/95f1ea2262e9157db13c93c0dc1c5d96.svg');
background: url("https://d31zlh4on95l9h.cloudfront.net/images/95f1ea2262e9157db13c93c0dc1c5d96.svg");
background-repeat: no-repeat;
background-size: 100% 100%;
height: 50rpx;
@ -753,4 +783,8 @@ height: 60rpx;
.back-to-top:active {
transform: scale(0.96);
}
.static-footer {
position: fixed;
bottom: 0;
}
</style>

9
pages/start/Registration/Registration.vue

@ -154,6 +154,7 @@
>已有账号登录
</text>
<footerBar class="static-footer" :type="type"></footerBar>
</view>
</template>
@ -162,7 +163,10 @@
import { ref } from "vue";
//
import countryList from "../login/list";
import footerBar from '../../../components/footerBar-cn.vue'
const type = ref('member')
const email = ref("");
const password = ref("");
const phone = ref("");
@ -652,4 +656,9 @@ function changeCheckbox() {
margin-left: 10rpx;
text-decoration: underline;
}
.static-footer {
position: fixed;
bottom: 0;
}
</style>

29
pages/start/login/login.vue

@ -121,7 +121,6 @@
placeholder="请输入验证码"
v-model="password"
/>
</view>
</view>
<view v-if="switchType === 'Phone'" class="phone-input-container">
@ -173,10 +172,7 @@
<!-- 用户协议 -->
<view @click="changeCheckbox" class="agreement-container-one">
<image
class="checkbox"
:src="checkboxUrl"
></image>
<image class="checkbox" :src="checkboxUrl"></image>
<text class="agreement-text-one"
>接受 <text class="link" @click="openAgreement">用户协议</text>
<text class="link" @click="openPrivacy">隐私政策</text></text
@ -187,10 +183,10 @@
><text @click="recoverPassword">忘记ID/密码</text>
</text>
</view>
<view v-else class="agreement-container">
<view v-else class="agreement-container">
<text class="agreement-text">
<!-- 添加占位元素防止页面变形 -->
<text style="visibility: hidden;">占位符</text>
<text style="visibility: hidden">占位符</text>
</text>
</view>
@ -222,6 +218,7 @@
<text class="third-party-text">通过 Google 登录</text>
</view>
</view>
<footerBar class="static-footer" :type="type"></footerBar>
</view>
</template>
@ -229,7 +226,9 @@
import { ref } from "vue";
//
import countryList from "./list.js";
import footerBar from '../../../components/footerBar-cn'
const type = ref('member')
const email = ref("");
const password = ref("");
const phone = ref("");
@ -240,8 +239,6 @@ const codeBtnText = ref("获取验证码");
const isCodeBtnDisabled = ref(false); //
const checkboxUrl = ref("../../../static/icons/Check-one-false.png");
// 使list.js
const countries = ref(
countryList.list.map((item) => ({
@ -428,10 +425,11 @@ function recoverPassword() {
console.log("忘记密码");
}
function changeCheckbox(){
function changeCheckbox() {
agreed.value = !agreed.value;
checkboxUrl.value = agreed.value ? "../../../static/icons/Check-one-true.png" : "../../../static/icons/Check-one-false.png";
checkboxUrl.value = agreed.value
? "../../../static/icons/Check-one-true.png"
: "../../../static/icons/Check-one-false.png";
}
</script>
@ -696,7 +694,7 @@ function changeCheckbox(){
margin-left: 20rpx;
font-size: 24rpx;
color: #666666;
white-space: nowrap;
white-space: nowrap;
}
.link {
@ -771,4 +769,9 @@ white-space: nowrap;
margin-left: 10rpx;
text-decoration: underline;
}
.static-footer {
position: fixed;
bottom: 0;
}
</style>
Loading…
Cancel
Save