Compare commits

...

72 Commits

Author SHA1 Message Date
34701892@qq.com ef818b9c22 fix(realtimeInfo): 将日历组件显示月份数从12个月调整为24个月
修改日历组件的monthNum属性,扩展显示范围以满足用户查看更长时间范围的需求
2026-02-02 17:18:13 +08:00
zzp 455aa810c2 feat(新闻信息): 添加日期选择功能并更新API
在新闻信息页面添加日期选择器组件,允许用户选择日期查询新闻
新增getTopNewsAllRelease API接口,支持按日期查询新闻数据
更新页面样式和交互逻辑以支持日期选择功能
2026-01-31 11:25:58 +08:00
34701892@qq.com a00988529d fix(rank): 修复未定义token时的登录弹窗逻辑
处理当Session中token为"undefined"字符串时的异常情况,移除无效token并显示登录弹窗
2026-01-21 13:32:50 +08:00
34701892@qq.com f67fee4aa5 fix: 修正资讯错别字为"精选资讯数量" 2025-12-03 14:47:58 +08:00
34701892@qq.com 2fcead28e6 refactor(article): 优化标签和作者信息显示逻辑
- 格式化标签循环代码,提高可读性
- 添加条件渲染判断,仅在数据存在时显示编辑和二校信息
- 为ETF关联标的添加显示条件判断
2025-12-03 10:53:42 +08:00
34701892@qq.com 431cb67c12 chore: 更新生产环境API地址为正式域名
将测试环境API地址切换为正式线上环境地址,确保生产环境使用正确的服务端点
2025-11-24 08:51:12 +08:00
34701892@qq.com 81c98ce3b2 fix: 修复ETF列表数据合并逻辑并更新开发环境API地址
修复indexEtf.vue中分页加载时相同day数据的合并问题,避免重复数据
更新.env.development中的VITE_API_URL为https://cankao.cs.com.cn/apih5
2025-11-24 08:49:41 +08:00
34701892@qq.com e4196bdc66 fix: 修复ETF详情页跳转链接缺少intoType参数的问题
在跳转到新闻详情页时添加intoType=etf参数,确保正确识别来源
2025-11-22 21:21:09 +08:00
zzp 34d2d5f895 fix: 修复ETF详情页来源显示及跳转问题
修改ETF详情页的来源显示逻辑,根据intoType参数显示固定来源"中国证券报"
添加ETF关联标的点击跳转功能
更新开发环境接口地址配置
2025-11-22 15:48:02 +08:00
zzp 62a3180714 fix(环境配置): 更新开发环境API地址
style(ETF页面): 调整样式布局和导航方法
- 修改indexEtfInfo.vue的返回方法为doBack
- 优化indexEtf.vue的搜索框和列表样式
- 统一组件属性换行格式
2025-11-21 11:01:37 +08:00
zzp 1e56d7c8f9 fix: 修复文章来源显示默认值及优化标签样式
修复文章组件中来源标签未定义时显示默认值"中国证券报"的问题
优化标签显示样式,移除冗余代码并简化模板结构
2025-11-21 10:31:26 +08:00
zzp 995f682ab8 chore: 更新开发环境API地址配置
将VITE_API_URL切换回123.60.153.169服务器地址,注释掉vicp.fun的临时地址
2025-11-21 10:23:50 +08:00
34701892@qq.com ea590f45b6 refactor(article): 调整编辑信息显示位置并添加二校信息
将编辑信息从顶部移至底部,并添加二校信息显示。同时调整相关元素的间距,使布局更合理。
2025-11-20 18:47:59 +08:00
34701892@qq.com 6dcc946e1c feat(ETF): 新增ETF详情页面及接口
- 添加fetchEtfDetail接口用于获取ETF详情数据
- 创建indexEtfInfo页面展示ETF详情信息
- 在indexEtf页面添加跳转到详情页功能
- 调整.env.development中的API地址配置
- 优化indexEtf页面样式和加载逻辑
2025-11-20 18:38:16 +08:00
34701892@qq.com 2b20a82484 feat(新闻详情): 添加摘要图标和AI关联标的展示
- 在新闻摘要前添加摘要图标
- 新增AI关联标的展示区域
- 为ETF列表项添加点击跳转功能
- 优化样式细节和代码格式
2025-11-20 14:08:28 +08:00
34701892@qq.com 6a0db7df63 feat(资讯页面): 实现资讯列表分页加载和搜索功能
- 添加分页加载逻辑,支持上拉加载更多
- 重构搜索功能,整合搜索和自定义搜索事件
- 优化资讯列表显示,使用格式化后的时间字符串
- 调整退出登录按钮样式和位置
2025-11-20 13:46:35 +08:00
34701892@qq.com 8c3b5c825f feat(资讯页): 添加搜索功能并优化样式布局
- 替换静态搜索框为可交互的u-search组件
- 调整标题位置和z-index防止遮挡
- 优化资讯标题过长时的显示效果
- 统一调整页面元素间距和位置
- 修复来源文本格式问题
2025-11-20 09:41:42 +08:00
34701892@qq.com 4c647c7d59 feat(实时信息页): 更新ETF页面banner标题图片并移除副标题
- 将banner_title2.png替换为banner_title3.png
- 移除"挖掘投资核心价值,提供决策先手信息"文本
- 调整banner标题图片尺寸
2025-11-20 09:28:20 +08:00
34701892@qq.com 967f2171c8 feat(ETF指数): 添加获取ETF指数列表功能
- 新增getEtfIndexList API接口
- 在indexEtf.vue页面中调用该接口获取数据
- 调整开发环境API地址配置
2025-11-20 09:24:35 +08:00
34701892@qq.com 718d74e41b feat(资讯): 新增ETF资讯页面及相关资源
- 添加indexEtf.vue页面组件,展示ETF资讯列表
- 新增页面路由配置
- 添加相关图片资源(banner、搜索图标、时间图标)
- 移除RankList组件中的调试console.log
2025-11-19 17:18:13 +08:00
34701892@qq.com 8dd919e8b0 refactor(rank.vue): 替换搜索输入框为自定义样式组件
将原有的u-input组件替换为自定义样式的div和input组合,以提供更灵活的样式控制和更好的用户体验
2025-11-10 10:51:04 +08:00
34701892@qq.com 8bead115f5 fix: 修复编辑精选页时间显示格式问题并添加搜索功能
添加formatTime函数处理时间戳格式,确保编辑精选页的时间显示正确
为搜索输入框添加回车和失焦事件触发搜索
更新开发环境API地址为正式环境
2025-11-10 10:13:15 +08:00
34701892@qq.com 11a885d039 fix: 更新生产环境API地址并优化登录处理逻辑
- 将生产环境API地址切换为正式域名
- 修改登录失效处理方式为页面刷新而非跳转
- 优化rank.vue页面布局和路由参数处理
- 移除登录页面的token参数
2025-11-09 22:56:18 +08:00
zzp 3ab1dfae30 fix(路由): 清除URL中的token参数并保留其他查询参数
当URL中包含token参数时,自动清除该参数并保留其他查询参数,防止token暴露在URL中
2025-11-08 17:53:00 +08:00
zzp d25f87a889 fix(realtimeInfo): 修复页面导航和登录逻辑问题
修复导航菜单条件渲染错误,优化登录流程处理token逻辑
移除多余的空行和console.log,格式化代码样式
2025-11-08 16:54:18 +08:00
zzp a9eef0d69f feat: 实现退出登录时调用后端接口
在多个组件和工具文件中添加了doLogout调用,确保用户退出时通知后端
更新环境配置文件中的API地址
2025-11-08 12:05:24 +08:00
34701892@qq.com a464d256a2 fix: 修复token验证逻辑并修正接口路径
修复路由token验证逻辑,增加加载状态和错误处理
修正sendToken接口路径错误
2025-11-06 20:46:30 +08:00
34701892@qq.com e6beded4de feat(财保): 添加财保token转发接口及处理逻辑
添加sendToken接口用于转发财保token,并在页面加载时检查并处理token参数
2025-11-06 20:09:37 +08:00
34701892@qq.com 365b770a50 fix(rank.vue): 移除调试日志并优化关键词高亮样式
- 删除getNewsList中的console.log调试输出
- 将关键词高亮颜色从红色改为#007aff
- 对标题也添加关键词高亮处理
2025-11-06 19:35:11 +08:00
34701892@qq.com 69aec22ab6 fix(页面布局): 修复文本溢出问题并优化导航栏显示逻辑
添加CSS样式防止文本溢出容器
修改PageTop组件导航栏显示条件
移除多余空行
2025-11-06 19:25:23 +08:00
34701892@qq.com c0a6629310 feat: 更新编辑精选功能并优化资讯展示
- 修改编辑精选接口路径
- 启用编辑精选菜单项
- 优化资讯列表和详情页的标签展示逻辑
- 添加关键词高亮功能
- 更新开发环境API地址
2025-11-06 19:15:30 +08:00
34701892@qq.com 258444e317 refactor: 优化代码格式并移除无用功能
- 格式化 RankList.vue 和 realtimeInfo/index.vue 中的代码
- 移除 PageTop.vue 中未使用的"编辑精选"菜单项
- 调整资讯列表的 limit_num 参数从 20 改为 1000
2025-11-06 11:24:23 +08:00
34701892@qq.com 9bbf2c10b3 feat(资讯): 添加编辑精选功能及相关组件
- 新增 Element Plus UI 库依赖
- 添加编辑精选接口及页面路由
- 实现编辑精选列表展示及搜索功能
- 在资讯页面顶部添加编辑精选入口
- 为编辑精选列表添加分页功能
2025-11-05 16:39:19 +08:00
zzp 383db107da style: 格式化 Vue 文件中的 HTML 标签和属性 2025-10-29 11:54:15 +08:00
34701892@qq.com 19b2583c57 fix: 将固定日期替换为动态计算最近7天的日期范围 2025-10-24 16:01:06 +08:00
zzp 69fffec976 feat(资讯排行): 添加按日获取头条资讯功能并优化列表展示
- 在newsInfo.ts中新增getTopNewsDay接口用于获取每日头条资讯
- 修改rank.vue使用新接口并简化模板代码
- 移除冗余的模板逻辑,保持代码简洁
2025-09-28 10:02:34 +08:00
34701892@qq.com f91fc47e2a feat(埋点): 添加点赞和登录的埋点记录功能
在点赞和登录功能中添加aplus_queue埋点记录,分别记录点赞/取消点赞和登录事件
2025-09-27 18:07:47 +08:00
34701892@qq.com 6aed6ace2d fix: 恢复新闻详情页底部评论组件显示 2025-09-27 17:56:28 +08:00
34701892@qq.com 653f9a8f5e Merge branch 'H5back' of https://gitee.com/zzpaym/zhongzheng-sample-clear-h5 into H5back 2025-09-27 17:54:49 +08:00
34701892@qq.com f4ceec3c7a feat(analytics): 添加阿里云日志服务埋点上报功能
在多个页面添加aplus埋点上报逻辑,包括PV和自定义事件上报
在index.html中添加阿里云日志服务SDK初始化配置
2025-09-27 17:54:47 +08:00
zzp 18ed8d531a fix(实时信息): 修复日历组件默认日期和响应式日期问题
将minDate和maxDate改为ref响应式变量
添加日历组件的default-date属性和key绑定
2025-09-23 13:17:55 +08:00
zzp 680f074c37 fix(资讯页面): 修复日历组件日期范围及样式问题
调整日历组件的最小日期为当前日期,修复日期格式不一致问题。优化页面多个视图容器的样式,移除冗余代码并统一格式。修改日期选择逻辑,确保时间格式统一。
2025-09-23 12:55:32 +08:00
34701892@qq.com 654b908f16 feat(资讯头条): 优化日期选择功能并显示当前选中日期
- 在日历图标旁显示当前选中的日期
- 调整日期选择范围从10天增加到20天
- 修复日期选择后的格式问题,确保包含时间信息
- 移除日历组件的range模式限制
2025-09-22 21:55:51 +08:00
34701892@qq.com 0c9a07e76d refactor(资讯页面): 优化布局样式并调整数据初始化顺序
调整页面元素的样式布局以提高可读性,将数据初始化逻辑重新排序以优化加载流程
2025-09-22 21:26:45 +08:00
zzp 3129d239a6 feat(资讯头条): 添加日期筛选功能并修改API请求参数
在资讯头条页面添加日历组件,允许用户选择日期范围进行筛选。同时修改getTopNews API请求参数,支持按日期范围查询数据。新增时间格式化工具函数用于处理日期参数。
2025-09-22 14:28:09 +08:00
zzp 36d03f14f5 feat(实时资讯): 在资讯列表上方添加"资讯头条 Top20"标题
增加标题以明确显示资讯列表的内容分类,提升用户体验
2025-09-22 13:39:53 +08:00
zzp b7f4539e63 fix: 修复JSON解析错误并恢复API端点
修复RankList组件中JSON.parse可能抛出异常的问题,添加try-catch处理
恢复newsInfo.ts中getTopNews的原始API端点
2025-09-17 15:33:46 +08:00
zzp d1d09f76f9 Merge branch 'H5back' of https://gitee.com/zzpaym/zhongzheng-sample-clear-h5 into H5back 2025-09-17 14:52:21 +08:00
zzp a775247a9f feat(时间格式化): 添加自定义时间格式化函数并替换dayjs使用
添加timeFormat函数用于更灵活地处理时间格式化,支持多种格式和不同时间戳类型
移除dayjs依赖,使用原生Date对象实现时间格式化功能
2025-09-17 14:52:18 +08:00
34701892@qq.com 8ce73d4bda refactor(组件): 优化代码格式并移除未使用的评论代码
- 在articleList组件中格式化HTML结构并移除被注释的列表项内容
- 在搜索页面简化输入组件结构并调整登录验证逻辑
- 统一代码缩进和样式格式
2025-09-15 20:09:46 +08:00
zzp df0b47d766 fix(articleList): 修复未登录状态下标题显示问题并优化登录状态获取
- 将未登录状态下的标题显示从text标签改为div并使用v-html渲染完整标题
- 修改登录状态获取方式,使用Session存储替代uni.getStorageSync
2025-09-15 13:31:18 +08:00
zzp 2a851c74a0 feat(图表): 为LineHol组件添加barColor属性并优化页面布局
- 在LineHol和LineHolYellow组件中新增barColor属性,支持自定义柱状图颜色
- 调整indexRelease.vue页面布局,移除部分注释代码
- 修改顶部导航标题为"编辑精选"
- 优化搜索跳转逻辑,使用Session替代uni.getStorageSync
2025-09-15 10:05:48 +08:00
34701892@qq.com 28409ef3b2 feat: 更新实时信息页面标题图片
添加新的标题图片banner_title2.png并替换原有图片
2025-09-13 20:26:45 +08:00
34701892@qq.com 9c62ac9ca3 fix: 修复API参数错误和图表初始化逻辑
修复newsInfo.ts中getTopSourcePeriod方法的参数名错误,将data.start_date改为data.start_time
优化LineHolYellow.vue图表组件,添加props.data的watch监听并移除mounted中的直接初始化
修正indexRelease.vue中行业和概念数据获取方法的调用错误
2025-09-13 20:02:14 +08:00
zzp ef3c530df5 refactor(页面布局): 重构实时资讯页面布局,将热度统计和搜索功能移至发布版本
- 将7天热度统计图表和相关功能从index.vue移至indexRelease.vue
- 在RankList组件中添加hasTag属性控制标签显示
- 清理未使用的代码和样式
- 更新API注释说明各接口用途
2025-09-13 15:05:05 +08:00
zzp 579f4c1390 style: 统一使用 #3C74F1 作为主色调
- 将实时信息页面的激活状态边框和背景色改为 #3C74F1
- 更新折线图组件的颜色配置,使用 #3C74F1 替代原有颜色
- 添加备用颜色列表并注释掉未使用的颜色函数
2025-09-12 16:57:40 +08:00
zzp 3a29305df7 feat(图表): 优化图表组件并添加动态数据支持
- 修改Line.vue组件,修复默认值格式和优化数据反转逻辑
- 更新newsInfo.ts API,修改热门标签/行业/来源的请求参数拼接方式
- 重构LineHol.vue组件,移除硬编码数据,支持动态数据绑定和样式优化
- 在realtimeInfo页面添加7天热度统计功能,支持不同标签切换
- 改进LineHolYellow.vue组件,支持动态数据并优化图表样式
2025-09-12 16:20:38 +08:00
zzp 2e68592cf1 feat(api): 新增热门标签时间段内topN列表接口
添加三个新接口用于获取不同维度(概念、行业、来源)的热门标签在特定时间段内的topN列表
2025-09-12 15:16:47 +08:00
zzp f9bd02af3c feat(新闻列表): 添加概念和行业标签展示并更新API端点
在RankList组件中添加概念标签和行业标签的展示区域,使用不同样式区分两种标签。同时更新新闻API端点从"/top_news_h5_d"改为"/top_news_release_h5_all"以获取更多数据。

修改watch逻辑,将返回数据中的concept_label和industry_label字段解析为数组格式并合并到列表项中。
2025-09-12 10:40:08 +08:00
zzp cabde71e62 feat(页面布局): 优化搜索页面和实时资讯页面的布局样式
- 在搜索页面添加返回按钮并调整输入框样式
- 重新设计实时资讯页面的搜索区域布局
- 新增index2.vue组件用于文章列表展示
- 调整多个页面的间距和边距样式
2025-09-12 10:10:07 +08:00
zzp 7d93c48a1e refactor(搜索页面): 优化搜索页面布局和交互逻辑
重构搜索页面样式,调整搜索框宽度和样式
添加搜索按钮并实现搜索确认功能
修改搜索结果为空时的显示样式
优化搜索结果跳转逻辑,增加登录判断
移除无用代码和注释
2025-09-12 09:57:38 +08:00
zzp 643f49a72f feat(实时信息): 添加搜索跳转功能并检查登录状态
添加goSreach函数用于跳转到搜索页面,在跳转前检查用户token状态
2025-09-12 09:55:31 +08:00
zzp 885109158d refactor(realtimeInfo): 调整搜索栏位置并优化样式
将搜索栏从banner区域移至内容区域,并修改相关样式。移除绝对定位,添加背景图片,调整高度和间距以改善布局。
2025-09-12 09:51:37 +08:00
zzp 725f4eb9af feat(实时资讯): 添加搜索栏组件及样式
实现实时资讯页面的搜索功能,包含logo和搜索框的布局与样式
2025-09-12 09:40:07 +08:00
zzp 9e2f08bbc2 fix: 修复周热度统计图表显示条件逻辑
添加对lineTabIndex为1时的图表显示支持,确保所有可能的tab状态都有对应的图表组件显示
2025-09-12 09:35:35 +08:00
zzp 4f5682c80a feat(实时资讯): 新增周热度统计图表组件及交互功能
添加LineHol和LineHolYellow图表组件用于展示周热度统计数据
实现行业、概念标签和媒体来源的tab切换功能
优化页面布局和样式,调整部分标题文字
2025-09-11 20:21:53 +08:00
zzp 2204df2614 Merge branch 'H5back' of https://gitee.com/zzpaym/zhongzheng-sample-clear-h5 into H5back 2025-09-09 15:20:12 +08:00
zzp bb5520b32c feat(实时信息): 添加首页banner和标签展示区域
- 新增顶部banner区域,包含背景图和标题
- 添加行业分类和概念标签的统计展示卡片
- 引入资讯评分分布区间图表组件
- 保留原有的排行榜列表功能
2025-09-09 15:19:36 +08:00
34701892@qq.com fb9df08f1e feat(实时信息): 添加顶部banner区域和标签展示组件
- 新增顶部banner区域,包含背景图片和标题
- 添加行业分类和概念标签的展示组件
- 引入资讯评分分布区间图表和头条榜展示
- 优化页面布局和样式
2025-09-06 16:20:06 +08:00
34701892@qq.com de20b194f0 feat(登录): 添加登录状态判断及内容模糊效果
实现未登录状态下内容模糊显示功能,添加登录弹窗组件及相关回调处理。同时优化部分页面样式布局。

