currency-list.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <template>
  2. <template v-if="!isSelect">
  3. <div class="header">
  4. <input
  5. class="input"
  6. @input="onInput"
  7. v-model="keywords"
  8. placeholder="Search name" />
  9. <img
  10. class="icon-clear"
  11. src="../static/img/icon-clear-search.svg"
  12. v-if="keywords"
  13. @click="clearIpt" >
  14. </div>
  15. <div class="list-wrapper" :class="{min: showSearch}">
  16. <template v-if="!showSearch">
  17. <div
  18. class="list-item"
  19. :key="index"
  20. v-for="(item, index) in currencyInfoList">
  21. <div
  22. class="item-title"
  23. v-if="item.data.length">
  24. <template v-if="item.type == 1">
  25. <img class="icon" src="../static/img/icon-currency-category-01.svg" />
  26. <span>Cash</span>
  27. </template>
  28. <template v-else>
  29. <img class="icon" src="../static/img/icon-currency-category-02.svg" />
  30. <span>Crypto</span>
  31. </template>
  32. </div>
  33. <div
  34. class="item-detail"
  35. v-for="(data, idx) in item.data"
  36. :key="idx"
  37. @click="selectCurrency(data)">
  38. <div class="left">
  39. <img class="icon-currency" :src="data.currencies[0].iconPath" />
  40. <div class="currency-info">
  41. <div class="name">{{ data.currencies[0].currencyCode == 'USD' ? 'USD' : data.currencies[0].tokenSymbol }}</div>
  42. <div class="desc">{{ data.currencies[0].currencyCode == 'USD' ? 'Paypal' : data.currencies[0].currencyName }}
  43. </div>
  44. </div>
  45. </div>
  46. </div>
  47. </div>
  48. <div class="no-data" v-if="show_empty">
  49. Not found
  50. </div>
  51. </template>
  52. <template v-else>
  53. <div
  54. class="item-detail"
  55. :key="idx"
  56. v-for="(data, idx) in searchList"
  57. @click="selectCurrency(data)">
  58. <div class="left">
  59. <img class="icon-currency" :src="data.currencies[0].iconPath" />
  60. <div class="currency-info">
  61. <div class="name">{{ data.currencies[0].currencyCode == 'USD' ? 'USD' : data.currencies[0].tokenSymbol }}</div>
  62. <div class="desc">{{ data.currencies[0].currencyName }}</div>
  63. </div>
  64. </div>
  65. </div>
  66. <div class="no-data" v-if="!searchList.length">
  67. Not found
  68. </div>
  69. </template>
  70. </div>
  71. </template>
  72. <template v-else>
  73. <div class="list-wrapper">
  74. <div class="list-item">
  75. <div
  76. :key="idx"
  77. v-for="(data, idx) in isSelectData"
  78. @click="selectItem(data)">
  79. <div class="item-title">
  80. <img class="icon" :src="data.chainInfo.iconPath" />
  81. {{data.chainInfo.chainName}}
  82. </div>
  83. <div class="item-detail">
  84. <div class="left">
  85. <img class="icon-currency" :src="data?.iconPath" />
  86. <div class="currency-info">
  87. <div class="name">{{ data.currencyCode == 'USD' ? 'USD' : data.tokenSymbol }}</div>
  88. <div class="desc">{{ data.currencyCode == 'USD' ? 'Paypal' : data.currencyName }}</div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. </template>
  96. </template>
  97. <script lang="ts" setup>
  98. import { ref, onBeforeMount, defineEmits } from 'vue';
  99. import Api from '../static/http/api';
  100. import { postRequest } from '../static/http';
  101. import { debounce } from '../static/utils';
  102. const keywords = ref('');
  103. const showSearch = ref(false);
  104. const currencyInfoList = ref([]);
  105. const searchList = ref([]);
  106. const show_empty = ref(false);
  107. const isSelect = ref(false);
  108. const isSelectData = ref(null);
  109. const listReqParams = {
  110. params: {
  111. pageNum: 1,
  112. pageSize: 100,
  113. },
  114. loadMore: false,
  115. };
  116. const emits = defineEmits(['selectCurrencyItem'])
  117. const clearIpt = () => {
  118. keywords.value = '';
  119. showSearch.value = false;
  120. searchList.value = [];
  121. }
  122. const onInput = (val: any) => {
  123. console.log(keywords.value);
  124. if (keywords.value) {
  125. showSearch.value = true;
  126. searchCurrency(keywords.value);
  127. } else {
  128. showSearch.value = false;
  129. searchList.value = [];
  130. }
  131. }
  132. const searchCurrency = debounce(function (searchWords: any) {
  133. postRequest(Api.searchCurrencyInfo, {
  134. params: {
  135. pageNum: 1,
  136. pageSize: 100,
  137. searchWords,
  138. filterFiatCurrency: false
  139. }
  140. }).then(res => {
  141. if (res.code == 0) {
  142. if (res.data.currencyCategories && res.data.currencyCategories.length) {
  143. let list = res.data.currencyCategories[0];
  144. if (list && list.data && list.data.length) {
  145. searchList.value = list.data;
  146. } else {
  147. searchList.value = [];
  148. }
  149. } else {
  150. searchList.value = [];
  151. }
  152. }
  153. })
  154. }, 500)
  155. const getCurrencyInfoList = () => {
  156. postRequest(Api.getCurrencyInfo, {
  157. params: {
  158. pageNum: listReqParams.params.pageNum,
  159. pageSize: listReqParams.params.pageSize,
  160. filterFiatCurrency: true,
  161. filterEmptyBalance: false
  162. }
  163. }).then(res => {
  164. if (res.code == 0) {
  165. let resData = res.data;
  166. if (resData && resData.currencyCategories.length) {
  167. if (listReqParams.params.pageNum < 2) {
  168. currencyInfoList.value = res.data.currencyCategories;
  169. if(resData.currencyCategories.length == 1 && (!resData.currencyCategories[0]['data'] || !resData.currencyCategories[0]['data'].length)) {
  170. show_empty.value = true
  171. }
  172. } else {
  173. let data = currencyInfoList.value;
  174. let currencyCategories = resData.currencyCategories;
  175. data = data.concat(currencyCategories);
  176. currencyInfoList.value = data;
  177. }
  178. listReqParams.loadMore = false;
  179. } else {
  180. show_empty.value = true
  181. }
  182. }
  183. })
  184. }
  185. const selectItem = (data: any) => {
  186. emits('selectCurrencyItem', data);
  187. }
  188. const selectCurrency = (data: any) => {
  189. if (data.currencies.length > 1) {
  190. isSelect.value = true;
  191. isSelectData.value = data.currencies;
  192. } else {
  193. emits('selectCurrencyItem', data.currencies[0]);
  194. }
  195. }
  196. onBeforeMount(() => {
  197. getCurrencyInfoList()
  198. })
  199. </script>
  200. <style lang="less" scoped>
  201. .header {
  202. display: flex;
  203. align-items: center;
  204. justify-content: center;
  205. height: 60px;
  206. background: #F7F7F7;
  207. .input {
  208. width: calc(100% - 20px);
  209. height: calc(100% - 20px);
  210. background: #f1f1f1;
  211. border-radius: 110px;
  212. box-sizing: border-box;
  213. border: none;
  214. outline: none;
  215. padding: 10px 80px 10px 22px;
  216. color: #adadad;
  217. }
  218. input::placeholder {
  219. color: #adadad;
  220. }
  221. .icon-clear {
  222. position: absolute;
  223. right: 6%;
  224. cursor: pointer;
  225. }
  226. }
  227. .list-wrapper {
  228. overflow-y: auto;
  229. max-height: calc(420px - 60px);
  230. &.min {
  231. min-height: 200px;
  232. }
  233. .list-item {
  234. .item-title {
  235. display: flex;
  236. align-items: center;
  237. height: 42px;
  238. padding: 0 10px;
  239. box-sizing: border-box;
  240. background: #fafafa;
  241. font-size: 14px;
  242. color: #a2a2a2;
  243. .icon {
  244. width: 24px;
  245. height: 24px;
  246. margin-right: 6px;
  247. }
  248. }
  249. }
  250. .item-detail {
  251. display: flex;
  252. justify-content: space-between;
  253. align-items: center;
  254. padding: 12px 20px;
  255. box-sizing: border-box;
  256. cursor: pointer;
  257. .left {
  258. display: flex;
  259. .icon-currency {
  260. width: 24px;
  261. height: 24px;
  262. margin-right: 12px;
  263. margin-top: 4px;
  264. }
  265. .currency-info {
  266. .name {
  267. font-weight: 500;
  268. font-size: 15px;
  269. margin-bottom: 5px;
  270. word-break: break-all;
  271. }
  272. .desc {
  273. font-weight: 400;
  274. font-size: 12px;
  275. color: #a2a2a2;
  276. }
  277. }
  278. }
  279. }
  280. .no-data {
  281. font-weight: 500;
  282. font-size: 22px;
  283. color: #BBBBBB;
  284. position: absolute;
  285. top: 50%;
  286. left: 50%;
  287. transform: translate(-50%, -50%);
  288. }
  289. }
  290. </style>