StockListItem.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. "use strict";
  2. const common_vendor = require("../common/vendor.js");
  3. const _sfc_main = {
  4. __name: "StockListItem",
  5. props: {
  6. stock: {
  7. type: Object,
  8. required: true
  9. },
  10. showDelete: {
  11. type: Boolean,
  12. default: false
  13. }
  14. },
  15. emits: ["delete"],
  16. setup(__props, { emit }) {
  17. const props = __props;
  18. let componentInstance = null;
  19. const deleteWidth = 60;
  20. const moveX = common_vendor.ref(0);
  21. let currentX = 0;
  22. const canvasId = common_vendor.ref(`chart-${props.stock.code}-${Math.random().toString(36).slice(2, 11)}`);
  23. const getMarketTag = (code) => {
  24. if (code.startsWith("6"))
  25. return "沪";
  26. if (code.startsWith("0"))
  27. return "深";
  28. if (code.startsWith("3"))
  29. return "创";
  30. return "沪";
  31. };
  32. const getMarketClass = (code) => {
  33. if (code.startsWith("6"))
  34. return "market-sh";
  35. if (code.startsWith("0"))
  36. return "market-sz";
  37. if (code.startsWith("3"))
  38. return "market-cy";
  39. return "market-sh";
  40. };
  41. const getChangeClass = (changePercent) => {
  42. if (!changePercent)
  43. return "";
  44. const str = String(changePercent).replace("%", "").replace("+", "");
  45. const value = parseFloat(str);
  46. if (value > 0)
  47. return "change-up";
  48. if (value < 0)
  49. return "change-down";
  50. return "";
  51. };
  52. const formatChangePercent = (changePercent) => {
  53. if (!changePercent)
  54. return "--";
  55. return String(changePercent);
  56. };
  57. const formatPrice = (price) => {
  58. if (!price)
  59. return "--";
  60. return parseFloat(price).toFixed(2);
  61. };
  62. const drawTrendChart = (instance) => {
  63. console.log("[趋势图] 开始绘制:", props.stock.code, canvasId.value);
  64. let trendData = props.stock.trendData;
  65. if (!trendData || !Array.isArray(trendData) || trendData.length === 0) {
  66. console.log("[趋势图] 使用模拟数据");
  67. trendData = generateMockTrendData();
  68. } else {
  69. console.log("[趋势图] 使用真实数据,数据点数:", trendData.length);
  70. }
  71. const ctx = common_vendor.index.createCanvasContext(canvasId.value, instance);
  72. const width = 100;
  73. const height = 30;
  74. const padding = 2;
  75. const maxValue = Math.max(...trendData);
  76. const minValue = Math.min(...trendData);
  77. const range = maxValue - minValue || 1;
  78. console.log("[趋势图] 数据范围:", { min: minValue, max: maxValue, range });
  79. const changePercent = parseFloat(String(props.stock.changePercent || "0").replace("%", "").replace("+", ""));
  80. const isUp = changePercent >= 0;
  81. const lineColor = isUp ? "#FF3B30" : "#34C759";
  82. const fillColor = isUp ? "rgba(255, 59, 48, 0.1)" : "rgba(52, 199, 89, 0.1)";
  83. console.log("[趋势图] 颜色:", { isUp, lineColor, changePercent });
  84. ctx.beginPath();
  85. trendData.forEach((value, index) => {
  86. const x = padding + index / (trendData.length - 1) * (width - padding * 2);
  87. const y = height - padding - (value - minValue) / range * (height - padding * 2);
  88. if (index === 0) {
  89. ctx.moveTo(x, y);
  90. } else {
  91. ctx.lineTo(x, y);
  92. }
  93. });
  94. ctx.setStrokeStyle(lineColor);
  95. ctx.setLineWidth(1);
  96. ctx.stroke();
  97. ctx.lineTo(width - padding, height - padding);
  98. ctx.lineTo(padding, height - padding);
  99. ctx.closePath();
  100. ctx.setFillStyle(fillColor);
  101. ctx.fill();
  102. ctx.draw();
  103. console.log("[趋势图] 绘制完成");
  104. };
  105. const generateMockTrendData = () => {
  106. const changePercent = parseFloat(String(props.stock.changePercent || "0").replace("%", "").replace("+", ""));
  107. const points = 30;
  108. const data = [];
  109. let baseValue = 100;
  110. const trend = changePercent / 100;
  111. for (let i = 0; i < points; i++) {
  112. const randomChange = (Math.random() - 0.5) * 2;
  113. const trendChange = i / points * trend * 100;
  114. baseValue = baseValue + randomChange + trendChange / points;
  115. data.push(baseValue);
  116. }
  117. return data;
  118. };
  119. const handleMoveChange = (e) => {
  120. currentX = e.detail.x;
  121. };
  122. const handleMoveEnd = () => {
  123. if (!props.showDelete)
  124. return;
  125. if (currentX < -deleteWidth / 3) {
  126. moveX.value = -deleteWidth;
  127. } else {
  128. moveX.value = 0;
  129. }
  130. };
  131. const handleDelete = () => {
  132. moveX.value = 0;
  133. emit("delete");
  134. };
  135. common_vendor.onMounted(() => {
  136. console.log("[趋势图] 组件挂载:", props.stock.code);
  137. componentInstance = common_vendor.getCurrentInstance();
  138. common_vendor.nextTick$1(() => {
  139. setTimeout(() => {
  140. drawTrendChart(componentInstance);
  141. }, 300);
  142. });
  143. });
  144. common_vendor.watch(() => props.stock.trendData, (newData) => {
  145. if (newData && componentInstance) {
  146. console.log("[趋势图] 数据更新,重新绘制:", props.stock.code);
  147. common_vendor.nextTick$1(() => {
  148. drawTrendChart(componentInstance);
  149. });
  150. }
  151. }, { deep: true });
  152. common_vendor.watch(() => props.stock.changePercent, () => {
  153. if (componentInstance) {
  154. common_vendor.nextTick$1(() => {
  155. drawTrendChart(componentInstance);
  156. });
  157. }
  158. });
  159. return (_ctx, _cache) => {
  160. return common_vendor.e({
  161. a: common_vendor.t(__props.stock.name),
  162. b: common_vendor.t(getMarketTag(__props.stock.code)),
  163. c: common_vendor.n(getMarketClass(__props.stock.code)),
  164. d: common_vendor.t(__props.stock.code),
  165. e: canvasId.value,
  166. f: canvasId.value,
  167. g: common_vendor.t(formatChangePercent(__props.stock.changePercent)),
  168. h: common_vendor.n(getChangeClass(__props.stock.changePercent)),
  169. i: common_vendor.t(formatPrice(__props.stock.currentPrice)),
  170. j: __props.showDelete
  171. }, __props.showDelete ? {
  172. k: common_vendor.o(handleDelete)
  173. } : {}, {
  174. l: moveX.value,
  175. m: common_vendor.o(handleMoveChange),
  176. n: common_vendor.o(handleMoveEnd)
  177. });
  178. };
  179. }
  180. };
  181. const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-29af7fd7"], ["__file", "D:/program/gupiao-wx/src/components/StockListItem.vue"]]);
  182. wx.createComponent(Component);