|
|
@ -82,7 +82,7 @@ |
|
|
<view class="welcome-message"> <text class="greeting">Hi, 我是您的股市随身顾问~</text> <text class="description">个股诊断、市场情绪解读,都可以找我。</text> |
|
|
<view class="welcome-message"> <text class="greeting">Hi, 我是您的股市随身顾问~</text> <text class="description">个股诊断、市场情绪解读,都可以找我。</text> |
|
|
</view> </view> |
|
|
</view> </view> |
|
|
</view> |
|
|
</view> |
|
|
<view class="chat-container" v-if="messages.length > 0"> |
|
|
|
|
|
|
|
|
<scroll-view class="chat-container" scroll-y="true" :scroll-top="chatScrollTop" @scroll="onChatScroll" v-if="messages.length > 0"> |
|
|
<view class="message-list" id="messageList"> |
|
|
<view class="message-list" id="messageList"> |
|
|
<view |
|
|
<view |
|
|
v-for="(message, index) in messages" |
|
|
v-for="(message, index) in messages" |
|
|
@ -101,20 +101,49 @@ |
|
|
></text> |
|
|
></text> |
|
|
<!-- 会话内容 --> |
|
|
<!-- 会话内容 --> |
|
|
<view class="message-content"> |
|
|
<view class="message-content"> |
|
|
<text class="message-text">{{ message.content }}</text> |
|
|
|
|
|
|
|
|
<!-- <text class="message-text">{{ message.content }}</text> --> |
|
|
<!-- loading --> |
|
|
<!-- loading --> |
|
|
<view |
|
|
<view |
|
|
class="loading-dots" |
|
|
class="loading-dots" |
|
|
v-if="message.isThinking || message.isTyping" |
|
|
v-if="message.isThinking || message.isTyping" |
|
|
> |
|
|
> |
|
|
<text class="dot"></text> |
|
|
|
|
|
<text class="dot"></text> |
|
|
|
|
|
<text class="dot"></text> |
|
|
|
|
|
|
|
|
<div class="thinking-process"> |
|
|
|
|
|
<div class="thinking-header"> |
|
|
|
|
|
<div class="thinking-icon">∞</div> |
|
|
|
|
|
<div class="thinking-title">深度思考 正在思考</div> |
|
|
|
|
|
<div class="thinking-count">25 个结果</div> |
|
|
|
|
|
<div class="thinking-toggle" @click="toggleThinking"> |
|
|
|
|
|
<span v-if="showThinking">↑</span> |
|
|
|
|
|
<span v-else>↓</span> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div v-show="showThinking" class="thinking-content"> |
|
|
|
|
|
<div class="thinking-item"> |
|
|
|
|
|
<div class="item-status"> |
|
|
|
|
|
<span class="checkmark">✓</span> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="item-text">问题分析完成</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="thinking-item"> |
|
|
|
|
|
<div class="item-status"> |
|
|
|
|
|
<span class="checkmark">✓</span> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="item-text">收集相关信息</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
</view> |
|
|
</view> |
|
|
|
|
|
<!-- 使用 rich-text 渲染 Markdown 内容 --> |
|
|
|
|
|
<rich-text |
|
|
|
|
|
v-if="!message.isUser" |
|
|
|
|
|
class="message-text" |
|
|
|
|
|
:nodes="renderMarkdown(message.content)" |
|
|
|
|
|
></rich-text> |
|
|
|
|
|
<text v-else class="message-text">{{ message.content }}</text> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
|
|
|
|
|
|
</scroll-view> |
|
|
</view> |
|
|
</view> |
|
|
|
|
|
|
|
|
<!-- 输入框区域 --> |
|
|
<!-- 输入框区域 --> |
|
|
@ -158,12 +187,32 @@ const { safeAreaInsets } = uni.getSystemInfoSync(); |
|
|
|
|
|
|
|
|
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue"; |
|
|
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue"; |
|
|
import footerBar from '../../components/footerBar-cn' |
|
|
import footerBar from '../../components/footerBar-cn' |
|
|
|
|
|
import marked from "marked"; // 引入 marked 库 |
|
|
import { onPageScroll } from '@dcloudio/uni-app' |
|
|
import { onPageScroll } from '@dcloudio/uni-app' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置 marked 选项 |
|
|
|
|
|
marked.setOptions({ |
|
|
|
|
|
renderer: new marked.Renderer(), |
|
|
|
|
|
highlight: null, // 如果需要代码高亮,可以设置适当的函数 |
|
|
|
|
|
langPrefix: "language-", |
|
|
|
|
|
pedantic: false, |
|
|
|
|
|
gfm: true, |
|
|
|
|
|
breaks: false, |
|
|
|
|
|
sanitize: false, |
|
|
|
|
|
smartLists: true, |
|
|
|
|
|
smartypants: false, |
|
|
|
|
|
xhtml: false, |
|
|
|
|
|
}); |
|
|
|
|
|
// 创建一个用于渲染 Markdown 的函数 |
|
|
|
|
|
const renderMarkdown = (content) => { |
|
|
|
|
|
if (!content) return ""; |
|
|
|
|
|
return marked.parse(content); |
|
|
|
|
|
}; |
|
|
const type = ref('member') |
|
|
const type = ref('member') |
|
|
const inputMessage = ref(""); |
|
|
const inputMessage = ref(""); |
|
|
|
|
|
const showThinking = ref(true); |
|
|
const isSending = ref(false); |
|
|
const isSending = ref(false); |
|
|
|
|
|
const chatScrollTop = ref(0); |
|
|
|
|
|
const chatContainerHeight = ref(0); |
|
|
const uuid = ref(""); |
|
|
const uuid = ref(""); |
|
|
const messages = ref([]); |
|
|
const messages = ref([]); |
|
|
const hotTopics = ref([ |
|
|
const hotTopics = ref([ |
|
|
@ -210,7 +259,7 @@ onMounted(() => { |
|
|
nextTick(startTabsMarquee); |
|
|
nextTick(startTabsMarquee); |
|
|
} |
|
|
} |
|
|
if (messages.value.length > 0) { |
|
|
if (messages.value.length > 0) { |
|
|
nextTick(() => { scrollToBottom(); }); |
|
|
|
|
|
|
|
|
nextTick(() => { measureChatContainer(); scrollToBottom(); }); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
@ -233,6 +282,15 @@ const generateUUID = () => { |
|
|
}); |
|
|
}); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 计算聊天容器可视高度 |
|
|
|
|
|
const measureChatContainer = () => { |
|
|
|
|
|
const q = uni.createSelectorQuery(); |
|
|
|
|
|
q.select('.chat-container').boundingClientRect(); |
|
|
|
|
|
q.exec((res) => { |
|
|
|
|
|
chatContainerHeight.value = res[0]?.height || 0; |
|
|
|
|
|
}); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 新会话 |
|
|
// 新会话 |
|
|
const newChat = () => { |
|
|
const newChat = () => { |
|
|
messages.value = []; |
|
|
messages.value = []; |
|
|
@ -289,7 +347,42 @@ const simulateBotResponse = (userMessage) => { |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// 模拟流式响应 |
|
|
// 模拟流式响应 |
|
|
let responseText = `我已经收到您的消息: "${userMessage}"。作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?作为您的股市顾问,我可以为您提供专业的投资建议。请问您想了解哪方面的信息?`; |
|
|
|
|
|
|
|
|
let responseText = `我已经收到您的消息: "${userMessage}"。 ## 股票分析报告 |
|
|
|
|
|
|
|
|
|
|
|
### 股票名称: Tesla Inc. (TSLA) |
|
|
|
|
|
|
|
|
|
|
|
- **当前价格**: 448.980 |
|
|
|
|
|
- **更新时间**: 23/10/2025 |
|
|
|
|
|
- **今日无变盘点** |
|
|
|
|
|
|
|
|
|
|
|
### 技术分析 |
|
|
|
|
|
- **CFTL**: 当前牵牛绳为红色,处于龙线区域,最近出现“牛刀小试”,度牛线目前处于青绿色区域。 |
|
|
|
|
|
- **空间预测**: |
|
|
|
|
|
- 预测低一值: 413.364 |
|
|
|
|
|
- 预测高一值: 426.636 |
|
|
|
|
|
- 预测低二值: 421.670 |
|
|
|
|
|
- 预测高二值: 448.314 |
|
|
|
|
|
- **能量分析**: AI智能均线多头排列,当前卖盘小于买盘 |
|
|
|
|
|
|
|
|
|
|
|
### 资金与主力 |
|
|
|
|
|
- **主力分析**: |
|
|
|
|
|
1. 该股庄家中长期筹码成本价格为 356.036,短期资金成本价格为 406.429。该股筹码分散,当日筹码成本价格为 439.322。 |
|
|
|
|
|
2. 近日没有出现主力集中吸筹。 |
|
|
|
|
|
3. 近期主力持仓比例大于散户持仓比例。当日主力持仓增加。当日散户持仓减少。 |
|
|
|
|
|
|
|
|
|
|
|
### 综合评价 |
|
|
|
|
|
- **个股走势评价**: |
|
|
|
|
|
- 该股整体趋势向好,出现暴涨的可能性较大,当前如果已经持有该股票,可以继续持股观察,如果尚未持有该股票,可持续进行观察,目前处于机会的初期,处于反弹阶段,可以分步建仓! |
|
|
|
|
|
|
|
|
|
|
|
- **核心证据链**: |
|
|
|
|
|
- 资金共识:当日多方资金流入。 |
|
|
|
|
|
- 趋势动能:该股中长期处于上升趋势,短期处于弱势状态。 |
|
|
|
|
|
|
|
|
|
|
|
- **牛股评级**: ★★★☆☆ |
|
|
|
|
|
- **暴涨概率**: 60% |
|
|
|
|
|
- **风险评估**: 非常安全 |
|
|
|
|
|
- **安全边际**: 432.671~458.057 |
|
|
|
|
|
- **黄金价域**: 427.995~440.835`; |
|
|
let index = 0; |
|
|
let index = 0; |
|
|
|
|
|
|
|
|
const botIndex = messages.value.length - 1; |
|
|
const botIndex = messages.value.length - 1; |
|
|
@ -328,31 +421,40 @@ const simulateBotResponse = (userMessage) => { |
|
|
setTimeout(typeWriter, 500); |
|
|
setTimeout(typeWriter, 500); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// 滚动到底部 |
|
|
|
|
|
|
|
|
// 当消息出现或变化时,测量容器并滚到底部 |
|
|
|
|
|
watch(messages, (arr) => { |
|
|
|
|
|
if (arr.length > 0) { |
|
|
|
|
|
nextTick(() => { |
|
|
|
|
|
measureChatContainer(); |
|
|
|
|
|
scrollToBottom(); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 滚动到底部(仅聊天区域滚动) |
|
|
const scrollToBottom = () => { |
|
|
const scrollToBottom = () => { |
|
|
if (!shouldAutoScroll.value) return; // 暂停自动滚动 |
|
|
|
|
|
|
|
|
if (!shouldAutoScroll.value) return; |
|
|
const query = uni.createSelectorQuery(); |
|
|
const query = uni.createSelectorQuery(); |
|
|
query.select("#messageList").boundingClientRect(); |
|
|
|
|
|
query.selectViewport().scrollOffset(); |
|
|
|
|
|
|
|
|
query.select('#messageList').boundingClientRect(); |
|
|
query.exec((res) => { |
|
|
query.exec((res) => { |
|
|
if (res[0] && res[1]) { |
|
|
|
|
|
|
|
|
if (res[0]) { |
|
|
latestContentHeight.value = res[0].height; |
|
|
latestContentHeight.value = res[0].height; |
|
|
uni.pageScrollTo({ scrollTop: res[0].height, duration: 100 }); |
|
|
|
|
|
|
|
|
chatScrollTop.value = res[0].height; // scroll-view 会自动夹紧到最大位置 |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
}; |
|
|
}; |
|
|
const scrollToTop = () => { |
|
|
const scrollToTop = () => { |
|
|
uni.pageScrollTo({ scrollTop: 0, duration: 200 }); |
|
|
|
|
|
|
|
|
chatScrollTop.value = 0; |
|
|
}; |
|
|
}; |
|
|
// 自动滚动控制:用户向上滚动时暂停自动滚到底部 |
|
|
// 自动滚动控制:用户向上滚动时暂停自动滚到底部 |
|
|
const shouldAutoScroll = ref(true); |
|
|
const shouldAutoScroll = ref(true); |
|
|
const latestContentHeight = ref(0); |
|
|
const latestContentHeight = ref(0); |
|
|
const lastScrollTop = ref(0); |
|
|
const lastScrollTop = ref(0); |
|
|
const windowHeight = uni.getSystemInfoSync().windowHeight; |
|
|
const windowHeight = uni.getSystemInfoSync().windowHeight; |
|
|
const AUTO_SCROLL_REENABLE_THRESHOLD = 1; // px,接近底部时恢复自动滚动 |
|
|
|
|
|
|
|
|
const AUTO_SCROLL_REENABLE_THRESHOLD = 400; // px,接近底部时恢复自动滚动 |
|
|
|
|
|
|
|
|
onPageScroll((e) => { |
|
|
|
|
|
const st = e.scrollTop; |
|
|
|
|
|
|
|
|
const onChatScroll = (e) => { |
|
|
|
|
|
const st = e.detail?.scrollTop || 0; |
|
|
const delta = st - lastScrollTop.value; |
|
|
const delta = st - lastScrollTop.value; |
|
|
lastScrollTop.value = st; |
|
|
lastScrollTop.value = st; |
|
|
|
|
|
|
|
|
@ -361,11 +463,11 @@ onPageScroll((e) => { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const distanceToBottom = latestContentHeight.value - st - windowHeight; |
|
|
|
|
|
|
|
|
const distanceToBottom = latestContentHeight.value - st - chatContainerHeight.value; |
|
|
if (distanceToBottom <= AUTO_SCROLL_REENABLE_THRESHOLD) { |
|
|
if (distanceToBottom <= AUTO_SCROLL_REENABLE_THRESHOLD) { |
|
|
shouldAutoScroll.value = true; |
|
|
shouldAutoScroll.value = true; |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 回到顶部图标拖拽状态 |
|
|
// 回到顶部图标拖拽状态 |
|
|
const backTopX = ref(0); |
|
|
const backTopX = ref(0); |
|
|
@ -445,10 +547,12 @@ const onBackTopClick = () => { |
|
|
.deepMate-page { |
|
|
.deepMate-page { |
|
|
display: flex; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
flex-direction: column; |
|
|
|
|
|
position: fixed; /* 充满视口,彻底禁用页面滚动 */ |
|
|
|
|
|
top: 0; left: 0; right: 0; bottom: 0; |
|
|
height: 100vh; |
|
|
height: 100vh; |
|
|
|
|
|
overflow: hidden; /* 锁定页面滚动 */ |
|
|
background-color: #ffffff; |
|
|
background-color: #ffffff; |
|
|
padding: 20rpx 0rpx; |
|
|
padding: 20rpx 0rpx; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.header { |
|
|
.header { |
|
|
@ -457,7 +561,7 @@ const onBackTopClick = () => { |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
padding: 20rpx 30rpx; |
|
|
padding: 20rpx 30rpx; |
|
|
background-color: #ffffff; |
|
|
background-color: #ffffff; |
|
|
|
|
|
|
|
|
|
|
|
box-shadow: 0 2rpx rgba(0, 0, 0, 0.1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.header-left, |
|
|
.header-left, |
|
|
@ -494,9 +598,11 @@ const onBackTopClick = () => { |
|
|
.main-content { |
|
|
.main-content { |
|
|
background-color: #fff; |
|
|
background-color: #fff; |
|
|
flex: 1; |
|
|
flex: 1; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
flex-direction: column; |
|
|
|
|
|
overflow: hidden; /* 内部滚动交给聊天容器 */ |
|
|
padding: 20rpx; |
|
|
padding: 20rpx; |
|
|
/* overflow-y: auto; 取消独立滚动,使用页面滚动以便自动到达底部 */ |
|
|
|
|
|
margin-top: 20rpx; |
|
|
|
|
|
|
|
|
margin-top: 1rpx; |
|
|
margin-bottom: 120rpx; |
|
|
margin-bottom: 120rpx; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -680,8 +786,9 @@ const onBackTopClick = () => { |
|
|
.chat-container { |
|
|
.chat-container { |
|
|
margin-top: 30rpx; |
|
|
margin-top: 30rpx; |
|
|
border-radius: 10rpx; |
|
|
border-radius: 10rpx; |
|
|
height: fit-content; |
|
|
|
|
|
/* overflow-y: auto; */ |
|
|
|
|
|
|
|
|
height: 65%; /* 缩短滚动区域,避免被输入框覆盖 */ |
|
|
|
|
|
overflow-y: auto; |
|
|
|
|
|
-webkit-overflow-scrolling: touch; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.message-list { |
|
|
.message-list { |
|
|
@ -843,7 +950,9 @@ const onBackTopClick = () => { |
|
|
color: #ffffff !important; |
|
|
color: #ffffff !important; |
|
|
opacity: 1; |
|
|
opacity: 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* .uni-scroll-view{ |
|
|
|
|
|
height: 92%; |
|
|
|
|
|
} */ |
|
|
.send-button { |
|
|
.send-button { |
|
|
background: url("https://d31zlh4on95l9h.cloudfront.net/images/95f1ea2262e9157db13c93c0dc1c5d96.svg"); |
|
|
background: url("https://d31zlh4on95l9h.cloudfront.net/images/95f1ea2262e9157db13c93c0dc1c5d96.svg"); |
|
|
background-repeat: no-repeat; |
|
|
background-repeat: no-repeat; |
|
|
@ -914,4 +1023,75 @@ const onBackTopClick = () => { |
|
|
position: fixed; |
|
|
position: fixed; |
|
|
bottom: 0; |
|
|
bottom: 0; |
|
|
} |
|
|
} |
|
|
|
|
|
.thinking-process { |
|
|
|
|
|
margin: 20rpx 0; |
|
|
|
|
|
border: 2rpx solid #e5e5e5; |
|
|
|
|
|
border-radius: 2rpx; |
|
|
|
|
|
background-color: #f9f9f9; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.thinking-header { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
padding: 20rpx 30rpx; |
|
|
|
|
|
cursor: pointer; |
|
|
|
|
|
background-color: #fff; |
|
|
|
|
|
border-bottom: 2px solid #e5e5e5; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.thinking-icon { |
|
|
|
|
|
font-size: 32rpx; |
|
|
|
|
|
margin-right: 16rpx; |
|
|
|
|
|
color: #d47c45; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.thinking-title { |
|
|
|
|
|
font-size: 28rpx; |
|
|
|
|
|
font-weight: 500; |
|
|
|
|
|
color: #d47c45; |
|
|
|
|
|
margin-right: 16rpx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.thinking-count { |
|
|
|
|
|
font-size: 24rpx; |
|
|
|
|
|
color: #666; |
|
|
|
|
|
margin-right: 16rpx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.thinking-toggle { |
|
|
|
|
|
font-size: 24rpx; |
|
|
|
|
|
color: #999; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.thinking-content { |
|
|
|
|
|
padding: 20rpx 30rpx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.thinking-item { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
margin-bottom: 16rpx; |
|
|
|
|
|
padding: 8rpx 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-status { |
|
|
|
|
|
width: 32rpx; |
|
|
|
|
|
height: 32rpx; |
|
|
|
|
|
border-radius: 50%; |
|
|
|
|
|
background-color: #f0f0f0; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
margin-right: 16rpx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.checkmark { |
|
|
|
|
|
font-size: 20rpx; |
|
|
|
|
|
color: #ff0000; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-text { |
|
|
|
|
|
font-size: 24rpx; |
|
|
|
|
|
color: #333; |
|
|
|
|
|
} |
|
|
</style> |
|
|
</style> |