Index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <template>
  2. <app-view class="g-detail">
  3. <template #header>
  4. <app-navbar :title="$t('quote.spot.title')" />
  5. </template>
  6. <Banner :data-list="topBanners" />
  7. <div class="g-detail__buy" v-if="quoteItem">
  8. <div class="title">
  9. <span>{{ quoteItem.wrstandardcode }} / {{ quoteItem.wrstandardname }}</span>
  10. </div>
  11. <div class="desc">
  12. <span>{{ quoteItem.warehousename }}</span>
  13. </div>
  14. <div class="info">
  15. <ul>
  16. <li>
  17. <span>{{ $t('quote.ask') }}</span>
  18. <span>{{ handleNumberValue(quoteItem.sellprice) }}</span>
  19. </li>
  20. <li>
  21. <span>{{ $t('quote.askvolume') }}</span>
  22. <span>{{ quoteItem.sellqty }}</span>
  23. </li>
  24. <li>
  25. <span>{{ $t('quote.bid') }}</span>
  26. <span>{{ handleNumberValue(quoteItem.buyprice) }}</span>
  27. </li>
  28. <li>
  29. <span>{{ $t('quote.bidvolume') }}</span>
  30. <span>{{ quoteItem.buyqty }}</span>
  31. </li>
  32. </ul>
  33. </div>
  34. </div>
  35. <div class="trade">
  36. <div class="trade-section sell" v-if="sellList.length">
  37. <Cell :title="$t('quote.spot.sellisting')" />
  38. <app-list :columns="columns" :data-list="sellList">
  39. <template #operate="{ row }">
  40. <Button size="small" round @click="delistingListing(row, BuyOrSell.Buy)">{{ $t('quote.buy') }}</Button>
  41. </template>
  42. </app-list>
  43. </div>
  44. <div class="trade-section buy" v-if="buyList.length">
  45. <Cell :title="$t('quote.spot.buylisting')" />
  46. <app-list :columns="columns" :data-list="buyList">
  47. <template #operate="{ row }">
  48. <Button size="small" round @click="delistingListing(row, BuyOrSell.Sell)">{{ $t('quote.sell') }}</Button>
  49. </template>
  50. </app-list>
  51. </div>
  52. </div>
  53. <div class="g-detail__desc">
  54. <template v-for="(url, index) in goodsImages" :key="index">
  55. <img :src="url" alt="" />
  56. </template>
  57. </div>
  58. <template #footer>
  59. <div class="g-form__footer">
  60. <!-- <div class="price" v-if="quoteItem">
  61. <span class="price-text">参考价:</span>
  62. <span class="price-unit">¥</span>
  63. <span class="price-integer">{{ quoteItem.spotgoodsprice }}</span>
  64. </div> -->
  65. <!-- <div class="submit"> -->
  66. <Button block type="danger" square class="submit-button danger"
  67. @click="toggleListing(BuyOrSell.Buy)">{{ $t('quote.spot.wantbuy') }}</Button>
  68. <Button block color="#199e00" square class="submit-button warning"
  69. @click="toggleListing(BuyOrSell.Sell)">{{ $t('quote.spot.wantsell') }}</Button>
  70. <!-- </div> -->
  71. </div>
  72. <component ref="componentRef" :is="componentMap.get(componentId)"
  73. v-bind="{ quoteItem, quoteDetail, buyorsell }" @closed="closeComponent" v-if="componentId" />
  74. </template>
  75. </app-view>
  76. </template>
  77. <script lang="ts" setup>
  78. import { shallowRef, computed, defineAsyncComponent, onUnmounted } from 'vue'
  79. import { Cell, Button } from 'vant'
  80. import { getFileUrl, handleNumberValue } from '@/filters'
  81. import { useRequest } from '@/hooks/request'
  82. import { useComponent } from '@/hooks/component'
  83. import { useNavigation } from '@mobile/router/navigation'
  84. import { BuyOrSell } from '@/constants/order'
  85. import { queryOrderQuote, queryOrderQuoteDetail } from '@/services/api/goods'
  86. import eventBus from '@/services/bus'
  87. import AppList from '@mobile/components/base/list/index.vue'
  88. import Banner from '@mobile/components/base/banner/index.vue'
  89. import service from '@/services'
  90. import { i18n } from "@/stores";
  91. const componentMap = new Map<string, unknown>([
  92. ['listing', defineAsyncComponent(() => import('./components/listing/index.vue'))], // 挂牌
  93. ['delisting', defineAsyncComponent(() => import('./components/delisting/index.vue'))], // 摘牌
  94. ])
  95. const { global: { t } } = i18n
  96. const { getQueryString } = useNavigation()
  97. const { componentRef, componentId, openComponent, closeComponent } = useComponent()
  98. const quoteDetail = shallowRef<Model.OrderQuoteDetailRsp>() // 买卖详情
  99. const buyorsell = shallowRef(BuyOrSell.Buy) // 买卖方向
  100. const oem = service.getServiceConfig('oem')
  101. const buyList = shallowRef<Model.OrderQuoteDetailRsp[]>([])
  102. const sellList = shallowRef<Model.OrderQuoteDetailRsp[]>([])
  103. const wrfactortypeid = getQueryString('wrfactortypeid') ?? '0'
  104. const { data: quoteItem, run: getOrderQuote } = useRequest(queryOrderQuote, {
  105. manual: true,
  106. defaultParams: {
  107. wrpricetype: 1,
  108. wrfactortypeid
  109. },
  110. onSuccess: (res) => {
  111. quoteItem.value = res.data[0]
  112. }
  113. })
  114. const { runAsync: getOrderQuoteDetail } = useRequest(queryOrderQuoteDetail, {
  115. manual: true,
  116. defaultParams: {
  117. wrpricetype: 1,
  118. haswr: 1,
  119. wrfactortypeid,
  120. buyorsell: buyorsell.value
  121. },
  122. })
  123. const columns: Model.TableColumn[] = oem != 'zrwyt' ? [
  124. { field: 'username', label: t('quote.spot.username') },
  125. { field: 'orderqty', label: t('quote.spot.orderqty') },
  126. { field: 'fixedprice', label: t('quote.spot.orderprice') },
  127. { field: 'operate', label: t('quote.spot.operate') },
  128. ] : [
  129. { field: 'orderqty', label: t('quote.spot.orderqty') },
  130. { field: 'fixedprice', label: t('quote.spot.orderprice') },
  131. { field: 'operate', label: t('quote.spot.operate') },
  132. ]
  133. // 商品banner
  134. const topBanners = computed(() => {
  135. const bannerpicurl = quoteItem.value?.bannerpicurl ?? ''
  136. return bannerpicurl?.split(',').map((path) => getFileUrl(path))
  137. })
  138. // 商品图片列表
  139. const goodsImages = computed(() => {
  140. const pictureurls = quoteItem.value?.pictureurls ?? ''
  141. return pictureurls.split(',').map((path) => getFileUrl(path))
  142. })
  143. // 挂牌下单
  144. const toggleListing = (value: BuyOrSell) => {
  145. buyorsell.value = value
  146. openComponent('listing')
  147. }
  148. // 摘牌下单
  149. const delistingListing = (row: Model.OrderQuoteDetailRsp, value: BuyOrSell) => {
  150. buyorsell.value = value
  151. quoteDetail.value = row
  152. openComponent('delisting')
  153. }
  154. // 刷新数据
  155. const refresh = () => {
  156. getOrderQuote()
  157. getOrderQuoteDetail({
  158. buyorsell: BuyOrSell.Buy
  159. }).then((res) => {
  160. buyList.value = res.data
  161. })
  162. getOrderQuoteDetail({
  163. buyorsell: BuyOrSell.Sell
  164. }).then((res) => {
  165. sellList.value = res.data
  166. })
  167. }
  168. // 接收仓单贸易成交通知
  169. const wrTradeDealedNtf = eventBus.$on('ListingOrderChangeNtf', () => refresh())
  170. onUnmounted(() => {
  171. wrTradeDealedNtf.cancel()
  172. })
  173. refresh()
  174. </script>
  175. <style lang="less">
  176. @import './index.less';
  177. </style>