tableQuote.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import { getGoodsDecimalplaceByGoodsCode, getQuoteDayInfoByCode } from '@/services/bus/goods';
  2. import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
  3. import { addSubscribeQuotation, removeSubscribeQuotation } from '@/services/socket/quota';
  4. import TimerUtils from '@/utils/timer/timerUtil';
  5. import { v4 } from 'uuid';
  6. import { onBeforeUnmount, onMounted, Ref, ref, watchEffect } from "vue";
  7. /**
  8. * 处理行情按需订阅
  9. * @param tableList 全部表格数据
  10. * @param codeKey 需要订阅商品code对应的key
  11. * @param itemTableHeight 表格每一行的高度
  12. * @param selector 当前的滚动区域的选择器
  13. */
  14. export function handleSubcriteOnDemandQuote<T extends object>(tableList: Ref<T[]>, codeKey = 'goodscode', itemTableHeight = 31, selector = '.ant-table-body') {
  15. const beforeScrollTop = ref<number>(0)
  16. const uuid = v4();
  17. onMounted(() => {
  18. listenSrcoll(document.querySelector(selector)!)
  19. });
  20. onBeforeUnmount(() => {
  21. stopSubcribe()
  22. })
  23. // 第一次自动订阅当前可视区域的数据
  24. const stop = watchEffect(() => {
  25. const len = tableList.value.length
  26. if (len) {
  27. const end = len > 16 ? 16 : len;
  28. subscribeAction(0, end)
  29. }
  30. })
  31. // 停止订阅
  32. function stopSubcribe() {
  33. removeSubscribeQuotation(uuid);
  34. TimerUtils.clearTimeout('subscribeQuote')
  35. stop()
  36. }
  37. function listenSrcoll(ele: Element) {
  38. ele.addEventListener('scroll', (event: any) => {
  39. stop && stop()
  40. debounceSroll(event)
  41. }, true)
  42. }
  43. // 判断滚动方向
  44. function srollDrection(event: any) {
  45. const { scrollTop, offsetHeight } = event.target
  46. const diffSrollTop = scrollTop - beforeScrollTop.value
  47. if (diffSrollTop === 0) {
  48. // 横向滚动
  49. return
  50. } else if (diffSrollTop > 0) {
  51. // 向下滚动
  52. caclcuteSubcribeNum(scrollTop, offsetHeight)
  53. } else {
  54. // 向上滚动
  55. caclcuteSubcribeNum(scrollTop, offsetHeight)
  56. }
  57. beforeScrollTop.value = scrollTop
  58. }
  59. /**
  60. *
  61. * @param scrollTop 当前滚动条所处的位置
  62. * @param offsetHeight 当前滚动范围的可视区域的高度
  63. */
  64. function caclcuteSubcribeNum(scrollTop: number, offsetHeight: number) {
  65. // 可视区域的列表行数
  66. const rowNum = Math.ceil(offsetHeight / itemTableHeight) - 1;
  67. const tableIndex = scrollTop < itemTableHeight ? 0 : Math.ceil(scrollTop / itemTableHeight)
  68. // 开始订阅
  69. subscribeAction(tableIndex, tableIndex + rowNum)
  70. }
  71. // 防抖
  72. function debounceSroll(event: any) {
  73. TimerUtils.clearTimeout('subscribeQuote')
  74. TimerUtils.setTimeout(() => {
  75. srollDrection(event)
  76. }, 200, 'subscribeQuote')
  77. }
  78. // 开始订阅
  79. function subscribeAction(start: number, end: number) {
  80. removeSubscribeQuotation(uuid);
  81. const result: Array<{ exchangeCode: 250, goodsCode: string, subState: 0 }> = []
  82. for (let i = start; i < end; i++) {
  83. const obj = tableList.value[i] as unknown as any
  84. if (obj) {
  85. if (Reflect.has(obj, codeKey)) {
  86. result.push({ exchangeCode: 250, goodsCode: obj[codeKey], subState: 0 })
  87. } else {
  88. console.warn(`订阅商品的code对应的key${codeKey}不存在,请手动传入!`)
  89. }
  90. }
  91. }
  92. console.log('开始订阅', result)
  93. addSubscribeQuotation(uuid, result);
  94. }
  95. return stopSubcribe
  96. }
  97. // 处理行情订阅,注意这里不是按需订阅
  98. export function handleSubcriteQuote() {
  99. const uuid = v4();
  100. function subscribeAction(goodscode: string[]) {
  101. removeSubscribeQuotation(uuid);
  102. const goodsList = goodscode.map(el => {
  103. return { exchangeCode: 250, goodsCode: el, subState: 0 };
  104. })
  105. // 行情订阅
  106. addSubscribeQuotation(uuid, goodsList);
  107. }
  108. onBeforeUnmount(() => {
  109. removeSubscribeQuotation(uuid);
  110. });
  111. return { subscribeAction }
  112. }
  113. function isPrice(price1: number | string, price2: number | string) {
  114. if (price2 && price2 !== '--' && price1 && price1 !== '--') {
  115. return true
  116. } else {
  117. return false
  118. }
  119. }
  120. /**
  121. * 处理行情价格颜色
  122. * @param value
  123. * @param presettle 昨结价
  124. * @returns
  125. */
  126. export function handleQuotePriceColor(value: number, presettle: number) {
  127. let result = '--'
  128. if (isPrice(value, presettle)) {
  129. if (value === presettle) {
  130. result = ''
  131. } else if (value > presettle) {
  132. result = 'up-quote-color'
  133. } else {
  134. result = 'down-quote-color'
  135. }
  136. }
  137. return result
  138. }
  139. // 外部行情 获取某个值
  140. export function getQuoteValue_out(goodscode: string, val: keyof QueryQuoteDayRsp) {
  141. const obj = getQuoteDayInfoByCode(goodscode)
  142. return obj ? obj[val] : '--'
  143. }
  144. // 外部行情 处理行情价格颜色
  145. export function handleQuotePriceColor_out(goodscode: string, val: keyof QueryQuoteDayRsp) {
  146. const obj = getQuoteDayInfoByCode(goodscode)
  147. let result = ''
  148. if (obj) {
  149. result = handleQuotePriceColor(obj[val] as number, obj.presettle)
  150. }
  151. return result
  152. }
  153. // 涨跌 最新价 - 昨结价
  154. export function quoteChange(record: QueryQuoteDayRsp | undefined, decimalplace = 2) {
  155. let result = '--'
  156. if (record) {
  157. const { presettle, last } = record
  158. if (isPrice(last, presettle)) {
  159. result = (last - presettle).toFixed(decimalplace)
  160. }
  161. }
  162. return result
  163. }
  164. // 外部行情 涨跌 最新价 - 昨结价
  165. export function quoteChange_out(goodscode: string) {
  166. const obj = getQuoteDayInfoByCode(goodscode)
  167. let result = '--'
  168. const decimalplace = getGoodsDecimalplaceByGoodsCode(goodscode)
  169. if (obj) {
  170. result = quoteChange(obj, decimalplace)
  171. }
  172. return result
  173. }
  174. // 幅度(最新价 - 昨结价) / 昨结价) * 100 %
  175. export function quoteAmplitude(record: QueryQuoteDayRsp, decimalplace = 2) {
  176. const result = quoteChange(record, decimalplace)
  177. return result === '--' ? '--' : (+result / record.presettle * 100).toFixed(2) + '%'
  178. }
  179. // 外部行情 幅度(最新价 - 昨结价) / 昨结价) * 100 %
  180. export function quoteAmplitude_out(goodscode: string) {
  181. const obj = getQuoteDayInfoByCode(goodscode)
  182. let result = '--'
  183. // const decimalplace = getGoodsDecimalplaceByGoodsCode(goodscode)
  184. if (obj) {
  185. result = quoteAmplitude(obj, 2)
  186. }
  187. return result
  188. }
  189. // 振幅 (最高价 - 最低价 ) / 昨结价 * 100 %
  190. export function quoteAmplituOfVibration(record: QueryQuoteDayRsp) {
  191. const { highest, lowest, presettle } = record
  192. let result = '--'
  193. if (isPrice(highest, lowest)) {
  194. if (presettle && (presettle as unknown as any) !== '--') {
  195. result = ((highest - lowest) / presettle * 100).toFixed(2) + '%'
  196. }
  197. }
  198. return result
  199. }
  200. // 处理 空值 或者 0的时候,显示 -- 的情况,
  201. export function handleNoneValue(value: number | string) {
  202. return value ? value : '--'
  203. }