| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- "use strict";
- const common_vendor = require("../common/vendor.js");
- const _sfc_main = {
- __name: "StockListItem",
- props: {
- stock: {
- type: Object,
- required: true
- },
- showDelete: {
- type: Boolean,
- default: false
- }
- },
- emits: ["delete"],
- setup(__props, { emit }) {
- const props = __props;
- let componentInstance = null;
- const deleteWidth = 60;
- const moveX = common_vendor.ref(0);
- let currentX = 0;
- let autoResetTimer = null;
- const AUTO_RESET_DELAY = 2e3;
- const startAutoResetTimer = () => {
- clearAutoResetTimer();
- autoResetTimer = setTimeout(() => {
- moveX.value = 0;
- currentX = 0;
- }, AUTO_RESET_DELAY);
- };
- const clearAutoResetTimer = () => {
- if (autoResetTimer) {
- clearTimeout(autoResetTimer);
- autoResetTimer = null;
- }
- };
- const canvasId = common_vendor.ref(`chart-${props.stock.code}-${Math.random().toString(36).slice(2, 11)}`);
- const getMarketTag = (code) => {
- if (code.startsWith("6"))
- return "沪";
- if (code.startsWith("0"))
- return "深";
- if (code.startsWith("3"))
- return "创";
- return "沪";
- };
- const getMarketClass = (code) => {
- if (code.startsWith("6"))
- return "market-sh";
- if (code.startsWith("0"))
- return "market-sz";
- if (code.startsWith("3"))
- return "market-cy";
- return "market-sh";
- };
- const getChangeClass = (changePercent) => {
- if (!changePercent)
- return "";
- const str = String(changePercent).replace("%", "").replace("+", "");
- const value = parseFloat(str);
- if (value > 0)
- return "change-up";
- if (value < 0)
- return "change-down";
- return "";
- };
- const formatChangePercent = (changePercent) => {
- if (!changePercent)
- return "--";
- return String(changePercent);
- };
- const formatPrice = (price) => {
- if (!price)
- return "--";
- return parseFloat(price).toFixed(2);
- };
- const hasValidChange = (changePercent) => {
- if (!changePercent)
- return false;
- const str = String(changePercent).replace("%", "").replace("+", "");
- const value = parseFloat(str);
- return value !== 0 && !isNaN(value);
- };
- const drawTrendChart = (instance) => {
- let trendData = props.stock.trendData;
- if (!trendData || !Array.isArray(trendData) || trendData.length === 0) {
- trendData = generateMockTrendData();
- }
- const ctx = common_vendor.index.createCanvasContext(canvasId.value, instance);
- const width = 100;
- const height = 30;
- const padding = 2;
- const maxValue = Math.max(...trendData);
- const minValue = Math.min(...trendData);
- const dataRange = maxValue - minValue;
- const avgValue = (maxValue + minValue) / 2;
- const minRange = avgValue * 0.03 || 1;
- const range = Math.max(dataRange, minRange);
- const baseValue = trendData[0];
- const baseY = height - padding - (baseValue - minValue) / range * (height - padding * 2);
- const changePercent = parseFloat(String(props.stock.changePercent || "0").replace("%", "").replace("+", ""));
- const isUp = changePercent >= 0;
- const lineColor = isUp ? "#FF3B30" : "#34C759";
- const fillColor = isUp ? "rgba(255, 59, 48, 0.15)" : "rgba(52, 199, 89, 0.15)";
- ctx.beginPath();
- ctx.setStrokeStyle("#e0e0e0");
- ctx.setLineWidth(0.5);
- ctx.setLineDash([2, 2], 0);
- ctx.moveTo(padding, baseY);
- ctx.lineTo(width - padding, baseY);
- ctx.stroke();
- ctx.setLineDash([], 0);
- ctx.beginPath();
- ctx.moveTo(padding, baseY);
- trendData.forEach((value, index) => {
- const x = padding + index / (trendData.length - 1) * (width - padding * 2);
- const y = height - padding - (value - minValue) / range * (height - padding * 2);
- ctx.lineTo(x, y);
- });
- ctx.lineTo(width - padding, baseY);
- ctx.closePath();
- ctx.setFillStyle(fillColor);
- ctx.fill();
- ctx.beginPath();
- trendData.forEach((value, index) => {
- const x = padding + index / (trendData.length - 1) * (width - padding * 2);
- const y = height - padding - (value - minValue) / range * (height - padding * 2);
- if (index === 0) {
- ctx.moveTo(x, y);
- } else {
- ctx.lineTo(x, y);
- }
- });
- ctx.setStrokeStyle(lineColor);
- ctx.setLineWidth(1.5);
- ctx.stroke();
- ctx.draw();
- };
- const generateMockTrendData = () => {
- const changePercent = parseFloat(String(props.stock.changePercent || "0").replace("%", "").replace("+", ""));
- const points = 15;
- const data = [];
- let baseValue = 100;
- const trend = changePercent / 100;
- for (let i = 0; i < points; i++) {
- const randomChange = (Math.random() - 0.5) * 6;
- const trendChange = i / points * trend * 100;
- baseValue = baseValue + randomChange + trendChange / points;
- data.push(baseValue);
- }
- return data;
- };
- const handleMoveChange = (e) => {
- currentX = e.detail.x;
- if (props.showDelete && currentX <= -deleteWidth / 2) {
- startAutoResetTimer();
- }
- };
- const handleMoveEnd = () => {
- if (!props.showDelete)
- return;
- if (currentX < -deleteWidth / 3) {
- moveX.value = -deleteWidth;
- startAutoResetTimer();
- } else {
- moveX.value = 0;
- currentX = 0;
- clearAutoResetTimer();
- }
- };
- const handleDelete = () => {
- clearAutoResetTimer();
- moveX.value = 0;
- emit("delete");
- };
- common_vendor.onMounted(() => {
- componentInstance = common_vendor.getCurrentInstance();
- common_vendor.nextTick$1(() => {
- setTimeout(() => {
- drawTrendChart(componentInstance);
- }, 300);
- });
- });
- common_vendor.watch(() => props.stock.trendData, (newData) => {
- if (newData && componentInstance) {
- common_vendor.nextTick$1(() => {
- drawTrendChart(componentInstance);
- });
- }
- }, { deep: true });
- common_vendor.watch(() => props.stock.changePercent, () => {
- if (componentInstance) {
- common_vendor.nextTick$1(() => {
- drawTrendChart(componentInstance);
- });
- }
- });
- common_vendor.watch(moveX, (newVal) => {
- if (newVal < 0 && props.showDelete) {
- if (!autoResetTimer) {
- startAutoResetTimer();
- }
- } else if (newVal === 0) {
- clearAutoResetTimer();
- }
- });
- common_vendor.onUnmounted(() => {
- clearAutoResetTimer();
- });
- return (_ctx, _cache) => {
- return common_vendor.e({
- a: common_vendor.t(__props.stock.name),
- b: common_vendor.t(getMarketTag(__props.stock.code)),
- c: common_vendor.n(getMarketClass(__props.stock.code)),
- d: common_vendor.t(__props.stock.code),
- e: canvasId.value,
- f: canvasId.value,
- g: hasValidChange(__props.stock.changePercent)
- }, hasValidChange(__props.stock.changePercent) ? {
- h: common_vendor.t(formatChangePercent(__props.stock.changePercent)),
- i: common_vendor.n(getChangeClass(__props.stock.changePercent))
- } : {}, {
- j: common_vendor.t(formatPrice(__props.stock.currentPrice)),
- k: __props.showDelete
- }, __props.showDelete ? {
- l: common_vendor.o(handleDelete)
- } : {}, {
- m: moveX.value,
- n: common_vendor.o(handleMoveChange),
- o: common_vendor.o(handleMoveEnd)
- });
- };
- }
- };
- const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-29af7fd7"], ["__file", "D:/program/gupiao-wx/src/components/StockListItem.vue"]]);
- wx.createComponent(Component);
|