Compare commits
94 Commits
master
...
wangyi/fea
-
9.hbuilderx/launch.json
-
90api/deepMate/deepMate.js
-
105api/start/login.js
-
198components/DeepMate.vue
-
385components/MarketOverview.vue
-
192components/footerBar-cn.vue
-
2components/footerBar.vue
-
159components/login-prompt.vue
-
110main.js
-
116main.js.bgk
-
13manifest.json
-
857package-lock.json
-
12package.json
-
119pages.json
-
23pages/blank/blank.vue
-
1524pages/deepMate/deepMate.vue
-
63pages/deepMate/scroll/scroll.vue
-
695pages/home/home.vue
-
949pages/start/Registration/Registration.vue
-
1341pages/start/Registration/list.js
-
13pages/start/agreement/agreement.vue
-
55pages/start/index/index.vue
-
1341pages/start/login/list.js
-
1111pages/start/login/login.vue
-
69pages/start/login/verification.js
-
13pages/start/privacy/privacy.vue
-
976pages/start/recoverPassword/recoverPassword.vue
-
175pages/start/select/select.vue
-
56pages/start/startup/startup.vue
-
23server/deepchart.json
-
131server/login.json
-
BINstatic/flag/ad.png
-
BINstatic/flag/ae.png
-
BINstatic/flag/af.png
-
BINstatic/flag/ag.png
-
BINstatic/flag/ai.png
-
BINstatic/flag/al.png
-
BINstatic/flag/am.png
-
BINstatic/flag/an.png
-
BINstatic/flag/ao.png
-
BINstatic/flag/aq.png
-
BINstatic/flag/ar.png
-
BINstatic/flag/as.png
-
BINstatic/flag/at.png
-
BINstatic/flag/au.png
-
BINstatic/flag/aw.png
-
BINstatic/flag/ax.png
-
BINstatic/flag/az.png
-
BINstatic/flag/ba.png
-
BINstatic/flag/bb.png
-
BINstatic/flag/bd.png
-
BINstatic/flag/be.png
-
BINstatic/flag/bf.png
-
BINstatic/flag/bg.png
-
BINstatic/flag/bh.png
-
BINstatic/flag/bi.png
-
BINstatic/flag/bj.png
-
BINstatic/flag/bl.png
-
BINstatic/flag/bm.png
-
BINstatic/flag/bn.png
-
BINstatic/flag/bo.png
-
BINstatic/flag/bq.png
-
BINstatic/flag/br.png
-
BINstatic/flag/bs.png
-
BINstatic/flag/bt.png
-
BINstatic/flag/bv.png
-
BINstatic/flag/bw.png
-
BINstatic/flag/by.png
-
BINstatic/flag/bz.png
-
BINstatic/flag/ca.png
-
BINstatic/flag/cc.png
-
BINstatic/flag/cd.png
-
BINstatic/flag/cf.png
-
BINstatic/flag/cg.png
-
BINstatic/flag/ch.png
-
BINstatic/flag/ci.png
-
BINstatic/flag/ck.png
-
BINstatic/flag/cl.png
-
BINstatic/flag/cm.png
-
BINstatic/flag/cn.png
-
BINstatic/flag/co.png
-
BINstatic/flag/cr.png
-
BINstatic/flag/cu.png
-
BINstatic/flag/cv.png
-
BINstatic/flag/cw.png
-
BINstatic/flag/cx.png
-
BINstatic/flag/cy.png
-
BINstatic/flag/cz.png
-
BINstatic/flag/de.png
-
BINstatic/flag/dj.png
-
BINstatic/flag/dk.png
-
BINstatic/flag/dm.png
-
BINstatic/flag/do.png
-
BINstatic/flag/dz.png
-
BINstatic/flag/ec.png
-
BINstatic/flag/ee.png
-
BINstatic/flag/eg.png
-
BINstatic/flag/eh.png
-
BINstatic/flag/er.png
-
BINstatic/flag/es.png
@ -0,0 +1,9 @@ |
|||||
|
{ |
||||
|
"version" : "1.0", |
||||
|
"configurations" : [ |
||||
|
{ |
||||
|
"playground" : "standard", |
||||
|
"type" : "uni-app:app-ios" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,90 @@ |
|||||
|
import { http } from '../../utils/http' |
||||
|
|
||||
|
|
||||
|
|
||||
|
export const getData = () => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: '/ka', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 意图识别 |
||||
|
{ |
||||
|
"content":"森那美", |
||||
|
"language": "cn", |
||||
|
"marketlist": "hk,cn,usa,my,sg,vi,in,gb", |
||||
|
"token": "9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnilrmTwo5Fb"qJ91WrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs" |
||||
|
"model":1 |
||||
|
} |
||||
|
|
||||
|
|
||||
|
* { |
||||
|
"code": 200, |
||||
|
"message": "操作成功", |
||||
|
"data": { |
||||
|
"code": "1A0001", |
||||
|
"market": "cn", |
||||
|
"name": "上证指数", |
||||
|
"refuse": "", |
||||
|
"recordId": 15, |
||||
|
"parentId": 14, |
||||
|
"stockId": 25, |
||||
|
"language": "cn", |
||||
|
"debug_url": "https://www.coze.cn/work_flow?execute_id=7564771475955515444&space_id=7564250621483040822&workflow_id=7564368306322292788&execute_mode=2" |
||||
|
} |
||||
|
*/ |
||||
|
|
||||
|
export const postIntent = (data) => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: '/intent', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取股票信息 |
||||
|
* data{ |
||||
|
"language": "cn", |
||||
|
"token": "9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs", |
||||
|
"recordId": 5214, |
||||
|
"parentId": 4887, |
||||
|
"stockId": 1523 |
||||
|
} |
||||
|
* |
||||
|
{"cftl":"当前股票处于安全区,牵牛绳为红色,出现蓝色推进K线","date":"更新时间: 24/10/2025","debug_url":"https://www.coze.cn/work_flow?execute_id=7565080703726846004&space_id=7564250621483040822&workflow_id=7564596757864071195&execute_mode=2","gfzl":"该股整体趋势相对较强,个股正处于推进上涨的关键阶段。若当前持有该股票,建议继续持有,进行持续跟踪。若当前无该股票,建议持续跟踪,等待适当时机再进行介入。","hxjzpg":"(1)牛股评级:★★☆☆☆\n(2)暴涨概率:40%\n(3)风险评估:非常安全\n(4)黄金价域:258.984~266.753\n(5)核心证据链\n 资金共识:当日多方资金流入\n 趋势动能:该股中长期处于上升趋势,短期处于强势状态。","kongjian":"预测低一值255.468,预测高一值257.692,预测低二值255.156,预测高二值255.807", |
||||
|
"markdown":"\n# <font color=\"#1890ff\">Alphabet Inc.全景作战报告</font>\n## 📊 股票分析报告\n### 📈 股票基本信息\n- **股票名称**: <font color=\"#52c41a\">Alphabet Inc.</font>\n- **股票代码**: <font color=\"#1890ff\">GOOGL</font>\n- **当前价格**: <font color=\"#ff4d4f\">259.920</font>\n- **更新时间**: 2025年10月24日\n- **时间节点**: 今日无变盘点\n\n### 🎯 核心价值评估\n- **安全边际**: <font color=\"#13c2c2\">164.424 ~ </font>\n- **黄金价域**: <font color=\"#faad14\">258.984 ~ 266.753</font>\n- **核心证据链**:\n - 🟢 **资金共识**: 当日多方资金<font color=\"#52c41a\">流入</font>\n - 🔥 **趋势动能**: 该股中长期处于<b><font color='#FF0000'>上升趋势</font></b>,短期处于<b><font color='#FF0000'>强势状态</font></b>。\n\n### 🕵️ 主力作战分析\n- **主力行为**:\n 1. 📊 该股庄家中长期筹码成本价格为 207.497,短期资金成本价格为 239.503。该股筹码分散,当日筹码成本价格为 254.335。\n 2. 🔍 近日没有出现主力集中吸筹。\n 3. 📈 近期主力持仓比例大于散户持仓比例。 当日主力持仓增加。 当日散户持仓减少。\n\n### 📊 技术分析\n- **空间维度**:\n - 📉 预测低一值: <font color=\"#13c2c2\">255.468</font>\n - 📈 预测高一值: <font color=\"#ff4d4f\">257.692</font>\n - 📉 预测低二值: <font color=\"#13c2c2\">255.156</font>\n - 📈 预测高二值: <font color=\"#ff4d4f\">255.807</font>\n- **能量分析**: <font color=\"#722ed1\">AI智能均线多头排列,当前卖盘小于买盘</font>\n\n### ⚡ 综合作战分析\n- **触发条件**: <font color=\"#fa8c16\">当前股票处于安全区,牵牛绳为红色,出现蓝色推进K线</font>\n- **攻防指令**: <font color=\"#eb2f96\">该股整体趋势相对较强,个股正处于推进上涨的关键阶段。若当前持有该股票,建议继续持有,进行持续跟踪。若当前无该股票,建议持续跟踪,等待适当时机再进行介入。</font>\n\n---\n<font color=\"#8c8c8c\">*该内容由AI生成,仅供参考,投资有风险,请注意甄别。*</font>\n ","message":"","name":"股票名称: Alphabet Inc.(GOOGL)","nengliang":"AI智能均线多头排列,当前卖盘小于买盘","price":"当前价格: 259.920","shijian":"今日无变盘点","zhuli1":"(1)该股庄家中长期筹码成本价格为 207.497,短期资金成本价格为 239.503。该股筹码分散,当日筹码成本价格为 254.335。","zhuli2":"(2)近日没有出现主力集中吸筹。","zhuli3":"(3)近期主力持仓比例大于散户持仓比例。 当日主力持仓增加。 当日散户持仓减少。"} |
||||
|
} |
||||
|
*/ |
||||
|
export const postStock = (data) => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: '/stocks', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取历史记录 |
||||
|
*/ |
||||
|
|
||||
|
export const postHistory = (data) => { |
||||
|
return http({ |
||||
|
method: 'POST', |
||||
|
url: '/history', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
|
||||
@ -0,0 +1,105 @@ |
|||||
|
import { http } from '../../utils/http' |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param data 模拟手机号码 |
||||
|
* { |
||||
|
"loginType":"EMAIL", //登录方式
|
||||
|
"account":"q614588746@163.com" , //登陆账号 手机号/邮箱/dccode
|
||||
|
"verifyCode":"837012", //验证码
|
||||
|
"password":"", //密码
|
||||
|
"useCode":"true", //是否使用验证码 true/false
|
||||
|
"idToken":"", //第三方登录idToken
|
||||
|
} |
||||
|
*/ |
||||
|
export const LoginApi = (data) => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: '/loginFailureWrongCode', |
||||
|
data: { |
||||
|
data |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 发送验证码 |
||||
|
* @param {*} phoneNumber |
||||
|
* @returns |
||||
|
*/ |
||||
|
export const SendCodeApi = (data) => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: '/sendCodeFailureTooFrequent', |
||||
|
data:{ |
||||
|
data |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 注册 |
||||
|
*/ |
||||
|
|
||||
|
export const register = (data) => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: '/register', |
||||
|
data: { |
||||
|
data |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改密码 |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
export const updatePassword = (data) => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: '/updatePassword', |
||||
|
data: { |
||||
|
data |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 通过苹果登录 |
||||
|
*/ |
||||
|
|
||||
|
export const postLoginAppleSimpleAPI = (phoneNumber) => { |
||||
|
return http({ |
||||
|
method: 'POST', |
||||
|
url: '/login', |
||||
|
data: { |
||||
|
phoneNumber, |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 通过谷歌登录 |
||||
|
*/ |
||||
|
|
||||
|
export const postLoginGoogleSimpleAPI = (phoneNumber) => { |
||||
|
return http({ |
||||
|
method: 'POST', |
||||
|
url: '/login/wxMin/simple', |
||||
|
data: { |
||||
|
phoneNumber, |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
@ -0,0 +1,198 @@ |
|||||
|
<template> |
||||
|
<view class="deepmate"> |
||||
|
<view class="deepmate-container"> |
||||
|
<view class="deepmate-header"> |
||||
|
<view class="title-container"> |
||||
|
<view class="title-left"> |
||||
|
<text class="deepmate-title">DeepMate</text> |
||||
|
<text class="deepmate-subtitle">您的市场最佳顾问~</text> |
||||
|
</view> |
||||
|
<view class="title-right"> |
||||
|
<image class="deepmate-icon" src="https://d31zlh4on95l9h.cloudfront.net/images/7faa683450cc071bcc746fea8191ff6b.png" mode="aspectFit"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="deepmate-content"> |
||||
|
<view class="deepmate-hotspots"> |
||||
|
<view class="deepmate-question"> |
||||
|
<text class="question-text">今日股票策略晨报</text> |
||||
|
</view> |
||||
|
<view class="hotspot-item"> |
||||
|
<text>热门股票分析</text> |
||||
|
</view> |
||||
|
<view class="hotspot-item"> |
||||
|
<text>行业趋势预测</text> |
||||
|
</view> |
||||
|
<view class="hotspot-item"> |
||||
|
<text>市场风险提示</text> |
||||
|
</view> |
||||
|
<view class="hotspot-item"> |
||||
|
<text>投资策略建议</text> |
||||
|
</view> |
||||
|
<view class="hotspot-item"> |
||||
|
<text>财经新闻解读</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="deepmate-action"> |
||||
|
<input class="stock-input" type="text" placeholder="请输入股票代码/名称,获取AI洞察" /> |
||||
|
<view class="send-button-container"> |
||||
|
<image class="send-button" src="https://d31zlh4on95l9h.cloudfront.net/images/3da018821a5c82b06a1d6ddc81b960ac.png" mode="aspectFit"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'DeepMate', |
||||
|
data() { |
||||
|
return { |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
/* DeepMate样式 */ |
||||
|
.deepmate-container { |
||||
|
background-color: #ffe6e6; |
||||
|
border-radius: 10px; |
||||
|
padding: 15px 15px 15px 15px; |
||||
|
margin: 0; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.deepmate-header { |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.title-container { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.title-left { |
||||
|
width: 50%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.title-right { |
||||
|
width: 50%; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.deepmate-title { |
||||
|
font-size: 18px; |
||||
|
font-weight: bold; |
||||
|
color: #ff4d4f; |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
.deepmate-icon { |
||||
|
width: 50px; |
||||
|
height: 50px; |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
|
||||
|
.deepmate-subtitle { |
||||
|
font-size: 12px; |
||||
|
color: #666; |
||||
|
display: block; |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
|
||||
|
.deepmate-hotspots { |
||||
|
margin: 10px 0; |
||||
|
background-color: #ffffff; |
||||
|
border-radius: 10px; |
||||
|
padding: 10px; |
||||
|
} |
||||
|
|
||||
|
.deepmate-question { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 10px; |
||||
|
padding-left: 10px; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.deepmate-question:before { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
width: 4px; |
||||
|
background-color: #ff4d4f; |
||||
|
border-radius: 2px; |
||||
|
} |
||||
|
|
||||
|
.question-text { |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.hotspot-item { |
||||
|
background-color: #f5f5f5; |
||||
|
padding: 8px 12px; |
||||
|
border-radius: 6px; |
||||
|
margin-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
.hotspot-item text { |
||||
|
font-size: 14px; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.deepmate-action { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
background-color: #ff4d4f; |
||||
|
padding: 8px 15px; |
||||
|
border-radius: 25px; |
||||
|
margin-top: 10px; |
||||
|
border: none; |
||||
|
} |
||||
|
|
||||
|
.stock-input { |
||||
|
flex: 1; |
||||
|
height: 36px; |
||||
|
font-size: 14px; |
||||
|
color: #ffffff; |
||||
|
padding: 0 10px; |
||||
|
border: none; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
|
||||
|
.stock-input::placeholder { |
||||
|
color: rgba(255, 255, 255, 0.8); |
||||
|
} |
||||
|
|
||||
|
.send-button-container { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 36px; |
||||
|
height: 36px; |
||||
|
background-color: #ffffff; |
||||
|
border-radius: 50%; |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.send-button { |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,385 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<!-- 第一行:白色背景,标题和按钮 --> |
||||
|
<view class="market-header"> |
||||
|
<text class="section-title">今日市场概览</text> |
||||
|
<text class="more-btn" @click="showMarketSelector">{{ buttonText }}</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 第二行:灰色圆角背景,市场数据 --> |
||||
|
<view class="market-content"> |
||||
|
<!-- 默认显示图片 --> |
||||
|
<view class="selected-market" v-if="!showForexMarket"> |
||||
|
<image class="market-image" src="https://d31zlh4on95l9h.cloudfront.net/images/dee46373b5593d5f315d91675a38fb61.png" mode="widthFix"></image> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 外汇市场样式 --> |
||||
|
<view class="selected-market" v-if="showForexMarket"> |
||||
|
<view class="forex-market"> |
||||
|
<!-- 上部分:三个汇率容器 --> |
||||
|
<view class="forex-rates"> |
||||
|
<view class="forex-rate-item up"> |
||||
|
<text class="forex-pair">美元/日元</text> |
||||
|
<text class="forex-value">151.13</text> |
||||
|
<text class="forex-change">+1.62%</text> |
||||
|
</view> |
||||
|
<view class="forex-rate-item down"> |
||||
|
<text class="forex-pair">美元/韩元</text> |
||||
|
<text class="forex-value">1424.900</text> |
||||
|
<text class="forex-change">-2.92%</text> |
||||
|
</view> |
||||
|
<view class="forex-rate-item up"> |
||||
|
<text class="forex-pair">美元/英镑</text> |
||||
|
<text class="forex-value">0.730</text> |
||||
|
<text class="forex-change">+2.92%</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 中部分:智能解读标题 --> |
||||
|
<view class="forex-analysis-title"> |
||||
|
<text class="analysis-title">智能解读</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 下部分:智能解读内容 --> |
||||
|
<view class="forex-analysis-content"> |
||||
|
<view class="analysis-icon-container"> |
||||
|
<image class="analysis-brain-icon" src="https://d31zlh4on95l9h.cloudfront.net/images/8f35e54c52412467101370aa70d8fdb2.png" mode="aspectFit"></image> |
||||
|
</view> |
||||
|
<view class="analysis-items"> |
||||
|
<view class="analysis-item"> |
||||
|
<text class="analysis-dot orange"></text> |
||||
|
<text class="analysis-text">今日市场情报: 偏乐观</text> |
||||
|
</view> |
||||
|
<view class="analysis-item"> |
||||
|
<text class="analysis-dot blue"></text> |
||||
|
<text class="analysis-text">市场风险评级: 需警惕潜在风险</text> |
||||
|
</view> |
||||
|
<view class="analysis-item"> |
||||
|
<text class="analysis-dot green"></text> |
||||
|
<text class="analysis-text">早盘解析: 今日高开, 芯片、稀土、公共</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 市场选择对话框 --> |
||||
|
<uni-popup ref="marketPopup" type="center" :mask-click="true" @change="popupChange"> |
||||
|
<view class="market-dialog"> |
||||
|
<view class="dialog-title"> |
||||
|
<text>选择市场</text> |
||||
|
</view> |
||||
|
<view class="market-list"> |
||||
|
<view class="market-option" v-for="(market, index) in marketOptions" :key="index" @click="selectMarket(market.id)"> |
||||
|
<view class="market-flag"> |
||||
|
<image :src="market.flag" mode="aspectFit" class="flag-image"></image> |
||||
|
</view> |
||||
|
<view class="market-name-container"> |
||||
|
<text class="market-option-name">{{ market.name }}</text> |
||||
|
</view> |
||||
|
<view class="market-checkbox"> |
||||
|
<radio :checked="selectedMarket === market.id" color="#4080ff" /> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="dialog-buttons"> |
||||
|
<button class="confirm-btn" @click="confirmMarketSelection">确认</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</uni-popup> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'MarketOverview', |
||||
|
data() { |
||||
|
return { |
||||
|
selectedMarket: 'forex', |
||||
|
tempSelectedMarket: 'forex', // 临时选择,确认后才会应用 |
||||
|
previousMarket: null, |
||||
|
buttonText: '切换市场', |
||||
|
showSelector: false, |
||||
|
showForexMarket: false, // 默认不显示外汇市场内容 |
||||
|
marketOptions: [ |
||||
|
{ id: 'forex', name: '外汇市场', flag: '/static/c2.png', value: '+1.62%', trend: 'up' } |
||||
|
], |
||||
|
marketData: { |
||||
|
'forex': { |
||||
|
name: '外汇市场', |
||||
|
value: '+1.62%', |
||||
|
trend: 'up', |
||||
|
indicators: [ |
||||
|
{ name: '美元/日元', value: '151.13 +1.62%', trend: 'up' }, |
||||
|
{ name: '美元/韩元', value: '1424.900 -2.92%', trend: 'down' }, |
||||
|
{ name: '美元/英镑', value: '0.79 +2.92%', trend: 'up' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
showMarketSelector() { |
||||
|
// 切换显示外汇市场内容 |
||||
|
this.showForexMarket = !this.showForexMarket; |
||||
|
// 更新按钮文本 |
||||
|
this.buttonText = this.showForexMarket ? '外汇市场' : '切换市场'; |
||||
|
}, |
||||
|
popupChange(e) { |
||||
|
// 对话框关闭时,如果没有确认,则恢复原来的选择 |
||||
|
if (!e.show && this.tempSelectedMarket !== this.selectedMarket) { |
||||
|
this.tempSelectedMarket = this.selectedMarket; |
||||
|
} |
||||
|
}, |
||||
|
selectMarket(marketId) { |
||||
|
// 临时选择市场,不立即应用 |
||||
|
this.tempSelectedMarket = marketId; |
||||
|
}, |
||||
|
confirmMarketSelection() { |
||||
|
// 确认选择,应用市场选择并关闭对话框 |
||||
|
this.selectedMarket = this.tempSelectedMarket; |
||||
|
this.showSelector = false; |
||||
|
this.$refs.marketPopup.close(); |
||||
|
}, |
||||
|
getSelectedMarketName() { |
||||
|
if (!this.selectedMarket) return ''; |
||||
|
return this.marketData[this.selectedMarket].name; |
||||
|
}, |
||||
|
getSelectedMarketValue() { |
||||
|
if (!this.selectedMarket) return ''; |
||||
|
return this.marketData[this.selectedMarket].value; |
||||
|
}, |
||||
|
getSelectedMarketTrend() { |
||||
|
if (!this.selectedMarket) return ''; |
||||
|
return this.marketData[this.selectedMarket].trend; |
||||
|
}, |
||||
|
getSelectedMarketIndicators() { |
||||
|
if (!this.selectedMarket) return []; |
||||
|
return this.marketData[this.selectedMarket].indicators; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
/* 市场概览样式 */ |
||||
|
.market-header { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 10px 15px; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.section-title { |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.more-btn { |
||||
|
font-size: 14px; |
||||
|
color: #4080ff; |
||||
|
} |
||||
|
|
||||
|
.market-content { |
||||
|
margin: 0 0 15px; |
||||
|
background-color: #f5f7fa; |
||||
|
border-radius: 8px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
/* 外汇市场样式 */ |
||||
|
.forex-market { |
||||
|
padding: 15px; |
||||
|
} |
||||
|
|
||||
|
.forex-rates { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
gap: 10px; |
||||
|
margin-bottom: 15px; |
||||
|
} |
||||
|
|
||||
|
.forex-rate-item { |
||||
|
width: 30%; |
||||
|
padding: 10px; |
||||
|
border-radius: 6px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.forex-rate-item.up { |
||||
|
background-color: rgba(82, 196, 26, 0.1); |
||||
|
border: 1px solid #52c41a; |
||||
|
} |
||||
|
|
||||
|
.forex-rate-item.down { |
||||
|
background-color: rgba(245, 34, 45, 0.1); |
||||
|
border: 1px solid #f5222d; |
||||
|
} |
||||
|
|
||||
|
.forex-pair { |
||||
|
font-size: 12px; |
||||
|
color: #666; |
||||
|
margin-bottom: 5px; |
||||
|
} |
||||
|
|
||||
|
.forex-value { |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
margin-bottom: 5px; |
||||
|
} |
||||
|
|
||||
|
.forex-change { |
||||
|
font-size: 12px; |
||||
|
color: #52c41a; |
||||
|
} |
||||
|
|
||||
|
.forex-rate-item.down .forex-change { |
||||
|
color: #f5222d; |
||||
|
} |
||||
|
|
||||
|
.forex-analysis-title { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 10px; |
||||
|
border-left: 3px solid #f5222d; |
||||
|
padding-left: 8px; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.analysis-title { |
||||
|
font-size: 14px; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.forex-analysis-content { |
||||
|
display: flex; |
||||
|
background-color: #fff; |
||||
|
border-radius: 6px; |
||||
|
padding: 12px; |
||||
|
} |
||||
|
|
||||
|
.analysis-icon-container { |
||||
|
width: 40px; |
||||
|
height: 40px; |
||||
|
margin-right: 10px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
align-self: center; |
||||
|
} |
||||
|
|
||||
|
.analysis-brain-icon { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.analysis-items { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.analysis-item { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
.analysis-item:last-child { |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.analysis-dot { |
||||
|
width: 8px; |
||||
|
height: 8px; |
||||
|
border-radius: 50%; |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
|
||||
|
.analysis-dot.orange { |
||||
|
background-color: #fa8c16; |
||||
|
} |
||||
|
|
||||
|
.analysis-dot.blue { |
||||
|
background-color: #1890ff; |
||||
|
} |
||||
|
|
||||
|
.analysis-dot.green { |
||||
|
background-color: #52c41a; |
||||
|
} |
||||
|
|
||||
|
.analysis-text { |
||||
|
font-size: 12px; |
||||
|
color: #333; |
||||
|
line-height: 1.4; |
||||
|
} |
||||
|
|
||||
|
/* 市场选择对话框样式 */ |
||||
|
.market-dialog { |
||||
|
width: 300px; |
||||
|
background-color: #fff; |
||||
|
border-radius: 10px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.dialog-title { |
||||
|
padding: 15px; |
||||
|
text-align: center; |
||||
|
border-bottom: 1px solid #eee; |
||||
|
} |
||||
|
|
||||
|
.market-list { |
||||
|
max-height: 300px; |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
|
||||
|
.market-option { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 12px 15px; |
||||
|
border-bottom: 1px solid #f5f5f5; |
||||
|
} |
||||
|
|
||||
|
.market-flag { |
||||
|
width: 24px; |
||||
|
height: 24px; |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
|
||||
|
.flag-image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
border-radius: 50%; |
||||
|
} |
||||
|
|
||||
|
.market-name-container { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.market-option-name { |
||||
|
font-size: 14px; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.dialog-buttons { |
||||
|
padding: 10px 15px 15px; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.confirm-btn { |
||||
|
width: 80%; |
||||
|
height: 40px; |
||||
|
line-height: 40px; |
||||
|
text-align: center; |
||||
|
background-color: #4080ff; |
||||
|
color: #fff; |
||||
|
border-radius: 20px; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
</style> |
||||
@ -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> |
||||
@ -0,0 +1,159 @@ |
|||||
|
<template> |
||||
|
<view class="login-prompt" v-if="showPrompt"> |
||||
|
<view |
||||
|
class="mask" |
||||
|
:class="{ 'mask-show': showAnimation }" |
||||
|
></view> |
||||
|
<view class="prompt-content" :class="{ 'slide-up': showAnimation }"> |
||||
|
<text class="prompt-title">登录以获得更好的体验</text> |
||||
|
<button class="login-btn" @click="goLogin">登录</button> |
||||
|
<button class="visitor-btn" @click="continueAsVisitor"> |
||||
|
以访客身份继续 |
||||
|
</button> |
||||
|
<text class="prompt-title-small" @click="goRegister">如果您还没有账号,点击注册</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, nextTick } from "vue"; |
||||
|
|
||||
|
// 定义响应式数据 |
||||
|
const showPrompt = ref(false); |
||||
|
const showAnimation = ref(false); |
||||
|
|
||||
|
// 显示弹窗 |
||||
|
const show = () => { |
||||
|
showPrompt.value = true; |
||||
|
// 在下一帧触发动画 |
||||
|
nextTick(() => { |
||||
|
setTimeout(() => { |
||||
|
showAnimation.value = true; |
||||
|
}, 10); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
// 隐藏弹窗 |
||||
|
const hide = () => { |
||||
|
showAnimation.value = false; |
||||
|
// 等待动画结束后再隐藏 |
||||
|
setTimeout(() => { |
||||
|
showPrompt.value = false; |
||||
|
}, 300); |
||||
|
}; |
||||
|
|
||||
|
// 跳转到登录页面 |
||||
|
const goLogin = () => { |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/login/login", |
||||
|
}); |
||||
|
hide(); |
||||
|
}; |
||||
|
// 跳转到登录页面 |
||||
|
const goRegister = () => { |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/Registration/Registration", |
||||
|
}); |
||||
|
hide(); |
||||
|
}; |
||||
|
|
||||
|
// 以访客身份继续 |
||||
|
const continueAsVisitor = () => { |
||||
|
// 设置访客模式 |
||||
|
uni.setStorageSync("visitorMode", true); |
||||
|
hide(); |
||||
|
}; |
||||
|
|
||||
|
// 暴露方法给外部使用 |
||||
|
defineExpose({ |
||||
|
show, |
||||
|
hide, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.login-prompt { |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
z-index: 999; |
||||
|
} |
||||
|
|
||||
|
.mask { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
background-color: rgba(0, 0, 0, 0.8); |
||||
|
opacity: 0; |
||||
|
transition: opacity 0.3s ease; |
||||
|
} |
||||
|
|
||||
|
.mask.mask-show { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
|
||||
|
.prompt-content { |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
height: 400rpx; |
||||
|
border-radius: 20rpx 20rpx 0 0; |
||||
|
background-color: white; |
||||
|
padding: 20rpx 70rpx; |
||||
|
transform: translateY(100%); |
||||
|
transition: transform 0.3s ease; |
||||
|
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.3); |
||||
|
} |
||||
|
|
||||
|
.prompt-content.slide-up { |
||||
|
transform: translateY(0); |
||||
|
} |
||||
|
|
||||
|
.prompt-title { |
||||
|
display: block; |
||||
|
text-align: center; |
||||
|
font-size: 40rpx; |
||||
|
font-weight: 700; |
||||
|
color: #000000; |
||||
|
margin-top: 30rpx; |
||||
|
margin-bottom: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.login-btn { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
background-color: rgb(0, 0, 0); |
||||
|
color: white; |
||||
|
font-size: 32rpx; |
||||
|
line-height: 80rpx; |
||||
|
border-radius: 40rpx; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.visitor-btn { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
background-color: #f5f5f5; |
||||
|
color: #333; |
||||
|
font-size: 32rpx; |
||||
|
line-height: 80rpx; |
||||
|
border-radius: 40rpx; |
||||
|
} |
||||
|
.prompt-title-small { |
||||
|
display: block; |
||||
|
text-align: center; |
||||
|
font-size: 24rpx; |
||||
|
color: #6a6a6a; |
||||
|
margin-top: 30rpx; |
||||
|
margin-bottom: 40rpx; |
||||
|
line-height: 15.5px; |
||||
|
letter-spacing: 0.3px; |
||||
|
font-style: normal; |
||||
|
font-family: "PingFang SC"; |
||||
|
} |
||||
|
</style> |
||||
@ -1,109 +1,39 @@ |
|||||
|
import App from './App' |
||||
|
import pinia from './stores/index.js' |
||||
|
|
||||
// #ifndef VUE3
|
// #ifndef VUE3
|
||||
import Vue from 'vue' |
import Vue from 'vue' |
||||
import App from './App' |
|
||||
|
import './uni.promisify.adaptor' |
||||
|
// 导入需要全局注册的组件
|
||||
|
import LoginPrompt from './components/login-prompt.vue' |
||||
|
|
||||
Vue.config.productionTip = false |
|
||||
|
// 全局注册组件
|
||||
|
Vue.component('LoginPrompt', LoginPrompt) |
||||
|
|
||||
|
Vue.config.productionTip = false |
||||
App.mpType = 'app' |
App.mpType = 'app' |
||||
|
|
||||
const app = new Vue({ |
const app = new Vue({ |
||||
...App |
|
||||
|
...App, |
||||
|
// 挂载 store
|
||||
|
pinia |
||||
}) |
}) |
||||
app.$mount() |
app.$mount() |
||||
// #endif
|
// #endif
|
||||
|
|
||||
// #ifdef VUE3
|
// #ifdef VUE3
|
||||
import { createSSRApp } from 'vue' |
import { createSSRApp } from 'vue' |
||||
import App from './App.vue' |
|
||||
import { createI18n } from 'vue-i18n' |
|
||||
|
|
||||
// 导入语言文件
|
|
||||
import en from './static/language/en.js' |
|
||||
import ms from './static/language/ms.js' |
|
||||
import th from './static/language/th.js' |
|
||||
import vi from './static/language/vi.js' |
|
||||
import zh_CN from './static/language/zh_CN.js' |
|
||||
import zh_HK from './static/language/zh_HK.js' |
|
||||
|
// 导入需要全局注册的组件
|
||||
|
import LoginPrompt from './components/login-prompt.vue' |
||||
|
|
||||
function getCurrentLocale() { |
|
||||
if (uni.getStorageSync('languageData') && uni.getStorageSync('languageData').code && uni |
|
||||
.getStorageSync('languageData').code != 'undefined') { |
|
||||
return uni.getStorageSync('languageData').code; |
|
||||
} else { |
|
||||
let language = uni.getSystemInfoSync().osLanguage; |
|
||||
// language = 'zh_CN'
|
|
||||
if (language.indexOf('th') != -1) { |
|
||||
language = 'th' |
|
||||
uni.setStorageSync('languageData', { |
|
||||
code: language |
|
||||
}) |
|
||||
console.log(language); |
|
||||
return language |
|
||||
} else if (language.indexOf('vi') != -1) { |
|
||||
language = 'vi' |
|
||||
uni.setStorageSync('languageData', { |
|
||||
code: language |
|
||||
}) |
|
||||
console.log(language); |
|
||||
return language |
|
||||
}else if (language.indexOf('zh') != -1) { |
|
||||
if (language.indexOf('CN') != -1) { |
|
||||
language = 'zh_CN' |
|
||||
uni.setStorageSync('languageData', { |
|
||||
code: language |
|
||||
}) |
|
||||
console.log(language); |
|
||||
return language |
|
||||
} else { |
|
||||
language = 'zh_HK' |
|
||||
uni.setStorageSync('languageData', { |
|
||||
code: language |
|
||||
}) |
|
||||
console.log(language); |
|
||||
return language |
|
||||
} |
|
||||
} else if (language.indexOf('en') != -1) { |
|
||||
language = 'en' |
|
||||
uni.setStorageSync('languageData', { |
|
||||
code: language |
|
||||
}) |
|
||||
console.log(language); |
|
||||
return language |
|
||||
} else if (language.indexOf('ms') != -1) { |
|
||||
language = 'ms' |
|
||||
uni.setStorageSync('languageData', { |
|
||||
code: language |
|
||||
}) |
|
||||
console.log(language); |
|
||||
return language |
|
||||
} else { |
|
||||
language = 'en' |
|
||||
uni.setStorageSync('languageData', { |
|
||||
code: language |
|
||||
}) |
|
||||
console.log(language); |
|
||||
return language |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
// 创建 i18n 实例
|
|
||||
const i18n = createI18n({ |
|
||||
locale: getCurrentLocale(), |
|
||||
legacy: false, // 使用 Composition API 模式
|
|
||||
globalInjection: true, // 全局注入 $t 函数
|
|
||||
messages: { |
|
||||
'en': en, |
|
||||
'ms': ms, |
|
||||
'th': th, |
|
||||
'vi': vi, |
|
||||
'zh_CN': zh_CN, |
|
||||
'zh_HK': zh_HK |
|
||||
} |
|
||||
}) |
|
||||
export function createApp() { |
export function createApp() { |
||||
const app = createSSRApp(App) |
const app = createSSRApp(App) |
||||
app.use(i18n) |
|
||||
|
|
||||
|
// 全局注册组件
|
||||
|
app.component('LoginPrompt', LoginPrompt) |
||||
|
|
||||
|
// 挂载 store
|
||||
|
app.use(pinia) |
||||
|
|
||||
return { |
return { |
||||
app |
app |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,116 @@ |
|||||
|
|
||||
|
// #ifndef VUE3 |
||||
|
import Vue from 'vue' |
||||
|
import App from './App' |
||||
|
import LoginPrompt from './components/login-prompt.vue' |
||||
|
|
||||
|
Vue.component('LoginPrompt', LoginPrompt) |
||||
|
Vue.config.productionTip = false |
||||
|
|
||||
|
App.mpType = 'app' |
||||
|
|
||||
|
const app = new Vue({ |
||||
|
...App |
||||
|
}) |
||||
|
app.$mount() |
||||
|
// #endif |
||||
|
|
||||
|
// #ifdef VUE3 |
||||
|
import { createSSRApp } from 'vue' |
||||
|
import App from './App.vue' |
||||
|
import { createI18n } from 'vue-i18n' |
||||
|
import LoginPrompt from './components/login-prompt.vue' |
||||
|
|
||||
|
|
||||
|
// 导入语言文件 |
||||
|
import en from './static/language/en.js' |
||||
|
import ms from './static/language/ms.js' |
||||
|
import th from './static/language/th.js' |
||||
|
import vi from './static/language/vi.js' |
||||
|
import zh_CN from './static/language/zh_CN.js' |
||||
|
import zh_HK from './static/language/zh_HK.js' |
||||
|
|
||||
|
function getCurrentLocale() { |
||||
|
if (uni.getStorageSync('languageData') && uni.getStorageSync('languageData').code && uni |
||||
|
.getStorageSync('languageData').code != 'undefined') { |
||||
|
return uni.getStorageSync('languageData').code; |
||||
|
} else { |
||||
|
let language = uni.getSystemInfoSync().osLanguage; |
||||
|
// language = 'zh_CN' |
||||
|
if (language.indexOf('th') != -1) { |
||||
|
language = 'th' |
||||
|
uni.setStorageSync('languageData', { |
||||
|
code: language |
||||
|
}) |
||||
|
console.log(language); |
||||
|
return language |
||||
|
} else if (language.indexOf('vi') != -1) { |
||||
|
language = 'vi' |
||||
|
uni.setStorageSync('languageData', { |
||||
|
code: language |
||||
|
}) |
||||
|
console.log(language); |
||||
|
return language |
||||
|
} else if (language.indexOf('zh') != -1) { |
||||
|
if (language.indexOf('CN') != -1) { |
||||
|
language = 'zh_CN' |
||||
|
uni.setStorageSync('languageData', { |
||||
|
code: language |
||||
|
}) |
||||
|
console.log(language); |
||||
|
return language |
||||
|
} else { |
||||
|
language = 'zh_HK' |
||||
|
uni.setStorageSync('languageData', { |
||||
|
code: language |
||||
|
}) |
||||
|
console.log(language); |
||||
|
return language |
||||
|
} |
||||
|
} else if (language.indexOf('en') != -1) { |
||||
|
language = 'en' |
||||
|
uni.setStorageSync('languageData', { |
||||
|
code: language |
||||
|
}) |
||||
|
console.log(language); |
||||
|
return language |
||||
|
} else if (language.indexOf('ms') != -1) { |
||||
|
language = 'ms' |
||||
|
uni.setStorageSync('languageData', { |
||||
|
code: language |
||||
|
}) |
||||
|
console.log(language); |
||||
|
return language |
||||
|
} else { |
||||
|
language = 'en' |
||||
|
uni.setStorageSync('languageData', { |
||||
|
code: language |
||||
|
}) |
||||
|
console.log(language); |
||||
|
return language |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// 创建 i18n 实例 |
||||
|
const i18n = createI18n({ |
||||
|
locale: getCurrentLocale(), |
||||
|
legacy: false, // 使用 Composition API 模式 |
||||
|
globalInjection: true, // 全局注入 $t 函数 |
||||
|
messages: { |
||||
|
'en': en, |
||||
|
'ms': ms, |
||||
|
'th': th, |
||||
|
'vi': vi, |
||||
|
'zh_CN': zh_CN, |
||||
|
'zh_HK': zh_HK |
||||
|
} |
||||
|
}) |
||||
|
export function createApp() { |
||||
|
const app = createSSRApp(App) |
||||
|
app.component('LoginPrompt', LoginPrompt) |
||||
|
app.use(i18n) |
||||
|
return { |
||||
|
app |
||||
|
} |
||||
|
} |
||||
|
// #endif |
||||
@ -0,0 +1,857 @@ |
|||||
|
{ |
||||
|
"name": "deepChartVueApp", |
||||
|
"lockfileVersion": 3, |
||||
|
"requires": true, |
||||
|
"packages": { |
||||
|
"": { |
||||
|
"dependencies": { |
||||
|
"json-server": "^1.0.0-beta.3", |
||||
|
"marked": "^2.0.1", |
||||
|
"pinia": "^3.0.3", |
||||
|
"pinia-plugin-persistedstate": "^4.5.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@babel/helper-string-parser": { |
||||
|
"version": "7.27.1", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"engines": { |
||||
|
"node": ">=6.9.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@babel/helper-validator-identifier": { |
||||
|
"version": "7.28.5", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"engines": { |
||||
|
"node": ">=6.9.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@babel/parser": { |
||||
|
"version": "7.28.5", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@babel/types": "^7.28.5" |
||||
|
}, |
||||
|
"bin": { |
||||
|
"parser": "bin/babel-parser.js" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=6.0.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@babel/types": { |
||||
|
"version": "7.28.5", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@babel/helper-string-parser": "^7.27.1", |
||||
|
"@babel/helper-validator-identifier": "^7.28.5" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=6.9.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@jridgewell/sourcemap-codec": { |
||||
|
"version": "1.5.5", |
||||
|
"license": "MIT", |
||||
|
"peer": true |
||||
|
}, |
||||
|
"node_modules/@polka/url": { |
||||
|
"version": "1.0.0-next.29", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/accepts": { |
||||
|
"version": "2.2.3", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"mime": "4.0.4", |
||||
|
"negotiator": "^0.6.3" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"type": "individual", |
||||
|
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/app": { |
||||
|
"version": "2.5.2", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/cookie": "2.1.1", |
||||
|
"@tinyhttp/proxy-addr": "2.2.1", |
||||
|
"@tinyhttp/req": "2.2.5", |
||||
|
"@tinyhttp/res": "2.2.5", |
||||
|
"@tinyhttp/router": "2.2.3", |
||||
|
"header-range-parser": "1.1.3", |
||||
|
"regexparam": "^2.0.2" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=14.21.3" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"type": "individual", |
||||
|
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/content-disposition": { |
||||
|
"version": "2.2.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"type": "individual", |
||||
|
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/content-type": { |
||||
|
"version": "0.1.4", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.4" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/cookie": { |
||||
|
"version": "2.1.1", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"type": "individual", |
||||
|
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/cookie-signature": { |
||||
|
"version": "2.1.1", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/cors": { |
||||
|
"version": "2.0.1", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/vary": "^0.1.3" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=12.20 || 14.x || >=16" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/encode-url": { |
||||
|
"version": "2.1.1", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/etag": { |
||||
|
"version": "2.1.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/forwarded": { |
||||
|
"version": "2.1.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/logger": { |
||||
|
"version": "2.1.0", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"colorette": "^2.0.20", |
||||
|
"dayjs": "^1.11.13", |
||||
|
"http-status-emojis": "^2.2.0" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=14.18 || >=16.20" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/proxy-addr": { |
||||
|
"version": "2.2.1", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/forwarded": "2.1.2", |
||||
|
"ipaddr.js": "^2.2.0" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/req": { |
||||
|
"version": "2.2.5", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/accepts": "2.2.3", |
||||
|
"@tinyhttp/type-is": "2.2.4", |
||||
|
"@tinyhttp/url": "2.1.1", |
||||
|
"header-range-parser": "^1.1.3" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/res": { |
||||
|
"version": "2.2.5", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/content-disposition": "2.2.2", |
||||
|
"@tinyhttp/cookie": "2.1.1", |
||||
|
"@tinyhttp/cookie-signature": "2.1.1", |
||||
|
"@tinyhttp/encode-url": "2.1.1", |
||||
|
"@tinyhttp/req": "2.2.5", |
||||
|
"@tinyhttp/send": "2.2.3", |
||||
|
"@tinyhttp/vary": "^0.1.3", |
||||
|
"es-escape-html": "^0.1.1", |
||||
|
"mime": "4.0.4" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/router": { |
||||
|
"version": "2.2.3", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/send": { |
||||
|
"version": "2.2.3", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/content-type": "^0.1.4", |
||||
|
"@tinyhttp/etag": "2.1.2", |
||||
|
"mime": "4.0.4" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/type-is": { |
||||
|
"version": "2.2.4", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/content-type": "^0.1.4", |
||||
|
"mime": "4.0.4" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/url": { |
||||
|
"version": "2.1.1", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@tinyhttp/vary": { |
||||
|
"version": "0.1.3", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.20" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/compiler-core": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@babel/parser": "^7.28.4", |
||||
|
"@vue/shared": "3.5.22", |
||||
|
"entities": "^4.5.0", |
||||
|
"estree-walker": "^2.0.2", |
||||
|
"source-map-js": "^1.2.1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/compiler-dom": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@vue/compiler-core": "3.5.22", |
||||
|
"@vue/shared": "3.5.22" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/compiler-sfc": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@babel/parser": "^7.28.4", |
||||
|
"@vue/compiler-core": "3.5.22", |
||||
|
"@vue/compiler-dom": "3.5.22", |
||||
|
"@vue/compiler-ssr": "3.5.22", |
||||
|
"@vue/shared": "3.5.22", |
||||
|
"estree-walker": "^2.0.2", |
||||
|
"magic-string": "^0.30.19", |
||||
|
"postcss": "^8.5.6", |
||||
|
"source-map-js": "^1.2.1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/compiler-ssr": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@vue/compiler-dom": "3.5.22", |
||||
|
"@vue/shared": "3.5.22" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/devtools-api": { |
||||
|
"version": "7.7.7", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@vue/devtools-kit": "^7.7.7" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/devtools-kit": { |
||||
|
"version": "7.7.7", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@vue/devtools-shared": "^7.7.7", |
||||
|
"birpc": "^2.3.0", |
||||
|
"hookable": "^5.5.3", |
||||
|
"mitt": "^3.0.1", |
||||
|
"perfect-debounce": "^1.0.0", |
||||
|
"speakingurl": "^14.0.1", |
||||
|
"superjson": "^2.2.2" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/devtools-shared": { |
||||
|
"version": "7.7.7", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"rfdc": "^1.4.1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/reactivity": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@vue/shared": "3.5.22" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/runtime-core": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@vue/reactivity": "3.5.22", |
||||
|
"@vue/shared": "3.5.22" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/runtime-dom": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@vue/reactivity": "3.5.22", |
||||
|
"@vue/runtime-core": "3.5.22", |
||||
|
"@vue/shared": "3.5.22", |
||||
|
"csstype": "^3.1.3" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/server-renderer": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@vue/compiler-ssr": "3.5.22", |
||||
|
"@vue/shared": "3.5.22" |
||||
|
}, |
||||
|
"peerDependencies": { |
||||
|
"vue": "3.5.22" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/@vue/shared": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true |
||||
|
}, |
||||
|
"node_modules/birpc": { |
||||
|
"version": "2.6.1", |
||||
|
"license": "MIT", |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/antfu" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/chalk": { |
||||
|
"version": "5.6.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": "^12.17.0 || ^14.13 || >=16.0.0" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/chalk/chalk?sponsor=1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/chokidar": { |
||||
|
"version": "4.0.3", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"readdirp": "^4.0.1" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">= 14.16.0" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://paulmillr.com/funding/" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/colorette": { |
||||
|
"version": "2.0.20", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/copy-anything": { |
||||
|
"version": "4.0.5", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"is-what": "^5.2.0" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=18" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/mesqueeb" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/csstype": { |
||||
|
"version": "3.1.3", |
||||
|
"license": "MIT", |
||||
|
"peer": true |
||||
|
}, |
||||
|
"node_modules/dayjs": { |
||||
|
"version": "1.11.18", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/deep-pick-omit": { |
||||
|
"version": "1.2.1", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/defu": { |
||||
|
"version": "6.1.4", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/destr": { |
||||
|
"version": "2.0.5", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/dot-prop": { |
||||
|
"version": "9.0.0", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"type-fest": "^4.18.2" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=18" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/sindresorhus" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/entities": { |
||||
|
"version": "4.5.0", |
||||
|
"license": "BSD-2-Clause", |
||||
|
"peer": true, |
||||
|
"engines": { |
||||
|
"node": ">=0.12" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/fb55/entities?sponsor=1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/es-escape-html": { |
||||
|
"version": "0.1.1", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.x" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/estree-walker": { |
||||
|
"version": "2.0.2", |
||||
|
"license": "MIT", |
||||
|
"peer": true |
||||
|
}, |
||||
|
"node_modules/eta": { |
||||
|
"version": "3.5.0", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=6.0.0" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/eta-dev/eta?sponsor=1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/header-range-parser": { |
||||
|
"version": "1.1.3", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=12.22.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/hookable": { |
||||
|
"version": "5.5.3", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/http-status-emojis": { |
||||
|
"version": "2.2.0", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/inflection": { |
||||
|
"version": "3.0.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=18.0.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/ipaddr.js": { |
||||
|
"version": "2.2.0", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">= 10" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/is-what": { |
||||
|
"version": "5.5.0", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=18" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/mesqueeb" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/json-server": { |
||||
|
"version": "1.0.0-beta.3", |
||||
|
"license": "SEE LICENSE IN ./LICENSE", |
||||
|
"dependencies": { |
||||
|
"@tinyhttp/app": "^2.4.0", |
||||
|
"@tinyhttp/cors": "^2.0.1", |
||||
|
"@tinyhttp/logger": "^2.0.0", |
||||
|
"chalk": "^5.3.0", |
||||
|
"chokidar": "^4.0.1", |
||||
|
"dot-prop": "^9.0.0", |
||||
|
"eta": "^3.5.0", |
||||
|
"inflection": "^3.0.0", |
||||
|
"json5": "^2.2.3", |
||||
|
"lowdb": "^7.0.1", |
||||
|
"milliparsec": "^4.0.0", |
||||
|
"sirv": "^2.0.4", |
||||
|
"sort-on": "^6.1.0" |
||||
|
}, |
||||
|
"bin": { |
||||
|
"json-server": "lib/bin.js" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=18.3" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/json5": { |
||||
|
"version": "2.2.3", |
||||
|
"license": "MIT", |
||||
|
"bin": { |
||||
|
"json5": "lib/cli.js" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=6" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/lowdb": { |
||||
|
"version": "7.0.1", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"steno": "^4.0.2" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=18" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/typicode" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/magic-string": { |
||||
|
"version": "0.30.21", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@jridgewell/sourcemap-codec": "^1.5.5" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/marked": { |
||||
|
"version": "2.0.1", |
||||
|
"license": "MIT", |
||||
|
"bin": { |
||||
|
"marked": "bin/marked" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">= 8.16.2" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/milliparsec": { |
||||
|
"version": "4.0.0", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=20" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/mime": { |
||||
|
"version": "4.0.4", |
||||
|
"funding": [ |
||||
|
"https://github.com/sponsors/broofa" |
||||
|
], |
||||
|
"license": "MIT", |
||||
|
"bin": { |
||||
|
"mime": "bin/cli.js" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=16" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/mitt": { |
||||
|
"version": "3.0.1", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/mrmime": { |
||||
|
"version": "2.0.1", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=10" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/nanoid": { |
||||
|
"version": "3.3.11", |
||||
|
"funding": [ |
||||
|
{ |
||||
|
"type": "github", |
||||
|
"url": "https://github.com/sponsors/ai" |
||||
|
} |
||||
|
], |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"bin": { |
||||
|
"nanoid": "bin/nanoid.cjs" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/negotiator": { |
||||
|
"version": "0.6.4", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">= 0.6" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/perfect-debounce": { |
||||
|
"version": "1.0.0", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/picocolors": { |
||||
|
"version": "1.1.1", |
||||
|
"license": "ISC", |
||||
|
"peer": true |
||||
|
}, |
||||
|
"node_modules/pinia": { |
||||
|
"version": "3.0.3", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@vue/devtools-api": "^7.7.2" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/posva" |
||||
|
}, |
||||
|
"peerDependencies": { |
||||
|
"typescript": ">=4.4.4", |
||||
|
"vue": "^2.7.0 || ^3.5.11" |
||||
|
}, |
||||
|
"peerDependenciesMeta": { |
||||
|
"typescript": { |
||||
|
"optional": true |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/pinia-plugin-persistedstate": { |
||||
|
"version": "4.5.0", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"deep-pick-omit": "^1.2.1", |
||||
|
"defu": "^6.1.4", |
||||
|
"destr": "^2.0.5" |
||||
|
}, |
||||
|
"peerDependencies": { |
||||
|
"@nuxt/kit": ">=3.0.0", |
||||
|
"@pinia/nuxt": ">=0.10.0", |
||||
|
"pinia": ">=3.0.0" |
||||
|
}, |
||||
|
"peerDependenciesMeta": { |
||||
|
"@nuxt/kit": { |
||||
|
"optional": true |
||||
|
}, |
||||
|
"@pinia/nuxt": { |
||||
|
"optional": true |
||||
|
}, |
||||
|
"pinia": { |
||||
|
"optional": true |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/postcss": { |
||||
|
"version": "8.5.6", |
||||
|
"funding": [ |
||||
|
{ |
||||
|
"type": "opencollective", |
||||
|
"url": "https://opencollective.com/postcss/" |
||||
|
}, |
||||
|
{ |
||||
|
"type": "tidelift", |
||||
|
"url": "https://tidelift.com/funding/github/npm/postcss" |
||||
|
}, |
||||
|
{ |
||||
|
"type": "github", |
||||
|
"url": "https://github.com/sponsors/ai" |
||||
|
} |
||||
|
], |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"nanoid": "^3.3.11", |
||||
|
"picocolors": "^1.1.1", |
||||
|
"source-map-js": "^1.2.1" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": "^10 || ^12 || >=14" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/readdirp": { |
||||
|
"version": "4.1.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">= 14.18.0" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"type": "individual", |
||||
|
"url": "https://paulmillr.com/funding/" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/regexparam": { |
||||
|
"version": "2.0.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=8" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/rfdc": { |
||||
|
"version": "1.4.1", |
||||
|
"license": "MIT" |
||||
|
}, |
||||
|
"node_modules/sirv": { |
||||
|
"version": "2.0.4", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@polka/url": "^1.0.0-next.24", |
||||
|
"mrmime": "^2.0.0", |
||||
|
"totalist": "^3.0.0" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">= 10" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/sort-on": { |
||||
|
"version": "6.1.1", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"dot-prop": "^9.0.0" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=18" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/sindresorhus" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/source-map-js": { |
||||
|
"version": "1.2.1", |
||||
|
"license": "BSD-3-Clause", |
||||
|
"peer": true, |
||||
|
"engines": { |
||||
|
"node": ">=0.10.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/speakingurl": { |
||||
|
"version": "14.0.1", |
||||
|
"license": "BSD-3-Clause", |
||||
|
"engines": { |
||||
|
"node": ">=0.10.0" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/steno": { |
||||
|
"version": "4.0.2", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=18" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/typicode" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/superjson": { |
||||
|
"version": "2.2.3", |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"copy-anything": "^4" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=16" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/totalist": { |
||||
|
"version": "3.0.1", |
||||
|
"license": "MIT", |
||||
|
"engines": { |
||||
|
"node": ">=6" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/type-fest": { |
||||
|
"version": "4.41.0", |
||||
|
"license": "(MIT OR CC0-1.0)", |
||||
|
"engines": { |
||||
|
"node": ">=16" |
||||
|
}, |
||||
|
"funding": { |
||||
|
"url": "https://github.com/sponsors/sindresorhus" |
||||
|
} |
||||
|
}, |
||||
|
"node_modules/vue": { |
||||
|
"version": "3.5.22", |
||||
|
"license": "MIT", |
||||
|
"peer": true, |
||||
|
"dependencies": { |
||||
|
"@vue/compiler-dom": "3.5.22", |
||||
|
"@vue/compiler-sfc": "3.5.22", |
||||
|
"@vue/runtime-dom": "3.5.22", |
||||
|
"@vue/server-renderer": "3.5.22", |
||||
|
"@vue/shared": "3.5.22" |
||||
|
}, |
||||
|
"peerDependencies": { |
||||
|
"typescript": "*" |
||||
|
}, |
||||
|
"peerDependenciesMeta": { |
||||
|
"typescript": { |
||||
|
"optional": true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
{ |
||||
|
"dependencies": { |
||||
|
"json-server": "^1.0.0-beta.3", |
||||
|
"marked": "^2.0.1", |
||||
|
"pinia": "^3.0.3", |
||||
|
"pinia-plugin-persistedstate": "^4.5.0" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"server-login": "json-server ./server/login.json --port 8888", |
||||
|
"server-deepchart": "json-server ./server/deepchart.json --port 8888" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<template> |
||||
|
<view class="blank-page"> |
||||
|
<text class="tip">当前特斯拉该如何布局?</text> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
// 空白页,无逻辑 |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.blank-page { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
height: 100vh; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
.tip { |
||||
|
color: #999999; |
||||
|
font-size: 28rpx; |
||||
|
} |
||||
|
</style> |
||||
1524
pages/deepMate/deepMate.vue
File diff suppressed because it is too large
View File
@ -0,0 +1,63 @@ |
|||||
|
<template> |
||||
|
<view class="container"> |
||||
|
<scroll-view |
||||
|
class="scroll-view" |
||||
|
scroll-y="true" |
||||
|
@scrolltolower="onScrollToLower" |
||||
|
> |
||||
|
<button @click="scrollTo">点击滚动</button> |
||||
|
<view v-for="(item, index) in list" :key="index"> |
||||
|
{{ item }} |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
<button @click="addItem">添加内容</button> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
list: Array.from({ length: 20 }, (_, i) => `Item ${i + 1}`), |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
onScrollToLower() { |
||||
|
console.log("滚动到底部了"); |
||||
|
// 可以在这里加载更多数据 |
||||
|
}, |
||||
|
addItem() { |
||||
|
this.list.push(`Item ${this.list.length + 1}`); |
||||
|
this.$nextTick(() => { |
||||
|
this.$refs.scrollView.scrollTo({ |
||||
|
top: 99999, |
||||
|
duration: 300, |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
scrollTo() { |
||||
|
uni.pageScrollTo({ |
||||
|
scrollTop: 100, |
||||
|
duration: 300, |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.container { |
||||
|
height: 100%; |
||||
|
} |
||||
|
.scroll-view { |
||||
|
height: 80%; |
||||
|
} |
||||
|
button { |
||||
|
width: 100%; |
||||
|
height: 50px; |
||||
|
line-height: 50px; |
||||
|
text-align: center; |
||||
|
background-color: #007aff; |
||||
|
color: white; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,949 @@ |
|||||
|
<template> |
||||
|
<view class="login-registration-container"> |
||||
|
<!-- 自定义导航栏 --> |
||||
|
<view |
||||
|
class="custom-navbar" |
||||
|
:style="{ paddingTop: safeAreaInsets?.top + 'px' }" |
||||
|
> |
||||
|
<!-- <view class="nav-left"> |
||||
|
<text class="back-btn" @click="goToIndex"><</text> |
||||
|
</view> --> |
||||
|
<view class="nav-right"> |
||||
|
<image |
||||
|
class="icons" |
||||
|
src="../../../static/icons/Headset.png" |
||||
|
alt="联系客服" |
||||
|
/> |
||||
|
<image |
||||
|
class="icons" |
||||
|
@click="goToIndex" |
||||
|
src="../../../static/icons/Frame.png" |
||||
|
alt="返回首页" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- Logo --> |
||||
|
<!-- <image class="logo" src="/static/logo.png" mode="aspectFit"></image> --> |
||||
|
|
||||
|
<!-- 欢迎语 --> |
||||
|
<text class="welcome-text">欢迎来到DeepChart</text> |
||||
|
|
||||
|
<!-- 邮箱/手机号切换 --> |
||||
|
<view class="switch-container"> |
||||
|
<text |
||||
|
class="switch-item" |
||||
|
:class="{ active: switchType === 'Email' }" |
||||
|
@click="switchEmail" |
||||
|
>邮箱</text |
||||
|
> |
||||
|
<text |
||||
|
class="switch-item" |
||||
|
:class="{ active: switchType === 'Phone' }" |
||||
|
@click="switchPhone" |
||||
|
>手机号</text |
||||
|
> |
||||
|
</view> |
||||
|
<!-- 输入框 --> |
||||
|
<view class="input-container"> |
||||
|
<view v-if="switchType === 'Email'"> |
||||
|
<!-- 修改邮箱输入框容器,将图标包含在内 --> |
||||
|
<view class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Mail.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
class="input-field" |
||||
|
type="text" |
||||
|
placeholder="请输入邮箱" |
||||
|
v-model="email" |
||||
|
/> |
||||
|
<view> |
||||
|
<button |
||||
|
class="send-code-btn-email" |
||||
|
:disabled="isCodeBtnDisabled" |
||||
|
:class="{ 'send-code-btn-disabled': isCodeBtnDisabled }" |
||||
|
@click="sendCode" |
||||
|
> |
||||
|
<text |
||||
|
class="send-code-text" |
||||
|
:class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }" |
||||
|
>{{ codeBtnText }}</text |
||||
|
> |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Text-recognition.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
class="input-field" |
||||
|
type="text" |
||||
|
placeholder="请输入验证码" |
||||
|
v-model="verifyCode" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view v-if="switchType === 'Phone'" class="phone-input-container"> |
||||
|
<view class="country-code-selector" @click="showCountryPicker"> |
||||
|
<image |
||||
|
class="country-flag-img" |
||||
|
src="../../../static/icons/Iphone.png" |
||||
|
mode="aspectFit" |
||||
|
></image> |
||||
|
<text class="country-code">{{ selectedCountry.code }}</text> |
||||
|
<!-- <text class="arrow-down">▼</text> --> |
||||
|
</view> |
||||
|
<input |
||||
|
class="input-field phone-input" |
||||
|
type="number" |
||||
|
placeholder="输入手机号" |
||||
|
v-model="phone" |
||||
|
@input="onPhoneInput" |
||||
|
/> |
||||
|
<view> |
||||
|
<button |
||||
|
class="send-code-btn" |
||||
|
:disabled="isCodeBtnDisabled" |
||||
|
:class="{ 'send-code-btn-disabled': isCodeBtnDisabled }" |
||||
|
@click="sendCode" |
||||
|
> |
||||
|
<text |
||||
|
class="send-code-text" |
||||
|
:class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }" |
||||
|
>{{ codeBtnText }}</text |
||||
|
> |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view v-if="switchType === 'Phone'" class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Text-recognition.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
class="input-field" |
||||
|
type="text" |
||||
|
placeholder="请输入验证码" |
||||
|
v-model="verifyCode" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 用户协议 --> |
||||
|
<view @click="changeCheckbox" class="agreement-container-one"> |
||||
|
<image class="checkbox" :src="checkboxUrl"></image> |
||||
|
<text class="agreement-text-one" |
||||
|
>接受 <text class="link" @click="openAgreement">用户协议</text> 和 |
||||
|
<text class="link" @click="openPrivacy">隐私政策</text></text |
||||
|
> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 注册按钮 --> |
||||
|
<button class="register-btn" @click="register">注册</button> |
||||
|
|
||||
|
<!-- 或者 --> |
||||
|
<text class="or-text" @click="goToLogin">已有账号? |
||||
|
<text class="link">登录</text> |
||||
|
</text> |
||||
|
|
||||
|
<!-- 同意弹窗 --> |
||||
|
<uniPopup ref="agreementPopup" type="dialog"> |
||||
|
<view class="popup-content"> |
||||
|
<text class="popup-message" |
||||
|
>请阅读并同意<text @click="openAgreement" class="popup-message-link" |
||||
|
>服务协议</text |
||||
|
>和<text @click="openPrivacy" class="popup-message-link" |
||||
|
>隐私权限</text |
||||
|
> |
||||
|
</text> |
||||
|
<view class="button-group"> |
||||
|
<button class="cancel-button" @click="handleCancel"> |
||||
|
<text class="cancel-text">取消</text> |
||||
|
</button> |
||||
|
<button class="agree-button" @click="handleAgree"> |
||||
|
<text class="agree-text">同意</text> |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</uniPopup> |
||||
|
<footerBar class="static-footer" :type="type"></footerBar> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref } from "vue"; |
||||
|
// 导入完整的国家列表 |
||||
|
import countryList from "../login/list"; |
||||
|
import footerBar from "../../../components/footerBar-cn.vue"; |
||||
|
import uniPopup from "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue"; |
||||
|
import { verificationPhone, verificationEmail } from "../login/verification"; |
||||
|
|
||||
|
const type = ref("member"); |
||||
|
const email = ref(""); |
||||
|
const password = ref(""); |
||||
|
const phone = ref(""); |
||||
|
const country = ref("+86"); |
||||
|
const agreed = ref(false); |
||||
|
const switchType = ref("Phone"); // 默认是邮箱注册 |
||||
|
const { safeAreaInsets } = uni.getSystemInfoSync(); |
||||
|
const codeBtnText = ref("获取验证码"); |
||||
|
const isCodeBtnDisabled = ref(false); // 添加验证码按钮禁用状态 |
||||
|
const checkboxUrl = ref("../../../static/icons/Check-one-false.png"); |
||||
|
const verifyCode = ref(""); |
||||
|
const account = ref(""); |
||||
|
|
||||
|
// 使用从list.js导入的完整国家列表数据 |
||||
|
const countries = ref( |
||||
|
countryList.list.map((item) => ({ |
||||
|
name: item.name, |
||||
|
code: `+${item.tel}`, |
||||
|
flag: item.flag, |
||||
|
short: item.short, |
||||
|
en: item.en, |
||||
|
})) |
||||
|
); |
||||
|
|
||||
|
// 默认选中的国家(中国) |
||||
|
const selectedCountry = ref( |
||||
|
countries.value.find((country) => country.short === "CN") || |
||||
|
countries.value[0] |
||||
|
); |
||||
|
|
||||
|
// 显示国家选择器 |
||||
|
function showCountryPicker() { |
||||
|
uni.showActionSheet({ |
||||
|
itemList: countries.value.map( |
||||
|
(country) => `${country.name} ${country.code}` |
||||
|
), |
||||
|
success: function (res) { |
||||
|
selectedCountry.value = countries.value[res.tapIndex]; |
||||
|
}, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function goToIndex() { |
||||
|
// 返回上一页 |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/index/index", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function switchEmail() { |
||||
|
// 切换到邮箱注册 |
||||
|
switchType.value = "Email"; |
||||
|
verifyCode.value = ""; |
||||
|
} |
||||
|
|
||||
|
function switchPhone() { |
||||
|
// 切换到手机注册 |
||||
|
switchType.value = "Phone"; |
||||
|
verifyCode.value = ""; |
||||
|
} |
||||
|
|
||||
|
// function register() { |
||||
|
// if (switchType.value === "Email") { |
||||
|
// // 登录逻辑 |
||||
|
// if (!email.value) { |
||||
|
// uni.showToast({ |
||||
|
// title: "请输入邮箱地址", |
||||
|
// icon: "none", |
||||
|
// }); |
||||
|
// return; |
||||
|
// } |
||||
|
|
||||
|
// // 发送登录请求 |
||||
|
// console.log("登录:", email.value); |
||||
|
// } |
||||
|
|
||||
|
// if (switchType.value === "Phone") { |
||||
|
// // 登录逻辑 |
||||
|
// if (!phone.value) { |
||||
|
// uni.showToast({ |
||||
|
// title: "请输入手机号码", |
||||
|
// icon: "none", |
||||
|
// }); |
||||
|
// return; |
||||
|
// } |
||||
|
|
||||
|
// // 发送登录请求 |
||||
|
// console.log("登录:", phone.value); |
||||
|
// } |
||||
|
// } |
||||
|
function register() { |
||||
|
if (!basicVerification()) { |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 基础验证 |
||||
|
function basicVerification() { |
||||
|
if (switchType.value === "User") { |
||||
|
if (!deepChartID.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入用户名", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (!password.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入密码", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (switchType.value === "Phone") { |
||||
|
// 登录逻辑 |
||||
|
if (!phone.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入手机号码", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
const phoneAll = `${country.value}${phone.value}`; |
||||
|
console.log("完整手机号" + phoneAll); |
||||
|
if (!validatePhoneNumber(country.value, phone.value)) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (!verifyCode.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入验证码", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (switchType.value === "Email") { |
||||
|
// 登录逻辑 |
||||
|
if (!email.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入邮箱地址", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
const bool = verificationEmail(email.value); |
||||
|
console.log("验证是否成功", bool); |
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "邮箱格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (!verifyCode.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入验证码", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!agreed.value) { |
||||
|
// 显示同意弹窗 |
||||
|
agreementPopup.value.open(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// 验证码验证 |
||||
|
function VerCodeVerfifcation() { |
||||
|
if (switchType.value === "Phone") { |
||||
|
if (!phone.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入手机号", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
const bool = verificationPhone(country.value, phone.value); |
||||
|
console.log("验证是否成功", bool); |
||||
|
|
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "手机号格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (switchType.value === "Email") { |
||||
|
if (!email.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入邮箱地址", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
const bool = verificationEmail(email.value); |
||||
|
console.log("验证是否成功", bool); |
||||
|
|
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "邮箱格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
function goToLogin() { |
||||
|
// 跳转到登录页 |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/login/login", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function onPhoneInput(e) { |
||||
|
// 确保只允许输入数字 |
||||
|
const value = e.detail.value; |
||||
|
// 使用 isNaN 检查是否为有效数字 |
||||
|
if (isNaN(value)) { |
||||
|
phone.value = ""; |
||||
|
} else { |
||||
|
phone.value = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function sendCode() { |
||||
|
|
||||
|
if (!VerCodeVerfifcation()) { |
||||
|
return ; |
||||
|
} |
||||
|
|
||||
|
// 如果按钮已禁用,则不执行后续逻辑 |
||||
|
if (isCodeBtnDisabled.value) return; |
||||
|
|
||||
|
// 设置按钮为禁用状态 |
||||
|
isCodeBtnDisabled.value = true; |
||||
|
codeBtnText.value = "重新发送"; |
||||
|
let time = 6; |
||||
|
const timer = setInterval(() => { |
||||
|
time--; |
||||
|
codeBtnText.value = "重新发送 " + time + "s"; |
||||
|
if (time <= 0) { |
||||
|
clearInterval(timer); |
||||
|
codeBtnText.value = "重新发送"; |
||||
|
// 倒计时结束后启用按钮 |
||||
|
isCodeBtnDisabled.value = false; |
||||
|
} |
||||
|
}, 1000); |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
function openAgreement() { |
||||
|
// 打开用户协议 |
||||
|
console.log("打开用户协议"); |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/agreement/agreement", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function openPrivacy() { |
||||
|
// 打开隐私政策 |
||||
|
console.log("打开隐私政策"); |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/privacy/privacy", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function changeCheckbox() { |
||||
|
agreed.value = !agreed.value; |
||||
|
checkboxUrl.value = agreed.value |
||||
|
? "../../../static/icons/Check-one-true.png" |
||||
|
: "../../../static/icons/Check-one-false.png"; |
||||
|
} |
||||
|
|
||||
|
// 验证手机号是否正确 |
||||
|
function validatePhoneNumber(countryCode, phoneNumber) { |
||||
|
// 检查是否为空 |
||||
|
if (!phoneNumber || phoneNumber.trim() === "") { |
||||
|
uni.showToast({ |
||||
|
title: "手机号不能为空", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
const bool = verificationPhone(countryCode, phoneNumber); |
||||
|
console.log("验证是否成功", bool); |
||||
|
|
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "手机号格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// 去掉+号后检查长度(手机号通常在7到15位之间) |
||||
|
const cleanNumber = phoneNumber.replace(/^\+/, ""); |
||||
|
if (cleanNumber.length < 7 || cleanNumber.length > 15) { |
||||
|
uni.showToast({ |
||||
|
title: "手机号长度不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// 添加弹窗引用 |
||||
|
const agreementPopup = ref(null); |
||||
|
|
||||
|
// 处理同意按钮点击 |
||||
|
function handleAgree() { |
||||
|
// 关闭弹窗 |
||||
|
agreementPopup.value.close(); |
||||
|
// 设置为已同意 |
||||
|
agreed.value = true; |
||||
|
checkboxUrl.value = "../../../static/icons/Check-one-true.png"; |
||||
|
// 继续登录流程 |
||||
|
} |
||||
|
|
||||
|
// 处理同意按钮点击 |
||||
|
function handleCancel() { |
||||
|
// 关闭弹窗 |
||||
|
agreementPopup.value.close(); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.login-registration-container { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 0 70rpx; |
||||
|
height: 100vh; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
/* 自定义导航栏样式 */ |
||||
|
.custom-navbar { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
/* z-index: 999; */ |
||||
|
width: 90%; |
||||
|
height: 80rpx; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 10rpx 40rpx; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.nav-left, |
||||
|
.nav-right { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.nav-right { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
|
||||
|
.icons { |
||||
|
margin: 20rpx; |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
/* margin-right: 10rpx; */ |
||||
|
} |
||||
|
|
||||
|
.back-btn, |
||||
|
.headphone-btn { |
||||
|
font-size: 36rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333333; |
||||
|
padding: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
width: 120rpx; |
||||
|
height: 120rpx; |
||||
|
margin-bottom: 60rpx; |
||||
|
border-radius: 20%; |
||||
|
} |
||||
|
|
||||
|
.welcome-text { |
||||
|
font-size: 48rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333333; |
||||
|
margin-bottom: 60rpx; |
||||
|
/* text-align: left; */ |
||||
|
/* align-self: flex-start; */ |
||||
|
} |
||||
|
|
||||
|
.switch-container { |
||||
|
display: flex; |
||||
|
margin-bottom: 40rpx; |
||||
|
align-self: flex-start; |
||||
|
} |
||||
|
|
||||
|
.switch-item { |
||||
|
font-size: 28rpx; |
||||
|
color: #999999; |
||||
|
padding: 10rpx 20rpx; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.switch-item::after { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
width: 60%; |
||||
|
/* 控制边框宽度 */ |
||||
|
height: 2rpx; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
|
||||
|
.switch-item.active { |
||||
|
color: #333333; |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
|
||||
|
.switch-item.active::after { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
top: 60rpx; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
width: 30%; |
||||
|
/* 控制边框宽度 */ |
||||
|
height: 7rpx; |
||||
|
background-color: #333333; |
||||
|
} |
||||
|
|
||||
|
.input-container { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
/* 添加图标输入框样式 */ |
||||
|
.input-with-icon { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
border-bottom: 2rpx solid #e5e5e5; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.input-icon { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
margin: 0 20rpx; |
||||
|
} |
||||
|
|
||||
|
.input-field { |
||||
|
flex: 1; |
||||
|
height: 80rpx; |
||||
|
padding: 15rpx 0; |
||||
|
font-size: 28rpx; |
||||
|
color: #333333; |
||||
|
border: none; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
|
||||
|
.phone-input-container { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 95.8%; |
||||
|
height: 80rpx; |
||||
|
/* border-radius: 20rpx; */ |
||||
|
/* border: 2rpx solid #e5e5e5; */ |
||||
|
/* background-color: #f5f5f5; */ |
||||
|
padding: 0 10rpx; |
||||
|
border-bottom: 2rpx solid #e5e5e5; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.country-code-selector { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 0 10rpx; |
||||
|
padding-bottom: 1rpx; |
||||
|
height: 100%; |
||||
|
/* border-right: 2rpx solid #e5e5e5; */ |
||||
|
/* background-color: #f5f5f5; */ |
||||
|
border-radius: 20rpx 0 0 20rpx; |
||||
|
} |
||||
|
|
||||
|
.country-code { |
||||
|
font-size: 28rpx; |
||||
|
color: #333333; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.country-flag-img { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.arrow-down { |
||||
|
font-size: 20rpx; |
||||
|
color: #999999; |
||||
|
} |
||||
|
|
||||
|
.phone-input { |
||||
|
flex: 1; |
||||
|
width: auto; |
||||
|
height: 100%; |
||||
|
border: none; |
||||
|
background-color: transparent; |
||||
|
padding: 0 0rpx; |
||||
|
} |
||||
|
|
||||
|
.send-code-btn { |
||||
|
width: 200rpx; |
||||
|
height: 60rpx; |
||||
|
display: inline-flex; |
||||
|
padding: 0rpx 10rpx; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
gap: 10px; |
||||
|
border-radius: 4px; |
||||
|
background: #000; |
||||
|
} |
||||
|
.send-code-btn-email { |
||||
|
width: 200rpx; |
||||
|
height: 60rpx; |
||||
|
display: inline-flex; |
||||
|
padding: 0rpx 10rpx; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
gap: 10px; |
||||
|
border-radius: 4px; |
||||
|
background: #000; |
||||
|
margin-right: 15rpx; |
||||
|
} |
||||
|
|
||||
|
.send-code-btn-disabled { |
||||
|
background: #e6e6e6; |
||||
|
/* 禁用状态下的灰色背景 */ |
||||
|
} |
||||
|
|
||||
|
.send-code-btn-disabled-text { |
||||
|
color: #999999 !important; |
||||
|
} |
||||
|
|
||||
|
.send-code-text { |
||||
|
color: #fff; |
||||
|
font-size: 28rpx; |
||||
|
} |
||||
|
|
||||
|
.agreement-container-one { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
align-self: flex-start; |
||||
|
margin-bottom: 80rpx; |
||||
|
} |
||||
|
|
||||
|
.agreement-container { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 40rpx; |
||||
|
margin-top: -75.5rpx; |
||||
|
align-self: flex-start; |
||||
|
} |
||||
|
|
||||
|
.checkbox { |
||||
|
width: 30rpx; |
||||
|
height: 30rpx; |
||||
|
margin-left: 20rpx; |
||||
|
/* flex: content; */ |
||||
|
} |
||||
|
|
||||
|
.agreement-text-one { |
||||
|
font-size: 22rpx; |
||||
|
color: #666666; |
||||
|
text-align: center; |
||||
|
margin-left: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.agreement-text { |
||||
|
margin-left: 20rpx; |
||||
|
font-size: 24rpx; |
||||
|
color: #666666; |
||||
|
} |
||||
|
|
||||
|
.link { |
||||
|
color: #333333; |
||||
|
font-weight: bold; |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
|
||||
|
.register-btn { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
background-color: #000000; |
||||
|
color: white; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: bold; |
||||
|
border-radius: 40rpx; |
||||
|
margin-bottom: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.or-text { |
||||
|
flex-direction: column; |
||||
|
font-size: 24rpx; |
||||
|
color: #999999; |
||||
|
margin-top: 330rpx; |
||||
|
margin-bottom: -22rpx; |
||||
|
} |
||||
|
|
||||
|
.third-party-login { |
||||
|
width: 100%; |
||||
|
margin-bottom: 60rpx; |
||||
|
} |
||||
|
|
||||
|
.third-party-text { |
||||
|
color: #ffffff; |
||||
|
font-weight: bold; |
||||
|
white-space: pre; |
||||
|
} |
||||
|
|
||||
|
.third-party-btn { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
background-color: rgb(0, 0, 0); |
||||
|
border: 2rpx solid #e5e5e5; |
||||
|
border-radius: 40rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
margin-bottom: 20rpx; |
||||
|
font-size: 28rpx; |
||||
|
color: #333333; |
||||
|
} |
||||
|
|
||||
|
.google-icon, |
||||
|
.apple-icon { |
||||
|
width: 60rpx; |
||||
|
height: 60rpx; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.existing-account { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.account-text { |
||||
|
font-size: 24rpx; |
||||
|
color: #666666; |
||||
|
} |
||||
|
|
||||
|
.login-link { |
||||
|
font-size: 24rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333333; |
||||
|
margin-left: 10rpx; |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
|
||||
|
.static-footer { |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
} |
||||
|
|
||||
|
/* 弹窗样式 */ |
||||
|
.popup-content { |
||||
|
background-color: #ffffff; |
||||
|
padding: 40rpx; |
||||
|
text-align: center; |
||||
|
border-radius: 10rpx; |
||||
|
width: 550rpx; |
||||
|
} |
||||
|
|
||||
|
.popup-message { |
||||
|
font-size: 28rpx; |
||||
|
color: #000000; |
||||
|
margin-bottom: 60rpx; |
||||
|
margin-top: 20rpx; |
||||
|
text-align: center; /* 水平居中 */ |
||||
|
display: flex; /* 使用flex布局 */ |
||||
|
justify-content: center; /* 水平居中 */ |
||||
|
align-items: center; /* 垂直居中 */ |
||||
|
font-weight: 300; |
||||
|
} |
||||
|
.popup-message-link { |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
.button-group { |
||||
|
display: flex; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
.agree-button { |
||||
|
width: 160rpx; |
||||
|
height: 56rpx; |
||||
|
background-color: #000000; |
||||
|
border-radius: 40rpx; |
||||
|
display: flex; /* 添加flex布局 */ |
||||
|
align-items: center; /* 垂直居中 */ |
||||
|
justify-content: center; /* 水平居中 */ |
||||
|
} |
||||
|
.agree-text { |
||||
|
color: #ffffff; |
||||
|
font-size: 34rpx; |
||||
|
/* 添加垂直居中相关样式 */ |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
line-height: 1; /* 确保文字垂直居中 */ |
||||
|
} |
||||
|
|
||||
|
.cancel-button { |
||||
|
width: 160rpx; |
||||
|
height: 56rpx; |
||||
|
background-color: #e5e5e5; |
||||
|
border-radius: 40rpx; |
||||
|
display: flex; /* 添加flex布局 */ |
||||
|
align-items: center; /* 垂直居中 */ |
||||
|
justify-content: center; /* 水平居中 */ |
||||
|
} |
||||
|
.cancel-text { |
||||
|
color: #333333; |
||||
|
font-size: 34rpx; |
||||
|
/* 添加垂直居中相关样式 */ |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
line-height: 1; /* 确保文字垂直居中 */ |
||||
|
} |
||||
|
</style> |
||||
1341
pages/start/Registration/list.js
File diff suppressed because it is too large
View File
@ -0,0 +1,13 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
用户协议 |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
|
||||
|
</style> |
||||
@ -0,0 +1,55 @@ |
|||||
|
<template> |
||||
|
<view class="content"> |
||||
|
<image class="logo" src="/static/logo.png"></image> |
||||
|
<view class="text-area"> |
||||
|
<text class="title" @click="showLoginPrompt">{{ title }}</text> |
||||
|
</view> |
||||
|
<LoginPrompt ref="loginPrompt"></LoginPrompt> |
||||
|
<button @click="toDeepMate">deepMate</button> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref } from "vue"; |
||||
|
|
||||
|
const title = ref("请先登录"); |
||||
|
const loginPrompt = ref(null); |
||||
|
|
||||
|
function showLoginPrompt() { |
||||
|
loginPrompt.value.show(); |
||||
|
} |
||||
|
|
||||
|
function toDeepMate() { |
||||
|
uni.navigateTo({ |
||||
|
url: '/pages/deepMate/deepMate' |
||||
|
}) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.content { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
height: 200rpx; |
||||
|
width: 200rpx; |
||||
|
margin-top: 200rpx; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
margin-bottom: 50rpx; |
||||
|
} |
||||
|
|
||||
|
.text-area { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-size: 36rpx; |
||||
|
color: #8f8f94; |
||||
|
} |
||||
|
</style> |
||||
1341
pages/start/login/list.js
File diff suppressed because it is too large
View File
1111
pages/start/login/login.vue
File diff suppressed because it is too large
View File
@ -0,0 +1,69 @@ |
|||||
|
|
||||
|
function verificationPhone(countryCode,phoneNumber) { |
||||
|
switch (countryCode) { |
||||
|
case '+86': |
||||
|
return verificationChina(phoneNumber); |
||||
|
case '+1': |
||||
|
return verificationAmerica(phoneNumber); |
||||
|
case '+65': |
||||
|
return verificationSingapore(phoneNumber); |
||||
|
case '+60': |
||||
|
return verificationMalaysia(phoneNumber); |
||||
|
case '+66': |
||||
|
return verificationThailand(phoneNumber); |
||||
|
case '+852': |
||||
|
return verificationHongKong(phoneNumber); |
||||
|
case '+84': |
||||
|
return verificationVietnam(phoneNumber); |
||||
|
default: |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function verificationChina(phoneNumber){ |
||||
|
const phoneRegex = /^1[3-9]\d{9}$/; |
||||
|
return phoneRegex.test(phoneNumber); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function verificationAmerica(phoneNumber){ |
||||
|
const phoneRegex = /^[2-9]\d{2}[- ]?\d{4}$/; |
||||
|
return phoneRegex.test(phoneNumber); |
||||
|
} |
||||
|
function verificationSingapore(phoneNumber){ |
||||
|
const phoneRegex = /^[89]\d{7}$/; |
||||
|
return phoneRegex.test(phoneNumber); |
||||
|
} |
||||
|
function verificationMalaysia(phoneNumber){ |
||||
|
const phoneRegex = /^01\d{8}$/; |
||||
|
return phoneRegex.test(phoneNumber); |
||||
|
} |
||||
|
|
||||
|
function verificationHongKong(phoneNumber){ |
||||
|
const phoneRegex = /^0[896]\d{8}$/; |
||||
|
return phoneRegex.test(phoneNumber); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function verificationThailand(phoneNumber){ |
||||
|
const phoneRegex = /^[5-9]\d{7}$/; |
||||
|
return phoneRegex.test(phoneNumber); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
function verificationVietnam(phoneNumber){ |
||||
|
const phoneRegex = /^(0)?[3-9]\d{8}$/; |
||||
|
return phoneRegex.test(phoneNumber); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
function verificationEmail(email) { |
||||
|
const emailRegex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/; |
||||
|
return emailRegex.test(email); |
||||
|
} |
||||
|
|
||||
|
export {verificationPhone,verificationEmail} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
隐私政策 |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
|
||||
|
</style> |
||||
@ -0,0 +1,976 @@ |
|||||
|
<template> |
||||
|
<view class="login-registration-container"> |
||||
|
<!-- 自定义导航栏 --> |
||||
|
<view |
||||
|
class="custom-navbar" |
||||
|
:style="{ paddingTop: safeAreaInsets?.top + 'px' }" |
||||
|
> |
||||
|
<view class="nav-left"> |
||||
|
<image |
||||
|
class="icons" |
||||
|
@click="goToBack" |
||||
|
src="../../../static/icons/back.png" |
||||
|
alt="返回首页" |
||||
|
/> |
||||
|
</view> |
||||
|
<view class="nav-right"> |
||||
|
<image |
||||
|
class="icons" |
||||
|
src="../../../static/icons/Headset.png" |
||||
|
alt="联系客服" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- Logo --> |
||||
|
<!-- <image class="logo" src="/static/logo.png" mode="aspectFit"></image> --> |
||||
|
|
||||
|
<!-- 欢迎语 --> |
||||
|
<text class="welcome-text">找回密码</text> |
||||
|
|
||||
|
<!-- 邮箱/手机号切换 --> |
||||
|
<view v-if="!isRecovering" class="switch-container"> |
||||
|
<text |
||||
|
class="switch-item" |
||||
|
:class="{ active: switchType === 'Email' }" |
||||
|
@click="switchEmail" |
||||
|
>邮箱</text |
||||
|
> |
||||
|
<text |
||||
|
class="switch-item" |
||||
|
:class="{ active: switchType === 'Phone' }" |
||||
|
@click="switchPhone" |
||||
|
>手机号</text |
||||
|
> |
||||
|
</view> |
||||
|
<view v-else class="switch-container-occupy"> </view> |
||||
|
<!-- 输入框 --> |
||||
|
<view v-if="isRecovering" class="input-container"> |
||||
|
<view > |
||||
|
<!-- 修改邮箱输入框容器,将图标包含在内 --> |
||||
|
<view class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Unlock.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
class="input-field" |
||||
|
|
||||
|
:type="newPasswordLookFirst ? 'text' : 'password'" |
||||
|
placeholder="输入新密码" |
||||
|
v-model="newPasswordFirst" |
||||
|
/> |
||||
|
<image |
||||
|
class="input-icon-eye" |
||||
|
@click="newPasswordLookFirst = !newPasswordLookFirst" |
||||
|
:src=" |
||||
|
!newPasswordLookFirst |
||||
|
? '../../../static/icons/unlook.png' |
||||
|
: '../../../static/icons/look.png' |
||||
|
" |
||||
|
alt="" |
||||
|
/> |
||||
|
</view> |
||||
|
<view class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Unlock.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
|
||||
|
class="input-field" |
||||
|
:type="newPasswordLookSecond ? 'text' : 'password'" |
||||
|
placeholder="再次确认" |
||||
|
v-model="newPasswordSecond" |
||||
|
/> |
||||
|
<image |
||||
|
class="input-icon-eye" |
||||
|
@click="newPasswordLookSecond = !newPasswordLookSecond" |
||||
|
:src=" |
||||
|
!newPasswordLookSecond |
||||
|
? '../../../static/icons/unlook.png' |
||||
|
: '../../../static/icons/look.png' |
||||
|
" |
||||
|
alt="" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view v-else class="input-container"> |
||||
|
<view v-if="switchType === 'Email'"> |
||||
|
<!-- 修改邮箱输入框容器,将图标包含在内 --> |
||||
|
<view class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Mail.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
class="input-field" |
||||
|
type="text" |
||||
|
placeholder="请输入邮箱" |
||||
|
v-model="email" |
||||
|
/> |
||||
|
<view> |
||||
|
<button |
||||
|
class="send-code-btn-email" |
||||
|
:disabled="isCodeBtnDisabled" |
||||
|
:class="{ 'send-code-btn-disabled': isCodeBtnDisabled }" |
||||
|
@click="sendCode" |
||||
|
> |
||||
|
<text |
||||
|
class="send-code-text" |
||||
|
:class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }" |
||||
|
>{{ codeBtnText }}</text |
||||
|
> |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Text-recognition.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
class="input-field" |
||||
|
type="text" |
||||
|
placeholder="请输入验证码" |
||||
|
v-model="verifyCode" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view v-if="switchType === 'Phone'" class="phone-input-container"> |
||||
|
<view class="country-code-selector" @click="showCountryPicker"> |
||||
|
<image |
||||
|
class="country-flag-img" |
||||
|
src="../../../static/icons/Iphone.png" |
||||
|
mode="aspectFit" |
||||
|
></image> |
||||
|
<text class="country-code">{{ selectedCountry.code }}</text> |
||||
|
<!-- <text class="arrow-down">▼</text> --> |
||||
|
</view> |
||||
|
<input |
||||
|
class="input-field phone-input" |
||||
|
type="number" |
||||
|
placeholder="输入手机号" |
||||
|
v-model="phone" |
||||
|
@input="onPhoneInput" |
||||
|
/> |
||||
|
<view> |
||||
|
<button |
||||
|
class="send-code-btn" |
||||
|
:disabled="isCodeBtnDisabled" |
||||
|
:class="{ 'send-code-btn-disabled': isCodeBtnDisabled }" |
||||
|
@click="sendCode" |
||||
|
> |
||||
|
<text |
||||
|
class="send-code-text" |
||||
|
:class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }" |
||||
|
>{{ codeBtnText }}</text |
||||
|
> |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view v-if="switchType === 'Phone'" class="input-with-icon"> |
||||
|
<image |
||||
|
class="input-icon" |
||||
|
src="../../../static/icons/Text-recognition.png" |
||||
|
alt="" |
||||
|
/> |
||||
|
<input |
||||
|
class="input-field" |
||||
|
type="text" |
||||
|
placeholder="请输入验证码" |
||||
|
v-model="verifyCode" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 用户协议 --> |
||||
|
<view @click="changeCheckbox" class="agreement-container-one"> |
||||
|
<text |
||||
|
class="agreement-text-one" |
||||
|
:style="!isRecovering ? 'visibility: hidden' : 'visibility: visible'" |
||||
|
> |
||||
|
密码最少8位数 |
||||
|
</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 注册按钮 --> |
||||
|
<button class="register-btn" @click="register"> |
||||
|
{{ isRecovering ? "确认" : "下一步" }} |
||||
|
</button> |
||||
|
|
||||
|
<!-- 或者 --> |
||||
|
<text class="or-text-one" @click="goToRegistration" |
||||
|
>如果您还没有账号,点击注册 |
||||
|
<image class="to-icon" src="../../../static/icons/To.png"></image> |
||||
|
</text> |
||||
|
|
||||
|
<!-- 或者 --> |
||||
|
<text class="or-text" @click="goToLogin">已有账号?登录 </text> |
||||
|
|
||||
|
<!-- 同意弹窗 --> |
||||
|
<uniPopup ref="agreementPopup" type="dialog"> |
||||
|
<view class="popup-content"> |
||||
|
<text class="popup-title">同意并继续</text> |
||||
|
<text class="popup-message">请阅读并同意服务协议和隐私权限</text> |
||||
|
<button class="agree-button" @click="handleAgree"> |
||||
|
<text class="agree-text">同意</text> |
||||
|
</button> |
||||
|
</view> |
||||
|
</uniPopup> |
||||
|
<footerBar class="static-footer" :type="type"></footerBar> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref } from "vue"; |
||||
|
// 导入完整的国家列表 |
||||
|
import countryList from "../login/list"; |
||||
|
import footerBar from "../../../components/footerBar-cn.vue"; |
||||
|
import uniPopup from "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue"; |
||||
|
import { verificationPhone, verificationEmail } from "../login/verification"; |
||||
|
|
||||
|
const type = ref("member"); |
||||
|
const email = ref(""); |
||||
|
const password = ref(""); |
||||
|
const newPasswordFirst = ref(""); |
||||
|
const newPasswordSecond = ref(""); |
||||
|
const phone = ref(""); |
||||
|
const country = ref("+86"); |
||||
|
const agreed = ref(false); |
||||
|
const switchType = ref("Phone"); // 默认是邮箱注册 |
||||
|
const { safeAreaInsets } = uni.getSystemInfoSync(); |
||||
|
const codeBtnText = ref("获取验证码"); |
||||
|
const isCodeBtnDisabled = ref(false); // 添加验证码按钮禁用状态 |
||||
|
const checkboxUrl = ref("../../../static/icons/Check-one-false.png"); |
||||
|
const verifyCode = ref(""); |
||||
|
const isRecovering = ref(false); |
||||
|
const newPasswordLookFirst = ref(false); |
||||
|
const newPasswordLookSecond = ref(false); |
||||
|
|
||||
|
// 使用从list.js导入的完整国家列表数据 |
||||
|
const countries = ref( |
||||
|
countryList.list.map((item) => ({ |
||||
|
name: item.name, |
||||
|
code: `+${item.tel}`, |
||||
|
flag: item.flag, |
||||
|
short: item.short, |
||||
|
en: item.en, |
||||
|
})) |
||||
|
); |
||||
|
|
||||
|
// 默认选中的国家(中国) |
||||
|
const selectedCountry = ref( |
||||
|
countries.value.find((country) => country.short === "CN") || |
||||
|
countries.value[0] |
||||
|
); |
||||
|
|
||||
|
// 显示国家选择器 |
||||
|
function showCountryPicker() { |
||||
|
uni.showActionSheet({ |
||||
|
itemList: countries.value.map( |
||||
|
(country) => `${country.name} ${country.code}` |
||||
|
), |
||||
|
success: function (res) { |
||||
|
selectedCountry.value = countries.value[res.tapIndex]; |
||||
|
}, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function goToBack() { |
||||
|
// 返回上一页 |
||||
|
uni.navigateBack(-1); |
||||
|
} |
||||
|
|
||||
|
function switchEmail() { |
||||
|
// 切换到邮箱注册 |
||||
|
switchType.value = "Email"; |
||||
|
verifyCode.value = ""; |
||||
|
} |
||||
|
|
||||
|
function switchPhone() { |
||||
|
// 切换到手机注册 |
||||
|
switchType.value = "Phone"; |
||||
|
verifyCode.value = ""; |
||||
|
} |
||||
|
|
||||
|
function register() { |
||||
|
if (isRecovering.value) { |
||||
|
if (!newPasswordFirst.value || !newPasswordSecond.value) { |
||||
|
uni.showToast({ |
||||
|
title: "密码不能为空", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (newPasswordFirst.value !== newPasswordSecond.value) { |
||||
|
uni.showToast({ |
||||
|
title: "前后密码不一致", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// 密码逻辑 |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (switchType.value === "Phone") { |
||||
|
// 登录逻辑 |
||||
|
if (!phone.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入手机号码", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
console.log("123"); |
||||
|
|
||||
|
|
||||
|
const phoneAll = `${country.value}${phone.value}`; |
||||
|
console.log("完整手机号" + phoneAll); |
||||
|
if (!validatePhoneNumber(country.value, phone.value)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!verifyCode.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入验证码", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (switchType.value === "Email") { |
||||
|
// 登录逻辑 |
||||
|
if (!email.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入邮箱地址", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
const bool = verificationEmail(email.value); |
||||
|
console.log("验证是否成功", bool); |
||||
|
|
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "邮箱格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!verifyCode.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入验证码", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// 发送登录请求 |
||||
|
console.log("登录:", email.value); |
||||
|
} |
||||
|
|
||||
|
isRecovering.value = !isRecovering.value; |
||||
|
|
||||
|
// 如果已经同意,则继续登录流程 |
||||
|
// uni.showToast({ |
||||
|
// title: "登录成功", |
||||
|
// icon: "success", |
||||
|
// }); |
||||
|
} |
||||
|
|
||||
|
function goToLogin() { |
||||
|
// 跳转到登录页 |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/login/login", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function onPhoneInput(e) { |
||||
|
// 确保只允许输入数字 |
||||
|
const value = e.detail.value; |
||||
|
// 使用 isNaN 检查是否为有效数字 |
||||
|
if (isNaN(value)) { |
||||
|
phone.value = ""; |
||||
|
} else { |
||||
|
phone.value = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 注册码码验证 |
||||
|
function VerCodeVerfifcation() { |
||||
|
if (switchType.value === "Phone") { |
||||
|
if (!phone.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入手机号", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
const bool = verificationPhone(country.value, phone.value); |
||||
|
console.log("验证是否成功", bool); |
||||
|
|
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "手机号格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (switchType.value === "Email") { |
||||
|
if (!email.value) { |
||||
|
uni.showToast({ |
||||
|
title: "请输入邮箱地址", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
const bool = verificationEmail(email.value); |
||||
|
console.log("验证是否成功", bool); |
||||
|
|
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "邮箱格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// 发送验证码 |
||||
|
function sendCode() { |
||||
|
if (!VerCodeVerfifcation()) { |
||||
|
return; |
||||
|
} |
||||
|
// 如果按钮已禁用,则不执行后续逻辑 |
||||
|
if (isCodeBtnDisabled.value) return; |
||||
|
|
||||
|
// 设置按钮为禁用状态 |
||||
|
isCodeBtnDisabled.value = true; |
||||
|
codeBtnText.value = "重新发送"; |
||||
|
let time = 6; |
||||
|
const timer = setInterval(() => { |
||||
|
time--; |
||||
|
codeBtnText.value = "重新发送 " + time + "s"; |
||||
|
if (time <= 0) { |
||||
|
clearInterval(timer); |
||||
|
codeBtnText.value = "重新发送"; |
||||
|
// 倒计时结束后启用按钮 |
||||
|
isCodeBtnDisabled.value = false; |
||||
|
} |
||||
|
}, 1000); |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
function openAgreement() { |
||||
|
// 打开用户协议 |
||||
|
console.log("打开用户协议"); |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/agreement/agreement", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function openPrivacy() { |
||||
|
// 打开隐私政策 |
||||
|
console.log("打开隐私政策"); |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/privacy/privacy", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function changeCheckbox() { |
||||
|
agreed.value = !agreed.value; |
||||
|
checkboxUrl.value = agreed.value |
||||
|
? "../../../static/icons/Check-one-true.png" |
||||
|
: "../../../static/icons/Check-one-false.png"; |
||||
|
} |
||||
|
|
||||
|
// 验证手机号是否正确 |
||||
|
function validatePhoneNumber(countryCode, phoneNumber) { |
||||
|
// 检查是否为空 |
||||
|
if (!phoneNumber || phoneNumber.trim() === "") { |
||||
|
uni.showToast({ |
||||
|
title: "手机号不能为空", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
const bool = verificationPhone(countryCode, phoneNumber); |
||||
|
console.log("验证是否成功", bool); |
||||
|
|
||||
|
// 检查格式是否正确 |
||||
|
if (!bool) { |
||||
|
uni.showToast({ |
||||
|
title: "手机号格式不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// 去掉+号后检查长度(手机号通常在7到15位之间) |
||||
|
const cleanNumber = phoneNumber.replace(/^\+/, ""); |
||||
|
if (cleanNumber.length < 7 || cleanNumber.length > 15) { |
||||
|
uni.showToast({ |
||||
|
title: "手机号长度不正确", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// 添加弹窗引用 |
||||
|
const agreementPopup = ref(null); |
||||
|
|
||||
|
// 处理同意按钮点击 |
||||
|
function handleAgree() { |
||||
|
// 关闭弹窗 |
||||
|
agreementPopup.value.close(); |
||||
|
// 设置为已同意 |
||||
|
agreed.value = true; |
||||
|
checkboxUrl.value = "../../../static/icons/Check-one-true.png"; |
||||
|
// 继续登录流程 |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.login-registration-container { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 0 70rpx; |
||||
|
height: 100vh; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
/* 自定义导航栏样式 */ |
||||
|
.custom-navbar { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
/* z-index: 999; */ |
||||
|
width: 90%; |
||||
|
height: 80rpx; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 10rpx 40rpx; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.nav-left, |
||||
|
.nav-right { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.nav-right { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
.nav-left { |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
|
||||
|
.icons { |
||||
|
margin: 20rpx; |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
/* margin-right: 10rpx; */ |
||||
|
} |
||||
|
|
||||
|
.back-btn, |
||||
|
.headphone-btn { |
||||
|
font-size: 36rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333333; |
||||
|
padding: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
width: 120rpx; |
||||
|
height: 120rpx; |
||||
|
margin-bottom: 60rpx; |
||||
|
border-radius: 20%; |
||||
|
} |
||||
|
|
||||
|
.welcome-text { |
||||
|
font-size: 48rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333333; |
||||
|
margin-bottom: 60rpx; |
||||
|
/* text-align: left; */ |
||||
|
/* align-self: flex-start; */ |
||||
|
} |
||||
|
|
||||
|
.switch-container { |
||||
|
display: flex; |
||||
|
margin-bottom: 40rpx; |
||||
|
align-self: flex-start; |
||||
|
} |
||||
|
|
||||
|
.switch-item { |
||||
|
font-size: 28rpx; |
||||
|
color: #999999; |
||||
|
padding: 10rpx 20rpx; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.switch-item::after { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
width: 60%; |
||||
|
/* 控制边框宽度 */ |
||||
|
height: 2rpx; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
|
||||
|
.switch-item.active { |
||||
|
color: #333333; |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
|
||||
|
.switch-item.active::after { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
top: 60rpx; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
width: 30%; |
||||
|
/* 控制边框宽度 */ |
||||
|
height: 7rpx; |
||||
|
background-color: #333333; |
||||
|
} |
||||
|
|
||||
|
.input-container { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
/* 添加图标输入框样式 */ |
||||
|
.input-with-icon { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
border-bottom: 2rpx solid #e5e5e5; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.input-icon { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
margin: 0 20rpx; |
||||
|
} |
||||
|
.input-icon-eye { |
||||
|
width: 40rpx; |
||||
|
height: 20rpx; |
||||
|
margin: 0 20rpx; |
||||
|
} |
||||
|
|
||||
|
.input-field { |
||||
|
flex: 1; |
||||
|
height: 80rpx; |
||||
|
padding: 15rpx 0; |
||||
|
font-size: 28rpx; |
||||
|
color: #333333; |
||||
|
border: none; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
|
||||
|
.phone-input-container { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 95.8%; |
||||
|
height: 80rpx; |
||||
|
/* border-radius: 20rpx; */ |
||||
|
/* border: 2rpx solid #e5e5e5; */ |
||||
|
/* background-color: #f5f5f5; */ |
||||
|
padding: 0 10rpx; |
||||
|
border-bottom: 2rpx solid #e5e5e5; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.country-code-selector { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 0 10rpx; |
||||
|
padding-bottom: 1rpx; |
||||
|
height: 100%; |
||||
|
/* border-right: 2rpx solid #e5e5e5; */ |
||||
|
/* background-color: #f5f5f5; */ |
||||
|
border-radius: 20rpx 0 0 20rpx; |
||||
|
} |
||||
|
|
||||
|
.country-code { |
||||
|
font-size: 28rpx; |
||||
|
color: #333333; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.country-flag-img { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.arrow-down { |
||||
|
font-size: 20rpx; |
||||
|
color: #999999; |
||||
|
} |
||||
|
|
||||
|
.phone-input { |
||||
|
flex: 1; |
||||
|
width: auto; |
||||
|
height: 100%; |
||||
|
border: none; |
||||
|
background-color: transparent; |
||||
|
padding: 0 0rpx; |
||||
|
} |
||||
|
|
||||
|
.send-code-btn { |
||||
|
width: 200rpx; |
||||
|
height: 60rpx; |
||||
|
display: inline-flex; |
||||
|
padding: 0rpx 10rpx; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
gap: 10px; |
||||
|
border-radius: 4px; |
||||
|
background: #000; |
||||
|
} |
||||
|
.send-code-btn-email { |
||||
|
width: 200rpx; |
||||
|
height: 60rpx; |
||||
|
display: inline-flex; |
||||
|
padding: 0rpx 10rpx; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
gap: 10px; |
||||
|
border-radius: 4px; |
||||
|
background: #000; |
||||
|
margin-right: 15rpx; |
||||
|
} |
||||
|
|
||||
|
.send-code-btn-disabled { |
||||
|
background: #e6e6e6; |
||||
|
/* 禁用状态下的灰色背景 */ |
||||
|
} |
||||
|
|
||||
|
.send-code-btn-disabled-text { |
||||
|
color: #999999 !important; |
||||
|
} |
||||
|
|
||||
|
.send-code-text { |
||||
|
color: #fff; |
||||
|
font-size: 28rpx; |
||||
|
} |
||||
|
|
||||
|
.agreement-container-one { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
align-self: flex-start; |
||||
|
margin-bottom: 80rpx; |
||||
|
} |
||||
|
|
||||
|
.agreement-container { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 40rpx; |
||||
|
margin-top: -75.5rpx; |
||||
|
align-self: flex-start; |
||||
|
} |
||||
|
|
||||
|
.checkbox { |
||||
|
width: 30rpx; |
||||
|
height: 30rpx; |
||||
|
margin-left: 20rpx; |
||||
|
/* flex: content; */ |
||||
|
} |
||||
|
|
||||
|
.agreement-text-one { |
||||
|
font-size: 22rpx; |
||||
|
color: #666666; |
||||
|
text-align: center; |
||||
|
margin-left: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.agreement-text { |
||||
|
margin-left: 20rpx; |
||||
|
font-size: 24rpx; |
||||
|
color: #666666; |
||||
|
} |
||||
|
|
||||
|
.link { |
||||
|
color: #333333; |
||||
|
font-weight: bold; |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
|
||||
|
.register-btn { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
background-color: #000000; |
||||
|
color: white; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: bold; |
||||
|
border-radius: 40rpx; |
||||
|
margin-bottom: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.or-text { |
||||
|
flex-direction: column; |
||||
|
font-size: 24rpx; |
||||
|
color: #999999; |
||||
|
margin-top: 294rpx; |
||||
|
margin-bottom: -22rpx; |
||||
|
} |
||||
|
|
||||
|
.to-icon { |
||||
|
width: 10rpx; |
||||
|
height: 16rpx; |
||||
|
} |
||||
|
|
||||
|
.or-text-one { |
||||
|
flex-direction: column; |
||||
|
font-size: 24rpx; |
||||
|
color: #999999; |
||||
|
} |
||||
|
|
||||
|
.third-party-login { |
||||
|
width: 100%; |
||||
|
margin-bottom: 60rpx; |
||||
|
} |
||||
|
|
||||
|
.third-party-text { |
||||
|
color: #ffffff; |
||||
|
font-weight: bold; |
||||
|
white-space: pre; |
||||
|
} |
||||
|
|
||||
|
.third-party-btn { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
background-color: rgb(0, 0, 0); |
||||
|
border: 2rpx solid #e5e5e5; |
||||
|
border-radius: 40rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
margin-bottom: 20rpx; |
||||
|
font-size: 28rpx; |
||||
|
color: #333333; |
||||
|
} |
||||
|
|
||||
|
.google-icon, |
||||
|
.apple-icon { |
||||
|
width: 60rpx; |
||||
|
height: 60rpx; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.existing-account { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.account-text { |
||||
|
font-size: 24rpx; |
||||
|
color: #666666; |
||||
|
} |
||||
|
|
||||
|
.login-link { |
||||
|
font-size: 24rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333333; |
||||
|
margin-left: 10rpx; |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
|
||||
|
.static-footer { |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
} |
||||
|
|
||||
|
/* 弹窗样式 */ |
||||
|
.popup-content { |
||||
|
background-color: #ffffff; |
||||
|
padding: 40rpx; |
||||
|
text-align: center; |
||||
|
border-radius: 10rpx; |
||||
|
width: 550rpx; |
||||
|
} |
||||
|
|
||||
|
.popup-title { |
||||
|
font-size: 36rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
margin-bottom: 80rpx; |
||||
|
text-align: center; /* 水平居中 */ |
||||
|
display: flex; /* 使用flex布局 */ |
||||
|
justify-content: center; /* 水平居中 */ |
||||
|
align-items: center; /* 垂直居中 */ |
||||
|
} |
||||
|
|
||||
|
.popup-message { |
||||
|
font-size: 28rpx; |
||||
|
color: #000000; |
||||
|
margin-bottom: 80rpx; |
||||
|
text-align: center; /* 水平居中 */ |
||||
|
display: flex; /* 使用flex布局 */ |
||||
|
justify-content: center; /* 水平居中 */ |
||||
|
align-items: center; /* 垂直居中 */ |
||||
|
} |
||||
|
|
||||
|
.agree-button { |
||||
|
width: 300rpx; |
||||
|
height: 80rpx; |
||||
|
background-color: #000000; |
||||
|
border-radius: 40rpx; |
||||
|
display: flex; /* 添加flex布局 */ |
||||
|
align-items: center; /* 垂直居中 */ |
||||
|
justify-content: center; /* 水平居中 */ |
||||
|
} |
||||
|
.agree-text { |
||||
|
color: #ffffff; |
||||
|
font-size: 34rpx; |
||||
|
/* 添加垂直居中相关样式 */ |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
line-height: 1; /* 确保文字垂直居中 */ |
||||
|
} |
||||
|
|
||||
|
.switch-container-occupy { |
||||
|
margin-top: 100rpx; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,175 @@ |
|||||
|
<template> |
||||
|
<view class="login-container"> |
||||
|
<!-- 顶部标题 --> |
||||
|
<view class="title-section"> |
||||
|
<text class="main-title">DeepChart</text> |
||||
|
</view> |
||||
|
<view class="subtitle-section"> |
||||
|
<text class="subtitle">您的股市随身顾问</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 手机卡片样式 --> |
||||
|
<view class="phone-card"> </view> |
||||
|
|
||||
|
<!-- 登录注册按钮 --> |
||||
|
<view class="button-group"> |
||||
|
<button class="login-button" @click="toLogin">登录</button> |
||||
|
<button class="register-button" @click="toRegistration">注册</button> |
||||
|
</view> |
||||
|
|
||||
|
<footerBar class="static-footer" :type="type"></footerBar> |
||||
|
|
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
|
||||
|
|
||||
|
import footerBar from '../../../components/footerBar-cn' |
||||
|
import { ref, reactive, toRefs, watch } from 'vue' |
||||
|
|
||||
|
const type = ref('member') |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
function toRegistration() { |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/Registration/Registration", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function toLogin() { |
||||
|
uni.navigateTo({ |
||||
|
url: "/pages/start/login/login", |
||||
|
}); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.login-container { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
/* justify-content: space-between; */ |
||||
|
padding: 40rpx; |
||||
|
height: 90vh; |
||||
|
background-color: #ffffff; |
||||
|
overflow: hidden; |
||||
|
max-height: 100vh; |
||||
|
-webkit-overflow-scrolling: none; |
||||
|
} |
||||
|
|
||||
|
.title-section { |
||||
|
text-align: center; |
||||
|
margin-top: 120rpx; |
||||
|
|
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.main-title { |
||||
|
text-align: center; |
||||
|
font-size: 64rpx; |
||||
|
font-weight: 300; |
||||
|
color: #000000; |
||||
|
margin-bottom: 10rpx; |
||||
|
} |
||||
|
.subtitle-section { |
||||
|
margin-bottom: 80rpx; |
||||
|
} |
||||
|
.subtitle { |
||||
|
/* font-weight: bold; */ |
||||
|
font-size: 32rpx; |
||||
|
color: #333333; |
||||
|
} |
||||
|
|
||||
|
.phone-card { |
||||
|
background-image: url("/static/select.png"); |
||||
|
background-repeat: no-repeat; |
||||
|
background-size: contain; |
||||
|
background-position: center; |
||||
|
/* background-position: center; */ |
||||
|
/* min-width: 300rpx; */ |
||||
|
|
||||
|
width: 420rpx; |
||||
|
height: 786rpx; |
||||
|
border-radius: 50rpx; |
||||
|
padding: 40rpx; |
||||
|
/* box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.3); */ |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.button-group { |
||||
|
display: flex; |
||||
|
gap: 40rpx; |
||||
|
margin: 80rpx 0; |
||||
|
width: 100%; |
||||
|
max-width: 600rpx; |
||||
|
} |
||||
|
|
||||
|
.login-button { |
||||
|
flex: 1; |
||||
|
background-color: #f5f5f5; |
||||
|
color: #000000; |
||||
|
border-radius: 60rpx; |
||||
|
font-size: 32rpx; |
||||
|
padding: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.register-button { |
||||
|
flex: 1; |
||||
|
background-color: #000000; |
||||
|
color: #ffffff; |
||||
|
border-radius: 60rpx; |
||||
|
font-size: 32rpx; |
||||
|
padding: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.bottom-nav { |
||||
|
display: flex; |
||||
|
justify-content: space-around; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
height: 100rpx; |
||||
|
background-color: #ffffff; |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
border-top: 1rpx solid #e5e5e5; |
||||
|
} |
||||
|
|
||||
|
.nav-item { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.nav-item.active .nav-icon { |
||||
|
transform: scale(1.2); |
||||
|
} |
||||
|
|
||||
|
.nav-icon { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
margin-bottom: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.nav-text { |
||||
|
font-size: 24rpx; |
||||
|
color: #666666; |
||||
|
} |
||||
|
|
||||
|
.nav-item.active .nav-text { |
||||
|
color: #000000; |
||||
|
} |
||||
|
|
||||
|
.static-footer { |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,56 @@ |
|||||
|
<template> |
||||
|
<view class="background"> |
||||
|
<image |
||||
|
class="logo" |
||||
|
src="../../../static/icons/start-logo.png" |
||||
|
mode="scaleToFill" |
||||
|
/> |
||||
|
<view class="logo-text"> DeepChart </view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { onShow } from "@dcloudio/uni-app"; |
||||
|
|
||||
|
onShow(() => { |
||||
|
setTimeout(() => { |
||||
|
uni.redirectTo({ |
||||
|
url: "/pages/start/select/select", |
||||
|
animationType: "slide-in-right", |
||||
|
animationDuration: 1000, |
||||
|
}); |
||||
|
}, 1500); |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.background { |
||||
|
background: linear-gradient(180deg, #FB6967, #FB6967); |
||||
|
width: 100vw; |
||||
|
height: 100vh; |
||||
|
} |
||||
|
|
||||
|
.logo-text { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
color: white; |
||||
|
font-weight: bold; |
||||
|
font-size: 24px; |
||||
|
position: absolute; |
||||
|
bottom: 5%; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
} |
||||
|
|
||||
|
.logo{ |
||||
|
width: 320rpx; |
||||
|
height: 200rpx; |
||||
|
position: absolute; |
||||
|
top: 30%; |
||||
|
left: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,23 @@ |
|||||
|
|
||||
|
|
||||
|
{ |
||||
|
"intent":{ |
||||
|
"code": 200, |
||||
|
"message": "操作成功", |
||||
|
"data": { |
||||
|
"code": "1A0001", |
||||
|
"market": "cn", |
||||
|
"name": "上证指数", |
||||
|
"refuse": "", |
||||
|
"recordId": 15, |
||||
|
"parentId": 14, |
||||
|
"stockId": 25, |
||||
|
"language": "cn", |
||||
|
"debug_url": "https://www.coze.cn/work_flow?execute_id=7564771475955515444&space_id=7564250621483040822&workflow_id=7564368306322292788&execute_mode=2" |
||||
|
} |
||||
|
}, |
||||
|
"stocks":{"code":"200","cftl":"当前股票处于安全区,牵牛绳为红色,出现蓝色推进K线","date":"更新时间: 24/10/2025","debug_url":"https://www.coze.cn/work_flow?execute_id=7565080703726846004&space_id=7564250621483040822&workflow_id=7564596757864071195&execute_mode=2","gfzl":"该股整体趋势相对较强,个股正处于推进上涨的关键阶段。若当前持有该股票,建议继续持有,进行持续跟踪。若当前无该股票,建议持续跟踪,等待适当时机再进行介入。","hxjzpg":"(1)牛股评级:★★☆☆☆\n(2)暴涨概率:40%\n(3)风险评估:非常安全\n(4)黄金价域:258.984~266.753\n(5)核心证据链\n 资金共识:当日多方资金流入\n 趋势动能:该股中长期处于上升趋势,短期处于强势状态。","kongjian":"预测低一值255.468,预测高一值257.692,预测低二值255.156,预测高二值255.807", |
||||
|
"markdown":" \n# <font style=\" line-height: 1.5 \" color=\"#1890ff\">Alphabet Inc.全景作战报告</font>\n## 📊 股票分析报告\n### 📈 股票基本信息\n- **股票名称**: <font color=\"#52c41a\">Alphabet Inc.</font>\n- **股票代码**: <font color=\"#1890ff\">GOOGL</font>\n- **当前价格**: <font color=\"#ff4d4f\">259.920</font>\n- **更新时间**: 2025年10月24日\n- **时间节点**: 今日无变盘点\n\n### 🎯 核心价值评估\n- **安全边际**: <font color=\"#13c2c2\">164.424 ~ </font>\n- **黄金价域**: <font color=\"#faad14\">258.984 ~ 266.753</font>\n- **核心证据链**:\n - 🟢 **资金共识**: 当日多方资金<font color=\"#52c41a\">流入</font>\n - 🔥 **趋势动能**: 该股中长期处于<b><font color='#FF0000'>上升趋势</font></b>,短期处于<b><font color='#FF0000'>强势状态</font></b>。\n\n### 🕵️ 主力作战分析\n- **主力行为**:\n 1. 📊 该股庄家中长期筹码成本价格为 207.497,短期资金成本价格为 239.503。该股筹码分散,当日筹码成本价格为 254.335。\n 2. 🔍 近日没有出现主力集中吸筹。\n 3. 📈 近期主力持仓比例大于散户持仓比例。 当日主力持仓增加。 当日散户持仓减少。\n\n### 📊 技术分析\n- **空间维度**:\n - 📉 预测低一值: <font color=\"#13c2c2\">255.468</font>\n - 📈 预测高一值: <font color=\"#ff4d4f\">257.692</font>\n - 📉 预测低二值: <font color=\"#13c2c2\">255.156</font>\n - 📈 预测高二值: <font color=\"#ff4d4f\">255.807</font>\n- **能量分析**: <font color=\"#722ed1\">AI智能均线多头排列,当前卖盘小于买盘</font>\n\n### ⚡ 综合作战分析\n- **触发条件**: <font color=\"#fa8c16\">当前股票处于安全区,牵牛绳为红色,出现蓝色推进K线</font>\n- **攻防指令**: <font color=\"#eb2f96\">该股整体趋势相对较强,个股正处于推进上涨的关键阶段。若当前持有该股票,建议继续持有,进行持续跟踪。若当前无该股票,建议持续跟踪,等待适当时机再进行介入。</font>\n\n---\n<font color=\"#8c8c8c\">*该内容由AI生成,仅供参考,投资有风险,请注意甄别。*</font>\n ","message":"","name":"股票名称: Alphabet Inc.(GOOGL)","nengliang":"AI智能均线多头排列,当前卖盘小于买盘","price":"当前价格: 259.920","shijian":"今日无变盘点","zhuli1":"(1)该股庄家中长期筹码成本价格为 207.497,短期资金成本价格为 239.503。该股筹码分散,当日筹码成本价格为 254.335。","zhuli2":"(2)近日没有出现主力集中吸筹。","zhuli3":"(3)近期主力持仓比例大于散户持仓比例。 当日主力持仓增加。 当日散户持仓减少。"} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,131 @@ |
|||||
|
{ |
||||
|
"loginSuccessByEmail": { |
||||
|
"code": 200, |
||||
|
"message": "登录成功", |
||||
|
"interface": "login", |
||||
|
"data": { |
||||
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
||||
|
"userInfo": { |
||||
|
"id": "123456789", |
||||
|
"username": "q614588746", |
||||
|
"email": "q614588746@163.com" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"loginFailureEmailNotFound": { |
||||
|
"code": 404, |
||||
|
"message": "账号不存在", |
||||
|
"interface": "login" |
||||
|
}, |
||||
|
"loginFailureWrongCode": { |
||||
|
"code": 400, |
||||
|
"message": "验证码错误", |
||||
|
"interface": "login" |
||||
|
}, |
||||
|
"loginSuccessByPhone": { |
||||
|
"code": 200, |
||||
|
"message": "登录成功", |
||||
|
"interface": "login", |
||||
|
"data": { |
||||
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
||||
|
"userInfo": { |
||||
|
"id": "987654321", |
||||
|
"username": "13800138000", |
||||
|
"phone": "13800138000" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"loginSuccessByPassword": { |
||||
|
"code": 200, |
||||
|
"message": "登录成功", |
||||
|
"interface": "login", |
||||
|
"data": { |
||||
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
||||
|
"userInfo": { |
||||
|
"id": "556677889", |
||||
|
"username": "testuser" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"sendCodeSuccess": { |
||||
|
"code": 200, |
||||
|
"message": "验证码发送成功", |
||||
|
"interface": "sendCode", |
||||
|
"data": { |
||||
|
"expireTime": 180 |
||||
|
} |
||||
|
}, |
||||
|
"sendCodeFailureInvalidFormat": { |
||||
|
"code": 400, |
||||
|
"message": "手机号格式错误", |
||||
|
"interface": "sendCode" |
||||
|
}, |
||||
|
"sendCodeFailureTooFrequent": { |
||||
|
"code": 429, |
||||
|
"message": "发送频率过高,请稍后再试", |
||||
|
"interface": "sendCode" |
||||
|
}, |
||||
|
"registerSuccess": { |
||||
|
"code": 200, |
||||
|
"message": "注册成功", |
||||
|
"interface": "register", |
||||
|
"data": { |
||||
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
||||
|
"userInfo": { |
||||
|
"id": "112233445", |
||||
|
"username": "newuser", |
||||
|
"email": "newuser@example.com" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"registerFailureEmailExist": { |
||||
|
"code": 400, |
||||
|
"message": "邮箱已被注册", |
||||
|
"interface": "register" |
||||
|
}, |
||||
|
"registerFailurePhoneExist": { |
||||
|
"code": 400, |
||||
|
"message": "手机号已被注册", |
||||
|
"interface": "register" |
||||
|
}, |
||||
|
"registerFailureWrongCode": { |
||||
|
"code": 400, |
||||
|
"message": "验证码错误", |
||||
|
"interface": "register" |
||||
|
}, |
||||
|
"updatePasswordSuccess": { |
||||
|
"code": 200, |
||||
|
"message": "密码修改成功", |
||||
|
"interface": "updatePassword" |
||||
|
}, |
||||
|
"updatePasswordFailureWrongOldPassword": { |
||||
|
"code": 400, |
||||
|
"message": "旧密码错误", |
||||
|
"interface": "updatePassword" |
||||
|
}, |
||||
|
"updatePasswordFailureWrongCode": { |
||||
|
"code": 400, |
||||
|
"message": "验证码错误", |
||||
|
"interface": "updatePassword" |
||||
|
}, |
||||
|
"forgotPasswordSuccessByEmail": { |
||||
|
"code": 200, |
||||
|
"message": "密码重置成功,新密码已发送至邮箱", |
||||
|
"interface": "forgotPassword" |
||||
|
}, |
||||
|
"forgotPasswordSuccessByPhone": { |
||||
|
"code": 200, |
||||
|
"message": "密码重置成功,新密码已发送至手机", |
||||
|
"interface": "forgotPassword" |
||||
|
}, |
||||
|
"forgotPasswordFailureAccountNotFound": { |
||||
|
"code": 404, |
||||
|
"message": "账号不存在", |
||||
|
"interface": "forgotPassword" |
||||
|
}, |
||||
|
"forgotPasswordFailureWrongCode": { |
||||
|
"code": 400, |
||||
|
"message": "验证码错误", |
||||
|
"interface": "forgotPassword" |
||||
|
} |
||||
|
} |
||||
|
After Width: 100 | Height: 70 | Size: 2.1 KiB |
|
After Width: 100 | Height: 50 | Size: 170 B |
|
After Width: 100 | Height: 67 | Size: 2.6 KiB |
|
After Width: 100 | Height: 67 | Size: 2.0 KiB |
|
After Width: 100 | Height: 50 | Size: 1.3 KiB |
|
After Width: 100 | Height: 71 | Size: 1.7 KiB |
|
After Width: 100 | Height: 50 | Size: 122 B |
|
After Width: 100 | Height: 67 | Size: 610 B |
|
After Width: 100 | Height: 67 | Size: 1.4 KiB |
|
After Width: 100 | Height: 100 | Size: 6.0 KiB |
|
After Width: 100 | Height: 63 | Size: 991 B |
|
After Width: 100 | Height: 50 | Size: 2.0 KiB |
|
After Width: 100 | Height: 67 | Size: 133 B |
|
After Width: 100 | Height: 50 | Size: 1.1 KiB |
|
After Width: 100 | Height: 67 | Size: 658 B |
|
After Width: 100 | Height: 65 | Size: 279 B |
|
After Width: 100 | Height: 50 | Size: 451 B |
|
After Width: 100 | Height: 50 | Size: 741 B |
|
After Width: 100 | Height: 67 | Size: 791 B |
|
After Width: 100 | Height: 60 | Size: 367 B |
|
After Width: 100 | Height: 87 | Size: 168 B |
|
After Width: 100 | Height: 67 | Size: 560 B |
|
After Width: 100 | Height: 60 | Size: 106 B |
|
After Width: 100 | Height: 60 | Size: 303 B |
|
After Width: 100 | Height: 60 | Size: 1.3 KiB |
|
After Width: 100 | Height: 67 | Size: 169 B |
|
After Width: 100 | Height: 67 | Size: 6.2 KiB |
|
After Width: 100 | Height: 50 | Size: 2.0 KiB |
|
After Width: 100 | Height: 50 | Size: 2.3 KiB |
|
After Width: 100 | Height: 68 | Size: 1.4 KiB |
|
After Width: 100 | Height: 67 | Size: 159 B |
|
After Width: 100 | Height: 70 | Size: 2.0 KiB |
|
After Width: 100 | Height: 50 | Size: 553 B |
|
After Width: 100 | Height: 67 | Size: 4.0 KiB |
|
After Width: 100 | Height: 73 | Size: 260 B |
|
After Width: 100 | Height: 67 | Size: 172 B |
|
After Width: 100 | Height: 50 | Size: 1.4 KiB |
|
After Width: 100 | Height: 67 | Size: 5.6 KiB |
|
After Width: 100 | Height: 50 | Size: 765 B |
|
After Width: 100 | Height: 50 | Size: 1.3 KiB |
|
After Width: 100 | Height: 75 | Size: 796 B |
|
After Width: 100 | Height: 67 | Size: 554 B |
|
After Width: 100 | Height: 67 | Size: 354 B |
|
After Width: 100 | Height: 100 | Size: 172 B |
|
After Width: 100 | Height: 67 | Size: 165 B |
|
After Width: 100 | Height: 50 | Size: 1.9 KiB |
|
After Width: 100 | Height: 67 | Size: 517 B |
|
After Width: 100 | Height: 67 | Size: 482 B |
|
After Width: 100 | Height: 67 | Size: 763 B |
|
After Width: 100 | Height: 67 | Size: 158 B |
|
After Width: 100 | Height: 60 | Size: 109 B |
|
After Width: 100 | Height: 50 | Size: 793 B |
|
After Width: 100 | Height: 59 | Size: 1.0 KiB |
|
After Width: 100 | Height: 67 | Size: 633 B |
|
After Width: 100 | Height: 50 | Size: 1.5 KiB |
|
After Width: 100 | Height: 67 | Size: 1.6 KiB |
|
After Width: 100 | Height: 67 | Size: 394 B |
|
After Width: 100 | Height: 60 | Size: 106 B |
|
After Width: 100 | Height: 67 | Size: 1.1 KiB |
|
After Width: 100 | Height: 76 | Size: 200 B |
|
After Width: 100 | Height: 50 | Size: 1.2 KiB |
|
After Width: 100 | Height: 67 | Size: 700 B |
|
After Width: 100 | Height: 67 | Size: 891 B |
|
After Width: 100 | Height: 67 | Size: 2.5 KiB |
|
After Width: 100 | Height: 64 | Size: 158 B |
|
After Width: 100 | Height: 67 | Size: 1.1 KiB |
|
After Width: 100 | Height: 50 | Size: 656 B |
|
After Width: 100 | Height: 50 | Size: 1.4 KiB |
|
After Width: 100 | Height: 67 | Size: 1.7 KiB |