index.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <template>
  2. <app-view class="supply-demand-details g-form">
  3. <template #header>
  4. <app-navbar title="供求详情" />
  5. </template>
  6. <div v-if="quoteItem" class="supply-demand-details__content">
  7. <Swipe class="banner" :autoplay="5000" indicator-color="white" lazy-render>
  8. <SwipeItem v-for="(url, index) in topBanners" :key="index">
  9. <img :src="url" />
  10. </SwipeItem>
  11. </Swipe>
  12. <div class="goods">
  13. <table cellspacing="0" cellpadding="0">
  14. <tr>
  15. <th colspan="3">
  16. <h1>{{ quoteItem.wrstandardname }}</h1>
  17. </th>
  18. </tr>
  19. <tr>
  20. <td>
  21. <span>卖价:</span>
  22. <span>{{ quoteItem.sellprice }}</span>
  23. </td>
  24. <td>
  25. <span>卖量:</span>
  26. <span>{{ quoteItem.sellqty }}</span>
  27. </td>
  28. <td rowspan="3" style="vertical-align:top">
  29. <div class="goods-price">
  30. <h4>参考价(元/{{ quoteItem.enumdicname }})</h4>
  31. <h2>{{ quoteItem.spotgoodsprice }}</h2>
  32. </div>
  33. </td>
  34. </tr>
  35. <tr>
  36. <td>
  37. <span>买价:</span>
  38. <span>{{ quoteItem.buyprice }}</span>
  39. </td>
  40. <td>
  41. <span>买量:</span>
  42. <span>{{ quoteItem.buyqty }}</span>
  43. </td>
  44. </tr>
  45. <tr>
  46. <td colspan="2">
  47. <span>仓库:</span>
  48. <span>{{ quoteItem.warehousename }}</span>
  49. </td>
  50. </tr>
  51. </table>
  52. </div>
  53. <div class="trade">
  54. <div class="trade-section sell" v-if="sellList.length">
  55. <Cell title="卖价" />
  56. <app-list :columns="columns" :data-list="sellList">
  57. <template #operate="{ row }">
  58. <Button size="small" round @click="delistingListing(row, BuyOrSell.Buy)">买入</Button>
  59. </template>
  60. </app-list>
  61. </div>
  62. <div class="trade-section buy" v-if="buyList.length">
  63. <Cell title="买价" />
  64. <app-list :columns="columns" :data-list="buyList">
  65. <template #operate="{ row }">
  66. <Button size="small" round @click="delistingListing(row, BuyOrSell.Sell)">卖出</Button>
  67. </template>
  68. </app-list>
  69. </div>
  70. </div>
  71. <div class="gallery">
  72. <Divider>商品详情</Divider>
  73. <template v-for="(url, index) in goodsImages" :key="index">
  74. <img :src="url" alt="" />
  75. </template>
  76. </div>
  77. </div>
  78. <Empty v-else />
  79. <template #footer>
  80. <div class="g-form__footer" v-if="quoteItem">
  81. <Button type="warning" block round @click="toggleListing(BuyOrSell.Sell)">我要卖</Button>
  82. <Button type="primary" block round @click="toggleListing(BuyOrSell.Buy)">我要买</Button>
  83. </div>
  84. <component ref="componentRef" :is="componentMap.get(componentId)" v-bind="{ quoteItem, quoteDetail, buyorsell }"
  85. @closed="closeComponent" v-if="componentId" />
  86. </template>
  87. </app-view>
  88. </template>
  89. <script lang="ts" setup>
  90. import { shallowRef, computed, defineAsyncComponent, onUnmounted } from 'vue'
  91. import { Cell, Swipe, SwipeItem, Empty, Divider, Button } from 'vant'
  92. import { getImageUrl } from '@/filters'
  93. import { useComponent } from '@/hooks/component'
  94. import { useNavigation } from '@/hooks/navigation'
  95. import { BuyOrSell } from '@/constants/order'
  96. import { queryOrderQuote } from '@/services/api/goods'
  97. import { useOrderQuoteDetail } from '@/business/goods'
  98. import eventBus from '@/services/bus'
  99. import AppList from '@mobile/components/base/list/index.vue'
  100. const componentMap = new Map<string, unknown>([
  101. ['listing', defineAsyncComponent(() => import('./components/listing/index.vue'))], // 挂牌
  102. ['delisting', defineAsyncComponent(() => import('./components/delisting/index.vue'))], // 摘牌
  103. ])
  104. const { getQueryString } = useNavigation()
  105. const { componentRef, componentId, openComponent, closeComponent } = useComponent()
  106. const quoteDetail = shallowRef<Model.OrderQuoteDetailRsp>() // 买卖详情
  107. const buyorsell = shallowRef(BuyOrSell.Buy) // 买卖方向
  108. const wrfactortypeid = getQueryString('wrfactortypeid')
  109. const quoteItem = shallowRef<Model.OrderQuoteRsp>() // 供求详情
  110. const { dataList: buyList, getOrderQuoteList: getOrderBuyList } = useOrderQuoteDetail(wrfactortypeid)
  111. const { dataList: sellList, getOrderQuoteList: getOrderSellList } = useOrderQuoteDetail(wrfactortypeid)
  112. const columns: Model.TableColumn[] = [
  113. { prop: 'username', label: '挂牌方' },
  114. { prop: 'orderqty', label: '数量' },
  115. { prop: 'fixedprice', label: '价格' },
  116. { prop: 'operate', label: '操作' },
  117. ]
  118. // 商品banner
  119. const topBanners = computed(() => {
  120. const bannerpicurl = quoteItem.value?.bannerpicurl ?? ''
  121. return bannerpicurl?.split(',').map((path) => getImageUrl(path))
  122. })
  123. // 商品图片列表
  124. const goodsImages = computed(() => {
  125. const pictureurls = quoteItem.value?.pictureurls ?? ''
  126. return pictureurls.split(',').map((path) => getImageUrl(path))
  127. })
  128. // 挂牌下单
  129. const toggleListing = (value: BuyOrSell) => {
  130. buyorsell.value = value
  131. openComponent('listing')
  132. }
  133. // 摘牌下单
  134. const delistingListing = (row: Model.OrderQuoteDetailRsp, value: BuyOrSell) => {
  135. buyorsell.value = value
  136. quoteDetail.value = row
  137. openComponent('delisting')
  138. }
  139. // 刷新数据
  140. const refresh = () => {
  141. queryOrderQuote({ wrpricetype: 1, wrfactortypeid }).then((res) => {
  142. quoteItem.value = res.data[0]
  143. })
  144. getOrderBuyList(BuyOrSell.Buy)
  145. getOrderSellList(BuyOrSell.Sell)
  146. }
  147. // 接收仓单贸易成交通知
  148. const wrTradeDealedNtf = eventBus.$on('ListingOrderChangeNtf', () => refresh())
  149. onUnmounted(() => {
  150. wrTradeDealedNtf.cancel()
  151. })
  152. refresh()
  153. </script>
  154. <style lang="less">
  155. @import './index.less';
  156. </style>