list.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <template>
  2. <view class="layout-page bg-panel-4" :style="themeStyle">
  3. <v-header v-if="!isSearch" :title="$t('base.a3')">
  4. <template #right>
  5. <van-icon @click="isSearch=true" name="search" size="20" color="rgba(129,151,164,1)" />
  6. </template>
  7. </v-header>
  8. <view style="height: var(--status-bar-height)"></view>
  9. <van-search
  10. background="transparent"
  11. class="bg-panel-1"
  12. v-if="isSearch"
  13. :value="searchText"
  14. show-action
  15. :action-text="$t('common.cancelButtonText')"
  16. @cancel="searchText='';$back(1);"
  17. @change="searchText=$event.detail"
  18. :placeholder="$t('base.d3')"
  19. />
  20. <view class="layout-main">
  21. <!-- 科创板 -->
  22. <view class="head_info m-y-xs">
  23. <van-tabs
  24. v-if="marketList.length"
  25. :active="infoActive"
  26. background="transparent"
  27. color="rgba(232,92,68,1)"
  28. title-active-color="rgba(232,92,68,1)"
  29. :line-width="0"
  30. :border="false"
  31. animated
  32. class="tabs-border border-b"
  33. >
  34. <van-tab
  35. v-for="parentItem in marketList"
  36. :key="parentItem.coin_name"
  37. :title="parentItem.coin_name"
  38. >
  39. <view class="layout-main">
  40. <table class="w-12/12">
  41. <thead>
  42. <tr class="color-gray-6">
  43. <th></th>
  44. <th class="fn-left p-y-xs fn-xs color-theme-6">{{$t('base.a8')}}</th>
  45. <th class="fn-left p-y-xs fn-xs color-theme-6">{{$t('base.a9')}}</th>
  46. <th class="fn-right p-y-xs p-r-md fn-xs color-theme-6">24H{{$t('base.b0')}}</th>
  47. </tr>
  48. </thead>
  49. <tbody class="fn-center">
  50. <tr
  51. @click="_router.push({path:'/pages/exchange/index',query:{'code':item.pair_name}})"
  52. tag="tr"
  53. class="border-t-original link-active"
  54. v-for="item in (parentItem.collect?collect:parentItem.marketInfoList)"
  55. :key="item.pair_name"
  56. v-show="isShow(item.pair_name)"
  57. >
  58. <td class="p-x-xs fn-18" @click.stop="option(item)">
  59. <van-icon v-if="isCoolect(item)" class="color-theme-1" name="star" />
  60. <van-icon v-else name="star-o" />
  61. </td>
  62. <td class="color-light fn-left p-y-xs">
  63. <view class="d-flex align-end">{{item.pair_name}}</view>
  64. </td>
  65. <td class="p-y-xs fn-left align-end">
  66. <view class="d-flex align-end">{{item.close}}</view>
  67. </td>
  68. <td class="fn-right p-y-xs p-r-md">
  69. <span :class="item.increase*1<0?'color-sell':'color-buy'">{{item.increaseStr}}</span>
  70. </td>
  71. </tr>
  72. </tbody>
  73. </table>
  74. </view>
  75. </van-tab>
  76. </van-tabs>
  77. </view>
  78. </view>
  79. </view>
  80. </template>
  81. <script>
  82. import Home from "@/api/home";
  83. import { mapState,mapGetters } from "vuex";
  84. export default {
  85. name: "list",
  86. data() {
  87. return {
  88. page: 0,
  89. list: [],
  90. searchText: "",
  91. isSearch: false,
  92. sendSearch: "",
  93. tab: "shares",
  94. gridActive: 0, // 头部选中
  95. query: {},
  96. infoActive: 0, // 详情选中,
  97. marketList: [],
  98. collect: [],
  99. };
  100. },
  101. computed: {
  102. gridList() {
  103. return [
  104. {
  105. name: this.$t("base.d4"),
  106. },
  107. {
  108. name: this.$t("base.d5"),
  109. },
  110. ];
  111. },
  112. ...mapState({
  113. ws: "ws",
  114. }),
  115. ...mapGetters(['themeStyle']),
  116. isLogin() {
  117. return Boolean(uni.getStorageSync("token"));
  118. },
  119. },
  120. methods: {
  121. isShow(str) {
  122. return (
  123. str.toLocaleLowerCase().indexOf(this.searchText.toLocaleLowerCase()) !=
  124. -1
  125. );
  126. },
  127. indexData() {
  128. let data = {
  129. p: this.page,
  130. code_type: this.tab,
  131. };
  132. Home.indexList(data).then((res) => {
  133. this.home = res.data.bannerList;
  134. this.notice = res.data.articleList;
  135. this.indexList = res.data.brokenLine;
  136. this.marketList = res.data.marketList;
  137. this.infoActive = 1;
  138. this.dunshift();
  139. this.getCollect();
  140. this.indexMarketList();
  141. });
  142. },
  143. dunshift() {
  144. if (this.marketList.filter((item) => item.collect).length) return;
  145. this.marketList.unshift({
  146. coin_name: this.$t("base.c7"),
  147. collect: true,
  148. marketInfoList: [],
  149. });
  150. },
  151. // 获取自选交易列表
  152. getCollect(call) {
  153. if (!this.isLogin) return;
  154. Home.getCollect()
  155. .then((res) => {
  156. this.collect = res.data || [];
  157. call && call();
  158. })
  159. .catch(() => {});
  160. },
  161. // 是否为自选
  162. isCoolect(i) {
  163. return this.collect.map((item) => item.pair_name).includes(i.pair_name);
  164. },
  165. // 替换自选数据
  166. replaceOptional() {
  167. let collect = this.collect.map((item) => item.pair_name);
  168. this.marketList.forEach((parentItem) => {
  169. parentItem.marketInfoList.forEach((item) => {
  170. let idx = collect.indexOf(item.pair_name);
  171. if (idx != -1) {
  172. this.collect.splice(idx, 1, item);
  173. }
  174. });
  175. });
  176. },
  177. // 添加自选
  178. option(item) {
  179. let data = {
  180. pair_name: item.pair_name,
  181. };
  182. Home.option(data)
  183. .then((res) => {
  184. this.getCollect();
  185. if (res.data) {
  186. this.$toast(this.$t("base.c8"));
  187. } else {
  188. this.$toast(this.$t("base.c9"));
  189. }
  190. })
  191. .catch(() => {});
  192. },
  193. // 链接socket
  194. indexMarketList() {
  195. // this.ws.send({
  196. // cmd: "sub",
  197. // msg: "indexMarketList",
  198. // });
  199. this.ws.on("message", (res) => {
  200. let { data, sub } = res;
  201. if (sub == "indexMarketList") {
  202. this.marketList = data;
  203. this.dunshift();
  204. this.replaceOptional();
  205. }
  206. });
  207. },
  208. },
  209. onLoad(query) {
  210. this.query = query;
  211. this.indexData();
  212. this.isSearch = !!query.isSearch;
  213. },
  214. destroyed() {
  215. // this.ws.send({
  216. // cmd: "unsub",
  217. // msg: "indexMarketList",
  218. // });
  219. },
  220. };
  221. </script>
  222. <style lang="scss" scoped>
  223. .head {
  224. padding: 16px 16px 0;
  225. ::v-deep.van-grid-item__content {
  226. padding: 6px 0;
  227. background-color: transparent;
  228. }
  229. ::v-deep.van-hairline--top::after {
  230. border-left-width: 1px;
  231. }
  232. ::v-deep.van-grid-item__text {
  233. color: rgba(123, 145, 159, 1);
  234. }
  235. .active {
  236. background: rgba(232, 92, 68, 1);
  237. ::v-deep.van-grid-item__text {
  238. color: #ffffff;
  239. }
  240. }
  241. }
  242. .l-n-px {
  243. line-height: 35px;
  244. }
  245. </style>