- 在indexNewsInfo.vue中添加登录状态判断及模糊效果
- 引入LoginPopup组件处理登录逻辑
- 优化realtimeInfo.vue页面布局和样式
2025-09-05 20:27:06 +08:00
zzp c2d8a180af feat(资讯): 新增获取全部热门资讯接口并修复列表显示逻辑
添加获取全部热门资讯的接口getTopNewsAll,替换原有接口
修复RankList组件中资讯评分显示条件错误的问题
当needExp为false时自动展开列表
2025-09-04 17:35:10 +08:00
zzp 413d374786 feat(实时资讯): 新增已发布资讯列表页面及接口
- 添加已发布资讯列表页面 indexRelease.vue
- 新增获取已发布列表的接口 getReleaseList
- 修改 RankList 组件支持隐藏展开按钮
- 在 pages.json 中注册新页面路由
2025-09-04 16:22:13 +08:00
37 changed files with 3430 additions and 422 deletions

View File

@ -3,9 +3,9 @@ ENV = development
# 本地环境接口地址 # 本地环境接口地址
# VITE_API_URL = http://123.60.153.169:8040/apih5 # VITE_API_URL = http://123.60.153.169:8040/apih5
# VITE_API_URL = https://4155gf93ll13.vicp.fun/apih5 # VITE_API_URL = http://4155gf93ll13.vicp.fun/apih5
# VITE_API_URL = http://123.60.79.143:8041/apih5 # VITE_API_URL = http://123.60.79.143:8041/apih5
# VITE_API_URL =http://ukfba3.natappfree.cc/apih5 # VITE_API_URL =http://192.168.0.135:8040/apih5
VITE_API_URL = https://cankao.cs.com.cn/apih5 VITE_API_URL = https://cankao.cs.com.cn/apih5
VITE_API_DATAV_URL = https://cankao.cs.com.cn/zzck_datav VITE_API_DATAV_URL = https://cankao.cs.com.cn/zzck_datav

View File

@ -32,6 +32,43 @@
<body> <body>
<div id="app"><!--app-html--></div> <div id="app"><!--app-html--></div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
<script>
(function (w, d, s, q, i) {
w[q] = w[q] || [];
var f = d.getElementsByTagName(s)[0], j = d.createElement(s);
j.async = true;
j.id = 'beacon-aplus';
j.src = 'https://d.alicdn.com/alilog/mlog/aplus/' + i + '.js';
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'aplus_queue', '203467608');
//集成应用的appKey
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['appKey', '68d7b06e8560e34872b9f3a7']
});
/************************以下内容为可选配置内容****************************/
//sdk提供手动pv发送机制启用手动pv(即关闭自动pv)需设置aplus-waiting=MAN;
//注意由于单页面路由改变时不会刷新页面无法自动发送pv所以对于单页应用强烈建议您关闭自动PV, 手动控制PV事件
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['aplus-waiting', 'MAN']
});
//是否开启调试模式
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['DEBUG', true]
});
//是否指定用作计算umid的id类型默认为cnaid目前支持:
//1. 微信和QQ: openid; 字节和百度 anonymousid; 支付宝 alipay_id
//2. 微信、QQ、字节、百度平台的 unionid
//3. 业务方自己生成的随机id uuid
// aplus_queue.push({
// action: 'aplus.setMetaInfo',
// arguments: ['aplus-idtype', 'xxxx'] //取值参考见附表1
// });
</script>
<!-- <script type="text/javascript"> <!-- <script type="text/javascript">
var link = location.href.split("#")[0]; var link = location.href.split("#")[0];
console.log("🚀 ~ link:", link); console.log("🚀 ~ link:", link);

164
package-lock.json generated
View File

