2.6 盈利能力模块表格完善

This commit is contained in:
尚政杰
2026-02-06 18:01:05 +08:00
parent 890be2e3e9
commit 6dc7d00e6a
48 changed files with 2831 additions and 697 deletions

View File

@@ -2,6 +2,7 @@
const common_vendor = require("../../common/vendor.js");
const request_api = require("../../request/api.js");
const common_assets = require("../../common/assets.js");
const echarts = require("../../uni_modules/lime-echart/static/echarts.min.js");
const _sfc_main = {
data() {
return {
@@ -149,7 +150,14 @@ const _sfc_main = {
//搜索结果
selectSearchStockInfo: null,
//选中的搜索股票信息
isShowTime: false
isShowTime: false,
ec: { lazyLoad: true },
// 延迟加载 ECharts
chart: null,
y2MaxText: "",
// 右侧顶部最大值文本2.36% / -0.89%
y2MinText: ""
// 右侧底部最小值文本(例:-3.12% / 0.56%
};
},
onLoad(e) {
@@ -354,6 +362,7 @@ const _sfc_main = {
};
request_api.marketHotspotOverview(param).then((res) => {
var _a;
const data = res == null ? void 0 : res.data;
const alerts = ((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.alerts) || [];
const changePct = res.data.index.change_pct;
let numPct = 0;
@@ -404,9 +413,247 @@ const _sfc_main = {
};
const sortedAlerts = processedAlerts.sort(sortByTimeDesc);
this.marketAlertsList = sortedAlerts;
this.initChart(data.index.timeline, processedAlerts);
}).catch((error) => {
});
},
async initChart(timeline, alerts) {
if (!timeline || timeline.length === 0)
return;
const chart = await this.$refs.chartRef.init(echarts);
this.chartInstance = chart;
const xAxisTime = timeline.map((item) => {
var _a;
return ((_a = item.time) == null ? void 0 : _a.trim()) || "";
});
const yAxisPrice = timeline.map((item) => Number(item.price) || 0);
const changePctList = timeline.map((item) => Number(item.change_pct)).filter((val) => !isNaN(val) && val !== null && val !== void 0);
const validPrices = yAxisPrice.filter((val) => val !== 0 && !isNaN(val));
const priceMin = validPrices.length > 0 ? Math.min(...validPrices) : 0;
const priceMax = validPrices.length > 0 ? Math.max(...validPrices) : 0;
const priceRange = priceMax - priceMin;
const yAxisMin = priceRange > 0 ? priceMin - priceRange * 0.1 : priceMin;
const yAxisMax = priceRange > 0 ? priceMax + priceRange * 0.25 : priceMax;
let y2Min = 0, y2Max = 0;
if (changePctList.length > 0) {
y2Min = Math.min(...changePctList);
y2Max = Math.max(...changePctList);
this.y2MaxText = Number(y2Max).toFixed(2) + "%";
this.y2MinText = Number(y2Min).toFixed(2) + "%";
} else {
this.y2MaxText = "0.00%";
this.y2MinText = "0.00%";
}
const alertObj = {};
let totalAlert = 0;
let sameTimeCount = 0;
let sameScoreCount = 0;
alerts.forEach((alert) => {
var _a;
if (!alert)
return;
const alertTime = ((_a = alert.time) == null ? void 0 : _a.trim()) || "";
const alertScore = Number(alert.importance_score);
if (alertTime === "" || isNaN(alertScore))
return;
const idx = xAxisTime.findIndex((t) => (t == null ? void 0 : t.trim()) === alertTime);
if (idx === -1)
return;
totalAlert++;
if (!alertObj[alertTime]) {
alertObj[alertTime] = { ...alert, idx, importance_score: alertScore };
} else {
sameTimeCount++;
const existAlert = alertObj[alertTime];
if (alertScore > existAlert.importance_score) {
alertObj[alertTime] = { ...alert, idx, importance_score: alertScore };
} else if (alertScore === existAlert.importance_score) {
sameScoreCount++;
}
}
});
const timeToMinutes = (timeStr) => {
const [hour, minute] = timeStr.split(":").map(Number);
return hour * 60 + minute;
};
const get10MinGroup = (minutes) => {
const startMin = Math.floor(minutes / 10) * 10;
const endMin = startMin + 9;
const formatTime = (m) => {
const h = Math.floor(m / 60).toString().padStart(2, "0");
const mi = (m % 60).toString().padStart(2, "0");
return `${h}:${mi}`;
};
return `${formatTime(startMin)}-${formatTime(endMin)}`;
};
const filterBy10MinGroup = (alertObj2) => {
const alertGroupList = Object.keys(alertObj2).filter((time) => time && time.includes(":")).map((time) => {
const minutes = timeToMinutes(time);
return {
group: get10MinGroup(minutes),
// 所属10分钟分组
score: alertObj2[time].importance_score,
// 告警评分
data: alertObj2[time]
// 原始告警数据
};
});
if (alertGroupList.length === 0)
return {};
const groupMap = {};
alertGroupList.forEach((item) => {
if (!groupMap[item.group]) {
groupMap[item.group] = [];
}
groupMap[item.group].push(item);
});
const finalAlertObj = {};
Object.keys(groupMap).forEach((groupName) => {
const groupItems = groupMap[groupName];
const sortedItems = groupItems.sort((a, b) => b.score - a.score);
const topItem = sortedItems[0];
finalAlertObj[topItem.data.time] = topItem.data;
});
return finalAlertObj;
};
const filteredAlertObj = filterBy10MinGroup(alertObj);
const originalKeyLen = Object.keys(alertObj).length;
const filteredKeyLen = Object.keys(filteredAlertObj).length;
const groupDetail = Object.keys(filteredAlertObj).map((time) => {
const minutes = timeToMinutes(time);
return { time, group: get10MinGroup(minutes), score: filteredAlertObj[time].importance_score };
});
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:957", "===== 告警点处理全统计10分钟分组版=====");
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:958", "1. 过滤后有效告警总数量:", totalAlert);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:959", "2. 相同时间的告警去重数量:", sameTimeCount);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:960", "3. 相同时间且相同评分数量:", sameScoreCount);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:961", "4. 基础去重后(同时间最高评分)数量:", originalKeyLen);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:962", "5. 10分钟分组后每组取最高评分数量", filteredKeyLen);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:963", "6. 分组详情(时间→所属分组→评分):", groupDetail);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:964", "7. 分组后最终告警详情:", filteredAlertObj);
const alertPoints = Object.values(filteredAlertObj).map((alert) => {
const validIdx = !isNaN(alert.idx) && alert.idx >= 0 && alert.idx < xAxisTime.length ? alert.idx : 0;
const xVal = xAxisTime[validIdx] || "";
const yVal = !isNaN(yAxisPrice[validIdx]) ? yAxisPrice[validIdx] : 0;
return {
name: alert.concept_name || "未知概念",
// 概念名兜底
coord: [xVal, yVal],
// 确保x轴值严格匹配xAxis.datay轴值有效
value: yVal,
itemStyle: { color: "#FF4444" },
// 告警点红色
label: {
formatter() {
return alert.concept_name;
},
show: true,
position: "top",
fontSize: 10,
color: "#FF4444",
fontWeight: "500",
distance: 5
}
};
}).filter(Boolean);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:991", "8. 最终ECharts告警点数据10分钟分组", alertPoints);
const option = {
grid: { left: "4%", right: "8%", bottom: "8%", top: "10%", containLabel: true },
xAxis: {
type: "category",
boundaryGap: false,
data: xAxisTime,
axisLabel: {
fontSize: 12,
rotate: 30,
interval: Math.floor(xAxisTime.length / 6)
},
axisTick: {
alignWithLabel: true,
interval: Math.floor(xAxisTime.length / 6)
}
},
yAxis: [
{
type: "value",
min: yAxisMin,
max: yAxisMax,
nameTextStyle: { fontSize: 12 },
axisLabel: {
formatter: (val) => val.toFixed(0),
fontSize: 12
},
splitLine: { lineStyle: { type: "dashed", color: "#EEEEEE" } },
boundaryGap: [0.05, 0.05]
// 上下留5%缓冲,避免顶点告警点被裁剪
}
],
dataZoom: [],
series: [
{
name: "上证指数",
type: "line",
smooth: true,
symbol: "circle",
symbolSize: 5,
itemStyle: { color: "#0092FF" },
lineStyle: {
width: 2,
color: "#0092FF",
shadowColor: "rgba(0,146,255,0.5)",
shadowBlur: 8,
shadowOffsetY: 3,
shadowOffsetX: 0
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(0,146,255,0.25)" },
{ offset: 1, color: "rgba(0,146,255,0)" }
])
},
data: yAxisPrice,
// 保留所有markPoint显示修复配置强制显示/层级/样式)
markPoint: {
show: true,
// 强制开启显示(关键!)
symbol: "circle",
symbolSize: 5,
// 比折线大,避免被遮挡
z: 10,
// 层级置顶,不被任何元素遮挡
data: alertPoints,
itemStyle: {
color: "#FF4444",
borderColor: "#fff",
// 白色描边,更醒目
borderWidth: 1
},
label: {
show: true,
position: "top",
fontSize: 10,
color: "#FF4444",
fontWeight: "500",
distance: 6,
backgroundColor: "rgba(255,255,255,0.8)",
// 标签白色背景,防融合
padding: [2, 4],
borderRadius: 2,
borderColor: "#FF4444",
// 白色描边,更醒目
borderWidth: 1
}
},
yAxisIndex: 0
}
]
};
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:1082", "7. 分组后最终告警详情:", JSON.stringify(option.series));
chart.setOption(option, true);
common_vendor.index.onWindowResize(() => {
this.chartInstance && this.chartInstance.resize();
});
},
itemDetails(item) {
common_vendor.index.navigateTo({
url: "/pagesStock/stockCenterDetails/stockCenterDetails?code=" + item.stock_code
@@ -441,7 +688,7 @@ const _sfc_main = {
},
handleDateChange(date) {
this.selectedDate = date;
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:828", "选中的日期:", date);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:1124", "选中的日期:", date);
},
confirmAction(index) {
if (index == 1) {
@@ -449,7 +696,7 @@ const _sfc_main = {
} else if (index == 2) {
if (this.selectedDate) {
this.currentDate = this.selectedDate;
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:837", "最终确认的日期:", this.currentDate);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:1133", "最终确认的日期:", this.currentDate);
} else {
const now = /* @__PURE__ */ new Date();
const year = now.getFullYear();
@@ -469,7 +716,7 @@ const _sfc_main = {
this.formattedAvg = item.formattedAvg, this.upCount = item.upCount, this.downCount = item.downCount, this.limit_up_ratio = item.limit_up_ratio, this.conceptStocksDetails(item.concept_id);
},
conceptStocksDetails(concept_id) {
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:864", "concept_id", concept_id);
common_vendor.index.__f__("log", "at pages/geGuCenter/geGuCenter.vue:1160", "concept_id", concept_id);
request_api.conceptStocks(concept_id, {}).then((res) => {
if (res.data && res.data.stocks) {
let rawData = res.data.stocks;
@@ -479,7 +726,7 @@ const _sfc_main = {
return bValue - aValue;
});
} else {
common_vendor.index.__f__("warn", "at pages/geGuCenter/geGuCenter.vue:883", "接口返回数据格式异常", res);
common_vendor.index.__f__("warn", "at pages/geGuCenter/geGuCenter.vue:1179", "接口返回数据格式异常", res);
}
}).catch((error) => {
});
@@ -505,15 +752,17 @@ const _sfc_main = {
};
if (!Array) {
const _easycom_navBar2 = common_vendor.resolveComponent("navBar");
const _easycom_l_echart2 = common_vendor.resolveComponent("l-echart");
const _easycom_uni_popup2 = common_vendor.resolveComponent("uni-popup");
const _easycom_LCCalendar22 = common_vendor.resolveComponent("LCCalendar2");
(_easycom_navBar2 + _easycom_uni_popup2 + _easycom_LCCalendar22)();
(_easycom_navBar2 + _easycom_l_echart2 + _easycom_uni_popup2 + _easycom_LCCalendar22)();
}
const _easycom_navBar = () => "../../components/navBar/navBar.js";
const _easycom_l_echart = () => "../../uni_modules/lime-echart/components/l-echart/l-echart.js";
const _easycom_uni_popup = () => "../../uni_modules/uni-popup/components/uni-popup/uni-popup.js";
const _easycom_LCCalendar2 = () => "../../components/LCCalendar2/LCCalendar2.js";
if (!Math) {
(_easycom_navBar + _easycom_uni_popup + _easycom_LCCalendar2)();
(_easycom_navBar + _easycom_l_echart + _easycom_uni_popup + _easycom_LCCalendar2)();
}
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return common_vendor.e({
@@ -587,11 +836,16 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
o: common_assets._imports_2$3,
p: common_vendor.o((...args) => $options.moreAction && $options.moreAction(...args)),
q: common_assets._imports_3$7,
r: common_vendor.t($data.currentDate),
s: common_assets._imports_4$1,
t: common_vendor.o(($event) => $options.allAction(2)),
v: common_assets._imports_3$7,
w: common_vendor.f($data.marketAlertsList, (item, index, i0) => {
r: common_assets._imports_4$1,
s: common_vendor.o(($event) => $options.allAction(1)),
t: common_vendor.t($data.currentDate),
v: common_assets._imports_4$1,
w: common_vendor.o(($event) => $options.allAction(2)),
x: common_vendor.sr("chartRef", "c7f5c964-1"),
y: common_vendor.t($data.y2MaxText),
z: common_vendor.t($data.y2MinText),
A: common_assets._imports_3$7,
B: common_vendor.f($data.marketAlertsList, (item, index, i0) => {
var _a, _b, _c, _d;
return common_vendor.e({
a: common_vendor.t(item.time),
@@ -615,40 +869,40 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
q: common_vendor.o(($event) => $options.bkydAction(item), index)
});
}),
x: common_assets._imports_5$3,
y: common_vendor.s("top:" + $data.contentTop + "px;"),
z: common_vendor.o(($event) => $options.closeAction(1)),
A: common_vendor.o(($event) => $options.confirmAction(1)),
B: common_vendor.f($data.typeList, (item, index, i0) => {
C: common_assets._imports_5$3,
D: common_vendor.s("top:" + $data.contentTop + "px;"),
E: common_vendor.o(($event) => $options.closeAction(1)),
F: common_vendor.o(($event) => $options.confirmAction(1)),
G: common_vendor.f($data.typeList, (item, index, i0) => {
return {
a: item.backIcon,
b: common_vendor.t(item.title),
c: index
};
}),
C: common_vendor.sr("typePopup", "c7f5c964-1"),
D: common_vendor.p({
type: "bottom",
safeArea: false
}),
E: common_vendor.o(($event) => $options.closeAction(2)),
F: common_vendor.o(($event) => $options.confirmAction(2)),
G: common_vendor.o($options.handleDateChange),
H: common_vendor.sr("datePopup", "c7f5c964-2"),
H: common_vendor.sr("typePopup", "c7f5c964-2"),
I: common_vendor.p({
type: "bottom",
safeArea: false
}),
J: common_assets._imports_6$1,
K: common_vendor.o(($event) => $options.closeAction(3)),
L: common_vendor.t($data.formattedAvg),
M: Number($data.formattedAvg) > 0 ? "#EC3440" : "#01AB5D",
N: common_vendor.t($data.upCount),
O: $data.upCount > 0 ? "#EC3440" : "#888888",
P: common_vendor.t($data.downCount),
Q: $data.downCount > 0 ? "#01AB5D" : "#888888",
R: common_vendor.t($options.formatLimitUpRatio($data.limit_up_ratio, 0)),
S: common_vendor.f($data.conceptStocksList, (item, index, i0) => {
J: common_vendor.o(($event) => $options.closeAction(2)),
K: common_vendor.o(($event) => $options.confirmAction(2)),
L: common_vendor.o($options.handleDateChange),
M: common_vendor.sr("datePopup", "c7f5c964-3"),
N: common_vendor.p({
type: "bottom",
safeArea: false
}),
O: common_assets._imports_6$1,
P: common_vendor.o(($event) => $options.closeAction(3)),
Q: common_vendor.t($data.formattedAvg),
R: Number($data.formattedAvg) > 0 ? "#EC3440" : "#01AB5D",
S: common_vendor.t($data.upCount),
T: $data.upCount > 0 ? "#EC3440" : "#888888",
U: common_vendor.t($data.downCount),
V: $data.downCount > 0 ? "#01AB5D" : "#888888",
W: common_vendor.t($options.formatLimitUpRatio($data.limit_up_ratio, 0)),
X: common_vendor.f($data.conceptStocksList, (item, index, i0) => {
return {
a: common_vendor.t(item.name),
b: common_vendor.t(item.code),
@@ -658,8 +912,8 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
f: index % 2 == 0 ? "#fff" : "#FAFAFC"
};
}),
T: common_vendor.sr("detailPopup", "c7f5c964-4"),
U: common_vendor.p({
Y: common_vendor.sr("detailPopup", "c7f5c964-5"),
Z: common_vendor.p({
type: "bottom",
safeArea: false
})