|
|
|
@ -1,3 +1,5 @@ |
|
|
|
<!-- @format --> |
|
|
|
|
|
|
|
<template> |
|
|
|
<view class="main"> |
|
|
|
<!-- 可滚动内容区域 --> |
|
|
|
@ -9,10 +11,10 @@ |
|
|
|
</view> |
|
|
|
<view class="global_index"> |
|
|
|
<view class="global_index_title"> |
|
|
|
{{ $t('marketSituation.globalIndex') }} |
|
|
|
{{ $t("marketSituation.globalIndex") }} |
|
|
|
</view> |
|
|
|
<view class="global_index_more" @click="goToGlobalIndex"> |
|
|
|
<text>{{ $t('marketSituation.globalIndexMore') }}</text> |
|
|
|
<text>{{ $t("marketSituation.globalIndexMore") }}</text> |
|
|
|
<image src="/static/marketSituation-image/more.png" mode="aspectFit"></image> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
@ -20,15 +22,13 @@ |
|
|
|
<!-- 卡片网格 --> |
|
|
|
<view class="cards_grid"> |
|
|
|
<view v-for="(card, index) in cardData" :key="index" class="card_item"> |
|
|
|
<IndexCard :flagIcon="card.flagIcon" :indexName="card.indexName" |
|
|
|
:currentPrice="card.currentPrice" :changeAmount="card.changeAmount" |
|
|
|
:changePercent="card.changePercent" :isRising="card.isRising" /> |
|
|
|
<IndexCard :flagIcon="card.flagIcon" :stockName="card.stockName" :currentPrice="card.currentPrice" :changeAmount="card.changeAmount" :changePercent="card.changePercent" :isRising="card.isRising" @click="viewIndexDetail(card)" /> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<view class="warn"> |
|
|
|
<image src="/static/marketSituation-image/warn.png" mode="aspectFit"></image> |
|
|
|
<view class="warn_text_container"> |
|
|
|
<text :class="warnTextClass">{{ $t('marketSituation.warn') }}</text> |
|
|
|
<text :class="warnTextClass">{{ $t("marketSituation.warn") }}</text> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<!-- 底部安全区域,防止被导航栏遮挡 --> |
|
|
|
@ -39,190 +39,210 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script setup> |
|
|
|
import { ref, onMounted, watch, nextTick, computed } from 'vue' |
|
|
|
import util from '../../common/util.js' |
|
|
|
import IndexCard from '../../components/IndexCard.vue' |
|
|
|
import { ref, onMounted, watch, nextTick, computed } from "vue"; |
|
|
|
import util from "../../common/util.js"; |
|
|
|
import IndexCard from "../../components/IndexCard.vue"; |
|
|
|
|
|
|
|
const iSMT = ref(0) |
|
|
|
const searchValue = ref('') |
|
|
|
const contentHeight = ref(0) |
|
|
|
const headerHeight = ref(0) // 动态计算的header高度 |
|
|
|
const isWarnTextOverflow = ref(false) // warn文字是否溢出 |
|
|
|
const iSMT = ref(0); |
|
|
|
const searchValue = ref(""); |
|
|
|
const contentHeight = ref(0); |
|
|
|
const headerHeight = ref(0); // 动态计算的header高度 |
|
|
|
const isWarnTextOverflow = ref(false); // warn文字是否溢出 |
|
|
|
|
|
|
|
const pageIndex = ref(0) |
|
|
|
const scrollToView = ref('') |
|
|
|
const pageIndex = ref(0); |
|
|
|
const scrollToView = ref(""); |
|
|
|
|
|
|
|
// 跳转图表示例页面 |
|
|
|
const goToChartExample = () => { |
|
|
|
uni.navigateTo({ |
|
|
|
url: '/pages/marketSituation/chartExample' |
|
|
|
}) |
|
|
|
} |
|
|
|
url: "/pages/marketSituation/chartExample", |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 计算属性:精准计算content区域的top值 |
|
|
|
const contentTopPosition = computed(() => { |
|
|
|
const statusBarHeight = iSMT.value || 0 |
|
|
|
const currentHeaderHeight = headerHeight.value > 0 ? headerHeight.value : 140 |
|
|
|
return statusBarHeight + currentHeaderHeight |
|
|
|
}) |
|
|
|
const statusBarHeight = iSMT.value || 0; |
|
|
|
const currentHeaderHeight = headerHeight.value > 0 ? headerHeight.value : 140; |
|
|
|
return statusBarHeight + currentHeaderHeight; |
|
|
|
}); |
|
|
|
|
|
|
|
// warn文字的class计算属性 |
|
|
|
const warnTextClass = computed(() => { |
|
|
|
return isWarnTextOverflow.value ? 'warn_text scroll-active' : 'warn_text' |
|
|
|
}) |
|
|
|
return isWarnTextOverflow.value ? "warn_text scroll-active" : "warn_text"; |
|
|
|
}); |
|
|
|
|
|
|
|
// 弹窗相关数据 |
|
|
|
const showCountryModal = ref(false) |
|
|
|
const selectedCountry = ref('概况') |
|
|
|
const countryList = ref([ |
|
|
|
'概况', '新加坡', '马来西亚', '印度尼西亚', '美国', '中国香港', |
|
|
|
'泰国', '中国', '加拿大', '越南', '外汇', '贵金属' |
|
|
|
]) |
|
|
|
const showCountryModal = ref(false); |
|
|
|
const selectedCountry = ref("概况"); |
|
|
|
const countryList = ref(["概况", "新加坡", "马来西亚", "印度尼西亚", "美国", "中国香港", "泰国", "中国", "加拿大", "越南", "外汇", "贵金属"]); |
|
|
|
|
|
|
|
// 卡片数据 |
|
|
|
const cardData = ref([ |
|
|
|
{ |
|
|
|
flagIcon: '🇺🇸', |
|
|
|
indexName: '道琼斯', |
|
|
|
currentPrice: '45757.90', |
|
|
|
changeAmount: '-125.22', |
|
|
|
changePercent: '-0.27%', |
|
|
|
isRising: false |
|
|
|
flagIcon: "🇺🇸", |
|
|
|
stockName: "道琼斯", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "45757.90", |
|
|
|
changeAmount: "-125.22", |
|
|
|
changePercent: "-0.27%", |
|
|
|
isRising: false, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇺🇸', |
|
|
|
indexName: '纳斯达克', |
|
|
|
currentPrice: '22333.96', |
|
|
|
changeAmount: '+125.22', |
|
|
|
changePercent: '+0.47%', |
|
|
|
isRising: true |
|
|
|
flagIcon: "🇺🇸", |
|
|
|
stockName: "纳斯达克", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "22333.96", |
|
|
|
changeAmount: "+125.22", |
|
|
|
changePercent: "+0.47%", |
|
|
|
isRising: true, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇺🇸', |
|
|
|
indexName: '标普500', |
|
|
|
currentPrice: '6606.08', |
|
|
|
changeAmount: '+125.22', |
|
|
|
changePercent: '+0.27%', |
|
|
|
isRising: true |
|
|
|
flagIcon: "🇺🇸", |
|
|
|
stockName: "标普500", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "6606.08", |
|
|
|
changeAmount: "+125.22", |
|
|
|
changePercent: "+0.27%", |
|
|
|
isRising: true, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇨🇳', |
|
|
|
indexName: '上证指数', |
|
|
|
currentPrice: '3333.96', |
|
|
|
changeAmount: '+125.22', |
|
|
|
changePercent: '+0.27%', |
|
|
|
isRising: true |
|
|
|
flagIcon: "🇨🇳", |
|
|
|
stockName: "上证指数", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "3333.96", |
|
|
|
changeAmount: "+125.22", |
|
|
|
changePercent: "+0.27%", |
|
|
|
isRising: true, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇨🇳', |
|
|
|
indexName: '科创50', |
|
|
|
currentPrice: '757.90', |
|
|
|
changeAmount: '-25.22', |
|
|
|
changePercent: '-0.27%', |
|
|
|
isRising: false |
|
|
|
flagIcon: "🇨🇳", |
|
|
|
stockName: "科创50", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "757.90", |
|
|
|
changeAmount: "-25.22", |
|
|
|
changePercent: "-0.27%", |
|
|
|
isRising: false, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇭🇰', |
|
|
|
indexName: '恒生指数', |
|
|
|
currentPrice: '19757.90', |
|
|
|
changeAmount: '-125.22', |
|
|
|
changePercent: '-0.63%', |
|
|
|
isRising: false |
|
|
|
flagIcon: "🇭🇰", |
|
|
|
stockName: "恒生指数", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "19757.90", |
|
|
|
changeAmount: "-125.22", |
|
|
|
changePercent: "-0.63%", |
|
|
|
isRising: false, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇸🇬', |
|
|
|
indexName: '道琼斯', |
|
|
|
currentPrice: '3757.90', |
|
|
|
changeAmount: '+85.22', |
|
|
|
changePercent: '+2.31%', |
|
|
|
isRising: true |
|
|
|
flagIcon: "🇸🇬", |
|
|
|
stockName: "道琼斯", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "3757.90", |
|
|
|
changeAmount: "+85.22", |
|
|
|
changePercent: "+2.31%", |
|
|
|
isRising: true, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇲🇾', |
|
|
|
indexName: '纳斯达克', |
|
|
|
currentPrice: '1657.90', |
|
|
|
changeAmount: '-15.22', |
|
|
|
changePercent: '-0.91%', |
|
|
|
isRising: false |
|
|
|
flagIcon: "🇲🇾", |
|
|
|
stockName: "纳斯达克", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "1657.90", |
|
|
|
changeAmount: "-15.22", |
|
|
|
changePercent: "-0.91%", |
|
|
|
isRising: false, |
|
|
|
}, |
|
|
|
{ |
|
|
|
flagIcon: '🇹🇭', |
|
|
|
indexName: '标普500', |
|
|
|
currentPrice: '1457.90', |
|
|
|
changeAmount: '+35.22', |
|
|
|
changePercent: '+2.48%', |
|
|
|
isRising: true |
|
|
|
} |
|
|
|
]) |
|
|
|
flagIcon: "🇹🇭", |
|
|
|
stockName: "标普500", |
|
|
|
stockCode: "noCode", |
|
|
|
currentPrice: "1457.90", |
|
|
|
changeAmount: "+35.22", |
|
|
|
changePercent: "+2.48%", |
|
|
|
isRising: true, |
|
|
|
}, |
|
|
|
]); |
|
|
|
|
|
|
|
// 搜索输入事件 |
|
|
|
const onSearchInput = (e) => { |
|
|
|
searchValue.value = e.detail.value |
|
|
|
} |
|
|
|
searchValue.value = e.detail.value; |
|
|
|
}; |
|
|
|
|
|
|
|
// 搜索确认事件 |
|
|
|
const onSearchConfirm = (e) => { |
|
|
|
console.log('搜索内容:', e.detail.value) |
|
|
|
console.log("搜索内容:", e.detail.value); |
|
|
|
// 这里可以添加搜索逻辑 |
|
|
|
performSearch(e.detail.value) |
|
|
|
} |
|
|
|
performSearch(e.detail.value); |
|
|
|
}; |
|
|
|
|
|
|
|
// 搜索图标点击事件 |
|
|
|
const onSearchClick = () => { |
|
|
|
if (searchValue.value.trim()) { |
|
|
|
performSearch(searchValue.value) |
|
|
|
} |
|
|
|
performSearch(searchValue.value); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 执行搜索 |
|
|
|
const performSearch = (keyword) => { |
|
|
|
if (!keyword.trim()) { |
|
|
|
uni.showToast({ |
|
|
|
title: '请输入搜索内容', |
|
|
|
icon: 'none' |
|
|
|
}) |
|
|
|
return |
|
|
|
title: "请输入搜索内容", |
|
|
|
icon: "none", |
|
|
|
}); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
uni.showToast({ |
|
|
|
title: `搜索: ${keyword}`, |
|
|
|
icon: 'none' |
|
|
|
}) |
|
|
|
icon: "none", |
|
|
|
}); |
|
|
|
// 这里添加实际的搜索逻辑 |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 检测warn文字是否溢出 |
|
|
|
const checkWarnTextOverflow = () => { |
|
|
|
nextTick(() => { |
|
|
|
setTimeout(() => { |
|
|
|
const query = uni.createSelectorQuery() |
|
|
|
const query = uni.createSelectorQuery(); |
|
|
|
|
|
|
|
// 同时查询容器和文字元素 |
|
|
|
query.select('.warn_text_container').boundingClientRect() |
|
|
|
query.select('.warn_text').boundingClientRect() |
|
|
|
query.select(".warn_text_container").boundingClientRect(); |
|
|
|
query.select(".warn_text").boundingClientRect(); |
|
|
|
query.exec((res) => { |
|
|
|
const containerRect = res[0] |
|
|
|
const textRect = res[1] |
|
|
|
const containerRect = res[0]; |
|
|
|
const textRect = res[1]; |
|
|
|
|
|
|
|
if (!containerRect || !textRect) { |
|
|
|
return |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 判断文字是否超出容器(留一些余量) |
|
|
|
const isOverflow = textRect.width > (containerRect.width - 10) |
|
|
|
|
|
|
|
isWarnTextOverflow.value = isOverflow |
|
|
|
}) |
|
|
|
}, 500) |
|
|
|
}) |
|
|
|
} |
|
|
|
const isOverflow = textRect.width > containerRect.width - 10; |
|
|
|
|
|
|
|
isWarnTextOverflow.value = isOverflow; |
|
|
|
}); |
|
|
|
}, 500); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 方法:查看指数详情 |
|
|
|
const viewIndexDetail = (item) => { |
|
|
|
console.log("查看指数详情:", item.stockName); |
|
|
|
// uni.showToast({ |
|
|
|
// title: `查看 ${item.stockName} 详情`, |
|
|
|
// icon: 'none', |
|
|
|
// duration: 2000 |
|
|
|
// }) |
|
|
|
// 这里可以跳转到具体的指数详情页面 |
|
|
|
uni.navigateTo({ |
|
|
|
url: `/pages/marketSituation/marketCondition?stockInformation=${encodeURIComponent(JSON.stringify(item))}`, |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 跳转到全球指数页面 |
|
|
|
const goToGlobalIndex = () => { |
|
|
|
uni.navigateTo({ |
|
|
|
url: '/pages/marketSituation/globalIndex' |
|
|
|
}) |
|
|
|
} |
|
|
|
url: "/pages/marketSituation/globalIndex", |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
// 状态栏高度 |
|
|
|
@ -231,30 +251,34 @@ onMounted(() => { |
|
|
|
// 确保DOM渲染完成后再查询高度 |
|
|
|
nextTick(() => { |
|
|
|
// 动态计算header实际高度 |
|
|
|
uni.createSelectorQuery().select('.header_fixed').boundingClientRect((rect) => { |
|
|
|
uni |
|
|
|
.createSelectorQuery() |
|
|
|
.select(".header_fixed") |
|
|
|
.boundingClientRect((rect) => { |
|
|
|
if (rect) { |
|
|
|
headerHeight.value = rect.height |
|
|
|
console.log('Header实际高度:', headerHeight.value, 'px') |
|
|
|
headerHeight.value = rect.height; |
|
|
|
console.log("Header实际高度:", headerHeight.value, "px"); |
|
|
|
} |
|
|
|
}).exec() |
|
|
|
}) |
|
|
|
.exec(); |
|
|
|
|
|
|
|
// 检测warn文字是否溢出 |
|
|
|
checkWarnTextOverflow() |
|
|
|
}) |
|
|
|
}) |
|
|
|
checkWarnTextOverflow(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
// 监听headerHeight变化,重新计算contentHeight |
|
|
|
watch(headerHeight, (newHeight) => { |
|
|
|
if (newHeight > 0) { |
|
|
|
const systemInfo = uni.getSystemInfoSync() |
|
|
|
const windowHeight = systemInfo.windowHeight |
|
|
|
const statusBarHeight = systemInfo.statusBarHeight || 0 |
|
|
|
const footerHeight = 100 |
|
|
|
const systemInfo = uni.getSystemInfoSync(); |
|
|
|
const windowHeight = systemInfo.windowHeight; |
|
|
|
const statusBarHeight = systemInfo.statusBarHeight || 0; |
|
|
|
const footerHeight = 100; |
|
|
|
|
|
|
|
contentHeight.value = windowHeight - statusBarHeight - newHeight - footerHeight |
|
|
|
console.log('重新计算contentHeight:', contentHeight.value) |
|
|
|
contentHeight.value = windowHeight - statusBarHeight - newHeight - footerHeight; |
|
|
|
console.log("重新计算contentHeight:", contentHeight.value); |
|
|
|
} |
|
|
|
}) |
|
|
|
}); |
|
|
|
</script> |
|
|
|
|
|
|
|
<style scoped> |
|
|
|
@ -413,7 +437,7 @@ watch(headerHeight, (newHeight) => { |
|
|
|
min-width: 40rpx; |
|
|
|
max-width: 120rpx; |
|
|
|
height: 8rpx; |
|
|
|
background-image: url('/static/marketSituation-image/bg.png'); |
|
|
|
background-image: url("/static/marketSituation-image/bg.png"); |
|
|
|
background-size: cover; |
|
|
|
background-position: center; |
|
|
|
background-repeat: no-repeat; |
|
|
|
@ -462,9 +486,9 @@ watch(headerHeight, (newHeight) => { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
background-color: #F3F3F3; |
|
|
|
background-color: #f3f3f3; |
|
|
|
border-radius: 30rpx; |
|
|
|
border: 1rpx solid #E0E0E0; |
|
|
|
border: 1rpx solid #e0e0e0; |
|
|
|
padding: 30rpx 20rpx; |
|
|
|
box-sizing: border-box; |
|
|
|
/* 设置最小高度保护,但允许内容撑开 */ |
|
|
|
|