You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

876 lines
24 KiB

4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
  1. <template>
  2. <LoginPrompt ref="loginPrompt"></LoginPrompt>
  3. <view class="main">
  4. <!-- 顶部状态栏占位 -->
  5. <view class="top" :style="{height:iSMT+'px'}"></view>
  6. <deepExploration_header></deepExploration_header>
  7. <view class="search">
  8. <input v-model="searchName" class="searchInput" type="text" placeholder="请输入股票名称、股票代码"
  9. placeholder-style="color: #A6A6A6; font-size: 28rpx;" />
  10. <image @click="searchStock" class="seachIcon" src="/static/deepExploration-images/search.png"
  11. mode="aspectFill"></image>
  12. </view>
  13. <view class="content">
  14. <view class="select">
  15. <image class="img" :src="navItems[currentIndex].icon" mode=""></image>
  16. <view v-for="(item, index) in navItems" :key="index" class="selectItem"
  17. :class="{ active: currentIndex === index }" @click="handleModel(index)">
  18. <button class="btn"></button>
  19. </view>
  20. </view>
  21. <view class="graphAndTxt">
  22. <view class="graph">
  23. <view class="graph_header">
  24. <view class="left">{{stockCode}}</view>
  25. <view class="center">
  26. <text>{{stockName}}</text>
  27. </view>
  28. <view class="right">{{stockTime}}</view>
  29. </view>
  30. <view class="graph_data">
  31. <text>{{stockPrice}}</text>
  32. <text>{{stockChange}}</text>
  33. <text>{{stockAdd}}</text>
  34. </view>
  35. <view class="graph_content">
  36. <view class="charts-box">
  37. <!-- uCharts 蜡烛图组件 -->
  38. <qiun-data-charts type="candle" :opts="opts" :chartData="chartData" :disableScroll="true"
  39. :ontouch="true" :onzoom="true" :key="chartKey" />
  40. </view>
  41. <image src="/static/deepExploration-images/kLineAll.png" mode="aspectFill"></image>
  42. </view>
  43. </view>
  44. <view class="txt">
  45. <view class="txtHeader">
  46. <image src="/static/deepExploration-images/plus.png" mode="aspectFill"></image>
  47. <text>{{navItems[currentIndex].name}}</text>
  48. </view>
  49. <view class="txtContent">
  50. <view v-if="loading" class="loading">加载中...</view>
  51. <rich-text :nodes="htmlContent"></rich-text>
  52. </view>
  53. </view>
  54. </view>
  55. </view>
  56. <!-- 底部切换栏 -->
  57. <footerBar class="static-footer" :type="type"></footerBar>
  58. </view>
  59. </template>
  60. <script setup>
  61. import {
  62. ref,
  63. onMounted,
  64. watch
  65. } from 'vue'
  66. import deepExploration_header from '@/components/deepExploration_header.vue'
  67. import footerBar from '@/components/footerBar.vue'
  68. import {
  69. onLoad
  70. } from '@dcloudio/uni-app'
  71. import {
  72. getModel1First,
  73. getModel1Second,
  74. getModel2First,
  75. getModel2Second,
  76. getModel3First,
  77. getModel3Second,
  78. getModel4First,
  79. getModel4Second,
  80. getModeldefault,
  81. getData
  82. } from '/api/deepExploration/deepExploration.js'
  83. import marked from 'marked'; // 引入 marked 库
  84. import hljs from 'highlight.js';
  85. import 'highlight.js/styles/atom-one-dark.css'; // 可替换为其他主题
  86. import {
  87. useDeepExplorationStore
  88. } from '@/stores/modules/deepExploration'
  89. import {
  90. getUserInfo
  91. } from "@/api/member"
  92. import {
  93. useUserStore
  94. } from '@/stores/modules/userInfo.js'
  95. const deepExplorationStore = useDeepExplorationStore()
  96. const userInfo = getUserInfo()
  97. //历史数据
  98. const historyData = ref({})
  99. //登录弹窗提示ref
  100. const loginPrompt = ref(null)
  101. // 响应式变量定义
  102. const type = ref('deepExploration')
  103. const iSMT = ref(0)
  104. const currentIndex = ref(0)
  105. const navItems = ref([{
  106. name: '主力追踪',
  107. icon: '/static/deepExploration-images/1.png'
  108. },
  109. {
  110. name: '主力雷达',
  111. icon: '/static/deepExploration-images/2.png'
  112. },
  113. {
  114. name: '主力解码',
  115. icon: '/static/deepExploration-images/3.png'
  116. },
  117. {
  118. name: '主力资金流',
  119. icon: '/static/deepExploration-images/4.png'
  120. },
  121. ])
  122. //搜索股票
  123. const searchStock = () => {
  124. htmlContent.value = ''
  125. console.log('搜索参数:', stockName.value, currentIndex.value);
  126. if (currentIndex.value >= 0 && currentIndex.value <= 3) {
  127. handleModels()
  128. } else {
  129. uni.showToast({
  130. title: '请选择模块',
  131. icon: 'none',
  132. duration: 2000
  133. })
  134. }
  135. }
  136. //点击四大模块
  137. const handleModel = async (index) => {
  138. htmlContent.value = ''
  139. currentIndex.value = index
  140. await handleModels()
  141. // await getServerData()
  142. }
  143. const stockName = ref('Tesla Inc.')
  144. const searchName = ref('')
  145. const stockCode = ref('TSLA')
  146. const language = ref('')
  147. const recordId = ref('')
  148. const parentId = ref('')
  149. const stockId = ref('')
  150. const market = ref('')
  151. const stockTime = ref('2025/10/24')
  152. const loading = ref(true);
  153. const error = ref('');
  154. const htmlContent = ref('');
  155. const markdownContent = ref('');
  156. const renderer = new marked.Renderer();
  157. renderer.heading = function(text, level) {
  158. return `<p>${text}</p>`;
  159. };
  160. // 初始化 marked 配置(支持代码高亮)
  161. marked.setOptions({
  162. highlight: (code, lang) => {
  163. if (lang && hljs.getLanguage(lang)) {
  164. return hljs.highlight(code, {
  165. language: lang
  166. }).value;
  167. }
  168. return hljs.highlightAuto(code).value;
  169. },
  170. renderer,
  171. breaks: true, // 换行转<br>
  172. gfm: true, // 支持GitHub flavored Markdown
  173. sanitize: false, // 保留HTML标签(如<span style>)
  174. });
  175. //获取模型数据
  176. const handleModels = async () => {
  177. try {
  178. if (userInfo.isVisitor) {
  179. console.log('是游客');
  180. loginPrompt.value.show()
  181. return
  182. }
  183. console.log('搜了吗');
  184. // markdownContent.value = '\n## 📊 主力追踪分析:\n\n### 🕵️ 主力行为\n\t1. 📊 该股庄家中长期筹码成本价格为 360.249,短期资金成本价格为 412.577。该股筹码分散,当日筹码成本价格为 444.330。\n\t2. 🔍 近日没有出现主力集中吸筹。\n\t3. 📈 近期主力持仓比例大于散户持仓比例。 当日主力持仓增加。 当日散户持仓减少。\n\n### 📊 空间维度:\n\t- 📉 预测低一值: <font color=\"#13c2c2\">443.092</font> \n - 📈 预测高一值: <font color=\"#ff4d4f\">466.458</font>\n\t- 📉 预测低二值: <font color=\"#13c2c2\">447.354</font>\n\t- 📈 预测高二值: <font color=\"#ff4d4f\">462.514</font>\n\t<font color=\"#722ed1\">AI智能均线空头排列,当前卖盘小于买盘</font>\n\n### 综合作战\n\t\t\t<font color=\"#fa8c16\">当前股票处于安全区,牵牛绳为红色,出现蓝色推进K线。</font>\n\t\t\t<font color=\"#eb2f96\">该股整体趋势相对较强,个股正处于推进上涨的关键阶段。若当前持有该股票,建议继续持有,进行持续跟踪。若当前无该股票,建议持续跟踪,等待适当时机再进行介入。</font>\n\n---\n<font color=\"#8c8c8c\">*该内容由AI生成,仅供参考,投资有风险,请注意甄别。*</font>\n '
  185. // htmlContent.value = marked.parse(markdownContent.value);
  186. loading.value = true;
  187. if (searchName.value == '') {
  188. console.log('没有搜索', searchName.value);
  189. handleDefault()
  190. } else {
  191. if (currentIndex.value == 0) {
  192. console.log('搜索', searchName.value);
  193. const result = await getModel1First({
  194. content: searchName.value,
  195. language: "cn",
  196. marketList: "hk,cn,usa,my,sg,vi,in,gb",
  197. model: currentIndex.value + 1
  198. })
  199. console.log('result', result);
  200. if (result.code == 200) {
  201. stockCode.value = result.data.code
  202. // stockName.value = result.data.name
  203. recordId.value = result.data.recordId
  204. parentId.value = result.data.parentId
  205. stockId.value = result.data.stockId
  206. language.value = result.data.language
  207. market.value = result.data.market
  208. const res = await getModel1Second({
  209. language: language.value,
  210. recordId: recordId.value,
  211. parentId: parentId.value,
  212. stockId: stockId.value,
  213. token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
  214. })
  215. if (res.code == 200) {
  216. const rawMarkdown = res.data.markdown;
  217. const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // 全局替换行首的###
  218. markdownContent.value = adaptedMarkdown;
  219. // markdownContent.value = res.data.markdown
  220. htmlContent.value = marked.parse(markdownContent.value);
  221. await getServerData()
  222. }
  223. console.log('res', res);
  224. } else if (result.code == 400) {
  225. markdownContent.value = result.message;
  226. htmlContent.value = marked.parse(markdownContent.value);
  227. } else {
  228. return
  229. }
  230. } else if (currentIndex.value == 1) {
  231. console.log('搜索', searchName.value);
  232. const result = await getModel2First({
  233. content: searchName.value,
  234. language: "cn",
  235. marketList: "hk,cn,usa,my,sg,vi,in,gb",
  236. model: currentIndex.value + 1
  237. })
  238. console.log('result', result);
  239. if (result.code == 200) {
  240. stockCode.value = result.data.code
  241. recordId.value = result.data.recordId
  242. parentId.value = result.data.parentId
  243. stockId.value = result.data.stockId
  244. language.value = result.data.language
  245. market.value = result.data.market
  246. const res = await getModel2Second({
  247. language: language.value,
  248. recordId: recordId.value,
  249. parentId: parentId.value,
  250. stockId: stockId.value,
  251. token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
  252. })
  253. if (res.code == 200) {
  254. const rawMarkdown = res.data.markdown;
  255. const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // 全局替换行首的###
  256. markdownContent.value = adaptedMarkdown;
  257. // markdownContent.value = res.data.markdown
  258. htmlContent.value = marked.parse(markdownContent.value);
  259. await getServerData()
  260. }
  261. console.log('res', res);
  262. } else if (result.code == 400) {
  263. markdownContent.value = result.message;
  264. htmlContent.value = marked.parse(markdownContent.value);
  265. } else {
  266. return
  267. }
  268. } else if (currentIndex.value == 2) {
  269. console.log('搜索', searchName.value);
  270. const result = await getModel3First({
  271. content: searchName.value,
  272. language: "cn",
  273. marketList: "hk,cn,usa,my,sg,vi,in,gb",
  274. model: currentIndex.value + 1
  275. })
  276. console.log('result', result);
  277. if (result.code == 200) {
  278. stockCode.value = result.data.code
  279. // stockName.value = result.data.name
  280. recordId.value = result.data.recordId
  281. parentId.value = result.data.parentId
  282. stockId.value = result.data.stockId
  283. language.value = result.data.language
  284. market.value = result.data.market
  285. const res = await getModel3Second({
  286. language: language.value,
  287. recordId: recordId.value,
  288. parentId: parentId.value,
  289. stockId: stockId.value,
  290. token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
  291. })
  292. if (res.code == 200) {
  293. const rawMarkdown = res.data.markdown;
  294. const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // 全局替换行首的###
  295. markdownContent.value = adaptedMarkdown;
  296. // markdownContent.value = res.data.markdown
  297. htmlContent.value = marked.parse(markdownContent.value);
  298. await getServerData()
  299. }
  300. console.log('res', res);
  301. } else if (result.code == 400) {
  302. markdownContent.value = result.message;
  303. htmlContent.value = marked.parse(markdownContent.value);
  304. } else {
  305. return
  306. }
  307. } else if (currentIndex.value == 3) {
  308. console.log('搜索', searchName.value);
  309. const result = await getModel4First({
  310. content: searchName.value,
  311. language: "cn",
  312. marketList: "hk,cn,usa,my,sg,vi,in,gb",
  313. model: currentIndex.value + 1
  314. })
  315. console.log('result', result);
  316. if (result.code == 200) {
  317. stockCode.value = result.data.code
  318. // stockName.value = result.data.name
  319. recordId.value = result.data.recordId
  320. parentId.value = result.data.parentId
  321. stockId.value = result.data.stockId
  322. language.value = result.data.language
  323. market.value = result.data.market
  324. const res = await getModel4Second({
  325. language: language.value,
  326. recordId: recordId.value,
  327. parentId: parentId.value,
  328. stockId: stockId.value,
  329. token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
  330. })
  331. if (res.code == 200) {
  332. const rawMarkdown = res.data.markdown;
  333. const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // 全局替换行首的###
  334. markdownContent.value = adaptedMarkdown;
  335. // markdownContent.value = res.data.markdown
  336. htmlContent.value = marked.parse(markdownContent.value);
  337. await getServerData()
  338. }
  339. console.log('res', res);
  340. } else if (result.code == 400) {
  341. markdownContent.value = result.message;
  342. htmlContent.value = marked.parse(markdownContent.value);
  343. } else {
  344. return
  345. }
  346. } else {
  347. return
  348. }
  349. }
  350. } catch (e) {
  351. error.value = e.message || '加载失败,请重试';
  352. } finally {
  353. loading.value = false;
  354. }
  355. }
  356. const handleDefault = async () => {
  357. const result = await getModeldefault({
  358. token: "pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q",
  359. model: currentIndex.value + 1
  360. })
  361. if (result.code == 200) {
  362. const rawMarkdown = result.data.markdown;
  363. const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // 全局替换行首的###
  364. markdownContent.value = adaptedMarkdown;
  365. htmlContent.value = marked.parse(markdownContent.value);
  366. } else {
  367. }
  368. }
  369. const stockPrice = ref('435.900')
  370. const stockAdd = ref('22.410')
  371. const stockChange = ref('5.120%')
  372. const chartKey = ref(0);
  373. const getServerData = async () => {
  374. const result = await getData({
  375. market: market.value || '',
  376. code: stockCode.value || '',
  377. language: "cn",
  378. brainPrivilegeState: 1,
  379. marketList: "usa.sg.my.hk.cn.can.vi.th.in.gb"
  380. })
  381. console.log('k线数据', result);
  382. stockName.value = result.data.StockInformation.Name || 'Tesla Inc.'
  383. stockCode.value = result.data.StockInformation.Code || 'TSLA'
  384. stockTime.value = result.data.StockInformation.Time || '2025/10/29'
  385. stockChange.value = result.data.StockInformation.Zhang || '5.120%'
  386. stockAdd.value = result.data.StockInformation.ZhangFu || '22.410'
  387. stockPrice.value = result.data.StockInformation.Price || '435.900'
  388. if (result.data.chartData) {
  389. const rawData = JSON.parse(JSON.stringify(result.data.chartData));
  390. if (rawData.categories.length > 1) { // 确保至少保留一个日期
  391. rawData.categories[rawData.categories.length - 1] = ''; // 删除最后一个日期
  392. console.log('删了;');
  393. }
  394. chartData.value = {
  395. ...rawData
  396. }
  397. chartKey.value++;
  398. console.log('chartData', chartData.value);
  399. }
  400. }
  401. // 1. K线图配置
  402. const opts = ref({
  403. rotate: false,
  404. rotateLock: false,
  405. color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
  406. padding: [15, 30, 0, 15],
  407. dataLabel: false,
  408. enableScroll: true,
  409. enableMarkLine: false,
  410. legend: {},
  411. xAxis: {
  412. labelCount: 4,
  413. itemCount: 20,
  414. disableGrid: true,
  415. gridColor: "#CCCCCC",
  416. gridType: "solid",
  417. dashLength: 4,
  418. scrollShow: false,
  419. rotate: 45,
  420. scrollAlign: "left",
  421. scrollColor: "#A6A6A6",
  422. scrollBackgroundColor: "#EFEBEF",
  423. labelColor: "#8C8C8C",
  424. fontSize: 9,
  425. },
  426. yAxis: {
  427. labelColor: "#8C8C8C",
  428. fontSize: 9
  429. },
  430. extra: {
  431. candle: {
  432. color: {
  433. upLine: "#f04864",
  434. upFill: "#f04864",
  435. downLine: "#2fc25b",
  436. downFill: "#2fc25b"
  437. },
  438. average: {
  439. show: false,
  440. name: ["MA5", "MA10", "MA30"],
  441. day: [5, 10, 20],
  442. color: ["#1890ff", "#2fc25b", "#facc14"]
  443. }
  444. },
  445. markLine: {
  446. type: "dash",
  447. dashLength: 5,
  448. data: [{
  449. value: 2150,
  450. lineColor: "#f04864",
  451. showLabel: false
  452. },
  453. {
  454. value: 2350,
  455. lineColor: "#f04864",
  456. showLabel: false
  457. }
  458. ]
  459. },
  460. tooltip: {
  461. showCategory: true
  462. }
  463. }
  464. })
  465. // 2. K线图数据(响应式定义)
  466. const chartData = ref({
  467. categories: [],
  468. series: [{
  469. name: '',
  470. data: []
  471. }]
  472. })
  473. //获取K线数据函数(直接定义,无需methods)
  474. // const getServerData1 = () => {
  475. // // 模拟服务器请求延时
  476. // setTimeout(() => {
  477. // const res = {
  478. // "categories": [
  479. // "2025/10/23",
  480. // "2025/10/24",
  481. // "2025/10/27"
  482. // ],
  483. // series: [{
  484. // "name": "贵州茅台",
  485. // "data": [
  486. // [
  487. // 1455.0,
  488. // 1468.8,
  489. // 1447.2,
  490. // 1467.98
  491. // ],
  492. // [
  493. // 1467.95,
  494. // 1478.88,
  495. // 1449.34,
  496. // 1450.0
  497. // ],
  498. // [
  499. // 1440.0,
  500. // 1452.49,
  501. // 1435.99,
  502. // 1440.41
  503. // ]
  504. // ],
  505. // }]
  506. // }
  507. // // 给响应式变量赋值(需修改.value)
  508. // chartData.value = JSON.parse(JSON.stringify(res))
  509. // }, 500)
  510. // }
  511. let unwatch = null;
  512. // 生命周期钩子:组件挂载后执行(替代onReady)
  513. onMounted(async () => {
  514. iSMT.value = uni.getSystemInfoSync().statusBarHeight
  515. getUserInfo()
  516. await handleModels()
  517. unwatch = watch(
  518. () => deepExplorationStore.deepExplorationInfo, // 监听的目标值(函数返回,避免响应式丢失)
  519. (newVal, oldVal) => {
  520. console.log('deepExplorationInfo 变化了:', newVal)
  521. historyData.value = {
  522. ...newVal
  523. }
  524. console.log(historyData.value.wokeFlowData);
  525. console.log('222', historyData.value.stockData.StockInformation);
  526. //工作流数据
  527. const rawMarkdown = historyData.value.wokeFlowData.One.markdown;
  528. const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // 全局替换行首的###
  529. markdownContent.value = adaptedMarkdown;
  530. // markdownContent.value = res.data.markdown
  531. htmlContent.value = marked.parse(markdownContent.value);
  532. //k线
  533. if (historyData.value.stockData.chartData.categories.length > 1) { // 确保至少保留一个日期
  534. historyData.value.stockData.chartData.categories[historyData.value.stockData.chartData.categories.length - 1] = ''; // 删除最后一个日期
  535. }
  536. chartData.value = {
  537. ...JSON.parse(JSON.stringify(historyData.value.stockData.chartData))
  538. }
  539. chartKey.value++;
  540. console.log('chartData', chartData.value);
  541. stockName.value = historyData.value.stockData.StockInformation.Name || 'Tesla Inc.'
  542. stockCode.value = historyData.value.stockData.StockInformation.Code || 'TSLA'
  543. stockTime.value = historyData.value.stockData.StockInformation.Time || '2025/10/29'
  544. stockChange.value = historyData.value.stockData.StockInformation.Zhang || '5.120%'
  545. stockAdd.value = historyData.value.stockData.StockInformation.ZhangFu || '22.410'
  546. stockPrice.value = historyData.value.stockData.StockInformation.Price || '435.900'
  547. currentIndex.value = historyData.value.model-1
  548. }, {
  549. deep: true,
  550. immediate: true
  551. } // 开启深度监听(对象内部属性变化也能触发)
  552. )
  553. })
  554. // 页面加载时执行
  555. onLoad((e) => {
  556. if (e.index) {
  557. // currentIndex.value = e.index - 1
  558. console.log('模块:', currentIndex.value)
  559. }
  560. if (e.stockName) {
  561. searchName.value = e.stockName
  562. console.log('股票名称:', searchName.value)
  563. }
  564. })
  565. </script>
  566. <style scoped lang="scss">
  567. .main {
  568. width: 100%;
  569. min-height: 100vh;
  570. background-color: #fff;
  571. padding-bottom: 120rpx;
  572. .search {
  573. position: relative;
  574. display: flex;
  575. align-items: center;
  576. background-color: #F3F3F3;
  577. width: calc(100% - 60rpx);
  578. height: 80rpx;
  579. border-radius: 50rpx;
  580. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  581. padding: 0 40rpx;
  582. margin: 15rpx 30rpx 0 30rpx;
  583. .seachIcon {
  584. position: absolute;
  585. right: 50rpx;
  586. width: 32rpx;
  587. height: 32rpx;
  588. }
  589. .searchInput {
  590. color: #111;
  591. width: 100%;
  592. }
  593. }
  594. .content {
  595. margin-top: 30rpx;
  596. padding-top: 30rpx;
  597. background-color: rgb(248, 248, 248);
  598. .select {
  599. position: relative;
  600. margin-bottom: -5rpx;
  601. .img {
  602. width: 750rpx;
  603. height: 198rpx;
  604. }
  605. .selectItem {
  606. .btn {
  607. position: absolute;
  608. width: 120rpx;
  609. height: 150rpx;
  610. background-color: transparent;
  611. &::after {
  612. border: none;
  613. }
  614. }
  615. &:nth-of-type(1) .btn {
  616. top: 30rpx;
  617. left: 60rpx;
  618. }
  619. &:nth-of-type(2) .btn {
  620. top: 30rpx;
  621. left: 230rpx;
  622. }
  623. &:nth-of-type(3) .btn {
  624. top: 30rpx;
  625. left: 400rpx;
  626. }
  627. &:nth-of-type(4) .btn {
  628. top: 30rpx;
  629. left: 570rpx;
  630. }
  631. }
  632. }
  633. .graphAndTxt {
  634. background-color: #fff;
  635. border-radius: 50rpx 50rpx 0 0;
  636. padding: 68.6rpx 36.5rpx 0 36.5rpx;
  637. .graph {
  638. border: 1rpx solid #e2e2e2;
  639. border-radius: 30rpx 30rpx 0 0;
  640. .graph_header {
  641. padding: 32rpx 20.5rpx 0 24rpx;
  642. display: flex;
  643. align-items: center;
  644. .left {
  645. color: #333333;
  646. font-family: "PingFang SC";
  647. font-size: 15px;
  648. font-style: normal;
  649. font-weight: 400;
  650. line-height: 15px;
  651. }
  652. .center {
  653. margin-left: 155rpx;
  654. display: flex;
  655. align-items: center;
  656. text {
  657. width: 160rpx;
  658. height: 36rpx;
  659. padding-left: 10rpx;
  660. color: #000000;
  661. white-space: nowrap;
  662. overflow: hidden;
  663. text-overflow: ellipsis;
  664. text-align: center;
  665. font-family: "PingFang SC";
  666. font-size: 18px;
  667. font-style: normal;
  668. font-weight: 500;
  669. line-height: 18px;
  670. }
  671. }
  672. .right {
  673. margin-left: 50rpx;
  674. color: #6a6a6a;
  675. font-family: "PingFang SC";
  676. font-size: 13px;
  677. font-style: normal;
  678. font-weight: 400;
  679. line-height: 15px;
  680. white-space: nowrap;
  681. }
  682. }
  683. .graph_data {
  684. display: flex;
  685. padding: 48rpx 24rpx;
  686. text {
  687. display: flex;
  688. color: #25ba5d;
  689. font-family: "PingFang SC";
  690. font-size: 17px;
  691. line-height: 17px;
  692. }
  693. text:nth-child(2) {
  694. margin-left: 120rpx;
  695. }
  696. text:nth-child(3) {
  697. margin-left: 150rpx;
  698. }
  699. }
  700. .graph_content {
  701. position: relative;
  702. min-height: 500rpx;
  703. image{
  704. position: absolute;
  705. bottom: 20rpx;
  706. right: 30rpx;
  707. width: 48rpx;
  708. height: 48rpx;
  709. }
  710. .charts-box {
  711. width: 100%;
  712. height: 100%;
  713. overflow: visible;
  714. }
  715. }
  716. }
  717. .txt {
  718. background-color: #F3F3F3;
  719. margin-top: 48rpx;
  720. border-radius: 30rpx;
  721. .txtHeader {
  722. padding: 30rpx 24rpx;
  723. image {
  724. width: 20rpx;
  725. height: 20rpx;
  726. }
  727. text {
  728. margin-left: 5rpx;
  729. background-color: #FFFFFF;
  730. color: #000000;
  731. padding: 5rpx 22rpx;
  732. border-radius: 22rpx;
  733. font-size: 28rpx;
  734. font-weight: 400;
  735. line-height: 37rpx;
  736. }
  737. }
  738. .txtContent {
  739. min-height: 300rpx;
  740. padding: 20rpx 30rpx;
  741. margin-bottom: 100rpx;
  742. ::v-deep * {
  743. box-sizing: border-box;
  744. width: 100% !important; // 强制所有解析后的标签占满容器宽度
  745. white-space: normal !important; // 取消强制不换行
  746. word-wrap: break-word !important; // 长词/长数字自动换行
  747. }
  748. // 标题样式(确保换行)
  749. ::v-deep h2 {
  750. font-size: 32rpx;
  751. color: #333;
  752. margin: 25rpx 0 15rpx;
  753. line-height: 1.5;
  754. }
  755. // 段落样式(核心换行控制)
  756. ::v-deep p {
  757. font-size: 26rpx;
  758. color: #666;
  759. margin: 15rpx 0;
  760. line-height: 1.8; // 增加行高,提升可读性
  761. text-align: justify; // 两端对齐,避免单侧参差不齐
  762. }
  763. // 列表样式(纵向排列)
  764. ::v-deep ul,
  765. ::v-deep ol {
  766. margin: 15rpx 0 15rpx 30rpx;
  767. }
  768. ::v-deep li {
  769. margin: 10rpx 0;
  770. line-height: 1.6;
  771. }
  772. // 加载状态样式
  773. .loading {
  774. text-align: center;
  775. padding: 50rpx 0;
  776. color: #666;
  777. font-size: 26rpx;
  778. }
  779. }
  780. }
  781. }
  782. }
  783. .static-footer {
  784. position: fixed;
  785. bottom: 0;
  786. width: 100%;
  787. }
  788. }
  789. * {
  790. box-sizing: border-box;
  791. }
  792. </style>