index.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <template>
  2. <v-page>
  3. <v-header class="nav-head" :title="$t('transfer.a8')">
  4. <template #right>
  5. <v-link to="/pages/transfer/bill">
  6. <van-icon class="fn-20 m-t-xs" name="todo-list-o" />
  7. </v-link>
  8. </template>
  9. </v-header>
  10. <main class="">
  11. <view style="height: var(--status-bar-height)"></view>
  12. <view class="top">
  13. <view style="height: var(--status-bar-height)"></view>
  14. </view>
  15. <view class="panel-box m-x-md rounded p-md bg-panel-3 box-shadow">
  16. <v-picker :list="fromList" v-model="form.from_account" class="from item border-b p-y-xs p-l-md">
  17. <view class="label fn-sm color-gray-6">{{ $t("transfer.a9") }}</view>
  18. <view class="select d-flex align-center">
  19. <span class="fn-lg color-light">{{
  20. accountMap[form.from_account]
  21. }}</span>
  22. <van-icon class="m-l-xs fn-lg" name="arrow" />
  23. </view>
  24. </v-picker>
  25. <v-picker :list="toList" v-model="form.to_account" class="to item p-y-xs p-l-md">
  26. <view class="label fn-sm color-gray-6">{{ $t("transfer.b0") }}</view>
  27. <view class="select d-flex align-center">
  28. <span class="fn-lg color-light">{{
  29. accountMap[form.to_account]
  30. }}</span>
  31. <van-icon class="m-l-xs fn-lg" name="arrow" />
  32. </view>
  33. </v-picker>
  34. <view class=""></view>
  35. <view class="exchange d-flex justify-center align-center bg-panel-3 box-shadow link-active"
  36. @click="swap">
  37. <van-icon style="transform:rotateZ(90deg)" class="fn-22 color-light" name="exchange" />
  38. </view>
  39. </view>
  40. <v-picker :list="coinList" v-model="form.coin_name" range-label="coin_name" range-value="coin_name"
  41. class="">
  42. <view class="m-md p-md d-flex rounded bg-panel-3 box-shadow">
  43. <view class="flex-fill">{{ $t("transfer.b1") }}</view>
  44. <view class="color-light">{{ form.coin_name }}</view>
  45. <van-icon class="m-l-xs" name="arrow" />
  46. </view>
  47. </v-picker>
  48. <view class="m-md p-md rounded bg-panel-3 box-shadow">
  49. <view class="label fn-sm d-flex justify-between">
  50. <view>{{ $t("transfer.b1") }}</view>
  51. <view class=" fn-sm">{{ $t("transfer.b2") }}:{{ activeCoin.usable_balance }}</view>
  52. </view>
  53. <view class="m-t-md">
  54. <v-input placeholder="0.000" v-model="form.amount" class="fn-20">
  55. <template #right>
  56. <view class="d-flex fn-md">
  57. <view class="m-r-xs">{{ form.coin_name }}</view>
  58. <view class="border-l color-buy p-l-xs" @click="change">{{ $t("transfer.b3") }}</view>
  59. </view>
  60. </template>
  61. </v-input>
  62. </view>
  63. </view>
  64. </main>
  65. <view class="m-x-md">
  66. <view class=" rounded-md ">
  67. <v-button class="w-max rounded-md" block type="blue" ref="btn" @click="fundsTransfer">
  68. {{ $t("common.confirm") }}</v-button>
  69. </view>
  70. </view>
  71. </v-page>
  72. </template>
  73. <script>
  74. import Wallet from "@/api/wallet";
  75. import {
  76. mapGetters
  77. } from "vuex";
  78. import lodash from "lodash";
  79. export default {
  80. data() {
  81. return {
  82. coinList: [],
  83. accountsList: [],
  84. //
  85. accountMap: {},
  86. // 转换映射列表
  87. transferList: {},
  88. form: {
  89. from_account: 1,
  90. to_account: 2,
  91. amount: ''
  92. },
  93. activeCoin: {},
  94. };
  95. },
  96. computed: {
  97. fromList() {
  98. return Object.keys(this.transferList).map((item) => {
  99. return {
  100. label: this.accountMap[item],
  101. value: item,
  102. };
  103. });
  104. },
  105. toList() {
  106. if (!this.transferList[this.form.from_account]) return [];
  107. return this.transferList[this.form.from_account].map((item) => {
  108. return {
  109. label: this.accountMap[item],
  110. value: item,
  111. };
  112. });
  113. },
  114. ...mapGetters(["themeStyle"]),
  115. },
  116. watch: {
  117. // 切换取默认值
  118. ["form.from_account"](n) {
  119. if (!this.transferList[n].includes(this.form.to_account)) {
  120. this.form.to_account = this.transferList[n][0];
  121. }
  122. this.getUserCoinAssets();
  123. },
  124. coinList() {
  125. if (!this.coinList.includes(this.form.coin_name)) {
  126. if (this.coinList[0]) {
  127. this.form.coin_name = this.coinList[0].coin_name;
  128. } else {
  129. this.form.coin_name = "";
  130. }
  131. }
  132. },
  133. },
  134. methods: {
  135. // 互换位置
  136. swap() {
  137. [this.form.from_account, this.form.to_account] = [
  138. this.form.to_account,
  139. this.form.from_account,
  140. ];
  141. },
  142. // 划转
  143. fundsTransfer() {
  144. if(!this.form.amount){
  145. this.$toast(this.$t('purchase.d2'))
  146. return
  147. }
  148. Wallet.transfer(this.form)
  149. .then(() => {
  150. this.$toast.success(this.$t("transfer.b4"));
  151. this.form.amount = "";
  152. this.getUserCoinAssets();
  153. })
  154. .catch(() => {});
  155. },
  156. // 获取划转币种
  157. getUserCoinAssets: lodash.debounce(function() {
  158. Wallet.coinList({
  159. from_account: this.form.from_account,
  160. to_account: this.form.to_account,
  161. })
  162. .then((res) => {
  163. this.coinList = res.data;
  164. if (this.coinList[0]) {
  165. this.form.coin_name = this.coinList[0].coin_name;
  166. this.getBalance();
  167. }
  168. })
  169. .catch(() => {});
  170. }, 300),
  171. // 获取划转类型
  172. accounts() {
  173. Wallet.accounts().then((res) => {
  174. this.accountsList = res.data;
  175. // 生成map
  176. this.accountsList.forEach((item) => {
  177. this.accountMap[item.id] = item.name;
  178. });
  179. // 生成映射 (谁转换谁)
  180. this.transferList = {};
  181. this.accountsList.forEach((item) => {
  182. let sourceId = this.accountsList.find(
  183. (item) => item.account == "UserWallet"
  184. ).id; //账户资产 可以转其他的资金,其他资金不能 转账户资产
  185. if (sourceId != item.id) {
  186. this.transferList[item.id] = [sourceId];
  187. if (!this.transferList[sourceId]) this.transferList[sourceId] = [];
  188. this.transferList[sourceId].push(item.id);
  189. }
  190. });
  191. this.getUserCoinAssets();
  192. });
  193. },
  194. // 获取余额
  195. getBalance: lodash.debounce(function() {
  196. let data = {
  197. account: this.form.from_account,
  198. coin_name: this.form.coin_name,
  199. };
  200. Wallet.getBalance(data).then((res) => {
  201. this.activeCoin = res.data;
  202. });
  203. }),
  204. change() {
  205. this.form.amount = this.activeCoin.usable_balance
  206. }
  207. },
  208. created() {
  209. this.accounts()
  210. // var fun=lodash.throttle((e)=>{
  211. // console.log(1,e)
  212. // },1000)
  213. // setInterval(() => {
  214. // fun(2)
  215. // }, 60);
  216. },
  217. };
  218. </script>
  219. <style lang="scss" scoped>
  220. .nav-head {
  221. position: absolute;
  222. left: 0;
  223. width: 100%;
  224. // background: transparent;
  225. &::after {
  226. border: none;
  227. }
  228. }
  229. .top {
  230. // background: linear-gradient(180deg, #c86b49, $theme-1);
  231. height: 150px;
  232. }
  233. .panel-box {
  234. margin-top: -70px;
  235. position: relative;
  236. .line {
  237. position: absolute;
  238. height: 100%;
  239. width: 1px;
  240. background: $border-color;
  241. transform: scale(0.5);
  242. top: 0;
  243. &::before,
  244. &::after {
  245. content: "";
  246. display: inline-block;
  247. position: absolute;
  248. left: 50%;
  249. transform: translateX(-50%);
  250. width: 12px;
  251. height: 12px;
  252. border-radius: 50%;
  253. }
  254. &::before {
  255. top: 0;
  256. background: $blue;
  257. }
  258. &::after {
  259. bottom: 0;
  260. background: $red;
  261. }
  262. }
  263. .exchange {
  264. position: absolute;
  265. right: $padding-sm;
  266. top: 50%;
  267. height: 40px;
  268. width: 40px;
  269. border-radius: 50%;
  270. transform: translateY(-50%);
  271. }
  272. }
  273. </style>