You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
4.6 KiB

  1. <!-- @format -->
  2. <template>
  3. <view class="index-card">
  4. <view class="card-header">
  5. <view class="flag-container">
  6. <image :src="getMarketFlag(market)" class="flag-icon" mode="aspectFit"></image>
  7. </view>
  8. <text class="index-name">{{ stockName }}</text>
  9. </view>
  10. <view class="price-info">
  11. <text class="current-price" :style="{ color: priceColor }">{{ currentPrice }}</text>
  12. <view class="change-info">
  13. <text class="change-amount" :style="{ color: priceColor }">{{ judgeSymbol(changeAmount) }}</text>
  14. <text class="change-percent" :style="{ color: priceColor }">{{ judgeSymbol(changePercent) }}</text>
  15. </view>
  16. </view>
  17. <view class="chart-container">
  18. <view class="mini-chart" :style="{ backgroundColor: chartBgColor }">
  19. <!-- 这里可以放置实际的图表组件目前用简单的波浪线表示 -->
  20. <view class="chart-line" :style="{ borderColor: priceColor }"></view>
  21. </view>
  22. </view>
  23. </view>
  24. </template>
  25. <script setup>
  26. import { computed } from "vue";
  27. // 定义组件属性
  28. const props = defineProps({
  29. // 国旗图标路径
  30. market: {
  31. type: String,
  32. required: true,
  33. },
  34. // 指数名称
  35. stockName: {
  36. type: String,
  37. required: true,
  38. },
  39. // 当前价格
  40. currentPrice: {
  41. type: [String, Number],
  42. required: true,
  43. },
  44. // 涨跌金额
  45. changeAmount: {
  46. type: [String, Number],
  47. required: true,
  48. },
  49. // 涨跌幅
  50. changePercent: {
  51. type: [String, Number],
  52. required: true,
  53. },
  54. // 是否上涨
  55. isRising: {
  56. type: Boolean,
  57. default: true,
  58. },
  59. });
  60. const judgeSymbol = (num) => {
  61. return num[0] === "-" ? num : "+" + num;
  62. };
  63. const getMarketFlag = (market) => {
  64. let imagePath;
  65. if (market === "cn") {
  66. imagePath = "/static/marketSituation-image/country-flag/cn.png";
  67. } else if (market === "hk") {
  68. imagePath = "/static/marketSituation-image/country-flag/hk.png";
  69. } else if (market === "can") {
  70. imagePath = "/static/marketSituation-image/country-flag/can.png";
  71. } else if (market === "my") {
  72. imagePath = "/static/marketSituation-image/country-flag/my.png";
  73. } else if (market === "sg") {
  74. imagePath = "/static/marketSituation-image/country-flag/sg.png";
  75. } else if (market === "th") {
  76. imagePath = "/static/marketSituation-image/country-flag/th.png";
  77. } else if (market === "vi") {
  78. imagePath = "/static/marketSituation-image/country-flag/vi.png";
  79. } else if (market === "us" || market === "usa") {
  80. imagePath = "/static/marketSituation-image/country-flag/us.png";
  81. } else {
  82. imagePath = "/static/marketSituation-image/country-flag/global.png";
  83. }
  84. return imagePath;
  85. };
  86. // 计算价格颜色
  87. const priceColor = computed(() => {
  88. return props.isRising ? "#00C853" : "#FF1744";
  89. });
  90. // 计算图表背景色
  91. const chartBgColor = computed(() => {
  92. return props.isRising ? "#E8F5E8" : "#FFEBEE";
  93. });
  94. </script>
  95. <style scoped>
  96. .index-card {
  97. background-color: #ffffff;
  98. border-radius: 12rpx;
  99. padding: 20rpx;
  100. margin: 16rpx;
  101. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  102. border: 1rpx solid #f0f0f0;
  103. }
  104. .card-header {
  105. display: flex;
  106. align-items: center;
  107. margin-bottom: 16rpx;
  108. }
  109. .flag-container {
  110. width: 48rpx;
  111. height: 32rpx;
  112. margin-right: 12rpx;
  113. border-radius: 4rpx;
  114. overflow: hidden;
  115. }
  116. .flag-icon {
  117. width: 100%;
  118. height: 100%;
  119. }
  120. .index-name {
  121. font-size: 28rpx;
  122. font-weight: 500;
  123. color: #333333;
  124. flex: 1;
  125. white-space: nowrap;
  126. overflow: hidden;
  127. text-overflow: ellipsis;
  128. }
  129. .price-info {
  130. margin-bottom: 20rpx;
  131. }
  132. .current-price {
  133. font-size: 36rpx;
  134. font-weight: bold;
  135. display: block;
  136. margin-bottom: 8rpx;
  137. }
  138. .change-info {
  139. display: flex;
  140. align-items: center;
  141. gap: 16rpx;
  142. }
  143. .change-amount {
  144. font-size: 24rpx;
  145. font-weight: 500;
  146. }
  147. .change-percent {
  148. font-size: 24rpx;
  149. font-weight: 500;
  150. }
  151. .chart-container {
  152. height: 80rpx;
  153. border-radius: 8rpx;
  154. overflow: hidden;
  155. }
  156. .mini-chart {
  157. width: 100%;
  158. height: 100%;
  159. position: relative;
  160. border-radius: 8rpx;
  161. }
  162. .chart-line {
  163. position: absolute;
  164. bottom: 20rpx;
  165. left: 10rpx;
  166. right: 10rpx;
  167. height: 2rpx;
  168. border-top: 2rpx solid;
  169. border-style: solid;
  170. }
  171. /* 添加一些波浪效果 */
  172. .chart-line::before {
  173. content: "";
  174. position: absolute;
  175. top: -10rpx;
  176. left: 20%;
  177. width: 20rpx;
  178. height: 20rpx;
  179. border: 2rpx solid;
  180. border-color: inherit;
  181. border-radius: 50%;
  182. background: transparent;
  183. }
  184. .chart-line::after {
  185. content: "";
  186. position: absolute;
  187. top: -6rpx;
  188. right: 30%;
  189. width: 12rpx;
  190. height: 12rpx;
  191. border: 2rpx solid;
  192. border-color: inherit;
  193. border-radius: 50%;
  194. background: transparent;
  195. }
  196. </style>