2.6 盈利能力模块表格完善
This commit is contained in:
@@ -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.data,y轴值有效
|
||||
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
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"navigationBarTitleText": "",
|
||||
"usingComponents": {
|
||||
"nav-bar": "../../components/navBar/navBar",
|
||||
"l-echart": "../../uni_modules/lime-echart/components/l-echart/l-echart",
|
||||
"uni-popup": "../../uni_modules/uni-popup/components/uni-popup/uni-popup",
|
||||
"l-c-calendar2": "../../components/LCCalendar2/LCCalendar2"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user