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.

498 lines
10 KiB

4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
  1. <!-- @format -->
  2. <template>
  3. <view class="content">
  4. <!-- 市场子Tab -->
  5. <view class="sub_tabs">
  6. <view v-for="(tab, i) in marketTabs" :key="tab" :class="['tab_item', i === activeTabIndex ? 'active' : '']" @click="switchTab(i)">
  7. <text>{{ tab }}</text>
  8. </view>
  9. </view>
  10. <!-- 大盘指数 -->
  11. <view class="section">
  12. <view class="section_header">
  13. <text class="section_title">大盘指数</text>
  14. <text class="section_action" @click="viewMore('indices')">查看更多 ></text>
  15. </view>
  16. <view class="indices_grid">
  17. <view v-for="(index, i) in countryInfo.mainIndices" :key="i" class="index_item">
  18. <IndexCard :market="countryInfo.market" :indexName="index.name" :currentPrice="index.price" :changeAmount="index.change" :changePercent="index.changePercent" :isRising="index.isRising" />
  19. </view>
  20. </view>
  21. <!-- 今日市场情绪温度 -->
  22. <view class="sentiment">
  23. <view class="section_subtitle">
  24. <text>今日市场情绪温度</text>
  25. </view>
  26. <view class="meters">
  27. <view class="meter_item" v-for="(m, i) in sentimentMeters" :key="i">
  28. <image class="meter_icon" :class="m.theme" :src="selectIcons[m.theme]" mode="aspectFit"></image>
  29. <view class="meter_info">
  30. <text class="meter_value" :class="m.theme">{{ m.value }}°C</text>
  31. <text class="meter_label" :class="m.theme">{{ m.label }}</text>
  32. </view>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. <!-- 板块 -->
  38. <view class="section">
  39. <view class="section_header">
  40. <text class="section_title">板块</text>
  41. <text class="section_action" @click="viewMore('sectors')">查看更多 ></text>
  42. </view>
  43. <view class="sectors_grid">
  44. <view v-for="(sec, i) in sectors" :key="i" class="sector_item">
  45. <view class="sector_header">
  46. <text class="sector_name">{{ sec.name }}</text>
  47. <text :class="['sector_change', sec.isRising ? 'rising' : 'falling']">
  48. {{ sec.change }}
  49. </text>
  50. </view>
  51. <view class="sector_price">{{ sec.price }}</view>
  52. </view>
  53. </view>
  54. </view>
  55. <!-- 股票 -->
  56. <view class="section">
  57. <view class="section_header">
  58. <text class="section_title">股票</text>
  59. <text class="section_action" @click="viewMore('stocks')">查看更多 ></text>
  60. </view>
  61. <view class="table">
  62. <view class="table_header">
  63. <text class="cell name">名称</text>
  64. <text class="cell price">最新</text>
  65. <text class="cell change">涨幅</text>
  66. </view>
  67. <view class="table_row" v-for="(stk, i) in stocks" :key="i">
  68. <view class="cell name">
  69. <text class="stk_name">{{ stk.name }}</text>
  70. <text class="stk_code">{{ stk.code }}</text>
  71. </view>
  72. <view class="cell price">
  73. <text class="stk_price">{{ stk.price }}</text>
  74. </view>
  75. <view class="cell change">
  76. <text :class="['stk_change', stk.isRising ? 'rising' : 'falling']">
  77. {{ stk.change }}
  78. </text>
  79. </view>
  80. </view>
  81. </view>
  82. </view>
  83. <!-- 底部安全区域 -->
  84. <view class="bottom_safe_area"></view>
  85. </view>
  86. </template>
  87. <script setup>
  88. import { ref, computed, onMounted } from "vue";
  89. import IndexCard from "../../components/IndexCard.vue";
  90. // 子Tab与操作
  91. // const marketTabs = ["全部", "美股", "纽交所", "纳斯达克"];
  92. const activeTabIndex = ref(0);
  93. const switchTab = (i) => {
  94. activeTabIndex.value = i;
  95. };
  96. // 今日情绪温度示例数据
  97. const sentimentMeters = [
  98. { value: 90, label: "道琼斯", theme: "hot" },
  99. { value: 60, label: "纳斯达克", theme: "warm" },
  100. { value: 20, label: "标普500", theme: "cool" },
  101. ];
  102. // 图标映射
  103. const selectIcons = {
  104. hot: "/static/marketSituation-image/hot.png",
  105. warm: "/static/marketSituation-image/warm.png",
  106. cool: "/static/marketSituation-image/cool.png",
  107. };
  108. // Props
  109. const props = defineProps({
  110. countryId: {
  111. type: Number,
  112. required: true,
  113. },
  114. marketTabs: {
  115. type: Array,
  116. },
  117. });
  118. // 国家/地区信息映射
  119. const countryInfoMap = {
  120. 2: {
  121. // 新加坡
  122. name: "新加坡",
  123. flag: "🇸🇬",
  124. isMarketOpen: true,
  125. mainIndices: [
  126. { name: "海峡时报指数", price: "3,234.56", change: "+12.34", changePercent: "+0.38%", isRising: true },
  127. { name: "FTSE ST Mid Cap", price: "1,234.56", change: "-5.67", changePercent: "-0.46%", isRising: false },
  128. ],
  129. hotStocks: [
  130. { name: "星展银行", code: "D05.SI", price: "35.20", change: "+0.15", isRising: true },
  131. { name: "华侨银行", code: "O39.SI", price: "13.45", change: "-0.05", isRising: false },
  132. ],
  133. },
  134. 3: {
  135. // 马来西亚
  136. name: "马来西亚",
  137. flag: "🇲🇾",
  138. isMarketOpen: false,
  139. mainIndices: [{ name: "富时大马KLCI指数", price: "1,567.89", change: "+8.90", changePercent: "+0.57%", isRising: true }],
  140. hotStocks: [
  141. { name: "马来亚银行", code: "1155.KL", price: "9.85", change: "+0.10", isRising: true },
  142. { name: "大众银行", code: "1295.KL", price: "4.32", change: "-0.02", isRising: false },
  143. ],
  144. },
  145. 4: {
  146. // 印度尼西亚
  147. name: "印度尼西亚",
  148. flag: "🇮🇩",
  149. isMarketOpen: true,
  150. mainIndices: [{ name: "雅加达综合指数", price: "7,234.56", change: "+45.67", changePercent: "+0.63%", isRising: true }],
  151. hotStocks: [],
  152. },
  153. 5: {
  154. // 美国
  155. name: "美国",
  156. flag: "🇺🇸",
  157. isMarketOpen: false,
  158. mainIndices: [
  159. { name: "道琼斯", price: "45,757.90", change: "-125.22", changePercent: "-0.27%", isRising: false },
  160. { name: "纳斯达克", price: "22,333.96", change: "+125.22", changePercent: "+0.47%", isRising: true },
  161. { name: "标普500", price: "6,606.08", change: "+125.22", changePercent: "+0.27%", isRising: true },
  162. ],
  163. hotStocks: [
  164. { name: "苹果", code: "AAPL", price: "195.89", change: "+2.34", isRising: true },
  165. { name: "微软", code: "MSFT", price: "378.85", change: "-1.23", isRising: false },
  166. ],
  167. },
  168. };
  169. // 计算当前国家信息
  170. const countryInfo = computed(() => {
  171. return (
  172. countryInfoMap[props.countryId] || {
  173. name: "未知地区",
  174. flag: "🌍",
  175. isMarketOpen: false,
  176. mainIndices: [],
  177. hotStocks: [],
  178. }
  179. );
  180. });
  181. // 计算当前国家的板块与股票
  182. const sectors = computed(() => {
  183. return countryInfoMap[props.countryId]?.sectors || [];
  184. });
  185. const stocks = computed(() => {
  186. return countryInfoMap[props.countryId]?.stocks || [];
  187. });
  188. // 查看更多占位
  189. const viewMore = (type) => {
  190. // 可根据 type 跳转到相应页面或加载更多
  191. // 例如:indices/sectors/stocks
  192. // uni.navigateTo({ url: `/pages/marketSituation/${type}List` })
  193. };
  194. </script>
  195. <style scoped>
  196. .content {
  197. padding: 0 20rpx 20rpx 20rpx;
  198. }
  199. /* 子Tab */
  200. .sub_tabs {
  201. display: flex;
  202. gap: 16rpx;
  203. padding: 0 20rpx 20rpx 20rpx;
  204. }
  205. .tab_item {
  206. padding: 6rpx 20rpx;
  207. border-radius: 5rpx;
  208. background: #f5f5f5;
  209. color: #666;
  210. font-size: 24rpx;
  211. }
  212. .tab_item.active {
  213. background: #ff4444;
  214. color: #fff;
  215. }
  216. .section {
  217. padding: 20rpx;
  218. border-radius: 16rpx;
  219. }
  220. .section_header {
  221. display: flex;
  222. justify-content: space-between;
  223. align-items: center;
  224. margin-bottom: 16rpx;
  225. }
  226. .section_title {
  227. font-size: 28rpx;
  228. font-weight: bold;
  229. color: #333;
  230. }
  231. .section_action {
  232. font-size: 24rpx;
  233. color: #999;
  234. }
  235. .indices_grid {
  236. padding: 20rpx;
  237. display: grid;
  238. grid-template-columns: repeat(3, 1fr);
  239. gap: 20rpx;
  240. background-color: #f6f6f6;
  241. }
  242. /* 情绪温度 */
  243. .sentiment {
  244. background-color: #f6f6f6;
  245. padding: 0 20rpx 20rpx 20rpx;
  246. }
  247. .section_subtitle {
  248. font-size: 24rpx;
  249. color: #000000;
  250. padding: 20rpx 0;
  251. }
  252. .meters {
  253. display: grid;
  254. grid-template-columns: repeat(3, 1fr);
  255. gap: 16rpx;
  256. }
  257. .meter_item {
  258. display: flex;
  259. align-items: center;
  260. /* padding: 10rpx; */
  261. background: #ffffff;
  262. border-radius: 12rpx;
  263. }
  264. .meter_item image {
  265. width: 100rpx;
  266. height: 100rpx;
  267. }
  268. .meter_info {
  269. display: flex;
  270. flex-direction: column;
  271. }
  272. .meter_value {
  273. font-size: 36rpx;
  274. }
  275. .meter_value.hot {
  276. color: #ff6b6b;
  277. }
  278. .meter_value.warm {
  279. color: #ffd166;
  280. }
  281. .meter_value.cool {
  282. color: #60a5fa;
  283. }
  284. .meter_label {
  285. font-size: 22rpx;
  286. }
  287. .meter_label.hot {
  288. color: #ff6b6b;
  289. }
  290. .meter_label.warm {
  291. color: #ffd166;
  292. }
  293. .meter_label.cool {
  294. color: #60a5fa;
  295. }
  296. /* 板块 */
  297. .sectors_grid {
  298. display: grid;
  299. grid-template-columns: repeat(3, 1fr);
  300. gap: 16rpx;
  301. }
  302. .sector_item {
  303. background: #fafafa;
  304. border-radius: 12rpx;
  305. padding: 16rpx;
  306. }
  307. .sector_header {
  308. display: flex;
  309. justify-content: space-between;
  310. align-items: center;
  311. margin-bottom: 12rpx;
  312. }
  313. .sector_name {
  314. font-size: 24rpx;
  315. color: #333;
  316. }
  317. .sector_change {
  318. font-size: 22rpx;
  319. }
  320. .sector_change.rising {
  321. color: #e74c3c;
  322. }
  323. .sector_change.falling {
  324. color: #27ae60;
  325. }
  326. .sector_price {
  327. font-size: 24rpx;
  328. color: #666;
  329. }
  330. /* 股票表 */
  331. .table {
  332. background: #fff;
  333. border-radius: 12rpx;
  334. overflow: hidden;
  335. }
  336. .table_header,
  337. .table_row {
  338. display: grid;
  339. grid-template-columns: 2fr 1fr 1fr;
  340. padding: 18rpx 20rpx;
  341. border-bottom: 1rpx solid #f0f0f0;
  342. }
  343. .table_header {
  344. background: #fafafa;
  345. }
  346. .cell.name {
  347. display: flex;
  348. flex-direction: column;
  349. }
  350. .stk_name {
  351. font-size: 26rpx;
  352. color: #333;
  353. }
  354. .stk_code {
  355. font-size: 22rpx;
  356. color: #999;
  357. }
  358. .stk_price {
  359. font-size: 26rpx;
  360. color: #333;
  361. }
  362. .stk_change {
  363. font-size: 24rpx;
  364. }
  365. .stk_change.rising {
  366. color: #e74c3c;
  367. }
  368. .stk_change.falling {
  369. color: #27ae60;
  370. }
  371. .index_item {
  372. background: #fff;
  373. border-radius: 12rpx;
  374. overflow: hidden;
  375. }
  376. .hot_stocks {
  377. margin-bottom: 30rpx;
  378. }
  379. .stocks_list {
  380. background: #fff;
  381. border-radius: 12rpx;
  382. overflow: hidden;
  383. }
  384. .stock_item {
  385. display: flex;
  386. justify-content: space-between;
  387. align-items: center;
  388. padding: 24rpx 20rpx;
  389. border-bottom: 1rpx solid #f0f0f0;
  390. }
  391. .stock_item:last-child {
  392. border-bottom: none;
  393. }
  394. .stock_info {
  395. flex: 1;
  396. }
  397. .stock_name {
  398. font-size: 28rpx;
  399. color: #333;
  400. display: block;
  401. margin-bottom: 8rpx;
  402. }
  403. .stock_code {
  404. font-size: 24rpx;
  405. color: #999;
  406. }
  407. .stock_price {
  408. text-align: right;
  409. }
  410. .price {
  411. font-size: 28rpx;
  412. color: #333;
  413. display: block;
  414. margin-bottom: 8rpx;
  415. }
  416. .change {
  417. font-size: 24rpx;
  418. }
  419. .change.rising {
  420. color: #e74c3c;
  421. }
  422. .change.falling {
  423. color: #27ae60;
  424. }
  425. .bottom_safe_area {
  426. height: 120rpx;
  427. }
  428. </style>