index.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <template>
  2. <v-page>
  3. <v-header :leftClick="()=>_router.replace('/pages/base/option-list')" :left-arrow="false">
  4. <template #left>
  5. <view @click="jumpBack()">
  6. <i class="van-icon van-icon-arrow-left van-nav-bar__arrow"></i>
  7. </view>
  8. <view class="fn-20 color-theme-1 m-l-xs" @click="optListShow = true">
  9. <i class="iconfont">&#xe655;</i>
  10. </view>
  11. </template>
  12. <template #title>
  13. <view class="head-top">{{ query.pair_time_name }}</view>
  14. </template>
  15. </v-header>
  16. <view class="layout-main">
  17. <view class="bg-panel-4 p-x-md p-t-md p-b-xs price-data" v-if="false">
  18. <view class="d-flex justify-between">
  19. <view class="coin fn-18 color-light">{{ query.pair_time_name }}</view>
  20. <view
  21. class="money fn-20"
  22. :class="lastData.increase >= 0 ? 'color-buy' : 'color-sell'"
  23. >
  24. {{ lastData.price }}
  25. <span class="zf fn-sm">{{ lastData.increaseStr }}</span>
  26. </view>
  27. </view>
  28. </view>
  29. <van-tabs :border="false" :active="activeTime" animated :ellipsis="false" @change="activeTime = $event.detail.name">
  30. <van-tab v-for="item in tileList" :name="item.value" :title="item.label" :key="item.label">
  31. </van-tab>
  32. </van-tabs>
  33. <view class="chart-box">
  34. <!-- 每分钟heightChart -->
  35. <highchart
  36. v-show="activeTime == '1'"
  37. :symbolName="symbolName"
  38. @newData="newData"
  39. />
  40. <!-- 其他 tradingview -->
  41. <!-- <tv-chart
  42. class="chart-tradingview"
  43. @changeInterval="changeInterval"
  44. :serveSymbolName="symbolName"
  45. :serveInterval="activeTime"
  46. /> -->
  47. <iframe v-if="activeTime != '1'" class="chart-tradingview" :src="`${mobileBase}static/tradingview.html?${
  48. setQuery(iframeQuery)
  49. }`" frameborder="0"></iframe>
  50. </view>
  51. <view class="option-panel ">
  52. <van-tabs
  53. :active="active"
  54. animated
  55. class="nav-tab"
  56. swipeable
  57. sticky
  58. offset-top="1.22667rem"
  59. :ellipsis="false"
  60. :border="false"
  61. >
  62. <van-tab
  63. v-for="item in funList"
  64. :title="item.title"
  65. :key="item.title"
  66. class="border-t m-t-xs"
  67. >
  68. <component
  69. v-on="{ ...item.on }"
  70. :ref="item.is"
  71. v-bind="{ ...item.props }"
  72. :is="item.is"
  73. ></component>
  74. </van-tab>
  75. </van-tabs>
  76. </view>
  77. </view>
  78. <!-- 左侧列表弹窗 -->
  79. <van-popup
  80. :show="optListShow"
  81. @close="optListShow = false"
  82. close-on-popstate
  83. position="left"
  84. custom-style="width:70%;height:100%"
  85. >
  86. <option-nav-list @close="optListShow = false" @check="changeCoin" />
  87. </van-popup>
  88. <!-- 购买的弹窗 -->
  89. <van-popup
  90. :show="buyOptShow"
  91. close-on-popstate
  92. position="bottom"
  93. custom-style="width:100%"
  94. class="option-form"
  95. >
  96. <buy-option-form
  97. @success="resetWaiting"
  98. @close="buyOptShow = false"
  99. :currentAndNext="currentAndNext"
  100. :query="query"
  101. :type="buyType"
  102. />
  103. </van-popup>
  104. </v-page>
  105. </template>
  106. <script>
  107. import highchart from "./highchart";
  108. import buyOption from "./buy-option";
  109. import waitingDelivery from "./waiting-delivery";
  110. import myDelivery from "./my-delivery";
  111. import deliveryRecord from "./delivery-record";
  112. import buyOptionForm from "./buy-option-form";
  113. import optionNavList from "./option-nav-list";
  114. import Option from "@/api/option";
  115. import { mapState } from "vuex";
  116. import qs from 'qs'
  117. import app from "app.js"
  118. export default {
  119. components: {
  120. highchart,
  121. buyOption,
  122. waitingDelivery,
  123. myDelivery,
  124. deliveryRecord,
  125. buyOptionForm,
  126. optionNavList,
  127. },
  128. computed: {
  129. funList() {
  130. return [
  131. {
  132. title: this.$t("option.d4"),
  133. is: "buy-option",
  134. on: {
  135. "buy-show": this.buyShow,
  136. "change-venue": () => {
  137. this.resetBill();
  138. setTimeout(() => {
  139. this.sceneDetail();
  140. this.resetWaiting();
  141. }, 2000);
  142. },
  143. },
  144. props: {
  145. currentAndNext: this.currentAndNext,
  146. query: this.query,
  147. },
  148. },
  149. {
  150. title: this.$t("option.d5"),
  151. is: "waiting-delivery",
  152. props: {
  153. query: this.query,
  154. },
  155. },
  156. {
  157. title: this.$t("option.d6"),
  158. is: "my-delivery",
  159. props: {
  160. query: this.query,
  161. },
  162. },
  163. {
  164. title: this.$t("option.d7"),
  165. is: "delivery-record",
  166. props: {
  167. query: this.query,
  168. },
  169. },
  170. ];
  171. },
  172. symbolName() {
  173. if (!this.query.pair_time_name) return "";
  174. let str = this.query.pair_time_name.split("-")[0];
  175. return str;
  176. },
  177. tileList() {
  178. let arr = [
  179. {
  180. label: this.$t("option.d10"),
  181. value: "1",
  182. },
  183. {
  184. label: "5 " + this.$t("option.d8"),
  185. value: "5",
  186. },
  187. {
  188. label: "15 " + this.$t("option.d8"),
  189. value: "15",
  190. },
  191. {
  192. label: "30 " + this.$t("option.d8"),
  193. value: "30",
  194. },
  195. {
  196. label: "1 " + this.$t("option.d9"),
  197. value: "60",
  198. },
  199. {
  200. label: "1 " + this.$t("option.e0"),
  201. value: "1D",
  202. },
  203. {
  204. label: "1 " + this.$t("option.e1"),
  205. value: "1W",
  206. },
  207. {
  208. label: "1 " + this.$t("option.e2"),
  209. value: "1M",
  210. },
  211. ];
  212. return arr;
  213. },
  214. activeTimeObj() {
  215. return this.tileList.find((item) => item.value == this.activeTime);
  216. },
  217. ...mapState({
  218. ws: "ws",
  219. }),
  220. iframeQuery(){
  221. return {
  222. getLinkUrl:app.baseUrl+'/api/app/option/getKline',
  223. symbol:this.symbolName,
  224. theme:'dark',
  225. ws:app.socketUrl,
  226. interval:this.activeTime
  227. }
  228. },
  229. mobileBase() {
  230. // #ifdef APP-PLUS
  231. if (plus.os.name == "Android") {
  232. return "";
  233. } else {
  234. return this.app.mobile+'/';
  235. }
  236. // #endif
  237. // #ifdef H5
  238. return '/';
  239. // #endif
  240. },
  241. },
  242. data() {
  243. return {
  244. active: 0,
  245. activeTime: "1",
  246. buyOptShow: false,
  247. optListShow: false,
  248. timeFilter: false,
  249. list: [],
  250. lastData: {},
  251. // 当前和下一场
  252. currentAndNext: {},
  253. buyType: 1,
  254. query: {},
  255. app
  256. };
  257. },
  258. watch: {
  259. query() {
  260. this.sceneDetail();
  261. },
  262. },
  263. methods: {
  264. setQuery:qs.stringify,
  265. resetWaiting() {
  266. let waitingDelivery =
  267. this.$refs["waiting-delivery"] && this.$refs["waiting-delivery"][0];
  268. if (waitingDelivery) {
  269. waitingDelivery.reset();
  270. }
  271. },
  272. resetBill() {
  273. let myDelivery =
  274. this.$refs["my-delivery"] && this.$refs["my-delivery"][0];
  275. if (myDelivery) {
  276. myDelivery.reset();
  277. }
  278. let deliveryRecord =
  279. this.$refs["delivery-record"] && this.$refs["delivery-record"][0];
  280. if (deliveryRecord) {
  281. deliveryRecord.reset();
  282. }
  283. },
  284. changeInterval($ev) {
  285. this.activeTime = $ev;
  286. },
  287. buyShow(idx) {
  288. this.buyType = idx;
  289. this.buyOptShow = true;
  290. },
  291. // 切换币种
  292. changeCoin(item) {
  293. this._router.replace({
  294. path: "/pages/option/index",
  295. query: {
  296. pair_time_name: item.pair_time_name,
  297. pair_id: item.pair_id,
  298. time_id: item.time_id,
  299. },
  300. });
  301. },
  302. // 获取最新价
  303. newData(data) {
  304. this.lastData = data;
  305. },
  306. // 获取当前和下一场
  307. sceneDetail() {
  308. let data = {
  309. pair_id: this.query.pair_id,
  310. time_id: this.query.time_id,
  311. };
  312. Option.sceneDetail(data)
  313. .then((res) => {
  314. let data = res.data;
  315. data.current_scene.seconds =
  316. data.current_scene.seconds + Math.random();
  317. data.next_scene.seconds = data.next_scene.seconds + Math.random();
  318. this.currentAndNext = data;
  319. this.ws.send({ cmd: "sub", msg: "sceneListNewPrice" });
  320. })
  321. .catch(() => {});
  322. },
  323. jumpBack(){
  324. this.$router.push({path:'/pages/base/option-list'});
  325. }
  326. },
  327. onUnload() {
  328. this.ws.send({ cmd: "unsub", msg: "sceneListNewPrice" });
  329. },
  330. onLoad(query) {
  331. this.query = query;
  332. this.sceneDetail();
  333. setTimeout(() => {
  334. this.resetBill();
  335. }, 3000);
  336. },
  337. destroyed() {},
  338. };
  339. </script>
  340. <style lang="scss" scoped>
  341. .price-data {
  342. position: relative;
  343. .filter {
  344. label {
  345. display: block;
  346. .button {
  347. border: none;
  348. background: none;
  349. &:active {
  350. color: $theme-1;
  351. }
  352. }
  353. input {
  354. display: none;
  355. }
  356. .filter-panel {
  357. position: absolute;
  358. top: 103%;
  359. left: $padding-md;
  360. right: $padding-md;
  361. overflow: hidden;
  362. z-index: 99;
  363. button {
  364. background: none;
  365. border: none;
  366. &.active,
  367. &:active {
  368. color: $white;
  369. }
  370. }
  371. }
  372. }
  373. }
  374. }
  375. .chart-box {
  376. height: 340px;
  377. }
  378. .chart-tradingview {
  379. height: 100%;
  380. width: 100%;
  381. }
  382. .option-form{
  383. /deep/ .van-popup{
  384. border-top-left-radius: 20px;
  385. border-top-right-radius: 20px;
  386. }
  387. }
  388. </style>