个股中心、涨停分析接口对接
This commit is contained in:
@@ -125,14 +125,45 @@
|
|||||||
this.getYesterdayDateData()
|
this.getYesterdayDateData()
|
||||||
this.generateMonthDateListData()
|
this.generateMonthDateListData()
|
||||||
// 新增:初始化时触发一次事件,传递当天数据给父页面
|
// 新增:初始化时触发一次事件,传递当天数据给父页面
|
||||||
this.emitDateChange(currentYear, currentMonth, currentDay, this.getTodayItem(currentYear, currentMonth, currentDay))
|
//this.emitDateChange(currentYear, currentMonth, currentDay, this.getTodayItem(currentYear, currentMonth, currentDay))
|
||||||
|
|
||||||
|
|
||||||
|
this.emitDateChange(
|
||||||
|
currentYear,
|
||||||
|
currentMonth,
|
||||||
|
currentDay,
|
||||||
|
this.getTodayItem(currentYear, currentMonth, currentDay),
|
||||||
|
this.getPrevDayItem(currentYear, currentMonth, currentDay) // 新增上一天数据
|
||||||
|
)
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getCalendarCombinedData()
|
this.getCalendarCombinedData()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 3. 在日历组件methods中新增getPrevDayItem方法
|
||||||
|
/**
|
||||||
|
* 获取指定日期的上一天数据
|
||||||
|
*/
|
||||||
|
getPrevDayItem(year, month, day) {
|
||||||
|
// 计算上一天日期
|
||||||
|
const currentDate = new Date(`${year}-${month}-${day}`);
|
||||||
|
const prevDate = new Date(currentDate.getTime() - 24 * 60 * 60 * 1000);
|
||||||
|
const prevYear = prevDate.getFullYear();
|
||||||
|
const prevMonth = prevDate.getMonth() + 1;
|
||||||
|
const prevDay = prevDate.getDate();
|
||||||
|
|
||||||
|
// 获取上一天的完整数据
|
||||||
|
const targetDate = `${prevYear}-${prevMonth > 9 ? prevMonth : '0' + prevMonth}-${prevDay > 9 ? prevDay : '0' + prevDay}`;
|
||||||
|
const currentMonthList = this.monthDateList[this.selectMonthIndex] || [];
|
||||||
|
const localItem = currentMonthList.find(item => item.date === targetDate) || null;
|
||||||
|
const apiData = this.getCalendarItemByDate(targetDate) || {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...localItem,
|
||||||
|
zt_count: apiData.zt_count || 0,
|
||||||
|
top_sector: apiData.top_sector || '-',
|
||||||
|
zaban_rate: apiData.zaban_rate || '0%'
|
||||||
|
};
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 获取当天的item数据(合并接口数据)
|
* 获取当天的item数据(合并接口数据)
|
||||||
*/
|
*/
|
||||||
@@ -156,13 +187,33 @@
|
|||||||
/**
|
/**
|
||||||
* 触发日期变更事件(传递包含接口数据的item)
|
* 触发日期变更事件(传递包含接口数据的item)
|
||||||
*/
|
*/
|
||||||
emitDateChange(year, month, day, item) {
|
// emitDateChange(year, month, day, item) {
|
||||||
|
// const yearMonth = `${year}-${month > 9 ? month : '0' + month}`;
|
||||||
|
// const fullDate = `${year}-${month > 9 ? month : '0' + month}-${day > 9 ? day : '0' + day}`;
|
||||||
|
// this.$emit('date-change', {
|
||||||
|
// yearMonth,
|
||||||
|
// fullDate,
|
||||||
|
// item: item || { // 兜底:无item时赋值空对象+默认值
|
||||||
|
// date: fullDate,
|
||||||
|
// year,
|
||||||
|
// month,
|
||||||
|
// day,
|
||||||
|
// zt_count: 0,
|
||||||
|
// top_sector: '-',
|
||||||
|
// zaban_rate: '0%'
|
||||||
|
// },
|
||||||
|
// year,
|
||||||
|
// month,
|
||||||
|
// day
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
emitDateChange(year, month, day, item, prevItem = { zt_count: 0 }) { // 新增prevItem参数,设置默认值兜底
|
||||||
const yearMonth = `${year}-${month > 9 ? month : '0' + month}`;
|
const yearMonth = `${year}-${month > 9 ? month : '0' + month}`;
|
||||||
const fullDate = `${year}-${month > 9 ? month : '0' + month}-${day > 9 ? day : '0' + day}`;
|
const fullDate = `${year}-${month > 9 ? month : '0' + month}-${day > 9 ? day : '0' + day}`;
|
||||||
this.$emit('date-change', {
|
this.$emit('date-change', {
|
||||||
yearMonth,
|
yearMonth,
|
||||||
fullDate,
|
fullDate,
|
||||||
item: item || { // 兜底:无item时赋值空对象+默认值
|
item: item || { // 兜底:无当前item时赋值空对象+默认值
|
||||||
date: fullDate,
|
date: fullDate,
|
||||||
year,
|
year,
|
||||||
month,
|
month,
|
||||||
@@ -171,11 +222,17 @@
|
|||||||
top_sector: '-',
|
top_sector: '-',
|
||||||
zaban_rate: '0%'
|
zaban_rate: '0%'
|
||||||
},
|
},
|
||||||
|
prevItem: prevItem || { // 新增:传递上一天数据,兜底默认值
|
||||||
|
zt_count: 0,
|
||||||
|
top_sector: '-',
|
||||||
|
zaban_rate: '0%'
|
||||||
|
},
|
||||||
year,
|
year,
|
||||||
month,
|
month,
|
||||||
day
|
day
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前时间前一天的数据
|
* 获取当前时间前一天的数据
|
||||||
*/
|
*/
|
||||||
@@ -259,7 +316,14 @@
|
|||||||
// 接口数据加载后,重新触发一次当前选中日期的事件,更新数据
|
// 接口数据加载后,重新触发一次当前选中日期的事件,更新数据
|
||||||
if (this.selectDateStr) {
|
if (this.selectDateStr) {
|
||||||
const [year, month, day] = this.selectDateStr.split('-').map(Number);
|
const [year, month, day] = this.selectDateStr.split('-').map(Number);
|
||||||
this.emitDateChange(year, month, day, this.getTodayItem(year, month, day));
|
//this.emitDateChange(year, month, day, this.getTodayItem(year, month, day));
|
||||||
|
this.emitDateChange(
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
day,
|
||||||
|
this.getTodayItem(year, month, day),
|
||||||
|
this.getPrevDayItem(year, month, day) // 新增上一天数据
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.calendarApiData = [];
|
this.calendarApiData = [];
|
||||||
@@ -475,13 +539,69 @@
|
|||||||
zaban_rate: apiData.zaban_rate || '0%', // 炸板率,示例字段
|
zaban_rate: apiData.zaban_rate || '0%', // 炸板率,示例字段
|
||||||
isWeekend: index % 7 === 0 || index % 7 === 6 // 是否周末
|
isWeekend: index % 7 === 0 || index % 7 === 6 // 是否周末
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ===== 新增:获取上一天的日期和数据 =====
|
||||||
|
// 2.1 计算上一天的日期
|
||||||
|
const currentDate = new Date(item.date);
|
||||||
|
const prevDate = new Date(currentDate.getTime() - 24 * 60 * 60 * 1000); // 减一天
|
||||||
|
const prevYear = prevDate.getFullYear();
|
||||||
|
const prevMonth = prevDate.getMonth() + 1;
|
||||||
|
const prevDay = prevDate.getDate();
|
||||||
|
const prevDateStr = `${prevYear}-${prevMonth > 9 ? prevMonth : '0' + prevMonth}-${prevDay > 9 ? prevDay : '0' + prevDay}`;
|
||||||
|
|
||||||
|
// 2.2 获取上一天的接口数据
|
||||||
|
const prevApiData = this.getCalendarItemByDate(prevDateStr) || {};
|
||||||
|
// 2.3 查找上一天的本地item(用于补全基础信息)
|
||||||
|
let prevLocalItem = null;
|
||||||
|
// 先在当前月份列表找
|
||||||
|
const currentMonthList = this.monthDateList[this.selectMonthIndex] || [];
|
||||||
|
prevLocalItem = currentMonthList.find(i => i.date === prevDateStr);
|
||||||
|
// 如果当前月份没有(跨月),找对应月份的列表
|
||||||
|
if (!prevLocalItem) {
|
||||||
|
const prevMonthIndex = this.selectMonthIndex - (prevMonth < item.month ? 1 : 0);
|
||||||
|
const prevMonthList = this.monthDateList[prevMonthIndex] || [];
|
||||||
|
prevLocalItem = prevMonthList.find(i => i.date === prevDateStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.4 合并上一天的完整数据
|
||||||
|
const prevMergedItem = {
|
||||||
|
...(prevLocalItem || {}),
|
||||||
|
zt_count: prevApiData.zt_count || 0,
|
||||||
|
top_sector: prevApiData.top_sector || '-',
|
||||||
|
zaban_rate: prevApiData.zaban_rate || '0%',
|
||||||
|
isWeekend: false // 兜底默认值
|
||||||
|
};
|
||||||
|
// =======================================
|
||||||
|
|
||||||
this.chgStockData = mergedItem;
|
this.chgStockData = mergedItem;
|
||||||
// 3. 解析日期,触发事件传递合并后的item
|
// 3. 解析日期,触发事件传递【当前数据+上一天数据】
|
||||||
const [year, month, day] = item.date.split('-').map(Number);
|
const [year, month, day] = item.date.split('-').map(Number);
|
||||||
this.emitDateChange(year, month, day, mergedItem);
|
this.emitDateChange(year, month, day, mergedItem, prevMergedItem); // 新增传递上一天数据
|
||||||
console.log('点击某天(含接口数据)', mergedItem);
|
console.log('点击某天(含接口数据)', { current: mergedItem, prev: prevMergedItem });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clickSelectDate(item, index) {
|
||||||
|
// if (!item.isCurrentMonth) return
|
||||||
|
// if (this.selectDateStr != item.date) {
|
||||||
|
// this.selectDateStr = item.date
|
||||||
|
|
||||||
|
// const apiData = this.getCalendarItemByDate(item.date) || {};
|
||||||
|
|
||||||
|
// const mergedItem = {
|
||||||
|
// ...item,
|
||||||
|
// zt_count: apiData.zt_count || 0,
|
||||||
|
// top_sector: apiData.top_sector || '-',
|
||||||
|
// zaban_rate: apiData.zaban_rate || '0%',
|
||||||
|
// isWeekend: index % 7 === 0 || index % 7 === 6
|
||||||
|
// };
|
||||||
|
// this.chgStockData = mergedItem;
|
||||||
|
|
||||||
|
// const [year, month, day] = item.date.split('-').map(Number);
|
||||||
|
// this.emitDateChange(year, month, day, mergedItem);
|
||||||
|
// console.log('点击某天(含接口数据)', mergedItem);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ export default {
|
|||||||
colorList: {
|
colorList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => ['#60A5FA', '#FEC200', '#EF4444'] // 外圈、中间、中心
|
default: () => ['#60A5FA', '#FEC200', '#EF4444'] // 外圈、中间、中心
|
||||||
|
},
|
||||||
|
// 新增:字号配置,让组件更灵活
|
||||||
|
fontSizeConfig: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
minSize: 12, // 最小字号
|
||||||
|
maxSize: 40, // 最大字号
|
||||||
|
scaleFactor: 0.1 // 缩放因子,越大字号差异越明显
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -113,6 +122,11 @@ export default {
|
|||||||
// 按权重排序(权重越大,文字越大)
|
// 按权重排序(权重越大,文字越大)
|
||||||
const sortedWords = [...this.wordData].sort((a, b) => b.value - a.value);
|
const sortedWords = [...this.wordData].sort((a, b) => b.value - a.value);
|
||||||
|
|
||||||
|
// 计算value的最大值和最小值,用于归一化
|
||||||
|
const values = sortedWords.map(item => item.value);
|
||||||
|
this.valueMax = Math.max(...values);
|
||||||
|
this.valueMin = Math.min(...values);
|
||||||
|
|
||||||
// 逐个绘制文字
|
// 逐个绘制文字
|
||||||
sortedWords.forEach((word, index) => {
|
sortedWords.forEach((word, index) => {
|
||||||
this.placeWord(word, index);
|
this.placeWord(word, index);
|
||||||
@@ -124,24 +138,22 @@ export default {
|
|||||||
const ctx = this.ctx;
|
const ctx = this.ctx;
|
||||||
// 优化1:提高最大尝试次数(从50→150),让更多文字能找到位置
|
// 优化1:提高最大尝试次数(从50→150),让更多文字能找到位置
|
||||||
const maxAttempts = 150;
|
const maxAttempts = 150;
|
||||||
const baseFontSize = 12; // 基础字体大小
|
const { minSize, maxSize, scaleFactor } = this.fontSizeConfig;
|
||||||
|
|
||||||
// 分段计算分母(适配不同value区间)
|
// ===== 核心优化:重新设计字号计算逻辑 =====
|
||||||
const value = word.value;
|
// 1. 归一化value(0-1区间)
|
||||||
const baseDenominator = 1000; // 基础分母
|
let normalizedValue = 1;
|
||||||
const interval = 500; // 区间步长
|
if (this.valueMax !== this.valueMin) {
|
||||||
const step = 500; // 分母每次增加的步长
|
normalizedValue = (word.value - this.valueMin) / (this.valueMax - this.valueMin);
|
||||||
|
}
|
||||||
|
|
||||||
// 计算当前value所属区间,动态确定分母
|
// 2. 计算字号:基于归一化值,确保最小到最大的平滑过渡
|
||||||
const intervalNum = Math.floor(value / interval);
|
// 公式:最小字号 + (最大字号 - 最小字号) * 归一化值 * 缩放因子
|
||||||
let denominator = baseDenominator + (intervalNum * step);
|
const fontSize = Math.min(
|
||||||
|
minSize + (maxSize - minSize) * normalizedValue * scaleFactor,
|
||||||
// 兜底:避免分母过小(比如value为0时)
|
maxSize
|
||||||
denominator = Math.max(denominator, baseDenominator);
|
);
|
||||||
|
// ==========================================
|
||||||
// 根据分段分母计算字体大小,限制最大值
|
|
||||||
const maxFontSize = 28; // 优化2:适当减小最大字体(从32→28),节省空间
|
|
||||||
const fontSize = Math.min(baseFontSize + (value / denominator) * 16, maxFontSize);
|
|
||||||
|
|
||||||
// 旋转角度:-60° 到 60°
|
// 旋转角度:-60° 到 60°
|
||||||
const rotateAngle = (Math.random() - 0.5) * 120 * Math.PI / 180;
|
const rotateAngle = (Math.random() - 0.5) * 120 * Math.PI / 180;
|
||||||
@@ -150,7 +162,7 @@ export default {
|
|||||||
ctx.font = `${fontSize}px sans-serif`;
|
ctx.font = `${fontSize}px sans-serif`;
|
||||||
|
|
||||||
// 获取文字宽度和高度(用于碰撞检测)
|
// 获取文字宽度和高度(用于碰撞检测)
|
||||||
const textWidth = ctx.measureText(word.name).width;
|
const textWidth = ctx.measureText(word.text || word.name).width; // 兼容text/name字段
|
||||||
// 优化3:更精准的文字高度估算(从1.2→1.05),减少无效空间
|
// 优化3:更精准的文字高度估算(从1.2→1.05),减少无效空间
|
||||||
const textHeight = fontSize * 1.05;
|
const textHeight = fontSize * 1.05;
|
||||||
|
|
||||||
@@ -193,7 +205,7 @@ export default {
|
|||||||
ctx.fillStyle = color;
|
ctx.fillStyle = color;
|
||||||
|
|
||||||
// 无重叠,绘制文字
|
// 无重叠,绘制文字
|
||||||
this.drawTextAtPosition(word.name, x, y, rotateAngle, fontSize);
|
this.drawTextAtPosition(word.text || word.name, x, y, rotateAngle, fontSize);
|
||||||
|
|
||||||
// 记录已放置的文字信息(用于后续碰撞检测)
|
// 记录已放置的文字信息(用于后续碰撞检测)
|
||||||
this.placedWords.push({
|
this.placedWords.push({
|
||||||
@@ -238,9 +250,9 @@ export default {
|
|||||||
// 四个顶点坐标(相对于中心)
|
// 四个顶点坐标(相对于中心)
|
||||||
const points = [
|
const points = [
|
||||||
{ x: -halfW, y: -halfH },
|
{ x: -halfW, y: -halfH },
|
||||||
{ x: halfW, y: -halfH },
|
{ x: -halfW, y: halfH },
|
||||||
{ x: halfW, y: halfH },
|
{ x: halfW, y: halfH },
|
||||||
{ x: -halfW, y: halfH }
|
{ x: halfW, y: -halfH }
|
||||||
];
|
];
|
||||||
|
|
||||||
// 旋转并平移到实际位置
|
// 旋转并平移到实际位置
|
||||||
|
|||||||
@@ -20,14 +20,26 @@
|
|||||||
style="font-size: 30rpx; font-weight: bold; margin-left: 10rpx; margin-right: 20rpx;">核心指标</text>
|
style="font-size: 30rpx; font-weight: bold; margin-left: 10rpx; margin-right: 20rpx;">核心指标</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
<view style="display: grid; gap: 15rpx; grid-template-columns: repeat(3, 1fr); margin: 20rpx;">
|
<view style="display: grid; gap: 15rpx; grid-template-columns: repeat(3, 1fr); margin: 20rpx;">
|
||||||
<view v-for="(item,index) in tabTypes" :key="index"
|
<view v-for="(item,index) in tabTypes" :key="index"
|
||||||
style="display: flex; align-items: center; justify-content: center; flex-direction: column; background-color: #FFF8F0; border: 1rpx solid #F59B38; border-radius: 5rpx; padding: 20rpx; box-sizing: border-box;">
|
style="display: flex; align-items: center; justify-content: center; flex-direction: column; background-color: #FFF8F0; border: 1rpx solid #F59B38; border-radius: 5rpx; padding: 20rpx; box-sizing: border-box;">
|
||||||
<view style="display: flex;align-items: center;justify-content: center;">
|
<view style="display: flex;align-items: center;justify-content: center;">
|
||||||
<view style="color: #F59B38; font-size: 30rpx;">{{item.data}}</view>
|
<view style="color: #F59B38; font-size: 30rpx;">{{item.data}}</view>
|
||||||
<view v-if="item.change > 0"
|
<!-- 优化:兼容正数、负数、0的显示 -->
|
||||||
style="margin-left: 10rpx; background-color: #F59B38; border-radius: 5rpx; color: white; padding: 0 5rpx; font-size: 24rpx; font-weight: bold;">
|
<view v-if="item.change !== 0" :style="[
|
||||||
+{{item.change}}</view>
|
{
|
||||||
|
marginLeft: '10rpx',
|
||||||
|
borderRadius: '5rpx',
|
||||||
|
color: 'white',
|
||||||
|
padding: '0 5rpx',
|
||||||
|
fontSize: '24rpx',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
},
|
||||||
|
item.change > 0 ? { backgroundColor: '#F59B38' } : { backgroundColor: '#EF4444' }
|
||||||
|
]">
|
||||||
|
{{item.change > 0 ? '+' + item.change : item.change}}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view style="color: #555555; font-size: 20rpx; margin-top: 5rpx;">{{item.title}}</view>
|
<view style="color: #555555; font-size: 20rpx; margin-top: 5rpx;">{{item.title}}</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -46,9 +58,9 @@
|
|||||||
<view style="font-size: 30rpx; font-weight: bold;">市场全景</view>
|
<view style="font-size: 30rpx; font-weight: bold;">市场全景</view>
|
||||||
<view style="font-size: 24rpx; font-weight: 500; margin-top: 10rpx;">
|
<view style="font-size: 24rpx; font-weight: 500; margin-top: 10rpx;">
|
||||||
<text
|
<text
|
||||||
style="color: #F3C368; border: 1rpx solid #F3C368; border-radius: 5rpx; text-align: center; padding: 0 10rpx;">35个板块</text>
|
style="color: #F3C368; border: 1rpx solid #F3C368; border-radius: 5rpx; text-align: center; padding: 0 10rpx;">{{bkList.length}}个板块</text>
|
||||||
<text
|
<text
|
||||||
style="color: #EC3440; border: 1rpx solid #EC3440; border-radius: 5rpx; text-align: center; padding: 0 10rpx; margin: 0 10rpx;">102只涨停</text>
|
style="color: #EC3440; border: 1rpx solid #EC3440; border-radius: 5rpx; text-align: center; padding: 0 10rpx; margin: 0 10rpx;">{{number_limit_stocks}}只涨停</text>
|
||||||
<text
|
<text
|
||||||
style="color: #F59B38; border: 1rpx solid #F59B38; border-radius: 5rpx; text-align: center; padding: 0 10rpx;">高位股风险:
|
style="color: #F59B38; border: 1rpx solid #F59B38; border-radius: 5rpx; text-align: center; padding: 0 10rpx;">高位股风险:
|
||||||
低</text>
|
低</text>
|
||||||
@@ -81,24 +93,28 @@
|
|||||||
</view>冷门
|
</view>冷门
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 7rpx; margin-top: 25rpx;">
|
<view style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 7rpx; margin-top: 25rpx;">
|
||||||
<view v-for="(item, index) in bkList" :key="index" @click="bkydAction(index)"
|
<view v-for="(item, index) in bkList" :key="index" @click="bkydAction(index)" :style="{
|
||||||
style="background-color: #EF4444; border-radius: 5rpx; padding: 15rpx; color: white; font-size: 24rpx; font-weight: 500;">
|
backgroundColor: item.bgColor,
|
||||||
<view>{{item.title}}</view>
|
borderRadius: '5rpx',
|
||||||
<view style="font-size: 22rpx;">{{item.count}}只</view>
|
padding: '15rpx',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '24rpx',
|
||||||
|
fontWeight: '500'
|
||||||
|
}">
|
||||||
|
<view class="single-line-ellipsis">{{item.title}}</view>
|
||||||
|
<view class="count-text">{{item.count}}只</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
<view
|
<view
|
||||||
style="margin: 25rpx; display: grid; grid-template-columns: repeat(3, 1fr); gap: 20rpx; color: #999999; font-size: 22rpx; font-weight: 500;">
|
style="margin: 25rpx; display: grid; grid-template-columns: repeat(3, 1fr); gap: 20rpx; color: #999999; font-size: 22rpx; font-weight: 500;">
|
||||||
<!-- <view v-for="(item, index) in bkTypes"
|
|
||||||
style="display: flex; align-items: center; justify-content: center; padding: 10rpx 20rpx;"
|
|
||||||
:style="{color: (index == 0 ? '#BB8520' : '#999999'), border: `1rpx solid ${index == 0 ? '#F2C369' : '#D2D2D2'}`, 'background-color' : (index == 0 ? '#FFFAF1' : '#FFF')}">
|
|
||||||
{{item}}
|
|
||||||
</view> -->
|
|
||||||
<view v-for="(item, index) in bkTypes" @click="switchTab(index)"
|
<view v-for="(item, index) in bkTypes" @click="switchTab(index)"
|
||||||
style="display: flex; align-items: center; justify-content: center; padding: 10rpx 20rpx; border-radius: 8rpx;"
|
style="display: flex; align-items: center; justify-content: center; padding: 10rpx 20rpx; border-radius: 8rpx;"
|
||||||
:style="{
|
:style="{
|
||||||
@@ -178,7 +194,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {getBaseURL1 } from '@/request/http.js'
|
import {
|
||||||
|
getBaseURL1
|
||||||
|
} from '@/request/http.js'
|
||||||
import {
|
import {
|
||||||
inject
|
inject
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
@@ -314,69 +332,28 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
wordData: [],
|
wordData: [],
|
||||||
bkList: [{
|
bkList: [],
|
||||||
title: '存储芯片',
|
number_limit_stocks: '',
|
||||||
count: 8
|
HEAT_LEVELS: [{
|
||||||
}, {
|
threshold: 0.7,
|
||||||
title: '存储芯片',
|
color: '#EF4444',
|
||||||
count: 8
|
level: '高热度'
|
||||||
},
|
}, // >70%
|
||||||
{
|
{
|
||||||
title: '存储芯片',
|
threshold: 0.4,
|
||||||
count: 8
|
color: '#F97316',
|
||||||
},
|
level: '中热度'
|
||||||
|
}, // 40%~70%
|
||||||
{
|
{
|
||||||
title: '存储芯片',
|
threshold: 0.2,
|
||||||
count: 8
|
color: '#F3B800',
|
||||||
},
|
level: '低热度'
|
||||||
|
}, // 20%~40%
|
||||||
{
|
{
|
||||||
title: '存储芯片',
|
threshold: 0,
|
||||||
count: 8
|
color: '#01AB5D',
|
||||||
},
|
level: '无热度'
|
||||||
{
|
} // ≤20%
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储芯片',
|
|
||||||
count: 8
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
bkTypes: [
|
bkTypes: [
|
||||||
'板块关联图',
|
'板块关联图',
|
||||||
@@ -460,7 +437,7 @@
|
|||||||
this.activeIndex = e.index
|
this.activeIndex = e.index
|
||||||
this.contentTop = this.navH + 20 / 750 * inject('windowWidth')
|
this.contentTop = this.navH + 20 / 750 * inject('windowWidth')
|
||||||
|
|
||||||
this.analyseHighStocks()
|
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -475,6 +452,14 @@
|
|||||||
//}
|
//}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getHeatColor(value, max) {
|
||||||
|
// 处理边界:最大值为0时直接返回绿色
|
||||||
|
if (max === 0) return '#01AB5D';
|
||||||
|
const ratio = value / max;
|
||||||
|
// 找到第一个满足「占比 > 阈值」的等级(因数组从高到低排序,匹配第一个即最高等级)
|
||||||
|
const matchedLevel = this.HEAT_LEVELS.find(level => ratio > level.threshold);
|
||||||
|
return matchedLevel ? matchedLevel.color : '#01AB5D';
|
||||||
|
},
|
||||||
// 切换标签
|
// 切换标签
|
||||||
async switchTab(index) {
|
async switchTab(index) {
|
||||||
this.activeType = index;
|
this.activeType = index;
|
||||||
@@ -536,7 +521,36 @@
|
|||||||
|
|
||||||
if (res.statusCode === 200 && res.data) {
|
if (res.statusCode === 200 && res.data) {
|
||||||
this.originData = res.data;
|
this.originData = res.data;
|
||||||
console.log('接口数据请求成功', this.originData.chart_data );
|
|
||||||
|
|
||||||
|
const chartData = this.originData.chart_data || {};
|
||||||
|
const labels = chartData.labels || [];
|
||||||
|
const counts = chartData.counts || [];
|
||||||
|
|
||||||
|
// 1. 找到counts中的最大值(用于计算热度颜色)
|
||||||
|
const maxCount = counts.length > 0 ? Math.max(...counts) : 0;
|
||||||
|
|
||||||
|
// 2. 遍历组装bkList(包含标题、数量、背景色、占比),先保证labels和counts长度一致
|
||||||
|
let bkList = [];
|
||||||
|
const maxLen = Math.min(labels.length, counts.length); // 取两者较短的长度,避免越界
|
||||||
|
for (let i = 0; i < maxLen; i++) {
|
||||||
|
const title = labels[i];
|
||||||
|
const count = counts[i] || 0;
|
||||||
|
// 计算背景色(当前count / 最大count → 匹配颜色)
|
||||||
|
const bgColor = this.getHeatColor(count, maxCount);
|
||||||
|
// 计算占比(保留2位小数,可选)
|
||||||
|
const ratio = maxCount === 0 ? 0 : ((count / maxCount) * 100).toFixed(2);
|
||||||
|
|
||||||
|
bkList.push({
|
||||||
|
title, // 板块名称
|
||||||
|
count, // 数量
|
||||||
|
bgColor, // 背景色
|
||||||
|
ratio // 占比(百分比,可选)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 核心:限制最多显示16条(切片操作放在最后)
|
||||||
|
this.bkList = bkList.slice(0, 16);
|
||||||
this.initPieChart();
|
this.initPieChart();
|
||||||
} else {
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
@@ -589,10 +603,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新饼图配置的data
|
// 更新饼图配置的data
|
||||||
this.pieOption.series[0].data = pieData.length > 0 ? pieData : [
|
this.pieOption.series[0].data = pieData.length > 0 ? pieData : [{
|
||||||
{ value: 10, name: '科技板块' },
|
value: 10,
|
||||||
{ value: 8, name: '人脑工程' },
|
name: '科技板块'
|
||||||
{ value: 9, name: '商业航天' }
|
},
|
||||||
|
{
|
||||||
|
value: 8,
|
||||||
|
name: '人脑工程'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 9,
|
||||||
|
name: '商业航天'
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 初始化ECharts并设置配置
|
// 初始化ECharts并设置配置
|
||||||
@@ -625,352 +647,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this.wordData = [{
|
|
||||||
// name: "脑机",
|
|
||||||
// value: 10000
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "航天",
|
|
||||||
// value: 3428
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "商业",
|
|
||||||
// value: 1747
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "智能",
|
|
||||||
// value: 1692
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "量产",
|
|
||||||
// value: 1589
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "落地",
|
|
||||||
// value: 1555
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "存储芯片",
|
|
||||||
// value: 1487
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "医疗",
|
|
||||||
// value: 1348
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "马斯克",
|
|
||||||
// value: 1346
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "业绩",
|
|
||||||
// value: 1234
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "康复",
|
|
||||||
// value: 1143
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "机器人",
|
|
||||||
// value: 1127
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "洁净室",
|
|
||||||
// value: 1078
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "标的",
|
|
||||||
// value: 1072
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "设备",
|
|
||||||
// value: 1071
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "算力",
|
|
||||||
// value: 1015
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "材料",
|
|
||||||
// value: 983
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "卫星",
|
|
||||||
// value: 970
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "科技",
|
|
||||||
// value: 947
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "资产",
|
|
||||||
// value: 828
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "半导体",
|
|
||||||
// value: 774
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "重估",
|
|
||||||
// value: 750
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "人脑",
|
|
||||||
// value: 747
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "平台",
|
|
||||||
// value: 737
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "产业链",
|
|
||||||
// value: 726
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "赛道",
|
|
||||||
// value: 715
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "电池",
|
|
||||||
// value: 694
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "估值",
|
|
||||||
// value: 689
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "景气",
|
|
||||||
// value: 682
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "A股",
|
|
||||||
// value: 662
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "商业化",
|
|
||||||
// value: 643
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "固态",
|
|
||||||
// value: 642
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "工程",
|
|
||||||
// value: 642
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "军工",
|
|
||||||
// value: 642
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "芯片",
|
|
||||||
// value: 615
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "医疗器械",
|
|
||||||
// value: 606
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "供应链",
|
|
||||||
// value: 585
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "弹性",
|
|
||||||
// value: 573
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "蓝箭",
|
|
||||||
// value: 551
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "市值",
|
|
||||||
// value: 541
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "高端",
|
|
||||||
// value: 527
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "植入",
|
|
||||||
// value: 523
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "耗材",
|
|
||||||
// value: 523
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "逻辑",
|
|
||||||
// value: 519
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "数据",
|
|
||||||
// value: 512
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "服务器",
|
|
||||||
// value: 504
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "供应商",
|
|
||||||
// value: 503
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "电子",
|
|
||||||
// value: 483
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "芳纶",
|
|
||||||
// value: 458
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "传闻",
|
|
||||||
// value: 454
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "国产化",
|
|
||||||
// value: 453
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "营销",
|
|
||||||
// value: 452
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "涨价",
|
|
||||||
// value: 450
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "临床",
|
|
||||||
// value: 449
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "转型",
|
|
||||||
// value: 444
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "强脑",
|
|
||||||
// value: 441
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "储能",
|
|
||||||
// value: 441
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "智能家居",
|
|
||||||
// value: 438
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "场景",
|
|
||||||
// value: 435
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "港股",
|
|
||||||
// value: 423
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "柔性",
|
|
||||||
// value: 422
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "人形",
|
|
||||||
// value: 414
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "国产",
|
|
||||||
// value: 411
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "接口技术",
|
|
||||||
// value: 401
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "消费",
|
|
||||||
// value: 399
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "创板",
|
|
||||||
// value: 397
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "全球",
|
|
||||||
// value: 389
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "替代",
|
|
||||||
// value: 389
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "融资",
|
|
||||||
// value: 388
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "补贴",
|
|
||||||
// value: 369
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "管线",
|
|
||||||
// value: 368
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "电极",
|
|
||||||
// value: 367
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "模态",
|
|
||||||
// value: 364
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "国家",
|
|
||||||
// value: 361
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "盈利",
|
|
||||||
// value: 359
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "测试",
|
|
||||||
// value: 356
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "子公司",
|
|
||||||
// value: 354
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "实控",
|
|
||||||
// value: 353
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "八院",
|
|
||||||
// value: 353
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "价格",
|
|
||||||
// value: 352
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "旗下",
|
|
||||||
// value: 351
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "组件",
|
|
||||||
// value: 346
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "电解液",
|
|
||||||
// value: 342
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: "中标",
|
|
||||||
// value: 340
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
|
|
||||||
//console.log('父页面设置词云数据:', JSON.stringify(this.wordData));
|
//console.log('父页面设置词云数据:', JSON.stringify(this.wordData));
|
||||||
},
|
},
|
||||||
handleDateChange(data) {
|
handleDateChange(data) {
|
||||||
console.log('从日历组件接收的参数:', data.item?.zt_count);
|
console.log('从日历组件接收的参数:', {
|
||||||
|
currentZtCount: data.item?.zt_count,
|
||||||
|
prevZtCount: data.prevItem?.zt_count
|
||||||
|
});
|
||||||
// 赋值到父页面的变量中
|
// 赋值到父页面的变量中
|
||||||
this.selectedYearMonth = data.yearMonth;
|
this.selectedYearMonth = data.yearMonth;
|
||||||
this.selectedFullDate = data.fullDate;
|
this.selectedFullDate = data.fullDate;
|
||||||
this.selectedItem = data.item;
|
this.selectedItem = data.item;
|
||||||
|
|
||||||
// 2. 格式化日期:年-月-日 → 月日(如 2026-01-14 → 1月14日)
|
// 2. 格式化日期:年-月-日 → 月日(如 2026-01-14 → 1月14日)
|
||||||
if (data.fullDate) {
|
if (data.fullDate) {
|
||||||
const [year, month, day] = data.fullDate.split('-').map(Number);
|
const [year, month, day] = data.fullDate.split('-').map(Number);
|
||||||
@@ -980,7 +669,17 @@
|
|||||||
// 3. 赋值涨停家数(优先取item中的zt_count,无数据则显示0)
|
// 3. 赋值涨停家数(优先取item中的zt_count,无数据则显示0)
|
||||||
const ztCount = data.item?.zt_count ?? 0;
|
const ztCount = data.item?.zt_count ?? 0;
|
||||||
this.tabTypes[1].data = ztCount.toString(); // 转为字符串保证格式统一
|
this.tabTypes[1].data = ztCount.toString(); // 转为字符串保证格式统一
|
||||||
|
this.number_limit_stocks = ztCount.toString();
|
||||||
|
|
||||||
|
// ===== 核心修改:新增0值判断逻辑 =====
|
||||||
|
const prevZtCount = data.prevItem?.zt_count ?? 0; // 上一天的涨停家数
|
||||||
|
// 条件:当天或上一天的zt_count为0 → 差值直接赋值0;否则计算真实差值
|
||||||
|
const changeValue = (ztCount === 0 || prevZtCount === 0) ?
|
||||||
|
0 :
|
||||||
|
ztCount - prevZtCount;
|
||||||
|
this.tabTypes[1].change = changeValue;
|
||||||
|
// =======================================
|
||||||
|
this.fetchData()
|
||||||
// this.analyseHighStocks()
|
// this.analyseHighStocks()
|
||||||
},
|
},
|
||||||
analyseHighStocks() {
|
analyseHighStocks() {
|
||||||
@@ -1024,4 +723,21 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
bottom: calc(55px + env(safe-area-inset-bottom));
|
bottom: calc(55px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 单行省略样式类 */
|
||||||
|
.single-line-ellipsis {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 120rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 数量行样式(可选抽离) */
|
||||||
|
.count-text {
|
||||||
|
font-size: 22rpx;
|
||||||
|
margin-top: 4rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user