feat(ETF): 新增ETF详情页面及接口
- 添加fetchEtfDetail接口用于获取ETF详情数据 - 创建indexEtfInfo页面展示ETF详情信息 - 在indexEtf页面添加跳转到详情页功能 - 调整.env.development中的API地址配置 - 优化indexEtf页面样式和加载逻辑
This commit is contained in:
parent
2b20a82484
commit
6dcc946e1c
|
|
@ -2,8 +2,8 @@
|
|||
ENV = development
|
||||
|
||||
# 本地环境接口地址
|
||||
VITE_API_URL = http://123.60.153.169:8040/apih5
|
||||
# VITE_API_URL = http://4155gf93ll13.vicp.fun/apih5
|
||||
# VITE_API_URL = http://123.60.153.169:8040/apih5
|
||||
VITE_API_URL = http://4155gf93ll13.vicp.fun/apih5
|
||||
# VITE_API_URL = http://123.60.79.143:8041/apih5
|
||||
# VITE_API_URL =http://localhost:8040/apih5
|
||||
# VITE_API_URL = https://cankao.cs.com.cn/apih5
|
||||
|
|
|
|||
|
|
@ -85,3 +85,8 @@ export const doLogout = (data: any) => {
|
|||
export const getEtfIndexList = (data: any) => {
|
||||
return Request.post("/news/etfIndexList", data);
|
||||
};
|
||||
|
||||
// 获取ETF详情
|
||||
export const fetchEtfDetail = (data: any) => {
|
||||
return Request.post("/news/etfList", data);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
{
|
||||
"path": "pages/realtimeInfo/indexEtf"
|
||||
},
|
||||
{
|
||||
"path": "pages/realtimeInfo/indexEtfInfo"
|
||||
},
|
||||
{
|
||||
"path": "pages/sreachReq/index"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@
|
|||
<text>{{ item.summary }}</text>
|
||||
</view>
|
||||
<view class="item_etf">
|
||||
<view v-for="etf in item.etfs" :key="etf.code" class="item_etf_item">
|
||||
<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>
|
||||
|
|
@ -95,22 +96,22 @@ 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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// day: "2026-10-26",
|
||||
// list: [
|
||||
// {
|
||||
// time: "11:30:56",
|
||||
// title: "刚果延长禁令后,中国钴价和库存飙升刚果延长禁令后,中国钴价和库存飙升",
|
||||
// summary: "刚果民主共和国将钴出口禁令延长至9月,导致全球约四分之三的钴供应受到影响。这一消息引…",
|
||||
// etfs: [
|
||||
// {
|
||||
// name: "医药 ETF",
|
||||
// code: "string",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
]);
|
||||
|
||||
const form = ref({
|
||||
|
|
@ -118,10 +119,15 @@ const form = ref({
|
|||
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 = [];
|
||||
|
|
@ -173,6 +179,13 @@ function goDetail(item, index) {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -487,15 +500,19 @@ onMounted(async () => {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,256 @@
|
|||
<template>
|
||||
<div class="index-etf-info">
|
||||
<!-- 头部 -->
|
||||
<view class="vipHeader">
|
||||
<view class="flashBack" @click="back">
|
||||
<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/Webkit中,new 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}`,
|
||||
});
|
||||
}
|
||||
|
||||
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>
|
||||
Loading…
Reference in New Issue