Browse Source

注册markdown格式

wangyi/feature-20251022162725-启动页登录注册
Ethereal 1 month ago
parent
commit
94682e1e24
  1. 20
      package-lock.json
  2. 5
      package.json
  3. 245
      pages/deepMate/deepMate.vue

20
package-lock.json

@ -2,5 +2,23 @@
"name": "deepChartVueApp",
"lockfileVersion": 3,
"requires": true,
"packages": {}
"packages": {
"": {
"dependencies": {
"marked": "^2.0.1"
}
},
"node_modules/marked": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/marked/-/marked-2.0.1.tgz",
"integrity": "sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==",
"license": "MIT",
"bin": {
"marked": "bin/marked"
},
"engines": {
"node": ">= 8.16.2"
}
}
}
}

5
package.json

@ -0,0 +1,5 @@
{
"dependencies": {
"marked": "^2.0.1"
}
}

245
pages/deepMate/deepMate.vue

@ -32,13 +32,16 @@
<!-- 顶部固定区域占位符 -->
<view class="banner-placeholder"></view>
<view class="banner-panel"
:class="messages.length === 0 ? '' : 'panelShow'"
>
<view
class="banner-panel"
:class="messages.length === 0 ? '' : 'panelShow'"
:style="{ paddingTop: safeAreaInsets?.top + 'px' }"
>
<image
src="https://d31zlh4on95l9h.cloudfront.net/images/42e18bd7fe97d4f4f37aa70439a0990b.svg"
class="pray-banner"
:class="messages.length === 0 ? '' : 'show'"
:style="{ paddingTop: safeAreaInsets?.top + 'px' }"
mode="aspectFill"
></image>
<view class="contain">
@ -106,7 +109,12 @@
<!-- 聊天区域 -->
<view class="chat-container" v-if="messages.length > 0">
<!-- 给聊天容器添加滚动引用 -->
<scroll-view class="chat-scroll-view" scroll-y="true" :scroll-top="scrollTop">
<scroll-view
class="chat-scroll-view"
scroll-y="true"
:scroll-top="scrollTop"
:style="{ paddingTop: safeAreaInsets?.top + 'px' }"
>
<view class="message-list" id="messageList">
<view
v-for="(message, index) in messages"
@ -125,16 +133,40 @@
></text>
<!-- 会话内容 -->
<view class="message-content">
<text class="message-text">{{ message.content }}</text>
<!-- loading -->
<view
class="loading-dots"
v-if="message.isThinking "
v-if="message.isThinking || !message.isUser"
>
<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>
<!-- 使用 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>
@ -179,14 +211,36 @@ const { safeAreaInsets } = uni.getSystemInfoSync();
import { ref, onMounted, nextTick, watch } from "vue";
import footerBar from "../../components/footerBar-cn.vue";
import marked from "marked"; // marked
// 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 showThinking = ref(true);
const isSending = ref(false);
const uuid = ref("");
const messages = ref([]);
const scrollTop = ref(0); // scroll-view
const dataInfo = ref("")
const hotTopics = ref([
{
id: 1,
@ -222,12 +276,16 @@ onMounted(() => {
});
//
watch(messages, (newMessages) => {
// DOM
setTimeout(() => {
scrollToBottom();
}, 100);
}, { deep: true });
watch(
messages,
(newMessages) => {
// DOM
setTimeout(() => {
scrollToBottom();
}, 100);
},
{ deep: true }
);
// UUID
const initUUID = () => {
@ -263,9 +321,13 @@ const goBlank = () => {
};
//
const sendMessage = () => {
const sendMessage = async () => {
if (inputMessage.value.trim() === "" || isSending.value) return;
const res = await getDataInfo();
console.log("数据格式为"+dataInfo.value);
const userMessage = {
content: inputMessage.value,
isUser: true,
@ -328,13 +390,50 @@ const simulateBotResponse = (userMessage) => {
}, 100);
//
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;
const typeWriter = () => {
if (index < responseText.length) {
// 使 Vue
messages.value[messages.value.length - 1].content = responseText.substring(0, index + 1);
messages.value[messages.value.length - 1].content =
responseText.substring(0, index + 1);
index++;
//
@ -374,6 +473,35 @@ const scrollToTop = () => {
//
scrollTop.value = 0;
};
const toggleThinking = () => {
showThinking.value = !showThinking.value;
};
// function getDataInfo() {
// return uni.request({
// url: 'http://localhost:8888/ka',
// data: {},
// header: {
// Accept: 'application/json',
// 'Content-Type': 'application/json',
// 'X-Requested-With': 'XMLHttpRequest'
// },
// method: 'GET',
// sslVerify: true,
// success: (res) => {
// console.log(res.data);
// res.data.forEach(item => {
// console.log("item"+item);
// dataInfo.value = item.name;
// });
// },
// fail: (error) => {}
// })
// }
</script>
<style scoped>
@ -808,7 +936,7 @@ const scrollToTop = () => {
overflow: hidden; /* 让圆角和内部层剪裁一致 */
border-radius: 15rpx;
}
.panelShow{
.panelShow {
height: 12%;
position: fixed;
top: 70rpx;
@ -826,7 +954,6 @@ const scrollToTop = () => {
z-index: 1; /* 在灰底之上、内容之下 */
}
.contain {
margin: 0 20rpx;
gap: 5rpx;
@ -849,12 +976,84 @@ const scrollToTop = () => {
transform: scale(0.96);
}
.static-footer {
position: fixed;
bottom: 0;
position: fixed;
bottom: 0;
z-index: 999;
}
/* 顶部固定区域占位符 */
.banner-placeholder {
height: 120rpx; /* 与header高度一致,防止内容被固定头部遮挡 */
}
.thinking-process {
margin: 10px 0;
border: 1px solid #e5e5e5;
border-radius: 8px;
background-color: #f9f9f9;
}
.thinking-header {
display: flex;
align-items: center;
padding: 10px 15px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #e5e5e5;
}
.thinking-icon {
font-size: 16px;
margin-right: 8px;
color: #d47c45;
}
.thinking-title {
font-size: 14px;
font-weight: 500;
color: #d47c45;
margin-right: 8px;
}
.thinking-count {
font-size: 12px;
color: #666;
margin-right: 8px;
}
.thinking-toggle {
font-size: 12px;
color: #999;
}
.thinking-content {
padding: 10px 15px;
}
.thinking-item {
display: flex;
align-items: center;
margin-bottom: 8px;
padding: 4px 0;
}
.item-status {
width: 16px;
height: 16px;
border-radius: 50%;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
margin-right: 8px;
}
.checkmark {
font-size: 10px;
color: #ff0000;
}
.item-text {
font-size: 12px;
color: #333;
}
</style>
Loading…
Cancel
Save