@ -26,6 +26,7 @@
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"dayjs": "^1.11.9", "dayjs": "^1.11.9",
"echarts": "^5.6.0", "echarts": "^5.6.0",
"element-plus": "^2.11.7",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"js-md5": "^0.8.3", "js-md5": "^0.8.3",
"pinia": "^2.0.36", "pinia": "^2.0.36",
@ -1785,6 +1786,14 @@
"license": "MIT", "license": "MIT",
"peer": true "peer": true
}, },
"node_modules/@ctrl/tinycolor": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
"integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
"engines": {
"node": ">=10"
}
},
"node_modules/@dcloudio/types": { "node_modules/@dcloudio/types": {
"version": "3.3.3", "version": "3.3.3",
"resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.3.3.tgz", "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.3.3.tgz",
@ -2237,6 +2246,14 @@
"vite": "^4.0.0" "vite": "^4.0.0"
} }
}, },
"node_modules/@element-plus/icons-vue": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
"integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==",
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.16.17", "version": "0.16.17",
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz", "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz",
@ -2567,6 +2584,28 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@floating-ui/core": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
"dependencies": {
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
"integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
"dependencies": {
"@floating-ui/core": "^1.7.3",
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
},
"node_modules/@intlify/core-base": { "node_modules/@intlify/core-base": {
"version": "9.1.9", "version": "9.1.9",
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz", "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz",
@ -3898,6 +3937,16 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@popperjs/core": {
"name": "@sxzz/popperjs-es",
"version": "2.11.7",
"resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rollup/pluginutils": { "node_modules/@rollup/pluginutils": {
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
@ -4073,6 +4122,19 @@
"license": "MIT", "license": "MIT",
"peer": true "peer": true
}, },
"node_modules/@types/lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA=="
},
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "24.0.4", "version": "24.0.4",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-24.0.4.tgz", "resolved": "https://registry.npmmirror.com/@types/node/-/node-24.0.4.tgz",
@ -4106,6 +4168,11 @@
"license": "MIT", "license": "MIT",
"peer": true "peer": true
}, },
"node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
},
"node_modules/@types/yargs": { "node_modules/@types/yargs": {
"version": "16.0.9", "version": "16.0.9",
"resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.9.tgz", "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.9.tgz",
@ -4506,6 +4573,39 @@
} }
} }
}, },
"node_modules/@vueuse/core": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz",
"integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.13.0",
"@vueuse/shared": "9.13.0",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/metadata": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
"integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
"dependencies": {
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@webassemblyjs/ast": { "node_modules/@webassemblyjs/ast": {
"version": "1.14.1", "version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz", "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz",
@ -4925,6 +5025,11 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"dev": true "dev": true
}, },
"node_modules/async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
},
"node_modules/asynckit": { "node_modules/asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
@ -5853,9 +5958,9 @@
} }
}, },
"node_modules/dayjs": { "node_modules/dayjs": {
"version": "1.11.9", "version": "1.11.19",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
"integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="
}, },
"node_modules/de-indent": { "node_modules/de-indent": {
"version": "1.0.2", "version": "1.0.2",
@ -6039,6 +6144,30 @@
"integrity": "sha512-HE43yYdUUiJVjewV2A9EP8o89Kb4AqMKplMQP2IxEPUws1Etu/ZkdsgUDabUZ/WmbP4ZbvJDOcunvbBUPPIfmw==", "integrity": "sha512-HE43yYdUUiJVjewV2A9EP8o89Kb4AqMKplMQP2IxEPUws1Etu/ZkdsgUDabUZ/WmbP4ZbvJDOcunvbBUPPIfmw==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/element-plus": {
"version": "2.11.7",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.11.7.tgz",
"integrity": "sha512-Bh47wuzsqaNBNDkbtlOlZER1cGcOB8GsXp/+C9b95MOrk0wvoHUV4NKKK7xMkfYNFYdYysQ752oMhnExgAL6+g==",
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.3.2",
"@floating-ui/dom": "^1.0.1",
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
"@types/lodash": "^4.17.20",
"@types/lodash-es": "^4.17.12",
"@vueuse/core": "^9.1.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.18",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-unified": "^1.0.3",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/emittery": { "node_modules/emittery": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz", "resolved": "https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz",
@ -9635,9 +9764,22 @@
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true, "license": "MIT"
"license": "MIT", },
"peer": true "node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
},
"node_modules/lodash-unified": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
"integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
"peerDependencies": {
"@types/lodash-es": "*",
"lodash": "*",
"lodash-es": "*"
}
}, },
"node_modules/lodash.camelcase": { "node_modules/lodash.camelcase": {
"version": "4.3.0", "version": "4.3.0",
@ -9729,6 +9871,11 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
"node_modules/merge": { "node_modules/merge": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz", "resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz",
@ -9942,6 +10089,11 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/normalize-wheel-es": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
"integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
},
"node_modules/npm-run-path": { "node_modules/npm-run-path": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz", "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz",

View File

@ -57,6 +57,7 @@
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"dayjs": "^1.11.9", "dayjs": "^1.11.9",
"echarts": "^5.6.0", "echarts": "^5.6.0",
"element-plus": "^2.11.7",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"js-md5": "^0.8.3", "js-md5": "^0.8.3",
"pinia": "^2.0.36", "pinia": "^2.0.36",

View File

@ -55,10 +55,38 @@ export const getUnlockList = (data: any) => {
return Request.post("/user/unlockList", data); return Request.post("/user/unlockList", data);
}; };
// 全文搜索 // 全文搜索
//
export const searchNews = (data: any) => { export const searchNews = (data: any) => {
return Request.post("/news/search", data); return Request.post("/news/search", data);
}; };
// 已发布列表
export const getReleaseList = (data: any) => {
return Request.post("/news/top_news_release_h5_d", data);
};
// 编辑精选接口
export const editTopNews = (data: any) => {
return Request.post("/news/list/published", data);
};
// 编辑精选接口
export const sendToken = (data: any) => {
return Request.post("/common/forward/financial", data);
};
// 退出登录
export const doLogout = (data: any) => {
console.log("🚀 ~ doLogout ~ data:", data);
return Request.post("/common/logout", data);
};
// 退出登录
export const getEtfIndexList = (data: any) => {
return Request.post("/news/etfIndexList", data);
};
// 获取ETF详情
export const fetchEtfDetail = (data: any) => {
return Request.post("/news/etfList", data);
};

View File

@ -16,10 +16,27 @@ export const getConceptCount = (data: any) => {
}; };
// 概念标签贴标 // 概念标签贴标
export const getTopNews = (data: any) => { export const getTopNewsDay = (data: any) => {
// return request.get("/top_news_h5_period?start_date=" + data.start_date + "&end_date=" + data.end_date + "&limit_num=" + data.limit_num, data);
return request.get("/top_news_h5_d", data); return request.get("/top_news_h5_d", data);
}; };
// 概念标签贴标
export const getTopNews = (data: any) => {
return request.get("/top_news_h5_period?start_date=" + data.start_date + "&end_date=" + data.end_date + "&limit_num=" + data.limit_num, data);
// return request.get("/top_news_h5_d", data);
};
// 概念标签贴标
export const getTopNewsAll = (data: any) => {
return request.get("/top_news_release_h5_all", data);
// return request.get("/news_release_ratingrank_h5_d", data);
};
// 概念标签贴标 release
export const getTopNewsAllRelease = (data: any) => {
return request.get("/news_release_ratingrank_h5_d?input_date=" + data.input_date + "&limit_num=10");
};
// 热门行业top10 // 热门行业top10
export const getTopIndustry_d = (data: any) => { export const getTopIndustry_d = (data: any) => {
return request.get("/top_industry_d", data); return request.get("/top_industry_d", data);
@ -34,3 +51,17 @@ export const getTopConcept_d = (data: any) => {
export const getNews_cnt_d = (data: any) => { export const getNews_cnt_d = (data: any) => {
return request.get("/news_cnt_d", data); return request.get("/news_cnt_d", data);
}; };
// 热门标签某时间段内topN列表左边第一个
export const getTopConceptPeriod = (data: any) => {
return request.get("/top_concept_period?start_date=" + data.start_time + "&end_date=" + data.end_time + "&limit_num=" + data.limit_num, data);
};
// 热门行业某时间段内topN列表中间第二个
export const getTopIndustryPeriod = (data: any) => {
return request.get("/top_industry_period?start_date=" + data.start_time + "&end_date=" + data.end_time + "&limit_num=" + data.limit_num, data);
};
// 热门标签某时间段内topN列表右边
export const getTopSourcePeriod = (data: any) => {
return request.get("/top_source_period?start_date=" + data.start_time + "&end_date=" + data.end_time + "&limit_num=" + data.limit_num, data);
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -6,7 +6,7 @@
<text class="date">({{ dayjs(new Date().getTime()).format("MM/DD") }})</text> <text class="date">({{ dayjs(new Date().getTime()).format("MM/DD") }})</text>
</view> </view>
<text class="sub_title">评分80分以上精选咨洵数量</text> <text class="sub_title">评分80分以上精选资讯数量</text>
</view> </view>
<view class="right"> <view class="right">
<!-- <text class="num">{{ count }}</text> --> <!-- <text class="num">{{ count }}</text> -->

View File

@ -1,19 +1,8 @@
<template> <template>
<view class="news-rank-list"> <view class="news-rank-list">
<u-skeleton <u-skeleton rows="5" title loading style="margin-bottom: 30rpx" v-if="loading"></u-skeleton>
rows="5"
title
loading
style="margin-bottom: 30rpx"
v-if="loading"
></u-skeleton>
<view class="list" v-else> <view class="list" v-else>
<view <view v-for="(item, index) in rankListLocal" :key="index" class="news-item" @click="goDetail(item, 0)">
v-for="(item, index) in rankListLocal"
:key="index"
class="news-item"
@click="goDetail(item, 0)"
>
<view class="rank-tag"> <view class="rank-tag">
<view v-if="index == 0" class="rank-text-top3"> <view v-if="index == 0" class="rank-text-top3">
<img src="@/assets/zixun/ranking_icon_1.png" /> <img src="@/assets/zixun/ranking_icon_1.png" />
@ -27,46 +16,63 @@
<text class="rank-text" v-else>{{ index + 1 }}</text> <text class="rank-text" v-else>{{ index + 1 }}</text>
</view> </view>
<view <view class="news-content" :style="{ filter: Session.get('token') ? '' : 'blur(5px)' }">
class="news-content"
:style="{ filter: Session.get('token') ? '' : 'blur(5px)' }"
>
<text class="news-title">{{ item.title }}</text> <text class="news-title">{{ item.title }}</text>
<text class="news-desc">{{ item.summary }}</text> <text class="news-desc">{{ item.summary }}</text>
<!-- 两个标签 start -->
<view class="r_r_tags" v-if="hasTag">
<view style="display: flex; margin-top: 20rpx; overflow-x: auto; width: 95vw">
<view class="r_tags">
<view class="tag" style="background-color: #fff9ec; color: #ffb100"
v-for="(item, index) in item.conceptLabels" :key="index">{{
item
}}</view>
</view>
</view>
<view style="display: flex; margin-top: 20rpx; overflow-x: auto; width: 100vw">
<view class="r_tags">
<view class="tag" style="background-color: #f5f8fe; color: #007aff"
v-for="(item, index) in item.industryLabels" :key="index">{{
item
}}</view>
</view>
</view>
</view>
<!-- 两个标签 end -->
<view class="news-meta"> <view class="news-meta">
<view> <view>
<text class="source">{{ item.source }}</text> <text class="source">{{ item.source }}</text>
<text class="time">{{ <!-- <text class="time">{{ dayjs(item.publish_time).format("YYYY-MM-DD HH:MM:ss") }}</text> -->
dayjs(item.publish_time).format("YYYY-MM-DD HH:MM:ss") <!-- .format('YYYY-MM-DD HH:mm:ss'); -->
}}</text> <text class="time">
{{ timeFormat(new Date(item.publish_time).getTime()) }}
</text>
</view> </view>
<text class="score"> <text class="score" v-if="needExp">
<text v-if="index < 3">资讯评分</text> <text v-if="index < 3">资讯评分</text>
{{ item.news_score }}</text {{ item.news_score }}</text>
>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view @click="isExp = !isExp" class="r_exp"> <view @click="isExp = !isExp" class="r_exp" v-if="needExp">
<text v-if="isExp">收起</text> <text v-if="isExp">收起</text>
<text v-else>展开全部</text> <text v-else>展开全部</text>
<img src="@/assets/zixun/up_icon.png" class="exp_up" v-if="isExp" /> <img src="@/assets/zixun/up_icon.png" class="exp_up" v-if="isExp" />
<img src="@/assets/zixun/down_icon.png" class="exp_up" v-else /> <img src="@/assets/zixun/down_icon.png" class="exp_up" v-else />
</view> </view>
<LoginPopup <LoginPopup :show="LoginShow" @handlePopupClose="handlePopupClose"
:show="LoginShow" @handlePopupSuccessCallback="handlePopupSuccessCallback" @handlePopupErrorCallback="handlePopupErrorCallback" />
@handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback"
@handlePopupErrorCallback="handlePopupErrorCallback"
/>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from "vue"; import { ref, watch, computed } from "vue";
import dayjs from "dayjs/esm/index"; import dayjs from "dayjs/esm/index";
import LoginPopup from "@/components/loginPopup/index.vue"; import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
@ -83,8 +89,17 @@ watch(
if (!isExp.value && index > 9) { if (!isExp.value && index > 9) {
return; return;
} }
let concept_label = "";
rankListLocal.value.push(item); let industry_label = "";
try {
concept_label = JSON.parse(item.concept_label);
industry_label = JSON.parse(item.industry_label);
} catch (e) { }
rankListLocal.value.push({
...item,
conceptLabels: concept_label,
industryLabels: industry_label,
});
}); });
loading.value = false; loading.value = false;
@ -94,13 +109,26 @@ watch(
watch( watch(
() => props.newsList, () => props.newsList,
(newValue, oldValue) => { (newValue, oldValue) => {
if (!props.needExp) {
isExp.value = true;
}
rankListLocal.value = []; rankListLocal.value = [];
props.newsList.forEach((item, index) => { props.newsList.forEach((item, index) => {
if (!isExp.value && index > 9) { if (!isExp.value && index > 9) {
return; return;
} }
let concept_label = "";
let industry_label = "";
try {
concept_label = JSON.parse(item.concept_label);
industry_label = JSON.parse(item.industry_label);
} catch (e) { }
rankListLocal.value.push(item); rankListLocal.value.push({
...item,
conceptLabels: concept_label,
industryLabels: industry_label,
});
}); });
loading.value = false; loading.value = false;
} }
@ -113,6 +141,14 @@ const props = defineProps({
required: true, required: true,
default: () => [], default: () => [],
}, },
needExp: {
type: Boolean,
default: true,
},
hasTag: {
type: Boolean,
default: false,
},
}); });
const clickItem = ref({}); const clickItem = ref({});
@ -147,6 +183,54 @@ const handlePopupSuccessCallback = () => {
const handlePopupErrorCallback = () => { const handlePopupErrorCallback = () => {
console.log("登录失败"); console.log("登录失败");
}; };
/**
* @description 格式化时间
* @param {String|Number} dateTime 需要格式化的时间戳
* @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
* @returns {string} 返回格式化后的字符串
*/
function timeFormat(dateTime = null, formatStr = "yyyy-mm-dd hh:MM:ss") {
let date;
//
if (!dateTime) {
date = new Date();
}
// unix
else if (/^\d{10}$/.test(dateTime.toString().trim())) {
date = new Date(dateTime * 1000);
}
// new Date
else if (typeof dateTime === "string" && /^\d+$/.test(dateTime.trim())) {
date = new Date(Number(dateTime));
}
// RFC 2822
else {
// Safari/Webkitnew Date/
date = new Date(typeof dateTime === "string" ? dateTime.replace(/-/g, "/") : dateTime);
}
const timeSource = {
y: date.getFullYear().toString(), //
m: (date.getMonth() + 1).toString().padStart(2, "0"), //
d: date.getDate().toString().padStart(2, "0"), //
h: date.getHours().toString().padStart(2, "0"), //
M: date.getMinutes().toString().padStart(2, "0"), //
s: date.getSeconds().toString().padStart(2, "0"), //
//
};
for (const key in timeSource) {
const [ret] = new RegExp(`${key}+`).exec(formatStr) || [];
if (ret) {
//
const beginIndex = key === "y" && ret.length === 2 ? 2 : 0;
formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex));
}
}
return formatStr;
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -223,11 +307,16 @@ const handlePopupErrorCallback = () => {
text-align: left; text-align: left;
font-style: normal; font-style: normal;
display: -webkit-box; /* 设置为WebKit内核的弹性盒子模型 */ display: -webkit-box;
-webkit-box-orient: vertical; /* 垂直排列 */ /* 设置为WebKit内核的弹性盒子模型 */
-webkit-line-clamp: 2; /* 限制显示三行 */ -webkit-box-orient: vertical;
overflow: hidden; /* 隐藏超出范围的内容 */ /* 垂直排列 */
text-overflow: ellipsis; /* 使用省略号 */ -webkit-line-clamp: 2;
/* 限制显示三行 */
overflow: hidden;
/* 隐藏超出范围的内容 */
text-overflow: ellipsis;
/* 使用省略号 */
} }
.news-meta { .news-meta {
@ -277,4 +366,27 @@ const handlePopupErrorCallback = () => {
align-items: center; align-items: center;
gap: 10rpx; gap: 10rpx;
} }
.r_r_tags {
// margin-left: 20rpx;
width: 85vw;
overflow-x: scroll;
}
.r_tags {
display: flex;
gap: 10rpx;
.tag {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 22rpx;
color: #3f80fa;
padding: 5rpx 20rpx;
border-radius: 10rpx;
white-space: nowrap;
}
}
</style> </style>

View File

@ -1,50 +1,68 @@
<template> <template>
<view class="main"> <view class="main">
<view class="title">{{ props.data.title }}</view> <view class="title" :class="{ mohu: !isLogin }">{{ props.data.title }}</view>
<view class="author"> <view class="author">
<view class="name"> <view class="name" :class="{ mohu: !isLogin }">
<text class="text">来源:</text> <text class="text">来源:</text>
<text class="text">{{ props.data.tag }}</text> <text class="text" v-if="intoType === 'etf'">中国证券报</text>
<text class="text" v-else>{{ props.data.tag ? props.data.tag : "中国证券报" }}</text>
</view> </view>
<view class="name" v-if="props.data.editor"> <!-- <view class="name" v-if="props.data.editor">
<text class="text">编辑:</text> <text class="text">编辑:</text>
<text class="text">{{ props.data.editor }}</text> <text class="text">{{ props.data.editor }}</text>
</view> </view> -->
<view class="time">{{ props.data.publishTime }}</view> <view class="time" :class="{ mohu: !isLogin }">{{ props.data.publishTime }}</view>
</view> </view>
<!-- 两个标签 start --> <!-- 两个标签 start -->
<view class="r_r_tags"> <view class="r_r_tags" :class="{ mohu: !isLogin }">
<view style="display: flex; margin-top: 20rpx; overflow-x: auto; width: 95vw"> <view style="display: flex; margin-top: 20rpx; overflow-x: auto; width: 95vw">
<view class="r_tags"> <view class="r_tags">
<view class="tag" style="background-color: #fff9ec; color: #ffb100" <view
v-for="(item, index) in props.data.conceptLabels" :key="index">{{ item }}</view> class="tag"
style="background-color: #fff9ec; color: #ffb100"
v-for="(item, index) in props.data.conceptLabels"
:key="index"
>{{ item }}</view
>
</view> </view>
</view> </view>
<view style="display: flex; margin-top: 20rpx; overflow-x: auto; width: 100vw"> <view style="display: flex; margin-top: 20rpx; overflow-x: auto; width: 100vw">
<view class="r_tags"> <view class="r_tags">
<view class="tag" style="background-color: #f5f8fe; color: #007aff" <view
v-for="(item, index) in props.data.industryLabels" :key="index">{{ item }}</view> class="tag"
style="background-color: #f5f8fe; color: #007aff"
v-for="(item, index) in props.data.industryLabels"
:key="index"
>{{ item }}</view
>
</view> </view>
</view> </view>
</view> </view>
<!-- 两个标签 end --> <!-- 两个标签 end -->
<!-- 摘要 --> <!-- 摘要 -->
<view class="desc" v-if="props.data.summary"> <view class="desc" v-if="props.data.summary" :class="{ mohu: !isLogin }">
<!-- <view class="bill_icon"></view> --> <!-- <view class="bill_icon"></view> -->
<image :src="zhaiyaoImg" mode="scaleToFill" class="zhaiyao_icon" />
<view>
{{ props.data.summary }} {{ props.data.summary }}
</view> </view>
</view>
<view class="thumbnail" v-if="props.data.picture"> <view class="thumbnail" v-if="props.data.picture">
<image :src="props.data.picture" mode="widthFix" /> <image :src="props.data.picture" mode="widthFix" />
</view> </view>
<view style="padding: 35rpx;"> <view style="padding: 35rpx" :class="{ mohu: !isLogin }">
<text class="articleDes" :class="props?.data?.needpay && 'needpay'" style="white-space: pre-wrap;" <text
v-html="props.data.content"> class="articleDes"
:class="props?.data?.needpay && 'needpay'"
style="white-space: pre-wrap"
v-html="props.data.content"
>
</text> </text>
</view> </view>
@ -54,24 +72,50 @@
v-html="props.data.content" v-html="props.data.content"
> >
</view> --> </view> -->
<view class="author" style="justify-content: flex-start; margin-top: -30rpx">
<view class="name" v-if="props.data.editor">
<text class="text">编辑:</text>
<text class="text">{{ props.data.editor }}</text>
</view>
<view class="name" style="margin-left: 40rpx" v-if="props.data.secondReviewer">
<text class="text">二校:</text>
<text class="text">{{ props.data.secondReviewer }}</text>
</view>
</view>
<view class="r_etf" style="margin-top: 80rpx" v-if="intoType == 'etf'">
<text class="etf_title">AI关联标的</text>
<view class="etfs">
<view v-for="(item, index) in data.etfs" class="etf_item" :key="index" @click="goEtfDetail(item)">
{{ item.name }}
</view>
</view>
</view>
<LoginPopup
:show="LoginShow"
@handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback"
@handlePopupErrorCallback="handlePopupErrorCallback"
/>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import { import { onLaunch, onShow, onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
onLaunch,
onShow,
onLoad,
onShareAppMessage,
onShareTimeline,
} from "@dcloudio/uni-app";
import articleMock from "@/mock/article.js"; import articleMock from "@/mock/article.js";
import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage";
import zhaiyaoImg from "../../assets/zixun/zhaiyao_icon.png";
const isLogin = ref(Session.get("token"));
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object, type: Object,
default: () => { }, default: () => {},
}, },
}); });
const tagList1 = ref([ const tagList1 = ref([
@ -85,6 +129,17 @@ const tagList1 = ref([
name: "医药生物-医疗服务", name: "医药生物-医疗服务",
}, },
]); ]);
const LoginShow = ref(false);
//
const handlePopupClose = () => {
LoginShow.value = false;
isLogin.value = Session.get("token");
};
//
const handlePopupSuccessCallback = () => {
isLogin.value = Session.get("token");
console.log("🚀 ~ handlePopupSuccessCallback ~ isLogin.value:", isLogin.value);
};
const tagList2 = ref([ const tagList2 = ref([
{ {
@ -104,10 +159,23 @@ const handleClick = (value: any) => {
show.value = value; show.value = value;
}; };
const intoType = ref(null);
onLoad((option) => { onLoad((option) => {
type.value = option?.type || "list"; type.value = option?.type || "list";
intoType.value = option?.intoType || null;
if (!isLogin.value) {
LoginShow.value = true;
}
}); });
function goEtfDetail(item) {
console.log("🚀 ~ goEtfDetail ~ item:", item);
uni.navigateTo({
url: `/pages/realtimeInfo/indexEtfInfo?name=${item.name}&code=${item.code}`,
});
}
const handleSub = () => { const handleSub = () => {
if (type.value === "list") { if (type.value === "list") {
let mainItemId = uni.getStorageSync("mainItem"); let mainItemId = uni.getStorageSync("mainItem");
@ -161,6 +229,7 @@ const handleSub = () => {
.main { .main {
position: relative; position: relative;
background-color: #fff; background-color: #fff;
padding-bottom: 120rpx;
.title { .title {
padding-top: 16rpx; padding-top: 16rpx;
@ -201,15 +270,16 @@ const handleSub = () => {
.desc { .desc {
padding: 12rpx; padding: 12rpx;
box-sizing: border-box; box-sizing: border-box;
background-color: #f5f5f5; background-color: #f2f4fa;
width: 700rpx; width: 700rpx;
margin: 30rpx auto; margin: 30rpx auto;
color: rgba(51, 51, 51, 0.6); color: #666666;
// font-size: 28rpx; // font-size: 28rpx;
font-size: var(--h2-font-size); font-size: var(--h2-font-size);
// text-indent: 0.5em; // text-indent: 0.5em;
white-space: pre-wrap; white-space: pre-wrap;
overflow-wrap: break-word; overflow-wrap: break-word;
line-height: 40rpx;
/* 在必要时单词内部断行 */ /* 在必要时单词内部断行 */
.bill_icon { .bill_icon {
@ -284,4 +354,58 @@ const handleSub = () => {
white-space: nowrap; white-space: nowrap;
} }
} }
.mohu {
filter: blur(4px);
}
.zhaiyao_icon {
width: 72rpx;
height: 51rpx;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.r_etf {
display: flex;
flex-direction: column;
padding: 0 30rpx;
.etfs {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
margin-top: 20rpx;
}
.etf_title {
font-family: PingFangSC, PingFang SC;
font-weight: bold;
font-size: 30rpx;
color: #222222;
line-height: 42rpx;
text-align: left;
font-style: normal;
}
.etf_item {
width: calc(50vw - 80rpx);
height: 64rpx;
background: #edf1f5;
border-radius: 8rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #666666;
line-height: 44rpx;
text-align: left;
font-style: normal;
display: flex;
align-items: center;
justify-content: center;
padding: 5rpx 20rpx;
}
}
</style> </style>

View File

@ -0,0 +1,326 @@
<template>
<view class="list" v-if="data.length">
<view class="listItem" v-for="item in props.data" :key="item.id" @click="handleClick(item)">
<view class="listItemHeader">
<view class="ListItemImg" v-if="item.picture">
<image :src="item.picture" class="ListItemImage" mode="widthFix" style="width: 204rpx" />
<image class="ListItemBg" :src="item.picture" style="width: 100%; height: 100%" />
<view class="tag" v-if="item.newType !== 'search'">{{ item.tag }}</view>
</view>
<view class="listItemHeaderContent">
<view v-if="!isLogin">
<div :class="['listItemTitle']" v-html="item.title"></div>
<!-- <text :class="['listItemTitle']">{{ item.title.slice(0, 3) }}</text>
<text :class="['listItemTitle', isLogin ? '' : 'mohu']">
{{ item.title.slice(3, item.title.length) }}
</text> -->
</view>
<view v-else>
<view :class="['listItemTitle1']" v-html="item.title"> </view>
</view>
<view :class="['listItemAbstract', isLogin ? '' : 'mohu']" v-if="item.newType !== 'search'"
v-html="item.summary"></view>
<view :class="['listItemAbstract', isLogin ? '' : 'mohu']" v-else
v-html="item.MarkInRedContent || item.abstract"></view>
</view>
</view>
<!-- <view class="tabContainer">
<view class="tag">{{ item.tag }}</view>
</view> -->
<!--
<view :class="['listItemContent', isLogin ? '' : 'mohu']">
<view style="display: flex">
<view class="tag">{{ item.tag }}</view>
<view class="listItemTime" style="margin-left: 10rpx">{{ item.time }}</view>
</view>
<view class="r_option">
<image class="option_icon" src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/eye_icon%402x.png"></image>
<text class="option_text">{{ item.readNums }}</text>
<image class="option_icon" src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/like_icon%402x.png"></image>
<text class="option_text">{{ item.likeNums }}</text>
<image class="option_icon" src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/share_icon%402x.png"></image>
<text class="option_text">{{ item.shareNums }}</text>
</view>
</view> -->
<!-- <view class="listItemFooter" v-if="item.needpay"></view> -->
</view>
</view>
<u-empty mode="news" v-else> </u-empty>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { onShow, onLoad } from "@dcloudio/uni-app";
import { Session } from "@/utils/storage";
const emit = defineEmits(["handleListJump", "onClick"]);
// const isLogin = ref(uni.getStorageSync("token"));
const isLogin = ref(Session.get("token"));
const props = defineProps({
//
data: {
type: Array,
default: () => [],
},
});
console.log("props ===>", props.data);
const handleListJump = (item) => {
emit("handleListJump", item);
};
//
const handleClick = (item: any) => {
emit("onClick", item);
};
</script>
<style lang="scss" scoped>
.list {
box-sizing: border-box;
background-color: #fff;
padding: 0 40rpx 30rpx 40rpx;
border-radius: 10rpx;
font-family: "SourceHanSansCN-Regular";
.listItem {
border-bottom: 2rpx solid rgba(51, 51, 51, 0.1);
box-sizing: border-box;
padding: 30rpx 0;
.listItemHeader {
display: flex;
justify-content: space-between;
.ListItemImg {
width: 204rpx;
height: 204rpx;
border-radius: 9rpx;
overflow: hidden;
background-color: #c4c4c4;
flex-shrink: 0;
position: relative;
margin-right: 12rpx;
.ListItemImage {
width: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 9;
}
.ListItemBg {
filter: blur(30rpx);
}
.tag {
position: absolute;
right: 0;
bottom: 0;
box-sizing: border-box;
padding: 6rpx 16rpx;
border-radius: 4rpx;
background-color: #e7303f;
// font-size: 20rpx;
font-size: var(--h6-font-size);
color: #fff;
z-index: 9;
}
}
.listItemHeaderContent {
// width: 100%;
box-sizing: border-box;
padding-left: 0rpx;
display: flex;
flex-direction: column;
.listItemTitle1 {
font-size: 32rpx;
font-size: var(--h1-font-size);
color: #333;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
word-break: break-all;
font-family: PingFangSC, PingFang SC;
font-weight: bold;
font-size: 32rpx;
color: #192236;
line-height: 45rpx;
text-align: left;
font-style: normal;
}
.listItemTitle {
// font-size: 32rpx;
// font-size: var(--h1-font-size);
// color: #333;
// display: -webkit-box;
// -webkit-box-orient: vertical;
// -webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
word-break: break-all;
font-family: PingFangSC, PingFang SC;
font-weight: bold;
font-size: 32rpx;
color: #192236;
line-height: 45rpx;
text-align: left;
font-style: normal;
// text-align: left;
&.noAbstract {
-webkit-line-clamp: 4;
}
.isVip {
display: inline-block;
width: 50rpx;
height: 29rpx;
background-image: url(https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/images/icon_vip.png);
background-size: cover;
}
}
.listItemTitleContent {
// font-size: 32rpx;
font-size: var(--h1-font-size);
// color: #333;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
// font-weight: bold;
.isVip {
display: inline-block;
width: 50rpx;
height: 29rpx;
background-image: url(https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/images/icon_vip.png);
background-size: cover;
box-sizing: border-box;
margin-right: 12rpx;
}
}
.listItemAbstract {
box-sizing: border-box;
padding-top: 12rpx;
// font-size: 26rpx;
font-size: var(--h3-font-size);
color: rgba(51, 51, 51, 0.6);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #2d3849;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
}
}
.listItemContent {
// font-size: 20rpx;
font-size: var(--h6-font-size);
color: #b9b9b9;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 21rpx 0 0 0;
.listItemData {
display: flex;
align-items: center;
justify-content: space-between;
.dataItem {
margin-right: 12rpx;
&:last-child {
margin-right: 0;
}
}
}
}
.tabContainer {
display: flex;
box-sizing: border-box;
padding-top: 21rpx;
.tag {
box-sizing: border-box;
padding: 6rpx 16rpx;
border-radius: 4rpx;
background-color: #e7303f;
// font-size: 20rpx;
font-size: var(--h6-font-size);
color: #fff;
}
}
.listItemFooter {
height: 74rpx;
margin-top: 15rpx;
background-image: url(https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/images/vip_sub_2.png);
background-size: cover;
}
}
}
.listItemTitleContentText {
font-family: "SourceHanSansCN-Medium";
}
.r_option {
display: flex;
align-items: center;
justify-content: center;
gap: 10rpx;
.option_icon {
width: 24rpx;
height: 24rpx;
}
.option_text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #192236;
line-height: 33rpx;
text-align: justify;
font-style: normal;
}
}
.mohu {
filter: blur(7rpx);
}
</style>

View File

@ -28,7 +28,7 @@ const colorList = ["#F05040", "#696BBE", "#93CFED", "#FE9F19", "#3C74F1"];
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object, type: Object,
default: () => { }, default: () => {},
}, },
}); });
@ -42,8 +42,8 @@ watch(
keys.value.push(item.key); keys.value.push(item.key);
values.value.push(item.doc_count); values.value.push(item.doc_count);
}); });
keys.value.reverse() keys.value.reverse();
values.value.reverse() values.value.reverse();
initChart(); initChart();
} }
); );

View File

@ -0,0 +1,164 @@
<template>
<view>
<div ref="chartDom" style="width: 100vw; height: 700rpx"></div>
</view>
</template>
<script setup>
import { watch, onMounted, reactive, ref } from "vue";
import * as echarts from "echarts";
import { newsInfoScore } from "@/api/newsInfo";
const chartDom = ref(null);
let myChart = null;
const data = reactive({});
const keys = ref([]);
const values = ref([]);
const props = defineProps({
data: {
type: Object,
default: () => {},
},
barColor: {
type: String,
default: "#3C74F1",
},
});
watch(
() => props.data,
(newVal) => {
if (newVal) {
initChart();
}
}
);
const colorList = ["#F05040", "#696BBE", "#93CFED", "#FE9F19", "#3C74F1", "#F05040", "#696BBE", "#93CFED", "#FE9F19", "#3C74F1"];
//
const initChart = () => {
myChart = echarts.init(chartDom.value);
const builderJson = {
all: 10887,
charts: {},
components: {
geo: 2788,
title: 9575,
legend: 9400,
tooltip: 9466,
grid: 9266,
markPoint: 3419,
markLine: 2984,
timeline: 2739,
dataZoom: 2744,
visualMap: 2466,
toolbox: 3034,
polar: 1945,
},
ie: 9743,
};
// value
const maxItem = props.data.reduce((prev, current) => {
// value
return current.value > prev.value ? current : prev;
}, props.data[0]); //
props.data.forEach((item) => {
builderJson.charts[item.content] = item.value;
});
builderJson.all = maxItem.value;
const waterMarkText = "ECHARTS";
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// canvas.width = canvas.height = 100;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.globalAlpha = 0.08;
ctx.font = "20px Microsoft Yahei";
ctx.translate(50, 50);
ctx.rotate(-Math.PI / 4);
ctx.fillText(waterMarkText, 0, 0);
let option = {
// backgroundColor: {
// type: "pattern",
// image: canvas,
// repeat: "repeat",
// },
tooltip: {},
title: [],
grid: [
{
top: 0,
width: "90%",
top: "5%",
bottom: "10%",
left: 10,
containLabel: true,
},
],
xAxis: [
{
type: "value",
max: builderJson.all,
splitLine: {
show: false,
},
},
],
yAxis: [
{
type: "category",
data: Object.keys(builderJson.charts),
axisLabel: {
interval: 0,
rotate: 30,
},
splitLine: {
show: false,
},
},
],
series: [
{
type: "bar",
stack: "chart",
z: 3,
label: {
position: "right",
show: true,
},
itemStyle: {
color: props.barColor,
normal: {
borderRadius: [0, 4, 4, 0],
color: props.barColor,
// color: function (params) {
// return colorList[params.dataIndex];
// },
},
},
data: Object.keys(builderJson.charts).map(function (key) {
return builderJson.charts[key];
}),
},
],
};
//使
myChart.setOption(option);
};
onMounted(async () => {
// await getData();
// initChart();
// setInterval(async () => {
// await getData();
// initChart();
// }, 5000);
});
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,139 @@
<template>
<view>
<div ref="chartDom" style="width: 100vw; height: 700rpx"></div>
</view>
</template>
<script setup>
import { watch, onMounted, reactive, ref } from "vue";
import * as echarts from "echarts";
import { newsInfoScore } from "@/api/newsInfo";
const chartDom = ref(null);
let myChart = null;
const data = reactive({});
const keys = ref([]);
const values = ref([]);
const props = defineProps({
data: {
type: Object,
default: () => {},
},
barColor: {
type: String,
default: "#3C74F1",
},
});
//
const initChart = () => {
myChart = echarts.init(chartDom.value);
let source = [];
source.push(["score", "amount", "product"]);
props.data.forEach((item) => {
source.push([item.value, item.value, item.content]);
});
let option = {
dataset: {
source: source,
// [
// ["score", "amount", "product"],
// [89.3, 58212, "Matcha Latte"],
// [57.1, 78254, "Milk Tea"],
// [74.4, 41032, "Cheese Cocoa"],
// [50.1, 12755, "Cheese Brownie"],
// [89.7, 20145, "Matcha Cocoa"],
// [68.1, 79146, "Tea"],
// [19.6, 91852, "Orange Juice"],
// [10.6, 101852, "Lemon Juice"],
// [32.7, 20112, "Walnut Brownie"],
// ],
},
grid: {
top: 0,
width: "90%",
top: "5%",
bottom: "10%",
left: 10,
containLabel: true,
},
xAxis: {
splitLine: {
show: false,
},
},
yAxis: {
type: "category",
axisLabel: {
interval: 0,
rotate: 30,
},
splitLine: {
show: false,
},
},
// visualMap: {
// show: false,
// orient: "horizontal",
// left: "center",
// min: 1,
// max: 100,
// text: ["High Score", "Low Score"],
// // Map the score column to color
// dimension: 0,
// inRange: {
// color: ["#65B581", "#FFCE34", "#FD665F"],
// },
// },
series: [
{
type: "bar",
label: {
position: "right",
show: true,
},
itemStyle: {
color: "#FFCE34",
normal: {
borderRadius: [0, 4, 4, 0],
color: props.barColor,
// color: function (params) {
// return colorList[params.dataIndex];
// },
},
},
encode: {
// Map the "amount" column to X axis.
x: "amount",
// Map the "product" column to Y axis
y: "product",
},
},
],
};
//使
myChart.setOption(option);
};
watch(
() => props.data,
(newVal) => {
if (newVal) {
initChart();
}
}
);
onMounted(async () => {
// await getData();
// initChart();
// setInterval(async () => {
// await getData();
// initChart();
// }, 5000);
});
</script>
<style scoped lang="scss"></style>

View File

@ -1,44 +1,34 @@
<template> <template>
<view class="comment"> <view class="comment">
<Tips v-if="messageShow" />
<view class="comment-input">
<input
type="text"
confrim-type="done"
placeholder="输入评论内容……"
class="input-field"
v-model="comment"
@confirm="handleSubmit"
/>
<!-- <view class="input-field">输入评论内容</view> -->
</view>
<view class="comment-count"> <view class="comment-count">
<view class="count" @click="handleClickLike"> <view class="count" @click="handleClickLike">
<image :src="props.data.isLike ? IconLikeActive : IconLike" class="icon" /> <image
<text class="num">{{ props.data.likeNums }}</text> :src="
props.data.isLike
? 'https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/zan_like_fill%402x.png'
: 'https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/zan_like_normal%402x.png'
"
class="icon"
/>
<text class="num">点赞</text>
</view> </view>
<view class="count" @click="handleClickStar"> <!-- <view class="count" @click="handleClickStar">
<image :src="props.data.isFav ? IconStarActive : IconStar" class="icon" /> <image
<text class="num">{{ props.data.favNums }}</text> :src="props.data.isFav ? 'https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/star_icon_fill%402x.png' : 'https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/star_icon_normal%402x.png'"
class="icon" />
<text class="num">收藏</text>
</view> </view>
<!-- <view class="count"> <button class="count" style="background-color: transparent;" open-type="share">
<image src="@/static/icon_message.png" class="icon" /> <image src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/share_icon%402x.png" class="icon" />
<text class="num">{{ <text class="num">分享</text>
props.data.comment > 1000 ? "999+" : props.data.comment </button> -->
}}</text>
</view> -->
</view> </view>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from "vue"; import { ref, watch } from "vue";
// import { likeNews } from "@/api";
import IconLike from "@/static/icon_like.png";
import IconStar from "@/static/icon_star.png";
import IconLikeActive from "@/static/icon_like_active.png";
import IconStarActive from "@/static/icon_star_active.png";
const emit = defineEmits(["handleClickLike", "handleClickStar"]); const emit = defineEmits(["handleClickLike", "handleClickStar"]);
const messageShow = ref(false); const messageShow = ref(false);
const props = defineProps({ const props = defineProps({
@ -78,7 +68,7 @@ const handleSubmit = () => {
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 112rpx; height: 160rpx;
background-color: #fff; background-color: #fff;
box-shadow: 0 0 10rpx rgba(51, 51, 51, 0.3); box-shadow: 0 0 10rpx rgba(51, 51, 51, 0.3);
display: flex; display: flex;
@ -89,6 +79,7 @@ const handleSubmit = () => {
.comment-input { .comment-input {
width: 100%; width: 100%;
.input-field { .input-field {
height: 72rpx; height: 72rpx;
background-color: #f5f5f5; background-color: #f5f5f5;
@ -100,6 +91,7 @@ const handleSubmit = () => {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.input-placeholder { .input-placeholder {
color: rgba(51, 51, 51, 0.6); color: rgba(51, 51, 51, 0.6);
} }
@ -107,12 +99,15 @@ const handleSubmit = () => {
.comment-count { .comment-count {
display: flex; display: flex;
justify-content: flex-end; width: 100vw;
align-items: center;
.count { .count {
display: flex; display: flex;
text-align: center;
justify-content: center;
align-items: center; align-items: center;
margin-left: 24rpx; margin-left: 24rpx;
width: 100%;
.num { .num {
margin-left: 12rpx; margin-left: 12rpx;
@ -128,4 +123,8 @@ const handleSubmit = () => {
} }
} }
} }
button::after {
border: 0;
}
</style> </style>

View File

@ -1,56 +1,29 @@
<template> <template>
<!-- <view class="loginPopup"> --> <!-- <view class="loginPopup"> -->
<u-popup <u-popup class="loginPopup" :show="props.show" closeable :mode="props.mode" round="12" :closeOnClickOverlay="false"
class="loginPopup" @close="handlePopupClose">
:show="props.show"
closeable
:mode="props.mode"
round="12"
:closeOnClickOverlay="false"
@close="handlePopupClose"
>
<view class="loginPopupContent"> <view class="loginPopupContent">
<view class="loginTitle">登录后掌握更多优质财经内容</view> <view class="loginTitle">登录后掌握更多优质财经内容</view>
<!-- 登录表单 --> <!-- 登录表单 -->
<view class="loginForm"> <view class="loginForm">
<u--form :model="state.loginForm" ref="uForm"> <u--form :model="state.loginForm" ref="uForm">
<u-form-item <u-form-item style="padding: 0" class="loginFormItem" prop="userInfo.name" borderBottom ref="item1">
style="padding: 0" <u--input class="loginFormInput" placeholder="请输入您的手机号" v-model="state.loginForm.phone"
class="loginFormItem" border="none"></u--input>
prop="userInfo.name"
borderBottom
ref="item1"
>
<u--input
class="loginFormInput"
placeholder="请输入您的手机号"
v-model="state.loginForm.phone"
border="none"
></u--input>
</u-form-item> </u-form-item>
<u-form-item <u-form-item class="loginFormItem" prop="userInfo.name" borderBottom ref="item1">
class="loginFormItem" <u--input class="loginFormInput" placeholder="请输入短信验证码" v-model="state.loginForm.code"
prop="userInfo.name" border="none"></u--input>
borderBottom
ref="item1"
>
<u--input
class="loginFormInput"
placeholder="请输入短信验证码"
v-model="state.loginForm.code"
border="none"
></u--input>
<view class="getCode" @click="captcha">{{ codeText }}</view> <view class="getCode" @click="captcha">{{ codeText }}</view>
</u-form-item> </u-form-item>
</u--form> </u--form>
<u-button class="loginFormBtn" text="登录" @click="Login"></u-button> <u-button class="loginFormBtn" text="登录" @click="Login"></u-button>
</view> </view>
<!-- 用户协议 --> <!-- 用户协议 -->
<view class="tips" <view class="tips">登录即代表已经阅读并同意
>登录即代表已经阅读并同意 <view class="userAgreement">用户协议</view>
<view class="userAgreement">用户协议</view></view </view>
>
</view> </view>
</u-popup> </u-popup>
<!-- </view> --> <!-- </view> -->
@ -130,6 +103,8 @@ const handlePopupSuccessCallback = () => {
const handlePopupErrorCallback = () => { const handlePopupErrorCallback = () => {
emit("handlePopupErrorCallback"); emit("handlePopupErrorCallback");
}; };
const { aplus_queue } = window;
// //
const Login = async () => { const Login = async () => {
if (!validatePhoneNumber(state.loginForm.phone)) { if (!validatePhoneNumber(state.loginForm.phone)) {
@ -155,6 +130,14 @@ const Login = async () => {
}); });
console.log(code, "<=== code"); console.log(code, "<=== code");
if (code === 200) { if (code === 200) {
aplus_queue.push({
action: 'aplus.record',
arguments: ['login', 'CLK', {
phone: data.phone,
}]
});
uni.hideLoading(); uni.hideLoading();
Session.set("token", data.token); Session.set("token", data.token);
Session.set("userPhone", data.phone); Session.set("userPhone", data.phone);
@ -163,6 +146,7 @@ const Login = async () => {
icon: "success", icon: "success",
}); });
handlePopupSuccessCallback(); handlePopupSuccessCallback();
} else { } else {
console.log(msg, "<=== msg"); console.log(msg, "<=== msg");
handlePopupErrorCallback(); handlePopupErrorCallback();
@ -188,6 +172,7 @@ const handlePopupClose = () => {
width: 100%; width: 100%;
height: 786rpx; height: 786rpx;
} }
.u-popup__content__close { .u-popup__content__close {
margin-top: 30rpx; margin-top: 30rpx;
} }
@ -223,11 +208,13 @@ const handlePopupClose = () => {
&:nth-child(2) { &:nth-child(2) {
margin: 32rpx 0; margin: 32rpx 0;
} }
::v-deep { ::v-deep {
.u-form-item__body { .u-form-item__body {
padding: 0; padding: 0;
} }
} }
.loginFormInput { .loginFormInput {
width: 100%; width: 100%;
height: 100rpx !important; height: 100rpx !important;
@ -244,6 +231,7 @@ const handlePopupClose = () => {
font-size: var(--h1-font-size); font-size: var(--h1-font-size);
color: rgba(51, 51, 51, 0.6); color: rgba(51, 51, 51, 0.6);
position: relative; position: relative;
&::before { &::before {
content: ""; content: "";
display: block; display: block;
@ -263,6 +251,7 @@ const handlePopupClose = () => {
border: none; border: none;
background-color: #e7303f; background-color: #e7303f;
color: #fff; color: #fff;
::v-deep { ::v-deep {
.u-button__text { .u-button__text {
font-size: var(--h1-font-size) !important; font-size: var(--h1-font-size) !important;
@ -277,6 +266,7 @@ const handlePopupClose = () => {
display: flex; display: flex;
justify-content: center; justify-content: center;
color: #717171; color: #717171;
.userAgreement { .userAgreement {
color: #333; color: #333;
} }

View File

@ -4,11 +4,7 @@
<view class="userContainer"> <view class="userContainer">
<u-avatar :src="avatarImg" size="60"></u-avatar> <u-avatar :src="avatarImg" size="60"></u-avatar>
<view class="userData"> <view class="userData">
<text class="phone">{{ <text class="phone">{{ !isLoginStatus ? "未登录用户" : maskPhoneNumber(Session.get("userPhone")) }}</text>
!isLoginStatus
? "未登录用户"
: maskPhoneNumber(Session.get("userPhone"))
}}</text>
<!-- <view class="setUserData"> <!-- <view class="setUserData">
编辑我的个人资料 编辑我的个人资料
<u-icon size="12" name="arrow-right"></u-icon> <u-icon size="12" name="arrow-right"></u-icon>
@ -98,9 +94,7 @@
<!-- 退出登录的按钮 --> <!-- 退出登录的按钮 -->
<view class="loginOut" :class="!isLoginStatus && 'loginBtn'"> <view class="loginOut" :class="!isLoginStatus && 'loginBtn'">
<u-button type="danger" size="large" @click="loginBtnStatus">{{ <u-button type="danger" size="large" @click="loginBtnStatus">{{ !isLoginStatus ? "点击登录" : "退出登录" }}</u-button>
!isLoginStatus ? "点击登录" : "退出登录"
}}</u-button>
</view> </view>
<!-- 登录弹框 --> <!-- 登录弹框 -->
@ -127,6 +121,8 @@ import like from "@/assets/images/like.png";
import time from "@/assets/images/time.png"; import time from "@/assets/images/time.png";
import vip from "@/assets/images/vip.png"; import vip from "@/assets/images/vip.png";
import { useShareStore } from "@/stores/shareStore"; import { useShareStore } from "@/stores/shareStore";
import { doLogout } from "@/api";
const stores = useShareStore(); const stores = useShareStore();
const curPages = getCurrentPages(); const curPages = getCurrentPages();
@ -177,6 +173,9 @@ const loginOut = () => {
icon: "none", icon: "none",
duration: 1500, duration: 1500,
}); });
doLogout({
financialAccount: Session.get("userPhone"),
});
// cookie // cookie
Session.clear(); Session.clear();
uni.removeStorageSync("subStatus"); uni.removeStorageSync("subStatus");

View File

@ -3,12 +3,14 @@ import pinia from "@/stores/index";
import App from "./App.vue"; import App from "./App.vue";
import uviewPlus from "@/uni_modules/uview-plus"; import uviewPlus from "@/uni_modules/uview-plus";
import "@/assets/fonts/font.css"; import "@/assets/fonts/font.css";
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
export function createApp() { export function createApp() {
const app = createSSRApp(App); const app = createSSRApp(App);
app.use(pinia).use(uviewPlus); app.use(pinia).use(uviewPlus);
app.use(ElementPlus)
return { return {
app, app,
}; };

View File

@ -19,6 +19,15 @@
{ {
"path": "pages/mine/index" "path": "pages/mine/index"
}, },
{
"path": "pages/realtimeInfo/indexRelease"
},
{
"path": "pages/realtimeInfo/indexEtf"
},
{
"path": "pages/realtimeInfo/indexEtfInfo"
},
{ {
"path": "pages/sreachReq/index" "path": "pages/sreachReq/index"
}, },

View File

@ -12,6 +12,7 @@
<!-- 文章正文 start --> <!-- 文章正文 start -->
<Article :data="data" /> <Article :data="data" />
<!-- 分割 --> <!-- 分割 -->
<view class="line"></view> <view class="line"></view>
<!-- 推荐栏目 --> <!-- 推荐栏目 -->
@ -23,23 +24,15 @@
/> --> /> -->
<!-- 底部栏 评论 / 收藏 --> <!-- 底部栏 评论 / 收藏 -->
<!-- <Comment <Comment :data="data" @handleClickLike="handleClickLike" @handleClickStar="handleClickStar" />
:data="data"
@handleClickLike="handleClickLike"
@handleClickStar="handleClickStar"
/> -->
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { onMounted, ref } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app"; import { onLoad, onShow } from "@dcloudio/uni-app";
import { onReachBottom } from "@dcloudio/uni-app"; import { onReachBottom } from "@dcloudio/uni-app";
import { import { fetchArticleDetail, fetchArticleLike, fetchArticleFavorate } from "@/api/detail";
fetchArticleDetail,
fetchArticleLike,
fetchArticleFavorate,
} from "@/api/detail";
import { getNewsList } from "@/api"; import { getNewsList } from "@/api";
import Article from "@/components/article/indexNewsInfo.vue"; import Article from "@/components/article/indexNewsInfo.vue";
import Column from "@/components/column/index.vue"; import Column from "@/components/column/index.vue";
@ -70,7 +63,7 @@ onLoad(async (option: any) => {
if (res.code === 200) { if (res.code === 200) {
data.value = res.data; data.value = res.data;
res.data.content = res.data.content.replace(/\n{3,}/g, '\n'); res.data.content = res.data.content.replace(/\n{3,}/g, "\n");
columnName.value = res.data.columnName1; columnName.value = res.data.columnName1;
newList(res.data.columnId1); newList(res.data.columnId1);
@ -94,6 +87,35 @@ const newList = async (columnId: number) => {
// //
const handleClickLike = async () => { const handleClickLike = async () => {
console.log("🚀 ~ handleClickLike ~ data.value.isLike:", data.value.isLike);
if (data.value.isLike == 1) {
//
aplus_queue.push({
action: "aplus.record",
arguments: [
"canncelLike",
"CLK",
{
param1: data.value.id,
param2: data.value.title,
},
],
});
} else {
//
aplus_queue.push({
action: "aplus.record",
arguments: [
"doLike",
"CLK",
{
param1: data.value.id,
param2: data.value.title,
},
],
});
}
// console.log("=== ===") // console.log("=== ===")
const res = await fetchArticleLike({ const res = await fetchArticleLike({
id: data.value.id, id: data.value.id,
@ -101,9 +123,7 @@ const handleClickLike = async () => {
}); });
if (res.code === 200) { if (res.code === 200) {
data.value.isLike = data.value.isLike ? 0 : 1; data.value.isLike = data.value.isLike ? 0 : 1;
data.value.likeNums = data.value.isLike data.value.likeNums = data.value.isLike ? data.value.likeNums + 1 : data.value.likeNums - 1;
? data.value.likeNums + 1
: data.value.likeNums - 1;
} }
}; };
@ -115,9 +135,7 @@ const handleClickStar = async () => {
}); });
if (res.code === 200) { if (res.code === 200) {
data.value.isFav = data.value.isFav ? 0 : 1; data.value.isFav = data.value.isFav ? 0 : 1;
data.value.favNums = data.value.isFav data.value.favNums = data.value.isFav ? data.value.favNums + 1 : data.value.favNums - 1;
? data.value.favNums + 1
: data.value.favNums - 1;
} }
}; };
@ -175,6 +193,27 @@ const jumpAll = () => {
} }
}; };
const { aplus_queue } = window;
onMounted(() => {
aplus_queue.push({
action: "aplus.sendPV",
arguments: [{ is_auto: false }], //
});
//demo
aplus_queue.push({
action: "aplus.record",
arguments: [
"goDetail",
"CLK",
{
id: data.value.id,
title: data.value.title,
},
],
});
});
// //
const jumpDetail = (item: any) => { const jumpDetail = (item: any) => {
// console.log(item) // console.log(item)

View File

@ -6,11 +6,7 @@
<img :src="bannerImg" class="banner_bk" /> <img :src="bannerImg" class="banner_bk" />
<view class="r_banner_title"> <view class="r_banner_title">
<img :src="bannerTitle" class="banner_title" /> <img :src="bannerTitle" class="banner_title" />
<text <text>数据更新时间:{{ dayjs(new Date().getTime()).format("YYYY-MM-DD") }}</text>
>数据更新时间:{{
dayjs(new Date().getTime()).format("YYYY-MM-DD")
}}</text
>
</view> </view>
</view> </view>
<!-- banner end --> <!-- banner end -->
@ -25,12 +21,7 @@
<view style="display: flex; margin-top: 15rpx"> <view style="display: flex; margin-top: 15rpx">
<!-- <text class="tag_num">{{ topNum.leftNum }}</text> --> <!-- <text class="tag_num">{{ topNum.leftNum }}</text> -->
<countTo <countTo :startVal="lastLeftNum" :endVal="topNum.leftNum" :duration="5000" class="tag_num"></countTo>
:startVal="lastLeftNum"
:endVal="topNum.leftNum"
:duration="5000"
class="tag_num"
></countTo>
<text class="tag_status">已处理</text> <text class="tag_status">已处理</text>
</view> </view>
@ -49,12 +40,7 @@
<text class="tag_title">概念标签贴标</text> <text class="tag_title">概念标签贴标</text>
<view style="display: flex; margin-top: 15rpx"> <view style="display: flex; margin-top: 15rpx">
<!-- <text class="tag_num">{{ topNum.rightNum }}</text> --> <!-- <text class="tag_num">{{ topNum.rightNum }}</text> -->
<countTo <countTo :startVal="lastRightNum" :endVal="topNum.rightNum" :duration="5000" class="tag_num"></countTo>
:startVal="lastRightNum"
:endVal="topNum.rightNum"
:duration="5000"
class="tag_num"
></countTo>
<text class="tag_status">已处理</text> <text class="tag_status">已处理</text>
</view> </view>
@ -72,35 +58,30 @@
<indexMenuTitle title="资讯评分分布区间"></indexMenuTitle> <indexMenuTitle title="资讯评分分布区间"></indexMenuTitle>
<Line style="margin-top: 30rpx" :data="lineData"></Line> <Line style="margin-top: 30rpx" :data="lineData"></Line>
<view <view style="display: flex; flex-direction: column; text-align: center; justify-content: center; align-items: center; padding-bottom: 30rpx">
style="
display: flex;
flex-direction: column;
text-align: center;
justify-content: center;
align-items: center;
padding-bottom: 30rpx;
"
>
<InfoSummary style="width: 85%" :count="newsNum"></InfoSummary> <InfoSummary style="width: 85%" :count="newsNum"></InfoSummary>
</view> </view>
</view> </view>
<view style="background-color: white; margin-top: 40rpx"> <view style="background-color: white; margin-top: 40rpx">
<indexMenuTitle title="资讯头条榜 Top20"></indexMenuTitle> <div style="display: flex; justify-content: space-between; align-items: center">
<indexMenuTitle title="资讯头条 Top20"></indexMenuTitle>
<view style="display: flex; align-items: center; margin-right: 15rpx; font-size: 30rpx; gap: 10rpx; margin-top: 10rpx" @click="showCalendar">
{{ chooseDate.startDate.split(" ")[0] }}
<u-icon name="calendar" size="26" style="margin-right: 10rpx"></u-icon>
</view>
<!-- <view style="display: flex; align-items: center; gap: 25rpx;margin-right: 15px;margin-top: 10px;">
<u-icon name="play-left-fill" color="#2979ff" size="20"></u-icon>
{{ chooseDate.startDate.split(' ')[0] }}
<u-icon name="play-right-fill" color="#2979ff" size="20"></u-icon>
</view> -->
</div>
<RankList :newsList="newsList"></RankList> <RankList :newsList="newsList"></RankList>
</view> </view>
<view style="background-color: white; margin-top: 40rpx"> <view style="background-color: white; margin-top: 40rpx">
<view <view style="display: flex; justify-content: space-between; align-items: center; padding-right: 30rpx; height: 100rpx">
style="
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 30rpx;
height: 100rpx;
"
>
<indexMenuTitle title="热门行业池 Top10"></indexMenuTitle> <indexMenuTitle title="热门行业池 Top10"></indexMenuTitle>
<view style="display: flex; gap: 3rpx"> <view style="display: flex; gap: 3rpx">
<text class="view-all" @click="onViewAll(0)">查看全部</text> <text class="view-all" @click="onViewAll(0)">查看全部</text>
@ -108,23 +89,11 @@
<u-icon size="12" name="arrow-right"></u-icon> <u-icon size="12" name="arrow-right"></u-icon>
</view> </view>
</view> </view>
<HotIndustryList <HotIndustryList :industryList="industryList" :type="0" @viewAll="handleViewAll" />
:industryList="industryList"
:type="0"
@viewAll="handleViewAll"
/>
</view> </view>
<view style="background-color: white; margin-top: 40rpx"> <view style="background-color: white; margin-top: 40rpx">
<view <view style="display: flex; justify-content: space-between; align-items: center; padding-right: 30rpx; height: 100rpx">
style="
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 30rpx;
height: 100rpx;
"
>
<indexMenuTitle title="风口概念池 Top10"></indexMenuTitle> <indexMenuTitle title="风口概念池 Top10"></indexMenuTitle>
<view style="display: flex; gap: 3rpx"> <view style="display: flex; gap: 3rpx">
<text class="view-all" @click="onViewAll(1)">查看全部</text> <text class="view-all" @click="onViewAll(1)">查看全部</text>
@ -132,23 +101,28 @@
<u-icon size="12" name="arrow-right"></u-icon> <u-icon size="12" name="arrow-right"></u-icon>
</view> </view>
</view> </view>
<HotIndustryList <HotIndustryList :type="1" :industryList="topConceptList" @viewAll="handleViewAll" />
:type="1"
:industryList="topConceptList"
@viewAll="handleViewAll"
/>
</view> </view>
<view class="logout" @click="loginOut" v-if="Session.get('token')" <view class="logout" @click="loginOut" v-if="Session.get('token')">退出登录</view>
>退出登录</view
>
<LoginPopup <LoginPopup
:show="LoginShow" :show="LoginShow"
@handlePopupClose="handlePopupClose" @handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback" @handlePopupSuccessCallback="handlePopupSuccessCallback"
@handlePopupErrorCallback="handlePopupErrorCallback" @handlePopupErrorCallback="handlePopupErrorCallback" />
/>
<u-calendar
:show="calendarShow"
min-date="2025-01-01"
closeOnClickOverlay
:max-date="maxDate"
:default-date="chooseDate.startDate"
monthNum="12"
:key="chooseDate.startDate"
@confirm="calendarConfirm"
@close="calendarShow = false">
</u-calendar>
</view> </view>
</template> </template>
@ -164,15 +138,7 @@ import tagicon_2 from "@/assets/zixun/tagicon_2.png";
import LoginPopup from "@/components/loginPopup/index.vue"; import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
import { import { getindustryCount, getConceptCount, getTopNews, getTopIndustry_d, getTopConcept_d, getNews_cnt_d, newsInfoScore } from "@/api/newsInfo";
getindustryCount,
getConceptCount,
getTopNews,
getTopIndustry_d,
getTopConcept_d,
getNews_cnt_d,
newsInfoScore,
} from "@/api/newsInfo";
import countTo from "@/components/count-to/vue-countTo.vue"; import countTo from "@/components/count-to/vue-countTo.vue";
import RankList from "@/components/RankList.vue"; // import RankList from "@/components/RankList.vue"; //
import InfoSummary from "@/components/InfoSummary.vue"; // import InfoSummary from "@/components/InfoSummary.vue"; //
@ -180,6 +146,15 @@ import indexMenuTitle from "@/components/indexMenuTitle.vue"; // 路径根据实
import dayjs from "dayjs/esm/index"; import dayjs from "dayjs/esm/index";
import HotIndustryList from "@/components/HotIndustryList.vue"; // import HotIndustryList from "@/components/HotIndustryList.vue"; //
const d = new Date();
const year = d.getFullYear();
let month = d.getMonth() + 1;
month = month < 10 ? `0${month}` : month;
const date = d.getDate();
const maxDate = ref(`${year}-${month}-${date} 23:59:59`);
const minDate = ref(`${year}-${month}-${date}`);
const calendarShow = ref(false);
const newsList = ref([]); const newsList = ref([]);
const lastLeftNum = ref(0); const lastLeftNum = ref(0);
@ -207,9 +182,34 @@ async function getTopNum() {
lastRightNum.value = topNum.value.rightNum; lastRightNum.value = topNum.value.rightNum;
} }
const chooseDate = reactive({
startDate: `${year}-${month}-${date}`,
endDate: null,
});
const today = new Date();
function calendarConfirm(dateList) {
console.log("🚀 ~ calendarConfirm ~ dateList:", dateList);
if (dateList && dateList.length > 0) {
chooseDate.startDate = dateList[0] + " 00:00:00";
chooseDate.endDate = dateList[dateList.length - 1] + " 23:59:59";
}
getNewsList();
calendarShow.value = false;
console.log("🚀 ~ calendarConfirm ~ chooseDate:", chooseDate);
}
// //
async function getNewsList() { async function getNewsList() {
newsList.value = await getTopNews({}); newsList.value = await getTopNews({
start_date: chooseDate.startDate
? timeFormat(chooseDate.startDate)
: timeFormat(new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0)),
end_date: chooseDate.endDate
? timeFormat(chooseDate.endDate)
: timeFormat(new Date(today.getFullYear(), today.getMonth(), today.getDate(), 12, 0, 0, 0)),
limit_num: 1000,
});
} }
// top10 // top10
@ -240,8 +240,7 @@ function initData() {
getLineData(); getLineData();
// //
getTopNum(); getTopNum();
//
getNewsList();
// top10 // top10
getTopIndustry_dFn(); getTopIndustry_dFn();
// top10 // top10
@ -250,9 +249,9 @@ function initData() {
getNews_cnt_dFn(); getNews_cnt_dFn();
} }
const type = ref(); const type = ref(null);
function onViewAll(type) { function onViewAll(type1) {
type.value = type; type.value = type1;
if (Session.get("token")) { if (Session.get("token")) {
uni.navigateTo({ uni.navigateTo({
url: "/pages/realtimeInfo/rankDetail?type=" + type, url: "/pages/realtimeInfo/rankDetail?type=" + type,
@ -266,6 +265,10 @@ const timer = setInterval(() => {
initData(); initData();
}, 5000); }, 5000);
function showCalendar() {
calendarShow.value = true;
}
const LoginShow = ref(false); const LoginShow = ref(false);
const isLoginStatus = ref(); const isLoginStatus = ref();
// //
@ -286,8 +289,12 @@ const handlePopupSuccessCallback = () => {
const handlePopupErrorCallback = () => { const handlePopupErrorCallback = () => {
console.log("登录失败"); console.log("登录失败");
}; };
import { doLogout } from "@/api";
function loginOut() { function loginOut() {
doLogout({
financialAccount: Session.get("userPhone"),
});
Session.clear(); Session.clear();
window.location.reload(); window.location.reload();
} }
@ -301,7 +308,64 @@ onMounted(async () => {
if (!Session.get("token")) { if (!Session.get("token")) {
LoginShow.value = true; LoginShow.value = true;
} }
//
getNewsList();
const { aplus_queue } = window;
aplus_queue.push({
action: "aplus.sendPV",
arguments: [{ is_auto: false }], //
});
}); });
/**
* @description 格式化时间
* @param {String|Number} dateTime 需要格式化的时间戳
* @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
* @returns {string} 返回格式化后的字符串
*/
function timeFormat(dateTime = null, formatStr = "yyyy-mm-dd hh:MM:ss") {
let date;
//
if (!dateTime) {
date = new Date();
}
// unix
else if (/^\d{10}$/.test(dateTime.toString().trim())) {
date = new Date(dateTime * 1000);
}
// new Date
else if (typeof dateTime === "string" && /^\d+$/.test(dateTime.trim())) {
date = new Date(Number(dateTime));
}
// RFC 2822
else {
// Safari/Webkitnew Date/
date = new Date(typeof dateTime === "string" ? dateTime.replace(/-/g, "/") : dateTime);
}
const timeSource = {
y: date.getFullYear().toString(), //
m: (date.getMonth() + 1).toString().padStart(2, "0"), //
d: date.getDate().toString().padStart(2, "0"), //
h: date.getHours().toString().padStart(2, "0"), //
M: date.getMinutes().toString().padStart(2, "0"), //
s: date.getSeconds().toString().padStart(2, "0"), //
//
};
for (const key in timeSource) {
const [ret] = new RegExp(`${key}+`).exec(formatStr) || [];
if (ret) {
//
const beginIndex = key === "y" && ret.length === 2 ? 2 : 0;
formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex));
}
}
return formatStr;
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -0,0 +1,594 @@
<template>
<!-- 顶部 banner 区域 -->
<!-- banner start -->
<view class="all">
<text class="top_menu_text">海外资讯</text>
<view class="banner">
<img :src="bannerImg" class="banner_bk" />
<view class="r_banner_title">
<img :src="bannerTitle2" class="banner_title" />
</view>
</view>
<!-- banner end -->
<view class="list_content">
<!-- 搜索 start -->
<view class="r_sreach">
<view class="sreach" style="height: 72rpx">
<u-search v-model="form.keyword" placeholder="搜索资讯" @search="onSreach" @custom="onSreach" />
<!-- <view class="sreach_icon">
<image :src="icon_search"></image>
</view>
<view class="sreach_text">
<text>搜索资讯</text>
</view> -->
</view>
</view>
<!-- 搜索 end -->
<view class="r_list">
<view v-for="item in listData" :key="item.day">
<!-- 时间轴顶部日期 start -->
<view class="item_top">
<view class="r_line">
<view class="item_point"></view>
<view class="item_line"></view>
</view>
<text class="item_day">{{ dayjs(item.day).format("YYYY年MM月DD日") }}</text>
</view>
<!-- 时间轴顶部日期 end -->
<view class="list_card">
<view class="card_left">
<img :src="time_icon" />
<view class="left_line"></view>
</view>
<view class="card_right">
<view v-for="item in item.list" :key="item.time" @click="goDetail(item)">
<view class="item_time">
<text>{{ item.timeStr }}</text>
<text class="item_source_title">来自 <text class="item_source">中国证券报</text></text>
</view>
<view class="item_title">
<text>{{ item.title }}</text>
</view>
<view class="item_summary">
<text>{{ item.summary }}</text>
</view>
<view class="item_etf">
<view v-for="etf in item.etfs" :key="etf.code" class="item_etf_item" @click.stop="goEtfDetail(etf)">
<view></view>
<text>{{ etf.name }}</text>
<div class="btn-play"></div>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="r_logout">
<view class="logout" @click="loginOut" v-if="Session.get('token')">退出登录</view>
</view>
<LoginPopup
:show="LoginShow"
@handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback"
@handlePopupErrorCallback="handlePopupErrorCallback"
/>
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted, reactive } from "vue";
import Line from "@/components/charts/Line.vue";
import bannerImg from "@/assets/zixun/banner_pic1.png";
import bannerTitle from "@/assets/zixun/banner_title.png";
import bannerTitle2 from "@/assets/zixun/banner_title3.png";
import icon_search from "@/assets/zixun/icon_search.png";
import time_icon from "@/assets/zixun/time_icon.png";
import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage";
import dayjs from "dayjs/esm/index";
import { onReachBottom } from "@dcloudio/uni-app";
import { getEtfIndexList } from "@/api/index";
const listData = ref([
// {
// day: "2026-10-26",
// list: [
// {
// time: "11:30:56",
// title: "",
// summary: "9",
// etfs: [
// {
// name: " ETF",
// code: "string",
// },
// ],
// },
// ],
// },
]);
const form = ref({
page: 1,
keyword: null,
});
async function getData() {
uni.showLoading({
title: "加载中",
});
let { code, data } = await getEtfIndexList({
...form.value,
size: 20,
});
uni.hideLoading();
if (code == 200) {
if (form.value.page == 1) {
listData.value = [];
listData.value = data.list;
} else {
// daydaylist
const newList = [...data.list];
const updatedList = [...listData.value];
newList.forEach(newItem => {
// day
const existingItemIndex = updatedList.findIndex(item => item.day === newItem.day);
if (existingItemIndex !== -1) {
// daylist
updatedList[existingItemIndex].list = [...updatedList[existingItemIndex].list, ...newItem.list];
} else {
// day
updatedList.push(newItem);
}
});
listData.value = updatedList;
}
}
}
const LoginShow = ref(false);
const isLoginStatus = ref();
//
const handlePopupClose = () => {
LoginShow.value = false;
};
//
const handlePopupSuccessCallback = () => {
isLoginStatus.value = true;
};
//
const handlePopupErrorCallback = () => {
console.log("登录失败");
};
import { doLogout } from "@/api";
import { onPullDownRefresh } from "@dcloudio/uni-app";
function loginOut() {
doLogout({
financialAccount: Session.get("userPhone"),
});
Session.clear();
window.location.reload();
}
onReachBottom(() => {
form.value.page++;
getData();
});
function goDetail(item, index) {
if (Session.get("token")) {
uni.navigateTo({
url: `/pages/detail/indexNewsInfo?id=${item.id}&intoType=etf`,
});
} else {
LoginShow.value = true;
}
}
function goEtfDetail(item) {
console.log("🚀 ~ goEtfDetail ~ item:", item);
uni.navigateTo({
url: `/pages/realtimeInfo/indexEtfInfo?name=${item.name}&code=${item.code}`,
});
}
function onSreach() {
if (Session.get("token")) {
form.value.page = 1;
getData();
} else {
LoginShow.value = true;
}
}
onMounted(async () => {
if (!Session.get("token")) {
LoginShow.value = true;
}
getData();
});
</script>
<style scoped lang="scss">
.all {
display: flex;
flex-direction: column;
position: relative;
.top_menu_text {
position: absolute;
top: 60rpx;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 34rpx;
color: #ffffff;
line-height: 36rpx;
text-align: center;
font-style: normal;
}
}
.banner {
position: relative;
}
.banner_bk {
width: 100vw;
}
.r_banner_title {
position: absolute;
top: 200rpx;
left: 50rpx;
display: flex;
flex-direction: column;
.banner_title {
width: 461rpx;
height: 110rpx;
}
text {
font-family: AlibabaPuHuiTiM;
font-size: 32rpx;
color: #ffffff;
line-height: 44rpx;
text-align: left;
font-style: normal;
}
}
.r_logout {
position: fixed;
bottom: 0rpx;
right: 0rpx;
z-index: 9999;
background-color: white;
width: 100vw;
height: auto;
box-shadow: 0 -10rpx 20rpx rgba(73, 73, 73, 0.1);
}
.logout {
// width: 100%;
height: 80rpx;
background-color: red;
display: flex;
text-align: center;
justify-content: center;
align-items: center;
color: white;
margin-top: 20rpx;
border-radius: 20rpx;
margin-left: 20rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
}
.logo_text {
width: 88rpx;
height: 40rpx;
}
.top_bk {
width: 100vw;
height: 60px;
}
.list_content {
position: relative;
z-index: 9999;
// margin-top: -70px;
// padding: 10rpx 30rpx;
background-color: #f3f5f8;
// background: linear-gradient(180deg, #ffffff 0%, #f3f5f8 100%);
// min-height: 80vh;
.r_sreach {
position: relative;
z-index: 99999;
margin-top: -120rpx;
border-radius: 24rpx 24rpx 0rpx 0rpx;
// width: 100%;
height: 120rpx;
display: flex;
align-items: center;
// margin-top: 30rpx;
padding-top: 30rpx;
padding: 0 30rpx;
background-color: white;
background-image: linear-gradient(to bottom, white 60rpx, #f3f5f8);
// background: linear-gradient(to bottom, #ffffff 0%, #f3f5f8 100%);
}
.sreach {
display: flex;
align-items: center;
padding: 0rpx 30rpx;
background-color: #fff;
border-radius: 100rpx;
width: 100%;
height: 100%;
background: #f3f5f8;
border-radius: 36rpx;
// box-shadow: 0 0 10rpx rgba(97, 97, 97, 0.1);
}
.sreach_icon {
margin-right: 10rpx;
display: flex;
align-items: center;
image {
width: 35rpx;
height: 35rpx;
margin-top: 5rpx;
}
}
.sreach_text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
}
.item_day {
font-family: PingFangSC, PingFang SC;
font-weight: bold;
font-size: 24rpx;
color: #222222;
text-align: left;
font-style: normal;
margin-top: -10rpx;
margin-left: 10rpx;
}
.r_list {
padding: 10rpx 30rpx;
margin-top: -30rpx;
}
.item_top {
display: flex;
margin-top: 40rpx;
padding: 0 30rpx;
.r_line {
display: flex;
flex-direction: column;
align-items: center;
}
.item_point {
width: 12rpx;
height: 12rpx;
background: #eb5d46;
border-radius: 100rpx;
}
.item_line {
width: 1rpx;
height: 35rpx;
border-left: 2px dashed #d9d7d7;
}
}
.list_card {
display: flex;
// height: 334rpx;
background: #ffffff;
border-radius: 24rpx;
padding: 30rpx 30rpx;
.card_left {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 25rpx;
img {
width: 8rpx;
height: 33rpx;
}
.left_line {
width: 1rpx;
height: 100%;
border-left: 2px dashed #d9d7d7;
margin-top: 10rpx;
}
}
.card_right {
display: flex;
flex-direction: column;
margin-left: 20rpx;
width: 95%;
margin-top: 10rpx;
gap: 10rpx;
.item_time {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 32rpx;
color: #222222;
line-height: 44rpx;
text-align: left;
font-style: normal;
display: flex;
justify-content: space-between;
margin-top: 10rpx;
}
.item_title {
width: 100%;
margin-top: 30rpx;
text {
font-family: PingFangSC, PingFang SC;
font-weight: bold;
font-size: 28rpx;
color: #222222;
line-height: 40rpx;
text-align: left;
font-style: normal;
display: inline-block;
/* 或 block */
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.item_summary {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #666666;
line-height: 44rpx;
text-align: left;
font-style: normal;
margin-top: 10rpx;
/* 1. 必须将元素设置为块级或弹性盒 */
display: -webkit-box;
/* 2. 定义盒模型的排列方向为垂直 */
-webkit-box-orient: vertical;
/* 3. 限制显示的行数 */
-webkit-line-clamp: 2;
/* 4. 隐藏超出的内容 */
overflow: hidden;
/* 5. (可选) 当文本溢出时显示省略号 */
text-overflow: ellipsis;
}
.item_source_title {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #b3b3b3;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
.item_source {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #5978b2;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
.item_etf {
display: flex;
flex-wrap: wrap;
margin-top: 10rpx;
gap: 20rpx;
margin-top: 30rpx;
margin-bottom: 30rpx;
.item_etf_item {
// width: 168rpx;
width: calc(50% - 60rpx);
height: 48rpx;
background: #edf1f5;
border-radius: 125rpx;
padding: 5rpx 25rpx;
display: flex;
align-items: center;
text-align: center;
justify-content: space-between;
text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #666666;
line-height: 44rpx;
text-align: left;
font-style: normal;
}
}
/* 容器样式(模拟红框) */
.btn-play {
display: inline-flex;
align-items: center;
border-radius: 10rpx;
}
/* 三角形伪元素 */
.btn-play::before {
content: "";
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 8px solid #999;
/* 注意这里是border-left因为三角形朝右时左边框是实心 */
margin-left: 4px;
/* 与文字的间距(从右边移到左边) */
}
/* 文字部分 */
.btn-play span {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #666666;
line-height: 44rpx;
text-align: left;
font-style: normal;
}
}
}
}
</style>

View File

@ -0,0 +1,262 @@
<template>
<div class="index-etf-info">
<!-- 头部 -->
<view class="vipHeader">
<view class="flashBack" @click="doBack">
<u-icon size="20" name="arrow-left" color="#000"></u-icon>
</view>
<view style="display: flex; flex-direction: column">
<view class="title">{{ name }}</view>
<view class="title_sub">{{ code }}</view>
</view>
<view style="width: 5%"></view>
</view>
<view style="width: 100vw; height: 10rpx; background-color: #f5f5f5"></view>
<!-- 指数ETF实时信息展示区域 -->
<view class="r_list">
<view v-for="(item, index) in etfInfoList" :key="index" class="news-item" @click="goDetail(item, 0)">
<view class="news-content">
<text class="news-title">{{ item.title }}</text>
<text class="news-desc">{{ item.summary }}</text>
<view class="news-meta">
<view>
<text class="time">
{{ timeFormat(new Date(item.publish_time).getTime()) }}
</text>
</view>
<text class="time">中国证券报</text>
</view>
</view>
</view>
</view>
</div>
</template>
<script setup>
import { onLoad } from "@dcloudio/uni-app";
import { ref } from "vue";
import { fetchEtfDetail } from "@/api/index";
// 使 Vue3 <script setup>
//
const etfInfoList = ref([]);
async function getEtfInfo() {
uni.showLoading({
title: "加载中",
});
let { code, data } = await fetchEtfDetail({
etfName: name.value,
});
uni.hideLoading();
if (code === 200) {
console.log(data);
etfInfoList.value = data.list;
}
}
/**
* @description 格式化时间
* @param {String|Number} dateTime 需要格式化的时间戳
* @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
* @returns {string} 返回格式化后的字符串
*/
function timeFormat(dateTime = null, formatStr = "yyyy-mm-dd hh:MM:ss") {
let date;
//
if (!dateTime) {
date = new Date();
}
// unix
else if (/^\d{10}$/.test(dateTime.toString().trim())) {
date = new Date(dateTime * 1000);
}
// new Date
else if (typeof dateTime === "string" && /^\d+$/.test(dateTime.trim())) {
date = new Date(Number(dateTime));
}
// RFC 2822
else {
// Safari/Webkitnew Date/
date = new Date(typeof dateTime === "string" ? dateTime.replace(/-/g, "/") : dateTime);
}
const timeSource = {
y: date.getFullYear().toString(), //
m: (date.getMonth() + 1).toString().padStart(2, "0"), //
d: date.getDate().toString().padStart(2, "0"), //
h: date.getHours().toString().padStart(2, "0"), //
M: date.getMinutes().toString().padStart(2, "0"), //
s: date.getSeconds().toString().padStart(2, "0"), //
//
};
for (const key in timeSource) {
const [ret] = new RegExp(`${key}+`).exec(formatStr) || [];
if (ret) {
//
const beginIndex = key === "y" && ret.length === 2 ? 2 : 0;
formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex));
}
}
return formatStr;
}
function goDetail(item, index) {
uni.navigateTo({
url: `/pages/detail/indexNewsInfo?id=${item.id}&intoType=etf`,
});
}
function doBack() {
uni.navigateBack({
delta: 1,
});
}
const name = ref("");
const code = ref("");
onLoad((option) => {
console.log(option.name);
name.value = option.name;
code.value = option.code;
getEtfInfo();
});
</script>
<style scoped lang="scss">
.news-item {
display: flex;
align-items: flex-start;
margin-bottom: 15px;
border-bottom: 1px solid #f2f2f2;
padding-bottom: 10px;
}
.news-content {
flex: 1;
display: flex;
flex-direction: column;
}
.r_list {
padding: 30rpx;
width: calc(100vw - 60rpx);
}
.news-title {
font-family: PingFangSC, PingFang SC;
font-weight: bold;
font-size: 30rpx;
color: #222222;
line-height: 42rpx;
text-align: left;
font-style: normal;
margin-bottom: 5px;
line-height: 1.2;
width: calc(100vw - 60rpx);
display: inline-block;
/* 或 block */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.news-desc {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #333333;
text-align: left;
font-style: normal;
display: -webkit-box;
/* 设置为WebKit内核的弹性盒子模型 */
-webkit-box-orient: vertical;
/* 垂直排列 */
-webkit-line-clamp: 2;
/* 限制显示三行 */
overflow: hidden;
/* 隐藏超出范围的内容 */
text-overflow: ellipsis;
/* 使用省略号 */
width: calc(100vw - 60rpx);
margin-top: 10rpx;
}
.news-meta {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #999;
margin-top: 26rpx;
}
.source,
.time,
.score {
// opacity: 0.8;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 22rpx;
color: #999999;
line-height: 30rpx;
text-align: left;
font-style: normal;
}
.time {
// margin-left: 10rpx;
}
.score {
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 22rpx;
color: #ffa800;
line-height: 30rpx;
text-align: center;
font-style: normal;
}
.vipHeader {
width: 100vw;
height: 120rpx;
background-color: white;
box-sizing: border-box;
padding: 32rpx 32rpx 6rpx 40rpx;
display: flex;
justify-content: space-between;
// position: sticky;
// top: 0;
// z-index: 9999;
.flashBack {
height: 100%;
display: flex;
align-items: center;
}
.title {
font-size: 32rpx;
color: #000;
font-weight: bold;
left: 0;
}
.title_sub {
font-size: 24rpx;
color: #999;
font-weight: 400;
left: 0;
}
}
</style>

View File

@ -0,0 +1,623 @@
<template>
<!-- 顶部 banner 区域 -->
<view class="all">
<!-- banner start -->
<view class="banner">
<img :src="bannerImg" class="banner_bk" />
<view class="r_banner_title">
<img :src="bannerTitle2" class="banner_title" />
<text>数据更新时间:{{ dayjs(new Date().getTime()).format("YYYY-MM-DD") }}</text>
</view>
</view>
<!-- banner end -->
<view>
<!-- <view class="tag">
<view class="r_tag_img">
<img :src="tagicon_1_bg" class="tag_bk" />
<view class="tag_content">
<view class="tag_item_left">
<text class="tag_title">行业分类贴标</text>
<view style="display: flex; margin-top: 15rpx">
<countTo :startVal="lastLeftNum" :endVal="topNum.leftNum" :duration="5000" class="tag_num"></countTo>
<text class="tag_status">已处理</text>
</view>
</view>
<view class="tag_item_right">
<img :src="tagicon_1" class="tag_icon" />
</view>
</view>
</view>
<view class="r_tag_img">
<img :src="tagicon_2_bg" class="tag_bk" />
<view class="tag_content">
<view class="tag_item_left">
<text class="tag_title">概念标签贴标</text>
<view style="display: flex; margin-top: 15rpx">
<countTo :startVal="lastRightNum" :endVal="topNum.rightNum" :duration="5000" class="tag_num"></countTo>
<text class="tag_status">已处理</text>
</view>
</view>
<view class="tag_item_right">
<img :src="tagicon_2" class="tag_icon" />
</view>
</view>
</view>
</view> -->
</view>
<view style="background-color: white; margin-top: -100rpx; position: relative; z-index: 9999">
<indexMenuTitle title="近7天热度统计"></indexMenuTitle>
<LineHol v-if="lineTabIndex === 0" barColor="#3C74F1" :data="lineTopData"></LineHol>
<LineHol v-else-if="lineTabIndex === 1" barColor="#FFCC65" :data="lineTopData"></LineHol>
<LineHolYellow v-else-if="lineTabIndex === 2" barColor="#8B2DD4" :data="lineTopData"></LineHolYellow>
<div style="display: flex; justify-content: center; margin-bottom: 20px; margin-top: 20px">
<div class="tabs">
<div :class="['tab', 'tab_left', { active: lineTabIndex === 0 }]" @click="handleTabClick(0)">申万行业</div>
<div :class="['tab', { active: lineTabIndex === 1 }]" @click="handleTabClick(1)">概念标签</div>
<div :class="['tab', 'tab_right', { active: lineTabIndex === 2 }]" @click="handleTabClick(2)">媒体来源</div>
</div>
</div>
</view>
<!-- <view style="background-color: white; margin-top: 40rpx">
<indexMenuTitle title="资讯评分分布区间"></indexMenuTitle>
<Line style="margin-top: 30rpx" :data="lineData"></Line>
<view style="display: flex; flex-direction: column; text-align: center; justify-content: center; align-items: center; padding-bottom: 30rpx">
<InfoSummary style="width: 85%" :count="newsNum"></InfoSummary>
</view>
</view> -->
<view style="background-color: white; padding-top: 40rpx">
<view style="width: 100vw; display: flex; justify-content: space-between; align-items: center">
<indexMenuTitle title="编辑精选" style="margin-top: 10rpx"></indexMenuTitle>
<view class="r_sreach">
<!-- <image class="top_bk" src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/top_bg.png"></image> -->
<!-- <image class="logo_text" src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/logo_text_icon.png"> </image> -->
<view class="sreach" @click="goSreach">
<view class="sreach_icon">
<image src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/icon_search_line.png"></image>
</view>
<view class="sreach_text">
<text>搜索资讯</text>
</view>
</view>
</view>
</view>
<view style="width: 100%; display: flex; justify-content: flex-end">
<view
style="
display: flex;
align-items: center;
margin-right: 15rpx;
font-size: 30rpx;
gap: 10rpx;
margin-top: 10rpx;
"
@click="showCalendar"
>
{{ chooseDate.startDate.split(" ")[0] }}
<u-icon name="calendar" size="26" style="margin-right: 10rpx"></u-icon>
</view>
</view>
<RankList hasTag :newsList="newsList" :needExp="false"></RankList>
</view>
<view class="logout" @click="loginOut" v-if="Session.get('token')">退出登录</view>
<u-calendar
:show="calendarShow"
min-date="2025-01-01"
closeOnClickOverlay
:max-date="maxDate"
:default-date="chooseDate.startDate"
monthNum="24"
:key="chooseDate.startDate"
@confirm="calendarConfirm"
@close="calendarShow = false"
>
</u-calendar>
<LoginPopup
:show="LoginShow"
@handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback"
@handlePopupErrorCallback="handlePopupErrorCallback"
/>
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted, reactive } from "vue";
import Line from "@/components/charts/Line.vue";
import bannerImg from "@/assets/zixun/banner_pic.png";
import bannerTitle from "@/assets/zixun/banner_title.png";
import bannerTitle2 from "@/assets/zixun/banner_title2.png";
import tagicon_1_bg from "@/assets/zixun/tagicon_1_bg.png";
import tagicon_2_bg from "@/assets/zixun/tagicon_2_bg.png";
import tagicon_1 from "@/assets/zixun/tagicon_1.png";
import tagicon_2 from "@/assets/zixun/tagicon_2.png";
import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage";
import LineHol from "@/components/charts/LineHol.vue";
import LineHolYellow from "@/components/charts/LineHolYellow.vue";
import {
getindustryCount,
getConceptCount,
getTopNewsAll,
getTopIndustry_d,
getTopConcept_d,
getNews_cnt_d,
newsInfoScore,
getTopConceptPeriod,
getTopIndustryPeriod,
getTopSourcePeriod,
getTopNewsAllRelease,
} from "@/api/newsInfo";
import countTo from "@/components/count-to/vue-countTo.vue";
import RankList from "@/components/RankList.vue"; //
import InfoSummary from "@/components/InfoSummary.vue"; //
import indexMenuTitle from "@/components/indexMenuTitle.vue"; //
import dayjs from "dayjs/esm/index";
import HotIndustryList from "@/components/HotIndustryList.vue"; //
const newsList = ref([]);
const lastLeftNum = ref(0);
const lastRightNum = ref(0);
const industryList = ref([]);
const topConceptList = ref([]);
const newsNum = ref(0);
const lineData = ref();
const handleViewAll = () => {
//
console.log("点击了查看全部");
};
const topNum = ref({});
const d = new Date();
const year = d.getFullYear();
let month = d.getMonth() + 1;
month = month < 10 ? `0${month}` : month;
const date = d.getDate();
const maxDate = ref(`${year}-${month}-${date} 23:59:59`);
const minDate = ref(`${year}-${month}-${date}`);
const calendarShow = ref(false);
const chooseDate = reactive({
startDate: `${year}-${month}-${date}`,
endDate: null,
});
function showCalendar() {
calendarShow.value = true;
}
function calendarConfirm(dateList) {
console.log("🚀 ~ calendarConfirm ~ dateList:", dateList);
if (dateList && dateList.length > 0) {
chooseDate.startDate = dateList[0] + " 00:00:00";
chooseDate.endDate = dateList[dateList.length - 1] + " 23:59:59";
}
getNewsList();
calendarShow.value = false;
console.log("🚀 ~ calendarConfirm ~ chooseDate:", chooseDate);
}
//
async function getTopNum() {
let res1 = await getindustryCount({});
topNum.value.leftNum = res1.aggregations.industry_non_empty.doc_count;
let res2 = await getConceptCount({});
topNum.value.rightNum = res2.aggregations.concept_non_empty.doc_count;
lastLeftNum.value = topNum.value.leftNum;
lastRightNum.value = topNum.value.rightNum;
}
//
async function getNewsList() {
console.log(`🚀 ~ getNewsList ~ chooseDate.startDate.split(" ")[0]:`, chooseDate.startDate.split(" ")[0]);
newsList.value = await getTopNewsAllRelease({
input_date: chooseDate.startDate.split(" ")[0],
});
}
// top10
async function getTopIndustry_dFn() {
industryList.value = await getTopIndustry_d({});
}
// top10
async function getTopConcept_dFn() {
topConceptList.value = await getTopConcept_d({});
}
//
async function getNews_cnt_dFn() {
let temp = await getNews_cnt_d({});
newsNum.value = temp[0].value;
}
//
async function getLineData() {
let res = await newsInfoScore({});
lineData.value = res;
}
function initData() {
//
getLineData();
//
getTopNum();
//
getNewsList();
// top10
getTopIndustry_dFn();
// top10
getTopConcept_dFn();
//
getNews_cnt_dFn();
}
const type = ref();
function onViewAll(type) {
type.value = type;
if (Session.get("token")) {
uni.navigateTo({
url: "/pages/realtimeInfo/rankDetail?type=" + type,
});
} else {
LoginShow.value = true;
}
}
const timer = setInterval(() => {
initData();
}, 5000);
const LoginShow = ref(false);
const isLoginStatus = ref();
//
const handlePopupClose = () => {
LoginShow.value = false;
};
//
const handlePopupSuccessCallback = () => {
isLoginStatus.value = true;
// uni.navigateTo({
// url: "/pages/realtimeInfo/rankDetail?type=" + type.value,
// });
};
//
const handlePopupErrorCallback = () => {
console.log("登录失败");
};
import { doLogout } from "@/api";
function loginOut() {
doLogout({
financialAccount: Session.get("userPhone"),
});
Session.clear();
window.location.reload();
}
const lineTabIndex = ref(0);
function handleTabClick(index) {
lineTabIndex.value = index;
getLineDataFn();
}
const lineTopData = ref({});
async function getLineDataFn() {
if (lineTabIndex.value == 0) {
//
getTopIndustryPeriod({
start_time: dayjs().subtract(7, "day").format("YYYY-MM-DD"),
end_time: dayjs().format("YYYY-MM-DD"),
limit_num: 10,
}).then((res) => {
lineTopData.value = res;
});
} else if (lineTabIndex.value == 1) {
//
getTopConceptPeriod({
start_time: dayjs().subtract(7, "day").format("YYYY-MM-DD"),
end_time: dayjs().format("YYYY-MM-DD"),
limit_num: 10,
}).then((res) => {
lineTopData.value = res;
});
} else if (lineTabIndex.value == 2) {
//
getTopSourcePeriod({
start_time: dayjs().subtract(7, "day").format("YYYY-MM-DD"),
end_time: dayjs().format("YYYY-MM-DD"),
limit_num: 10,
}).then((res) => {
lineTopData.value = res;
});
}
}
function goSreach() {
if (Session.get("token")) {
uni.navigateTo({
url: "/pages/sreachReq/index",
});
} else {
LoginShow.value = true;
}
}
onUnmounted(() => {
clearInterval(timer);
});
const { aplus_queue } = window;
onMounted(async () => {
initData();
if (!Session.get("token")) {
LoginShow.value = true;
}
getLineDataFn();
aplus_queue.push({
action: "aplus.sendPV",
arguments: [{ is_auto: false }], //
});
});
</script>
<style scoped lang="scss">
.all {
display: flex;
flex-direction: column;
background: #f3f5f8;
}
.banner {
position: relative;
}
.banner_bk {
width: 100vw;
}
.r_banner_title {
position: absolute;
top: 160rpx;
left: 50rpx;
display: flex;
flex-direction: column;
.banner_title {
width: 364rpx;
height: 134rpx;
}
text {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: rgba(255, 255, 255, 0.8);
}
}
.tag {
display: flex;
margin-top: -150rpx;
position: relative;
z-index: 999;
padding: 0 25rpx;
gap: 20rpx;
}
.r_tag_img {
width: calc(50vw - 20rpx);
height: 175rpx;
position: relative;
box-shadow: 0 10rpx 10rpx rgba(80, 80, 80, 0.1);
border-radius: 20rpx;
}
.tag_bk {
width: 100%;
height: 100%;
}
.tag_content {
display: flex;
position: absolute;
top: 40rpx;
left: 30rpx;
width: 83%;
justify-content: space-between;
.tag_item_left {
display: flex;
flex-direction: column;
}
.tag_title {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #222222;
line-height: 33rpx;
}
.tag_num {
font-family:
PingFangSC,
PingFang SC;
font-weight: bold;
font-size: 38rpx;
color: #222222;
line-height: 56rpx;
}
.tag_status {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 22rpx;
color: #999999;
line-height: 33rpx;
margin-top: 15rpx;
margin-left: 7rpx;
}
.tag_item_right {
width: 70rpx;
height: 84rpx;
}
}
.tag_icon {
width: 70rpx;
height: 84rpx;
}
.view-all {
font-size: 14px;
color: #999;
text-decoration: underline;
}
.logout {
// width: 100%;
height: 80rpx;
background-color: red;
display: flex;
text-align: center;
justify-content: center;
align-items: center;
color: white;
margin-top: 50rpx;
border-radius: 20rpx;
margin-left: 20rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
}
.tabs {
display: flex;
align-items: center;
height: 30px;
border-radius: 10px;
.tab {
width: 100px;
height: 100%;
display: flex;
text-align: center;
justify-content: center;
align-items: center;
border: 1px solid #e7e7e7;
color: #000;
font-size: 12px;
}
.tab_left {
border-start-start-radius: 10px;
border-end-start-radius: 10px;
border-right: 0;
}
.tab_right {
border-start-end-radius: 10px;
border-end-end-radius: 10px;
border-left: 0;
}
.active {
border: 1px solid #3c74f1;
background-color: #3c74f1;
color: #fff;
}
}
.r_sreach {
height: 60px;
display: flex;
align-items: center;
padding: 0 30rpx;
// position: absolute;
// top: 10px;
// left: 0;
// z-index: 9999;
// background: url("https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/top_bg.png");
}
.logo_text {
width: 88rpx;
height: 40rpx;
}
.sreach {
display: flex;
align-items: center;
padding: 0rpx 30rpx;
background-color: #fff;
border-radius: 100rpx;
// width: 90vw;
height: 63rpx;
margin-left: 20rpx;
border: 1px solid #e7e7e7;
margin-top: 5rpx;
// box-shadow: 0 0 10rpx rgba(97, 97, 97, 0.1);
}
.sreach_icon {
margin-right: 10rpx;
display: flex;
align-items: center;
image {
width: 35rpx;
height: 35rpx;
margin-top: 5rpx;
}
}
.sreach_text {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
.top_bk {
width: 100vw;
height: 60px;
}
</style>

View File

@ -2,6 +2,7 @@
<view class="page_top"> <view class="page_top">
<view class="r_menu"> <view class="r_menu">
<image src="@/assets/images/logo.png" class="logo"></image> <image src="@/assets/images/logo.png" class="logo"></image>
<view class="r_menu_item" @click="tabChange(1)"> <view class="r_menu_item" @click="tabChange(1)">
<text class="menu_item">资讯头条榜</text> <text class="menu_item">资讯头条榜</text>
<view class="line" v-if="tabIndex == 1"></view> <view class="line" v-if="tabIndex == 1"></view>
@ -16,6 +17,11 @@
<text class="menu_item">风口概念</text> <text class="menu_item">风口概念</text>
<view class="line" v-if="tabIndex == 3"></view> <view class="line" v-if="tabIndex == 3"></view>
</view> </view>
<view class="r_menu_item" @click="tabChange(4)">
<text class="menu_item">编辑精选</text>
<view class="line" v-if="tabIndex == 4"></view>
</view>
</view> </view>
<view @click="logout" v-if="Session.get('token')"> <view @click="logout" v-if="Session.get('token')">
@ -25,9 +31,10 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, onUnmounted, reactive } from "vue"; import { ref, onMounted, onUnmounted, reactive, nextTick } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app"; import { onLoad, onShow } from "@dcloudio/uni-app";
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
import { doLogout } from "@/api";
const tabIndex = ref(0); const tabIndex = ref(0);
function tabChange(type) { function tabChange(type) {
@ -38,13 +45,41 @@ function tabChange(type) {
}); });
} }
function logout() { import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
async function logout() {
if (Session.get("userPhone")) {
await doLogout({
financialAccount: Session.get("userPhone"),
});
}
Session.clear(); Session.clear();
// token
const { token, ...otherQuery } = route.query;
// token
if (token) {
router.replace({
path: route.path, //
query: otherQuery, //
});
}
nextTick(() => {
setTimeout(() => {
window.location.reload(); window.location.reload();
}, 500);
});
} }
onLoad((e) => { onLoad((e) => {
if (e.type) tabIndex.value = e.type; if (e.type) tabIndex.value = e.type;
console.log("🚀 ~ route.query.token:", route.query.token);
}); });
</script> </script>

View File

@ -19,6 +19,8 @@ onMounted(async () => {
if (route.query.id) { if (route.query.id) {
infoId.value = route.query.id; infoId.value = route.query.id;
} }
// token
console.log("🚀 ~ route.query:", route.query);
if (route.query.type) { if (route.query.type) {
switch (route.query.type) { switch (route.query.type) {
@ -38,11 +40,13 @@ onMounted(async () => {
case "3": case "3":
layoutName.value = "top10"; layoutName.value = "top10";
uni.navigateTo({ uni.navigateTo({
url: url: "/pages/realtimeInfo/pc/top10?type=" + route.query.type + "&name=" + route.query.name,
"/pages/realtimeInfo/pc/top10?type=" + });
route.query.type + break;
"&name=" + case "4":
route.query.name, layoutName.value = "rank";
uni.navigateTo({
url: "/pages/realtimeInfo/pc/rank?type=" + route.query.type,
}); });
break; break;
} }

View File

@ -2,10 +2,7 @@
<view class="pc_all"> <view class="pc_all">
<PageTop></PageTop> <PageTop></PageTop>
<view <view class="content" :style="{ filter: Session.get('token') ? '' : 'blur(5px)' }">
class="content"
:style="{ filter: Session.get('token') ? '' : 'blur(5px)' }"
>
<view class="top" @click="goBack"> <view class="top" @click="goBack">
<image src="@/assets/zixun/icon_fanhui.png" class="icon_back" /> <image src="@/assets/zixun/icon_fanhui.png" class="icon_back" />
<text>返回列表</text> <text>返回列表</text>
@ -22,64 +19,42 @@
<text class="time"> {{ infoData?.publishTime }}</text> <text class="time"> {{ infoData?.publishTime }}</text>
</view> </view>
<view class="abstract"> <view class="abstract" v-if="infoData?.summary">
{{ infoData?.summary }} {{ infoData?.summary }}
</view> </view>
<!-- 两个标签 start --> <!-- 两个标签 start -->
<view class="r_tag_two"> <view class="r_tag_two">
<view <view style="display: flex" v-if="infoData?.industryLabels && infoData?.industryLabels.length > 0">
style="display: flex"
v-if="infoData?.conceptLabels && infoData?.conceptLabels.length > 0"
>
<text class="tag_title">行业分类</text> <text class="tag_title">行业分类</text>
<view class="r_tags"> <view class="r_tags">
<view <view class="tag" style="background-color: #fff9ec; color: #ffb100"
class="tag" v-for="(item, index) in infoData?.industryLabels" :key="index">{{
style="background-color: #fff9ec; color: #ffb100" item
v-for="(item, index) in infoData?.industryLabels" }}</view>
:key="index"
>{{ item }}</view
>
</view> </view>
</view> </view>
<view <view style="display: flex" v-if="infoData?.conceptLabels && infoData?.conceptLabels.length > 0">
style="display: flex"
v-if="infoData?.industryLabels && infoData?.industryLabels.length > 0"
>
<text class="tag_title">概念标签</text> <text class="tag_title">概念标签</text>
<view class="r_tags"> <view class="r_tags">
<view <view class="tag" style="background-color: #f5f8fe; color: #007aff"
class="tag" v-for="(item, index) in infoData?.conceptLabels" :key="index">{{
style="background-color: #f5f8fe; color: #007aff" item
v-for="(item, index) in infoData?.conceptLabels" }}</view>
:key="index"
>{{ item }}</view
>
</view> </view>
</view> </view>
</view> </view>
<!-- 两个标签 end --> <!-- 两个标签 end -->
<view <view class="text" v-html="infoData.content" style="white-space: pre-wrap"> </view>
class="text"
v-html="infoData.content"
style="white-space: pre-wrap"
>
</view>
<!-- <view class="text"> <!-- <view class="text">
<text >{{ infoData.content }}</text> <text >{{ infoData.content }}</text>
</view> --> </view> -->
</view> </view>
<LoginPopup <LoginPopup :show="LoginShow" mode="center" @handlePopupClose="handlePopupClose"
:show="LoginShow" @handlePopupSuccessCallback="handlePopupSuccessCallback" @handlePopupErrorCallback="handlePopupErrorCallback" />
mode="center"
@handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback"
@handlePopupErrorCallback="handlePopupErrorCallback"
/>
</view> </view>
</template> </template>
@ -90,6 +65,7 @@ import { fetchArticleDetail } from "@/api/detail";
import LoginPopup from "@/components/loginPopup/index.vue"; import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
function goBack() { function goBack() {
// uni.navigateBack(); // uni.navigateBack();
@ -268,6 +244,8 @@ const handlePopupErrorCallback = () => {
border-radius: 20rpx; border-radius: 20rpx;
margin-top: 50rpx; margin-top: 50rpx;
} }
.r_tag_two { .r_tag_two {

View File

@ -2,55 +2,76 @@
<view class="pc_all"> <view class="pc_all">
<PageTop></PageTop> <PageTop></PageTop>
<view <view class="content" :style="{ filter: Session.get('token') ? '' : 'blur(5px)' }">
class="content"
:style="{ filter: Session.get('token') ? '' : 'blur(5px)' }"
>
<view class="top_title"> <view class="top_title">
<text class="pageTitle">资讯头条榜</text> <text class="pageTitle" v-if="pageType != 4">资讯头条榜</text>
<image src="@/assets/zixun/top20_icon.png" class="title_icon"></image> <text class="pageTitle" v-if="pageType == 4">编辑精选</text>
<image src="@/assets/zixun/top20_icon.png" class="title_icon" v-if="pageType != 4"></image>
<!-- <u-input v-if="pageType == 4" placeholder="请输入搜索内容" v-model="form.keyword" prefixIcon="search"
@keyup.enter="getNewsList" @blur="getNewsList" prefixIconStyle="font-size: 22px;color: #909399"
style="margin-left: 40rpx; margin-top: 5rpx; border-radius: 20rpx">
<template #suffix>
<u-button @tap="getNewsList" text="搜索" size="mini" class="search_btn"></u-button>
</template>
</u-input> -->
<div class="r_input" v-if="pageType == 4">
<input
v-model="form.keyword"
placeholder="请输入搜索内容"
class="input"
@keyup.enter="getNewsList"
@clear="getNewsList"
@blur="getNewsList"
/>
<div class="input_button" @click="getNewsList">搜索</div>
</div>
</view> </view>
<view class="line"></view> <view class="line"></view>
<view class="r_list"> <view class="r_list">
<view class="list_item" v-for="(item, index) in newsList" :key="index"> <view class="list_item" v-for="(item, index) in newsList" :key="index">
<view class="r_list_item_num"> <view class="r_list_item_num" v-if="pageType != 4">
<view class="list_item_num num1" v-if="index < 3 && index == 0">{{ <view class="list_item_num num1" v-if="index < 3 && index == 0">{{ index + 1 }}</view>
index + 1 <view class="list_item_num num2" v-else-if="index < 3 && index == 1">{{ index + 1 }}</view>
}}</view> <view class="list_item_num num3" v-else-if="index < 3 && index == 2">{{ index + 1 }}</view>
<view
class="list_item_num num2"
v-else-if="index < 3 && index == 1"
>{{ index + 1 }}</view
>
<view
class="list_item_num num3"
v-else-if="index < 3 && index == 2"
>{{ index + 1 }}</view
>
<view class="list_item_num nol_num" v-else>{{ index + 1 }}</view> <view class="list_item_num nol_num" v-else>{{ index + 1 }}</view>
</view> </view>
<view class="list_item_content"> <view class="list_item_content">
<text class="item_title" @click="goDetail(item)">{{ <text class="item_title" @click="goDetail(item)" v-html="item.title"></text>
item.title <text class="item_summary" v-if="pageType != 4">{{ item.summary }}</text>
}}</text> <text class="item_summary" v-if="pageType == 4" v-html="item.summary"></text>
<text class="item_summary">{{ item.summary }}</text>
<view class="item_bottom"> <view class="item_bottom">
<view> <view>
<text class="time">{{ item.source }}</text> <text class="time">{{ item.source }}</text>
<text class="time" style="margin-left: 30rpx">{{ <text class="time" style="margin-left: 30rpx" v-if="pageType != 4">{{
dayjs(item.publish_time).format("YYYY-MM-DD HH:MM:ss") dayjs(item.publish_time).format("YYYY-MM-DD HH:MM:ss")
}}</text> }}</text>
<text class="time" style="margin-left: 30rpx" v-if="pageType == 4">{{ formatTime(item.time) }}</text>
</view> </view>
<text class="score">{{ item.news_score }}</text> <text class="score" v-if="pageType != 4">{{ item.news_score }}</text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<div
style="width: 100%; display: flex; justify-content: center"
v-if="pageType == 4 && newsList && newsList.length > 0"
>
<el-pagination
v-model:current-page="currentPage"
:page-size="form.size"
layout="prev, pager, next"
:total="form.total"
@current-change="currentChange"
@size-change="sizeChange"
/>
</div>
</view> </view>
<LoginPopup <LoginPopup
:show="LoginShow" :show="LoginShow"
@ -65,30 +86,133 @@
<script setup> <script setup>
import { ref, onMounted, onUnmounted, reactive } from "vue"; import { ref, onMounted, onUnmounted, reactive } from "vue";
import PageTop from "@/pages/realtimeInfo/pc/components/PageTop.vue"; import PageTop from "@/pages/realtimeInfo/pc/components/PageTop.vue";
import { getTopNews } from "@/api/newsInfo"; import { getTopNewsDay } from "@/api/newsInfo";
import dayjs from "dayjs/esm/index"; import dayjs from "dayjs/esm/index";
import LoginPopup from "@/components/loginPopup/index.vue"; import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
import { editTopNews } from "@/api/index";
import { sendToken } from "@/api/index";
import { useRoute, useRouter } from "vue-router";
const pageSizes = ref([10, 20, 30, 40]);
const form = reactive({
keyword: "",
page: 1,
size: 10,
total: 10,
});
const currentPage = ref(form.page);
const route = useRoute();
const router = useRouter();
const pageType = ref(route.query.type);
const newsList = ref([]); const newsList = ref([]);
// function formatTime(timestamp) {
const date = new Date(Number(timestamp).toString().length === 10 ? timestamp * 1000 : timestamp);
return (
[
date.getFullYear(),
(date.getMonth() + 1).toString().padStart(2, "0"),
date.getDate().toString().padStart(2, "0"),
].join("-") +
" " +
[
date.getHours().toString().padStart(2, "0"),
date.getMinutes().toString().padStart(2, "0"),
date.getSeconds().toString().padStart(2, "0"),
].join(":")
);
}
async function getNewsList() { async function getNewsList() {
newsList.value = await getTopNews({}); if (pageType.value == 4) {
//
let { code, data } = await editTopNews({
...form,
});
if (code == 200) {
newsList.value = data.list;
form.total = data.total;
data.list.forEach((item) => {
item.summary = item.summary.replace(form.keyword, "<span style='color: #007aff'>" + form.keyword + "</span>");
item.title = item.title.replace(form.keyword, "<span style='color: #007aff'>" + form.keyword + "</span>");
});
}
} else {
//
newsList.value = await getTopNewsDay({});
}
} }
function goDetail(item) { function goDetail(item) {
let id = null;
if (pageType.value != 4) {
id = item.news_id;
} else {
id = item.id;
}
uni.navigateTo({ uni.navigateTo({
url: "/pages/realtimeInfo/pc/indexPC?id=" + item.news_id + "&type=1", url: "/pages/realtimeInfo/pc/indexPC?id=" + id + "&type=" + pageType.value,
}); });
} }
onMounted(async (e) => { function currentChange(page) {
form.page = page;
getNewsList(); getNewsList();
}
if (!Session.get("token")) { onMounted(async (e) => {
console.log("🚀 ~ route.query:", route.query);
console.log(`🚀 ~ Session.get("token"):`, Session.get("token"));
if (Session.get("token") == "undefined") {
Session.remove("token");
}
if (route.query?.token && (!Session.get("token") || Session.get("token") == "undefined")) {
uni.showLoading({
title: "加载中",
mask: true,
});
sendToken({
token: route.query.token,
}).then((res) => {
uni.hideLoading();
if (res.code == 200) {
Session.set("token", res.data.token);
Session.set("userPhone", res.data.phone);
// token
const { token, ...otherQuery } = route.query;
// token
if (token) {
router.replace({
path: route.path, //
query: otherQuery, //
});
}
setTimeout(() => {
window.location.reload();
}, 500);
}
});
} else {
if (!Session.get("token") || Session.get("token") == "undefined") {
LoginShow.value = true; LoginShow.value = true;
} }
}
// token
const { token, ...otherQuery } = route.query;
// token
if (token) {
router.replace({
path: route.path, //
query: otherQuery, //
});
}
getNewsList();
}); });
const LoginShow = ref(false); const LoginShow = ref(false);
@ -170,7 +294,9 @@ const handlePopupErrorCallback = () => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-family: PingFangSC, PingFang SC; font-family:
PingFangSC,
PingFang SC;
font-weight: 500; font-weight: 500;
font-size: 18px; font-size: 18px;
color: #ffffff; color: #ffffff;
@ -186,13 +312,16 @@ const handlePopupErrorCallback = () => {
background: linear-gradient(169deg, #a9c3e3 0%, #92b2e0 100%); background: linear-gradient(169deg, #a9c3e3 0%, #92b2e0 100%);
border-radius: 3px; border-radius: 3px;
} }
.num3 { .num3 {
background: linear-gradient(169deg, #f2996e 0%, #f77741 100%); background: linear-gradient(169deg, #f2996e 0%, #f77741 100%);
border-radius: 3px; border-radius: 3px;
} }
.nol_num { .nol_num {
font-family: PingFangSC, PingFang SC; font-family:
PingFangSC,
PingFang SC;
font-weight: 500; font-weight: 500;
font-size: 20px; font-size: 20px;
color: #93a2b3; color: #93a2b3;
@ -211,8 +340,11 @@ const handlePopupErrorCallback = () => {
.item_title:hover { .item_title:hover {
color: #057cff; color: #057cff;
} }
.item_title { .item_title {
font-family: PingFangSC, PingFang SC; font-family:
PingFangSC,
PingFang SC;
font-weight: bold; font-weight: bold;
font-size: 20px; font-size: 20px;
color: #1a1a1a; color: #1a1a1a;
@ -220,11 +352,30 @@ const handlePopupErrorCallback = () => {
} }
.item_summary { .item_summary {
font-family: PingFangSC, PingFang SC; font-family:
PingFangSC,
PingFang SC;
font-weight: normal; font-weight: normal;
font-size: 16px; font-size: 16px;
color: #333333; color: #333333;
margin-top: 20rpx; margin-top: 20rpx;
/* 必须:限制内容不溢出容器 */
overflow: hidden;
/* 必须:超出部分显示省略号 */
text-overflow: ellipsis;
/* 必须将元素设置为webkit弹性盒模型用于控制行数 */
display: -webkit-box;
/* 关键限制显示的行数这里设为2行 */
-webkit-line-clamp: 2;
/* 必须:设置弹性盒的排列方向为垂直(让文本换行) */
-webkit-box-orient: vertical;
/* 可选调整行高和容器高度确保刚好容纳2行文本 */
line-height: 1.5;
/* 行高 */
max-height: 3em;
/* 2行总高度 = 行高 × 21.5×2=3 */
} }
} }
@ -233,8 +384,11 @@ const handlePopupErrorCallback = () => {
justify-content: space-between; justify-content: space-between;
margin-top: 30rpx; margin-top: 30rpx;
margin-bottom: 10rpx; margin-bottom: 10rpx;
.time { .time {
font-family: PingFangSC, PingFang SC; font-family:
PingFangSC,
PingFang SC;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
color: #919191; color: #919191;
@ -244,7 +398,9 @@ const handlePopupErrorCallback = () => {
} }
.score { .score {
font-family: PingFangSC, PingFang SC; font-family:
PingFangSC,
PingFang SC;
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: 18px;
color: #ffa800; color: #ffa800;
@ -253,4 +409,75 @@ const handlePopupErrorCallback = () => {
font-style: normal; font-style: normal;
} }
} }
.search_btn {
border: none;
display: flex;
width: 56px;
height: 44px;
padding: 8px 15px;
justify-content: center;
align-items: center;
gap: 10px;
flex-shrink: 0;
border-radius: 8px;
background: #0062d9;
margin-right: 5px;
}
.input {
border: none;
flex: 1;
margin-left: 10px;
}
.input_button {
display: flex;
width: 140px;
height: 100%;
// padding: 8px 15px;
justify-content: center;
align-items: center;
gap: 10px;
flex-shrink: 0;
border-radius: 0 10px 10px 0;
background: #007aff;
color: white;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 18px;
color: #ffffff;
line-height: 25px;
text-align: left;
font-style: normal;
cursor: pointer;
}
.r_input {
background-color: white;
border-radius: 10px;
border: 1px solid #e3e3e3;
flex: 1;
height: 52px;
display: flex;
align-items: center;
margin-left: 30px;
margin-top: 3px;
:deep(.el-input__inner::placeholder) {
color: #ccced3;
font-family: "PingFang SC";
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
:deep(.el-input__wrapper) {
box-shadow: 0 0 0 #fff;
}
}
</style> </style>

View File

@ -1,19 +1,12 @@
<template> <template>
<view class="all"> <view class="all">
<PageHeaderView <PageHeaderView :title="type == 0 ? '热门行业池Top10' : '风口概念池Top10'"></PageHeaderView>
:title="type == 0 ? '热门行业池Top10' : '风口概念池Top10'"
></PageHeaderView>
<!-- 类目标签 start --> <!-- 类目标签 start -->
<view class="page_content"> <view class="page_content">
<view class="tag_list"> <view class="tag_list">
<view <view :class="['tag_item', clickTagIndex == index ? tagClickedClass : '']" class="tag_item"
:class="['tag_item', clickTagIndex == index ? tagClickedClass : '']" v-for="(item, index) in tagList" :key="index" @click="clickTag(index)">
class="tag_item"
v-for="(item, index) in tagList"
:key="index"
@click="clickTag(index)"
>
{{ item.content }} {{ item.content }}
</view> </view>
</view> </view>
@ -22,12 +15,7 @@
<!-- 列表 start --> <!-- 列表 start -->
<view class="list"> <view class="list">
<view <view v-for="(item, index) in list" :key="index" class="news-item" @click="goDetail(item)">
v-for="(item, index) in list"
:key="index"
class="news-item"
@click="goDetail(item)"
>
<view class="news-content"> <view class="news-content">
<text class="news-title">{{ item.title }}</text> <text class="news-title">{{ item.title }}</text>
<text class="news-desc">{{ item.summary }}</text> <text class="news-desc">{{ item.summary }}</text>
@ -165,6 +153,12 @@ onMounted(async () => {
} }
getListByTagFn(); getListByTagFn();
const { aplus_queue } = window;
aplus_queue.push({
action: 'aplus.sendPV',
arguments: [{ is_auto: false }] //
});
}); });
</script> </script>
@ -254,11 +248,16 @@ onMounted(async () => {
text-align: left; text-align: left;
font-style: normal; font-style: normal;
display: -webkit-box; /* 设置为WebKit内核的弹性盒子模型 */ display: -webkit-box;
-webkit-box-orient: vertical; /* 垂直排列 */ /* 设置为WebKit内核的弹性盒子模型 */
-webkit-line-clamp: 2; /* 限制显示三行 */ -webkit-box-orient: vertical;
overflow: hidden; /* 隐藏超出范围的内容 */ /* 垂直排列 */
text-overflow: ellipsis; /* 使用省略号 */ -webkit-line-clamp: 2;
/* 限制显示三行 */
overflow: hidden;
/* 隐藏超出范围的内容 */
text-overflow: ellipsis;
/* 使用省略号 */
} }
.news-meta { .news-meta {

View File

@ -1,64 +1,58 @@
<template> <template>
<view class="sreachcss"> <view class="sreachcss">
<!-- 导航栏 start -->
<!-- <view
class="custom-bav-bar"
:style="{
position: 'sticky',
top: getNavHeight() + 'px',
left: 0,
background: '#fff',
zIndex: '9999',
}">
<view class="left">
<image src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/static/icon_left.png" class="back_icon" @click="handleBack" />
</view>
<view class="center">
<image src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/images/detail_logo.png" class="logo_icon" />
</view>
</view> -->
<!-- 搜索 start --> <!-- 搜索 start -->
<view class="sreach"> <view class="sreach">
<view <image src="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/static/icon_left.png" class="back_icon"
style="height: 100%; display: flex; align-items: center" @click="handleBack" />
@click="goBack"
>
<u-icon name="arrow-left" color="#333" size="20" bold></u-icon>
</view>
<view style="width: 60vw; margin-left: 50rpx"> <view style="width: 75vw">
<u-input <u-input v-model="keyWord" @change="handleChange" confirm-type="search" @confirm="getData()" prefixIcon="search"
v-model="keyWord" style="flex: 1" placeholder="搜索资讯" class="sreach_input" :border="false" />
@change="handleChange"
prefixIcon="search"
style="flex: 1"
placeholder="搜索快讯"
class="sreach_input"
:border="false"
/>
</view> </view>
<text class="serach_btn" @click="getData()">搜索</text>
</view> </view>
<!-- 搜索 end --> <!-- 搜索 end -->
<List <List :data="screenList" @onClick="handleSwiperJump" v-if="screenList.length !== 0" />
:data="screenList"
@onClick="handleSwiperJump"
v-if="screenList.length !== 0"
/>
<!-- 列表 end --> <!-- 列表 end -->
<!-- 加载更多的按钮 --> <!-- 加载更多的按钮 -->
<view <!-- <view class="onLoad-btn" @click="onload" v-if="finish === false && inputValue">加载更多</view> -->
class="onLoad-btn"
@click="onload"
v-if="finish === false && inputValue"
>加载更多</view
>
<u-empty <view style="margin-top: 20vh">
v-if="screenList.length === 0" <u-empty v-if="screenList.length === 0" text="无搜索结果" width="157" height="100"
text="搜索结果为空" icon="https://cankao.obs.cn-east-3.myhuaweicloud.com/mini/newmini/nosearch_icon%E5%A4%87%E4%BB%BD%402x.png"></u-empty>
mode="search" </view>
style="margin-top: 20vh"
></u-empty>
<view v-if="finish && screenList.length > 0" class="noMore"> <!-- <view v-if="finish && screenList.length > 0" class="noMore">
<view class="line"></view> <view class="line"></view>
<view class="text">暂无更多结果</view> <view class="text">暂无更多结果</view>
<view class="line"></view> <view class="line"></view>
</view> </view> -->
<!-- 订阅 支付 --> <!-- 订阅 支付 -->
<Pay :show="payShow" @onClick="handleClose" @handleSub="handleSub" /> <Pay :show="payShow" @onClick="handleClose" @handleSub="handleSub" />
<!-- 登录弹框 --> <!-- 登录弹框 -->
<LoginPopup <LoginPopup :show="LoginShow" @handlePopupClose="handlePopupClose"
:show="LoginShow" @handlePopupSuccessCallback="handlePopupSuccessCallback" />
@handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback"
/>
</view> </view>
</template> </template>
@ -66,7 +60,7 @@
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
import { onShow, onLoad } from "@dcloudio/uni-app"; import { onShow, onLoad } from "@dcloudio/uni-app";
import List from "@/components/articleList/index.vue"; import List from "@/components/articleList/index2.vue";
import { searchNews, unlockColumn } from "@/api"; import { searchNews, unlockColumn } from "@/api";
import { extractText, formatTimestamp } from "@/utils/util"; import { extractText, formatTimestamp } from "@/utils/util";
import LoginPopup from "@/components/loginPopup/index.vue"; import LoginPopup from "@/components/loginPopup/index.vue";
@ -82,6 +76,13 @@ function goBack() {
uni.navigateBack(); uni.navigateBack();
} }
//
const handleBack = () => {
uni.navigateBack({
delta: 1,
});
};
// login // login
const LoginShow = ref(false); const LoginShow = ref(false);
@ -99,6 +100,7 @@ const handleSub = async () => {
if (item.type === itemType) { if (item.type === itemType) {
item.needpay = false; item.needpay = false;
} }
return item; return item;
}); });
articleList.value = articleResult; articleList.value = articleResult;
@ -140,14 +142,19 @@ const handleShowPay = (type) => {
// //
const handleSwiperJump = (item: any) => { const handleSwiperJump = (item: any) => {
console.log("item ===>", item); console.log("item ===>", item);
if (item.needpay) { if (Session.get("token")) {
//
handleShowPay(item.type);
} else {
uni.navigateTo({ uni.navigateTo({
url: `/pages/detail/index?id=${item.id}&type=${item.type}`, url: `/pages/detail/indexNewsInfo?id=${item.id}&type=${item.type}`,
}); });
} }
// if (item.needpay) {
// //
// handleShowPay(item.type);
// } else {
// uni.navigateTo({
// url: `/pages/detail/indexNewsInfo?id=${item.id}&type=${item.type}`,
// });
// }
}; };
const handleChange = (val: string) => { const handleChange = (val: string) => {
@ -188,16 +195,14 @@ const getData = async () => {
screenResult = res.data.filter((item) => { screenResult = res.data.filter((item) => {
item.newType = "search"; item.newType = "search";
item.time = formatTimestamp(item.time); item.time = formatTimestamp(item.time);
item.MarkInRedTitle = item.title.replace( item.MarkInRedTitle = item.title.replace(new RegExp(inputValue.value, "gi"), `<text style="color: #E7303F">$&</text>`);
new RegExp(inputValue.value, "gi"),
`<text style="color: #E7303F">$&</text>` item.title = item.title.replace(keyWord.value, '<span style="color: red;">' + keyWord.value + "</span>");
); console.log("🚀 ~ getData ~ item.title :", item.title);
item.MarkInRedContent = item.MarkInRedContent =
item.contentText && item.contentText &&
extractText(item.contentText, inputValue.value).replace( extractText(item.contentText, inputValue.value).replace(new RegExp(inputValue.value, "gi"), `<text style="color: #E7303F">$&</text>`);
new RegExp(inputValue.value, "gi"),
`<text style="color: #E7303F">$&</text>`
);
return item; return item;
}); });
if (screenList.value.length > 0) { if (screenList.value.length > 0) {
@ -223,13 +228,13 @@ onShow(() => {
.sreachcss { .sreachcss {
min-height: 100vh; min-height: 100vh;
background-color: #ffffff; background-color: #ffffff;
padding: 0 30rpx; // padding: 0 30rpx;
.sreach { .sreach {
display: flex; display: flex;
align-items: center; align-items: center;
// height: 60rpx; // height: 60rpx;
gap: 20rpx; // gap: 20rpx;
box-sizing: border-box; box-sizing: border-box;
padding: 12rpx 0; padding: 12rpx 0;
position: sticky; position: sticky;
@ -244,6 +249,12 @@ onShow(() => {
height: 70%; height: 70%;
border-radius: 20rpx; border-radius: 20rpx;
padding: 0 20rpx; padding: 0 20rpx;
border-radius: 100rpx;
margin-left: 10rpx;
}
:deep(.u-input) {
background-color: rgba(118, 118, 128, 0.12);
} }
.tabsListContainer { .tabsListContainer {
@ -260,11 +271,13 @@ onShow(() => {
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
padding: 21rpx 0; padding: 21rpx 0;
.line { .line {
width: 69rpx; width: 69rpx;
height: 3rpx; height: 3rpx;
background-color: #b9b9b9; background-color: #b9b9b9;
} }
.text { .text {
padding: 0 10rpx; padding: 0 10rpx;
} }
@ -282,4 +295,52 @@ onShow(() => {
color: #828b92; color: #828b92;
} }
} }
.back_icon {
width: 50rpx;
height: 50rpx;
margin-left: 10rpx;
}
.custom-bav-bar {
width: 100%;
height: 88rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.logo_icon {
width: 168rpx;
height: 40rpx;
margin-right: 6rpx;
}
.left {
position: absolute;
top: 24rpx;
left: 40rpx;
}
.center {
display: flex;
align-items: center;
justify-content: center;
// font-size: 28rpx;
font-size: var(--h2-font-size);
color: #333;
}
}
.serach_btn {
font-family: PingFangSC, PingFang SC;
font-weight: bold;
font-size: 32rpx;
color: #d13e3c;
line-height: 45rpx;
text-align: right;
font-style: normal;
margin-left: 50rpx;
}
</style> </style>

View File

@ -3,6 +3,7 @@ import type { AxiosResponse } from "axios";
// import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'; // import { ElMessage, ElMessageBox, ElNotification } from 'element-plus';
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
import qs from "qs"; import qs from "qs";
import { doLogout } from "@/api";
// 配置新建一个 axios 实例 // 配置新建一个 axios 实例
const service = axios.create({ const service = axios.create({
@ -52,9 +53,13 @@ service.interceptors.response.use(
// `token` 过期或者账号已在别处登录 // `token` 过期或者账号已在别处登录
if (res.code === 401 || res.code === 4001) { if (res.code === 401 || res.code === 4001) {
doLogout({
financialAccount: Session.get("userPhone"),
});
Session.clear(); // 清除浏览器全部临时缓存 Session.clear(); // 清除浏览器全部临时缓存
window.location.href = "/"; // 去登录页 window.location.reload();
console.log("你已被登出,请重新登录"); // window.location.href = "/"; // 去登录页
// console.log("你已被登出,请重新登录");
// ElMessageBox.alert('你已被登出,请重新登录', '提示', {}) // ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
// .then(() => {}) // .then(() => {})
// .catch(() => {}); // .catch(() => {});

View File

@ -3,6 +3,7 @@ import type { AxiosResponse } from "axios";
// import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'; // import { ElMessage, ElMessageBox, ElNotification } from 'element-plus';
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
import qs from "qs"; import qs from "qs";
import { doLogout } from "@/api";
// 配置新建一个 axios 实例 // 配置新建一个 axios 实例
const service = axios.create({ const service = axios.create({
@ -52,6 +53,9 @@ service.interceptors.response.use(
// `token` 过期或者账号已在别处登录 // `token` 过期或者账号已在别处登录
if (res.status === 401 || res.status === 4001) { if (res.status === 401 || res.status === 4001) {
doLogout({
financialAccount: Session.get("userPhone"),
});
Session.clear(); // 清除浏览器全部临时缓存 Session.clear(); // 清除浏览器全部临时缓存
window.location.href = "/"; // 去登录页 window.location.href = "/"; // 去登录页
console.log("你已被登出,请重新登录"); console.log("你已被登出,请重新登录");