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
|
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 = http://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://localhost:8040/apih5
|
# VITE_API_URL =http://localhost:8040/apih5
|
||||||
# VITE_API_URL = https://cankao.cs.com.cn/apih5
|
# VITE_API_URL = https://cankao.cs.com.cn/apih5
|
||||||
|
|
|
||||||
|
|
@ -85,3 +85,8 @@ export const doLogout = (data: any) => {
|
||||||
export const getEtfIndexList = (data: any) => {
|
export const getEtfIndexList = (data: any) => {
|
||||||
return Request.post("/news/etfIndexList", data);
|
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/indexEtf"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/realtimeInfo/indexEtfInfo"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/sreachReq/index"
|
"path": "pages/sreachReq/index"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,8 @@
|
||||||
<text>{{ item.summary }}</text>
|
<text>{{ item.summary }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="item_etf">
|
<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>
|
<text>{{ etf.name }}</text>
|
||||||
<div class="btn-play"></div>
|
<div class="btn-play"></div>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -95,22 +96,22 @@ import { onReachBottom } from "@dcloudio/uni-app";
|
||||||
import { getEtfIndexList } from "@/api/index";
|
import { getEtfIndexList } from "@/api/index";
|
||||||
|
|
||||||
const listData = ref([
|
const listData = ref([
|
||||||
{
|
// {
|
||||||
day: "2026-10-26",
|
// day: "2026-10-26",
|
||||||
list: [
|
// list: [
|
||||||
{
|
// {
|
||||||
time: "11:30:56",
|
// time: "11:30:56",
|
||||||
title: "刚果延长禁令后,中国钴价和库存飙升刚果延长禁令后,中国钴价和库存飙升",
|
// title: "刚果延长禁令后,中国钴价和库存飙升刚果延长禁令后,中国钴价和库存飙升",
|
||||||
summary: "刚果民主共和国将钴出口禁令延长至9月,导致全球约四分之三的钴供应受到影响。这一消息引…",
|
// summary: "刚果民主共和国将钴出口禁令延长至9月,导致全球约四分之三的钴供应受到影响。这一消息引…",
|
||||||
etfs: [
|
// etfs: [
|
||||||
{
|
// {
|
||||||
name: "医药 ETF",
|
// name: "医药 ETF",
|
||||||
code: "string",
|
// code: "string",
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({
|
||||||
|
|
@ -118,10 +119,15 @@ const form = ref({
|
||||||
keyword: null,
|
keyword: null,
|
||||||
});
|
});
|
||||||
async function getData() {
|
async function getData() {
|
||||||
|
uni.showLoading({
|
||||||
|
title: "加载中",
|
||||||
|
});
|
||||||
let { code, data } = await getEtfIndexList({
|
let { code, data } = await getEtfIndexList({
|
||||||
...form.value,
|
...form.value,
|
||||||
size: 20,
|
size: 20,
|
||||||
});
|
});
|
||||||
|
uni.hideLoading();
|
||||||
|
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
if (form.value.page == 1) {
|
if (form.value.page == 1) {
|
||||||
listData.value = [];
|
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() {
|
function onSreach() {
|
||||||
if (Session.get("token")) {
|
if (Session.get("token")) {
|
||||||
form.value.page = 1;
|
form.value.page = 1;
|
||||||
|
|
@ -487,15 +500,19 @@ onMounted(async () => {
|
||||||
margin-top: 10rpx;
|
margin-top: 10rpx;
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
margin-top: 30rpx;
|
margin-top: 30rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
|
||||||
.item_etf_item {
|
.item_etf_item {
|
||||||
// width: 168rpx;
|
// width: 168rpx;
|
||||||
|
width: calc(50% - 60rpx);
|
||||||
height: 48rpx;
|
height: 48rpx;
|
||||||
background: #edf1f5;
|
background: #edf1f5;
|
||||||
border-radius: 125rpx;
|
border-radius: 125rpx;
|
||||||
padding: 5rpx 25rpx;
|
padding: 5rpx 25rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
text {
|
text {
|
||||||
font-family: PingFangSC, PingFang SC;
|
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