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.

217 lines
4.5 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 }">{{ changeAmount }}</text>
  14. <text class="change-percent" :style="{ color: priceColor }">{{ 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 getMarketFlag = (market) => {
  61. let imagePath;
  62. if (market === "cn") {
  63. imagePath = "/static/marketSituation-image/country-flag/cn.png";
  64. } else if (market === "hk") {
  65. imagePath = "/static/marketSituation-image/country-flag/hk.png";
  66. } else if (market === "can") {
  67. imagePath = "/static/marketSituation-image/country-flag/can.png";
  68. } else if (market === "my") {
  69. imagePath = "/static/marketSituation-image/country-flag/my.png";
  70. } else if (market === "sg") {
  71. imagePath = "/static/marketSituation-image/country-flag/sg.png";
  72. } else if (market === "th") {
  73. imagePath = "/static/marketSituation-image/country-flag/th.png";
  74. } else if (market === "vi") {
  75. imagePath = "/static/marketSituation-image/country-flag/vi.png";
  76. } else if (market === "us" || market === "usa") {
  77. imagePath = "/static/marketSituation-image/country-flag/us.png";
  78. } else {
  79. imagePath = "/static/marketSituation-image/country-flag/global.png";
  80. }
  81. return imagePath;
  82. };
  83. // 计算价格颜色
  84. const priceColor = computed(() => {
  85. return props.isRising ? "#00C853" : "#FF1744";
  86. });
  87. // 计算图表背景色
  88. const chartBgColor = computed(() => {
  89. return props.isRising ? "#E8F5E8" : "#FFEBEE";
  90. });
  91. </script>
  92. <style scoped>
  93. .index-card {
  94. background-color: #ffffff;
  95. border-radius: 12rpx;
  96. padding: 20rpx;
  97. margin: 16rpx;
  98. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  99. border: 1rpx solid #f0f0f0;
  100. }
  101. .card-header {
  102. display: flex;
  103. align-items: center;
  104. margin-bottom: 16rpx;
  105. }
  106. .flag-container {
  107. width: 48rpx;
  108. height: 32rpx;
  109. margin-right: 12rpx;
  110. border-radius: 4rpx;
  111. overflow: hidden;
  112. }
  113. .flag-icon {
  114. width: 100%;
  115. height: 100%;
  116. }
  117. .index-name {
  118. font-size: 28rpx;
  119. font-weight: 500;
  120. color: #333333;
  121. flex: 1;
  122. white-space: nowrap;
  123. overflow: hidden;
  124. text-overflow: ellipsis;
  125. }
  126. .price-info {
  127. margin-bottom: 20rpx;
  128. }
  129. .current-price {
  130. font-size: 36rpx;
  131. font-weight: bold;
  132. display: block;
  133. margin-bottom: 8rpx;
  134. }
  135. .change-info {
  136. display: flex;
  137. align-items: center;
  138. gap: 16rpx;
  139. }
  140. .change-amount {
  141. font-size: 24rpx;
  142. font-weight: 500;
  143. }
  144. .change-percent {
  145. font-size: 24rpx;
  146. font-weight: 500;
  147. }
  148. .chart-container {
  149. height: 80rpx;
  150. border-radius: 8rpx;
  151. overflow: hidden;
  152. }
  153. .mini-chart {
  154. width: 100%;
  155. height: 100%;
  156. position: relative;
  157. border-radius: 8rpx;
  158. }
  159. .chart-line {
  160. position: absolute;
  161. bottom: 20rpx;
  162. left: 10rpx;
  163. right: 10rpx;
  164. height: 2rpx;
  165. border-top: 2rpx solid;
  166. border-style: solid;
  167. }
  168. /* 添加一些波浪效果 */
  169. .chart-line::before {
  170. content: "";
  171. position: absolute;
  172. top: -10rpx;
  173. left: 20%;
  174. width: 20rpx;
  175. height: 20rpx;
  176. border: 2rpx solid;
  177. border-color: inherit;
  178. border-radius: 50%;
  179. background: transparent;
  180. }
  181. .chart-line::after {
  182. content: "";
  183. position: absolute;
  184. top: -6rpx;
  185. right: 30%;
  186. width: 12rpx;
  187. height: 12rpx;
  188. border: 2rpx solid;
  189. border-color: inherit;
  190. border-radius: 50%;
  191. background: transparent;
  192. }
  193. </style>