dapan.vue 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. <template>
  2. <view class="container">
  3. <view class="status">
  4. <uni-icons
  5. customPrefix="iconfont"
  6. color="#fff"
  7. type="icon-24gf-clockCircle"
  8. size="18"
  9. ></uni-icons>
  10. <span class="time" style="margin-left: 10px">
  11. {{ timeFormat(timestamp, "yyyy-mm-dd hh:MM:ss") }}
  12. </span>
  13. <span
  14. class="status-right"
  15. style="margin-left: 10px"
  16. :class="{ active: !isOpen }"
  17. >
  18. {{ !isOpen ? "闭盘" : "开盘" }}
  19. </span>
  20. </view>
  21. <view class="notice-box">
  22. <view class="iconfont icon-tixing"></view>
  23. <up-notice-bar
  24. icon=""
  25. :text="text1"
  26. :step="true"
  27. bgColor="#fff"
  28. color="#000"
  29. ></up-notice-bar>
  30. </view>
  31. <view class="home">
  32. <view class="page">
  33. <view class="tab_header">
  34. <view class="col col-one">商品</view>
  35. <view class="col" style="width: calc(100% / 13 * 3)">回购</view>
  36. <view class="col" style="width: calc(100% / 13 * 3)">销售</view>
  37. <view class="col col-four" style="width: calc(100% / 13 * 3)"
  38. >高/低</view
  39. >
  40. </view>
  41. <view class="tab_content">
  42. <!-- VIP 区域 -->
  43. <view class="theme-container">
  44. <view class="horizontal-title">VIP</view>
  45. <view class="theme-item">
  46. <!-- 黄金 -->
  47. <view class="price-table-row">
  48. <view class="col" style="width: calc(100% / 13 * 3)">
  49. <view class="name symbol-name">黄金</view>
  50. </view>
  51. <!-- 回购价(动态颜色) -->
  52. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  53. <view
  54. class="sall symbol-name"
  55. :class="{
  56. 'symbol-price-rise': vipGoldRecycleStatus === 'rise',
  57. 'symbol-price-fall': vipGoldRecycleStatus === 'down',
  58. }"
  59. >
  60. {{ vipRealGoldRecyclePrice.toFixed(2) }}
  61. </view>
  62. </view>
  63. <!-- 销售价(动态颜色) -->
  64. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  65. <view
  66. class="back symbol-name"
  67. :class="{
  68. 'symbol-price-rise': vipGoldSellStatus === 'rise',
  69. 'symbol-price-fall': vipGoldSellStatus === 'down',
  70. }"
  71. >
  72. {{ viprealGoldprice.toFixed(2) }}
  73. </view>
  74. </view>
  75. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  76. <view class="symbole-price">
  77. <view class="symbol-price-rise">{{
  78. vipGoldTodayHigh.toFixed(2)
  79. }}</view>
  80. <view class="symbol-price-fall fall">{{
  81. vipGoldTodayLow.toFixed(2)
  82. }}</view>
  83. </view>
  84. </view>
  85. </view>
  86. <!-- K金 -->
  87. <view class="price-table-row">
  88. <view class="col" style="width: calc(100% / 13 * 3)">
  89. <view class="name symbol-name">K金</view>
  90. </view>
  91. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  92. <view
  93. class="sall symbol-name"
  94. :class="{
  95. 'symbol-price-rise': vipKGoldRecycleStatus === 'rise',
  96. 'symbol-price-fall': vipKGoldRecycleStatus === 'down',
  97. }"
  98. >
  99. {{ viprealKGoldRecyclePrice.toFixed(2) }}
  100. </view>
  101. </view>
  102. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  103. <view
  104. class="back symbol-name"
  105. :class="{
  106. 'symbol-price-rise': vipKGoldSellStatus === 'rise',
  107. 'symbol-price-fall': vipKGoldSellStatus === 'down',
  108. }"
  109. >
  110. {{ viprealKGoldprice.toFixed(2) }}
  111. </view>
  112. </view>
  113. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  114. <view class="symbole-price">
  115. <view class="symbol-price-rise">{{
  116. vipkGoldTodayHigh.toFixed(2)
  117. }}</view>
  118. <view class="symbol-price-fall fall">{{
  119. vipkGoldTodayLow.toFixed(2)
  120. }}</view>
  121. </view>
  122. </view>
  123. </view>
  124. <!-- 铂金 -->
  125. <view class="price-table-row">
  126. <view class="col" style="width: calc(100% / 13 * 3)">
  127. <view class="name symbol-name">铂金</view>
  128. </view>
  129. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  130. <view
  131. class="sall symbol-name"
  132. :class="{
  133. 'symbol-price-rise': vipPtRecycleStatus === 'rise',
  134. 'symbol-price-fall': vipPtRecycleStatus === 'down',
  135. }"
  136. >
  137. {{ viprealPtRecyclePrice.toFixed(2) }}
  138. </view>
  139. </view>
  140. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  141. <view
  142. class="back symbol-name"
  143. :class="{
  144. 'symbol-price-rise': vipPtSellStatus === 'rise',
  145. 'symbol-price-fall': vipPtSellStatus === 'down',
  146. }"
  147. >
  148. {{ viprealPtprice.toFixed(2) }}
  149. </view>
  150. </view>
  151. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  152. <view class="symbole-price">
  153. <view class="symbol-price-rise">{{
  154. vipptTodayHigh.toFixed(2)
  155. }}</view>
  156. <view class="symbol-price-fall fall">{{
  157. vipptTodayLow.toFixed(2)
  158. }}</view>
  159. </view>
  160. </view>
  161. </view>
  162. <!-- 白银 -->
  163. <view class="price-table-row">
  164. <view class="col" style="width: calc(100% / 13 * 3)">
  165. <view class="name symbol-name">白银</view>
  166. </view>
  167. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  168. <view
  169. class="sall symbol-name"
  170. :class="{
  171. 'symbol-price-rise': vipAgRecycleStatus === 'rise',
  172. 'symbol-price-fall': vipAgRecycleStatus === 'down',
  173. }"
  174. >
  175. {{ viprealAgRecyclePrice.toFixed(2) }}
  176. </view>
  177. </view>
  178. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  179. <view
  180. class="back symbol-name"
  181. :class="{
  182. 'symbol-price-rise': vipAgSellStatus === 'rise',
  183. 'symbol-price-fall': vipAgSellStatus === 'down',
  184. }"
  185. >
  186. {{ viprealAgprice.toFixed(2) }}
  187. </view>
  188. </view>
  189. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  190. <view class="symbole-price">
  191. <view class="symbol-price-rise">{{
  192. vipagTodayHigh.toFixed(2)
  193. }}</view>
  194. <view class="symbol-price-fall fall">{{
  195. vipagTodayLow.toFixed(2)
  196. }}</view>
  197. </view>
  198. </view>
  199. </view>
  200. </view>
  201. </view>
  202. <!-- SVIP 区域 -->
  203. <view class="theme-container">
  204. <view class="horizontal-title">SVIP</view>
  205. <view class="theme-item">
  206. <!-- 黄金 -->
  207. <view class="price-table-row">
  208. <view class="col" style="width: calc(100% / 13 * 3)">
  209. <view class="name symbol-name">黄金</view>
  210. </view>
  211. <!-- SVIP回购价(动态颜色) -->
  212. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  213. <view
  214. class="sall symbol-name"
  215. :class="{
  216. 'symbol-price-rise': svipGoldRecycleStatus === 'rise',
  217. 'symbol-price-fall': svipGoldRecycleStatus === 'down',
  218. }"
  219. >
  220. {{ svipRealGoldRecyclePrice.toFixed(2) }}
  221. </view>
  222. </view>
  223. <!-- SVIP销售价(复用VIP销售价状态) -->
  224. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  225. <view
  226. class="back symbol-name"
  227. :class="{
  228. 'symbol-price-rise': vipGoldSellStatus === 'rise',
  229. 'symbol-price-fall': vipGoldSellStatus === 'down',
  230. }"
  231. >
  232. {{ viprealGoldprice.toFixed(2) }}
  233. </view>
  234. </view>
  235. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  236. <view class="symbole-price">
  237. <view class="symbol-price-rise">{{
  238. vipGoldTodayHigh.toFixed(2)
  239. }}</view>
  240. <view class="symbol-price-fall fall">{{
  241. vipGoldTodayLow.toFixed(2)
  242. }}</view>
  243. </view>
  244. </view>
  245. </view>
  246. <!-- K金 -->
  247. <view class="price-table-row">
  248. <view class="col" style="width: calc(100% / 13 * 3)">
  249. <view class="name symbol-name">K金</view>
  250. </view>
  251. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  252. <view
  253. class="sall symbol-name"
  254. :class="{
  255. 'symbol-price-rise': svipKGoldRecycleStatus === 'rise',
  256. 'symbol-price-fall': svipKGoldRecycleStatus === 'down',
  257. }"
  258. >
  259. {{ sviprealKGoldRecyclePrice.toFixed(2) }}
  260. </view>
  261. </view>
  262. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  263. <view
  264. class="back symbol-name"
  265. :class="{
  266. 'symbol-price-rise': vipKGoldSellStatus === 'rise',
  267. 'symbol-price-fall': vipKGoldSellStatus === 'down',
  268. }"
  269. >
  270. {{ viprealKGoldprice.toFixed(2) }}
  271. </view>
  272. </view>
  273. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  274. <view class="symbole-price">
  275. <view class="symbol-price-rise">{{
  276. vipkGoldTodayHigh.toFixed(2)
  277. }}</view>
  278. <view class="symbol-price-fall fall">{{
  279. vipkGoldTodayLow.toFixed(2)
  280. }}</view>
  281. </view>
  282. </view>
  283. </view>
  284. <!-- 铂金 -->
  285. <view class="price-table-row">
  286. <view class="col" style="width: calc(100% / 13 * 3)">
  287. <view class="name symbol-name">铂金</view>
  288. </view>
  289. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  290. <view
  291. class="sall symbol-name"
  292. :class="{
  293. 'symbol-price-rise': svipPtRecycleStatus === 'rise',
  294. 'symbol-price-fall': svipPtRecycleStatus === 'down',
  295. }"
  296. >
  297. {{ sviprealPtRecyclePrice.toFixed(2) }}
  298. </view>
  299. </view>
  300. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  301. <view
  302. class="back symbol-name"
  303. :class="{
  304. 'symbol-price-rise': vipPtSellStatus === 'rise',
  305. 'symbol-price-fall': vipPtSellStatus === 'down',
  306. }"
  307. >
  308. {{ viprealPtprice.toFixed(2) }}
  309. </view>
  310. </view>
  311. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  312. <view class="symbole-price">
  313. <view class="symbol-price-rise">{{
  314. vipptTodayHigh.toFixed(2)
  315. }}</view>
  316. <view class="symbol-price-fall fall">{{
  317. vipptTodayLow.toFixed(2)
  318. }}</view>
  319. </view>
  320. </view>
  321. </view>
  322. <!-- 白银 -->
  323. <view class="price-table-row">
  324. <view class="col" style="width: calc(100% / 13 * 3)">
  325. <view class="name symbol-name">白银</view>
  326. </view>
  327. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  328. <view
  329. class="sall symbol-name"
  330. :class="{
  331. 'symbol-price-rise': svipAgRecycleStatus === 'rise',
  332. 'symbol-price-fall': svipAgRecycleStatus === 'down',
  333. }"
  334. >
  335. {{ sviprealAgRecyclePrice.toFixed(2) }}
  336. </view>
  337. </view>
  338. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  339. <view
  340. class="back symbol-name"
  341. :class="{
  342. 'symbol-price-rise': vipAgSellStatus === 'rise',
  343. 'symbol-price-fall': vipAgSellStatus === 'down',
  344. }"
  345. >
  346. {{ viprealAgprice.toFixed(2) }}
  347. </view>
  348. </view>
  349. <view class="col" style="width: calc(100% / 13 * (10 / 3))">
  350. <view class="symbole-price">
  351. <view class="symbol-price-rise">
  352. {{ vipagTodayHigh.toFixed(2) }}
  353. </view>
  354. <view class="symbol-price-fall fall">
  355. {{ vipagTodayLow.toFixed(2) }}
  356. </view>
  357. </view>
  358. </view>
  359. </view>
  360. </view>
  361. </view>
  362. <view class="tips">
  363. <up-parse :content="dapan_agreement"></up-parse>
  364. <!-- <view @click="navigate">点击查看详情</view> -->
  365. </view>
  366. <view class="pageFooter">
  367. <view class="item">
  368. <view class="address">
  369. <view>
  370. {{ appStore.$wxConfig.mailerName }} :
  371. {{ appStore.$wxConfig.mailerPhone }}
  372. </view>
  373. <view class="address-detail" style="margin-top: 4px">
  374. <text class="receive-address">地址:</text>
  375. {{ appStore.$wxConfig.mailingAddress }}
  376. </view>
  377. </view>
  378. </view>
  379. </view>
  380. </view>
  381. </view>
  382. </view>
  383. </view>
  384. </template>
  385. <script setup>
  386. import { ref, computed, watch, nextTick } from "vue";
  387. import { onLoad } from "@dcloudio/uni-app";
  388. import { timeFormat } from "@/uni_modules/uview-plus";
  389. import { useRealtimeTimestamp } from "@/utils/useRealtimeTimestamp.js";
  390. import { useAppStore } from "@/stores/app";
  391. import { getUserLevelInfo } from "@/api/user";
  392. import useRealGoldPrice from "@/hooks/useRealGoldPrice";
  393. import { agreementGetoneApi } from "@/api/user";
  394. import { useToast } from "@/hooks/useToast";
  395. import { getMiniProgramData } from "@/api/api";
  396. import { Calc } from "@/utils/util";
  397. const { Toast } = useToast();
  398. // 全局状态和时间
  399. const appStore = useAppStore();
  400. const { timestamp } = useRealtimeTimestamp();
  401. const isOpen = ref(false);
  402. const contactHandle = () => {
  403. uni.navigateTo({ url: "/pages/message_create/message_create" });
  404. };
  405. // 点击查看详情
  406. const navigate = () => {
  407. uni.navigateTo({ url: "/pages/VIP/VIP" });
  408. };
  409. // 配置滚动文字
  410. const text1 = ref(["以下行情仅供参考", "更多详情咨询与客服联系"]);
  411. // 实时价格处理
  412. const {
  413. realGoldprice, // 黄金实时销售价(基础)
  414. goldTodayHigh, // 黄金最高价
  415. goldTodayLow, // 黄金最低价
  416. realPtprice, // 铂金实时销售价(基础)
  417. ptTodayHigh, // 铂金最高价
  418. ptTodayLow, // 铂金最低价
  419. realAgprice, // 白银实时销售价(基础)
  420. agTodayHigh, // 白银最高价
  421. agTodayLow, // 白银最低价
  422. realKGoldprice, // K金实时销售价(基础)
  423. kGoldTodayHigh, // K金最高价
  424. kGoldTodayLow, // K金最低价
  425. realGoldRecyclePrice, // 黄金实时回收价(基础)
  426. realPtRecyclePrice, // 铂金实时回收价(基础)
  427. realAgRecyclePrice, // 白银实时回收价(基础)
  428. realKGoldRecyclePrice, // K金实时回收价(基础)
  429. } = useRealGoldPrice({});
  430. // 用户权益数据
  431. const userBenefits = ref({});
  432. const adjustGoldPrice = ref({});
  433. const adjustKgoldPrice = ref({});
  434. const adjustPtPrice = ref({});
  435. const adjustAgPrice = ref({});
  436. // svip权益
  437. const svipGoldPrice = ref(0);
  438. const svipKgoldPrice = ref(0);
  439. const svipPtPrice = ref(0);
  440. const svipAgPrice = ref(0);
  441. onLoad(() => {
  442. getUserBenefits();
  443. agreementGetoneFn();
  444. appStore.isLogin && updateWxSettingInfo();
  445. });
  446. const updateWxSettingInfo = async () => {
  447. const { data } = await getMiniProgramData();
  448. if (!data?.metalConfigs) return;
  449. data.metalConfigs.forEach((item) => {
  450. switch (item.metalType) {
  451. case "au":
  452. svipGoldPrice.value = item.svipDiscountPerGram || 0;
  453. break;
  454. case "kau":
  455. svipKgoldPrice.value = item.svipDiscountPerGram || 0;
  456. break;
  457. case "pt":
  458. svipPtPrice.value = item.svipDiscountPerGram || 0;
  459. break;
  460. case "ag":
  461. svipAgPrice.value = item.svipDiscountPerGram || 0;
  462. break;
  463. default:
  464. break;
  465. }
  466. });
  467. };
  468. const dapan_agreement = ref("");
  469. const agreementGetoneFn = () => {
  470. agreementGetoneApi({ name: "dapan_agreement" }).then((res) => {
  471. dapan_agreement.value = res.data?.content;
  472. });
  473. };
  474. const getUserBenefits = async () => {
  475. try {
  476. const res = await getUserLevelInfo(appStore?.userInfo?.userId || 0);
  477. userBenefits.value = res.data || { sold: 0, buy: 0, silverSold: 0 }; // 默认权益为0,避免NaN
  478. isOpen.value = res.data?.isOpen;
  479. if (
  480. userBenefits?.value?.nobleMeta &&
  481. userBenefits.value.nobleMeta.length > 0
  482. ) {
  483. const nobleMeta = userBenefits.value.nobleMeta;
  484. nobleMeta.forEach((item) => {
  485. switch (item.name) {
  486. case "黄金":
  487. adjustGoldPrice.value = item;
  488. break;
  489. case "K金":
  490. adjustKgoldPrice.value = item;
  491. break;
  492. case "铂金":
  493. adjustPtPrice.value = item;
  494. break;
  495. case "白银":
  496. adjustAgPrice.value = item;
  497. break;
  498. default:
  499. break;
  500. }
  501. });
  502. }
  503. } catch (error) {
  504. console.error("获取用户权益失败:", error);
  505. userBenefits.value = { sold: 0, buy: 0, silverSold: 0 }; // 出错时默认权益为0
  506. }
  507. };
  508. // VIP 价格计算
  509. const vipRealGoldRecyclePrice = computed(() => {
  510. // console.log("vipRealGoldRecyclePrice", realGoldRecyclePrice.value);
  511. // console.log("userBenefits", userBenefits.value.sold);
  512. // console.log("adjustGoldPrice", adjustGoldPrice.value.buyPriceAdjust);
  513. // console.log(
  514. // "================>",
  515. // Number(realGoldRecyclePrice.value) +
  516. // Number(userBenefits.value.sold) -
  517. // Number(adjustGoldPrice.value.buyPriceAdjust)
  518. // );
  519. return (
  520. Number(realGoldRecyclePrice.value) +
  521. Number(userBenefits.value.sold) -
  522. Number(adjustGoldPrice.value.buyPriceAdjust)
  523. );
  524. });
  525. const viprealGoldprice = computed(
  526. () =>
  527. Number(realGoldprice.value) -
  528. Number(userBenefits.value.buy) +
  529. Number(adjustGoldPrice.value.sellPriceAdjust)
  530. );
  531. const viprealKGoldRecyclePrice = computed(
  532. () =>
  533. Number(realKGoldRecyclePrice.value) +
  534. Number(userBenefits.value.sold) -
  535. Number(adjustKgoldPrice.value.buyPriceAdjust)
  536. );
  537. const viprealKGoldprice = computed(
  538. () =>
  539. Number(realKGoldprice.value) -
  540. Number(userBenefits.value.buy) +
  541. Number(adjustKgoldPrice.value.sellPriceAdjust)
  542. );
  543. const viprealPtRecyclePrice = computed(
  544. () =>
  545. Number(realPtRecyclePrice.value) +
  546. Number(userBenefits.value.sold) -
  547. Number(adjustPtPrice.value.buyPriceAdjust)
  548. );
  549. const viprealPtprice = computed(
  550. () =>
  551. Number(realPtprice.value) -
  552. Number(userBenefits.value.buy) +
  553. Number(adjustPtPrice.value.sellPriceAdjust)
  554. );
  555. const viprealAgRecyclePrice = computed(() =>
  556. Calc.add(
  557. Number(realAgRecyclePrice.value),
  558. Number(userBenefits.value.silverSold || 0)
  559. )
  560. .sub(Number(adjustAgPrice.value.buyPriceAdjust))
  561. .truncate()
  562. .valueOf()
  563. );
  564. const viprealAgprice = computed(
  565. () =>
  566. Number(realAgprice.value) -
  567. Number(userBenefits.value.buy) +
  568. Number(adjustAgPrice.value.sellPriceAdjust)
  569. );
  570. // SVIP 价格计算(回购价多+0.02,销售价复用VIP)
  571. const svipRealGoldRecyclePrice = computed(() =>
  572. Calc.add(vipRealGoldRecyclePrice.value, svipGoldPrice.value)
  573. .truncate()
  574. .valueOf()
  575. );
  576. const sviprealKGoldRecyclePrice = computed(() =>
  577. Calc.add(viprealKGoldRecyclePrice.value, svipKgoldPrice.value)
  578. .truncate()
  579. .valueOf()
  580. );
  581. const sviprealPtRecyclePrice = computed(() =>
  582. Calc.add(viprealPtRecyclePrice.value, svipPtPrice.value).truncate().valueOf()
  583. );
  584. const sviprealAgRecyclePrice = computed(() =>
  585. Calc.add(viprealAgRecyclePrice.value, svipAgPrice.value).truncate().valueOf()
  586. );
  587. // 高低价计算
  588. const vipGoldTodayHigh = computed(
  589. () =>
  590. Number(goldTodayHigh.value) -
  591. Number(userBenefits.value.buy) +
  592. Number(adjustGoldPrice.value.sellPriceAdjust)
  593. );
  594. const vipGoldTodayLow = computed(
  595. () =>
  596. Number(goldTodayLow.value) -
  597. Number(userBenefits.value.buy) +
  598. Number(adjustGoldPrice.value.sellPriceAdjust)
  599. );
  600. const vipkGoldTodayHigh = computed(
  601. () =>
  602. Number(kGoldTodayHigh.value) -
  603. Number(userBenefits.value.buy) +
  604. Number(adjustKgoldPrice.value.sellPriceAdjust)
  605. );
  606. const vipkGoldTodayLow = computed(
  607. () =>
  608. Number(kGoldTodayLow.value) -
  609. Number(userBenefits.value.buy) +
  610. Number(adjustKgoldPrice.value.sellPriceAdjust)
  611. );
  612. const vipptTodayHigh = computed(
  613. () =>
  614. Number(ptTodayHigh.value) -
  615. Number(userBenefits.value.buy) +
  616. Number(adjustPtPrice.value.sellPriceAdjust)
  617. );
  618. const vipptTodayLow = computed(
  619. () =>
  620. Number(ptTodayLow.value) -
  621. Number(userBenefits.value.buy) +
  622. Number(adjustPtPrice.value.sellPriceAdjust)
  623. );
  624. const vipagTodayHigh = computed(
  625. () =>
  626. Number(agTodayHigh.value) -
  627. Number(userBenefits.value.buy) +
  628. Number(adjustAgPrice.value.sellPriceAdjust)
  629. );
  630. const vipagTodayLow = computed(
  631. () =>
  632. Number(agTodayLow.value) -
  633. Number(userBenefits.value.buy) +
  634. Number(adjustAgPrice.value.sellPriceAdjust)
  635. );
  636. // 判断是否为周末(周六6/周日0)
  637. const isWeekend = computed(() => {
  638. const date = new Date(timestamp.value);
  639. const day = date.getDay();
  640. return day === 0 || day === 6;
  641. });
  642. // 历史价格记录(用于对比变动)
  643. // VIP 历史价
  644. const vipGoldRecyclePrev = ref(0); // VIP黄金回购价-历史
  645. const vipGoldSellPrev = ref(0); // VIP黄金销售价-历史
  646. const vipKGoldRecyclePrev = ref(0); // VIP K金回购价-历史
  647. const vipKGoldSellPrev = ref(0); // VIP K金销售价-历史
  648. const vipPtRecyclePrev = ref(0); // VIP 铂金回购价-历史
  649. const vipPtSellPrev = ref(0); // VIP 铂金销售价-历史
  650. const vipAgRecyclePrev = ref(0); // VIP 白银回购价-历史
  651. const vipAgSellPrev = ref(0); // VIP 白银销售价-历史
  652. // SVIP 历史价(仅回购价,销售价复用VIP)
  653. const svipGoldRecyclePrev = ref(0);
  654. const svipKGoldRecyclePrev = ref(0);
  655. const svipPtRecyclePrev = ref(0);
  656. const svipAgRecyclePrev = ref(0);
  657. // 监听实时价格更新,用nextTick延迟更新历史价(关键修复)
  658. // VIP 价格监听
  659. watch(vipRealGoldRecyclePrice, async (newVal, oldVal) => {
  660. if (newVal === 0) return; // 排除初始0值
  661. await nextTick(); // 等待状态计算完成后再更新历史值
  662. vipGoldRecyclePrev.value = oldVal;
  663. });
  664. watch(viprealGoldprice, async (newVal, oldVal) => {
  665. if (newVal === 0) return;
  666. await nextTick();
  667. vipGoldSellPrev.value = oldVal;
  668. });
  669. watch(viprealKGoldRecyclePrice, async (newVal, oldVal) => {
  670. if (newVal === 0) return;
  671. await nextTick();
  672. vipKGoldRecyclePrev.value = oldVal;
  673. });
  674. watch(viprealKGoldprice, async (newVal, oldVal) => {
  675. if (newVal === 0) return;
  676. await nextTick();
  677. vipKGoldSellPrev.value = oldVal;
  678. });
  679. watch(viprealPtRecyclePrice, async (newVal, oldVal) => {
  680. if (newVal === 0) return;
  681. await nextTick();
  682. vipPtRecyclePrev.value = oldVal;
  683. });
  684. watch(viprealPtprice, async (newVal, oldVal) => {
  685. if (newVal === 0) return;
  686. await nextTick();
  687. vipPtSellPrev.value = oldVal;
  688. });
  689. watch(viprealAgRecyclePrice, async (newVal, oldVal) => {
  690. if (newVal === 0) return;
  691. await nextTick();
  692. vipAgRecyclePrev.value = oldVal;
  693. });
  694. watch(viprealAgprice, async (newVal, oldVal) => {
  695. if (newVal === 0) return;
  696. await nextTick();
  697. vipAgSellPrev.value = oldVal;
  698. });
  699. // SVIP 价格监听(仅回购价)
  700. watch(svipRealGoldRecyclePrice, async (newVal, oldVal) => {
  701. // 排除初始无权益时的0.02
  702. if (Math.abs(newVal - 0.02) < 0.001) return;
  703. await nextTick();
  704. svipGoldRecyclePrev.value = oldVal;
  705. });
  706. watch(sviprealKGoldRecyclePrice, async (newVal, oldVal) => {
  707. if (Math.abs(newVal - 0.02) < 0.001) return;
  708. await nextTick();
  709. svipKGoldRecyclePrev.value = oldVal;
  710. });
  711. watch(sviprealPtRecyclePrice, async (newVal, oldVal) => {
  712. if (Math.abs(newVal - 0.02) < 0.001) return;
  713. await nextTick();
  714. svipPtRecyclePrev.value = oldVal;
  715. });
  716. watch(sviprealAgRecyclePrice, async (newVal, oldVal) => {
  717. if (Math.abs(newVal - 0.02) < 0.001) return;
  718. await nextTick();
  719. svipAgRecyclePrev.value = oldVal;
  720. });
  721. // 计算价格变动状态(rise=上升红,down=下降绿,unchanged=不变保持原色)
  722. // VIP 状态
  723. const vipGoldRecycleStatus = computed(() => {
  724. const curr = vipRealGoldRecyclePrice.value;
  725. const prev = vipGoldRecyclePrev.value;
  726. // console.log(curr, prev);
  727. if (prev === 0) return "unchanged"; // 初始状态不显示颜色
  728. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  729. });
  730. const vipGoldSellStatus = computed(() => {
  731. const curr = viprealGoldprice.value;
  732. const prev = vipGoldSellPrev.value;
  733. if (prev === 0) return "unchanged";
  734. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  735. });
  736. const vipKGoldRecycleStatus = computed(() => {
  737. const curr = viprealKGoldRecyclePrice.value;
  738. const prev = vipKGoldRecyclePrev.value;
  739. if (prev === 0) return "unchanged";
  740. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  741. });
  742. const vipKGoldSellStatus = computed(() => {
  743. const curr = viprealKGoldprice.value;
  744. const prev = vipKGoldSellPrev.value;
  745. if (prev === 0) return "unchanged";
  746. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  747. });
  748. const vipPtRecycleStatus = computed(() => {
  749. const curr = viprealPtRecyclePrice.value;
  750. const prev = vipPtRecyclePrev.value;
  751. if (prev === 0) return "unchanged";
  752. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  753. });
  754. const vipPtSellStatus = computed(() => {
  755. const curr = viprealPtprice.value;
  756. const prev = vipPtSellPrev.value;
  757. if (prev === 0) return "unchanged";
  758. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  759. });
  760. const vipAgRecycleStatus = computed(() => {
  761. const curr = viprealAgRecyclePrice.value;
  762. const prev = vipAgRecyclePrev.value;
  763. if (prev === 0) return "unchanged";
  764. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  765. });
  766. const vipAgSellStatus = computed(() => {
  767. const curr = viprealAgprice.value;
  768. const prev = vipAgSellPrev.value;
  769. if (prev === 0) return "unchanged";
  770. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  771. });
  772. // SVIP 状态(仅回购价)
  773. const svipGoldRecycleStatus = computed(() => {
  774. const curr = svipRealGoldRecyclePrice.value;
  775. const prev = svipGoldRecyclePrev.value;
  776. if (prev === 0) return "unchanged";
  777. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  778. });
  779. const svipKGoldRecycleStatus = computed(() => {
  780. const curr = sviprealKGoldRecyclePrice.value;
  781. const prev = svipKGoldRecyclePrev.value;
  782. if (prev === 0) return "unchanged";
  783. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  784. });
  785. const svipPtRecycleStatus = computed(() => {
  786. const curr = sviprealPtRecyclePrice.value;
  787. const prev = svipPtRecyclePrev.value;
  788. if (prev === 0) return "unchanged";
  789. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  790. });
  791. const svipAgRecycleStatus = computed(() => {
  792. const curr = sviprealAgRecyclePrice.value;
  793. const prev = svipAgRecyclePrev.value;
  794. if (prev === 0) return "unchanged";
  795. return curr > prev ? "rise" : curr < prev ? "down" : "unchanged";
  796. });
  797. </script>
  798. <style lang="scss" scoped>
  799. page {
  800. height: 100%;
  801. background: #252525 !important;
  802. }
  803. .callService {
  804. padding: 20px 10px 0px;
  805. // background-color: #ddcca3;
  806. display: flex;
  807. justify-content: center;
  808. flex-direction: column;
  809. font-size: 16px;
  810. // margin-bottom: 30rpx;
  811. .list-box {
  812. background: #fff;
  813. border-radius: 20px;
  814. .list-item {
  815. width: 100%;
  816. height: 100rpx;
  817. display: flex;
  818. justify-content: center;
  819. align-items: center;
  820. border-bottom: 1px solid #e1e1e1;
  821. }
  822. }
  823. }
  824. .notice-box {
  825. width: 98%;
  826. margin: 0 auto;
  827. background: #ffffff;
  828. display: flex;
  829. padding: 8rpx 30rpx;
  830. border-radius: 10rpx;
  831. // height: ;
  832. align-items: center;
  833. .iconfont {
  834. width: 44rpx;
  835. height: 44rpx;
  836. border-radius: 50%;
  837. text-align: center;
  838. line-height: 44rpx;
  839. // background-color: #fe960f;
  840. color: #000;
  841. font-size: 30rpx;
  842. margin-right: 15rpx;
  843. &.icon-wechat {
  844. background-color: #41b035;
  845. }
  846. &.icon-zhifubao {
  847. background-color: #06b4fd;
  848. }
  849. }
  850. }
  851. .status {
  852. margin: 20rpx 0;
  853. .time {
  854. font-size: 26rpx;
  855. }
  856. .status-right {
  857. font-size: 30rpx;
  858. color: #33cc33;
  859. &.active {
  860. color: red;
  861. }
  862. }
  863. }
  864. .address-container {
  865. display: flex;
  866. .address {
  867. width: 100rpx;
  868. }
  869. }
  870. .tips {
  871. margin-top: 20rpx;
  872. }
  873. .price-table-row-not {
  874. display: none !important;
  875. }
  876. ::v-deep .center {
  877. height: 100%;
  878. display: flex;
  879. flex-direction: column;
  880. justify-content: center;
  881. align-items: center;
  882. }
  883. .divider {
  884. width: 100%;
  885. line-height: 1px;
  886. height: 1px;
  887. background-color: #999;
  888. }
  889. .divider2 {
  890. width: 100%;
  891. height: 3px;
  892. background-color: #000;
  893. }
  894. .container {
  895. height: 100%;
  896. max-width: 100% !important;
  897. display: flex;
  898. flex-direction: column;
  899. background: #252525 !important;
  900. .status {
  901. text-align: right;
  902. padding-top: 3px;
  903. padding-right: 10px;
  904. display: inline-block;
  905. color: red !important;
  906. background: #252525 !important;
  907. font-size: 15px;
  908. }
  909. }
  910. .header {
  911. display: flex;
  912. align-items: center;
  913. padding: 4px;
  914. }
  915. .page,
  916. .header {
  917. background: #fff !important;
  918. }
  919. .home {
  920. height: 100%;
  921. flex-grow: 1;
  922. overflow: auto;
  923. color: #fff;
  924. margin-top: 5px;
  925. .page {
  926. background: #18293a;
  927. overflow: auto;
  928. box-sizing: border-box;
  929. position: relative;
  930. .tab_header {
  931. display: flex;
  932. background: #b5aa90;
  933. font-size: 16px;
  934. width: 100%;
  935. justify-content: space-between;
  936. align-items: center;
  937. box-sizing: border-box;
  938. &.white {
  939. background-color: #fff;
  940. }
  941. .col {
  942. text-align: center;
  943. padding: 24rpx 0;
  944. line-height: 23px;
  945. }
  946. .col-one {
  947. width: 245rpx;
  948. box-sizing: border-box;
  949. padding-left: 46rpx;
  950. }
  951. }
  952. .theme-container {
  953. display: flex;
  954. border-bottom: 4rpx solid #000;
  955. .horizontal-title {
  956. color: #000;
  957. background-color: #e6e6e6;
  958. font-size: 14px;
  959. width: 86rpx;
  960. text-align: center;
  961. word-break: break-all;
  962. -webkit-box-sizing: border-box;
  963. box-sizing: border-box;
  964. display: flex;
  965. justify-content: center;
  966. align-items: center;
  967. border-right: 2rpx solid #999;
  968. font-weight: 500;
  969. }
  970. .theme-item {
  971. flex-grow: 1;
  972. flex-shrink: 1;
  973. .ditem {
  974. &.greywhite {
  975. background: #e6e6e6;
  976. }
  977. }
  978. }
  979. }
  980. }
  981. }
  982. .tab_header .col {
  983. border-bottom: 1px solid #999;
  984. }
  985. .tab_content .col {
  986. border-right: 1px solid #999;
  987. text-align: center;
  988. &:last-child {
  989. border: none;
  990. }
  991. }
  992. .tab_content {
  993. overflow-y: auto;
  994. .price-table-row {
  995. display: flex;
  996. justify-content: center;
  997. color: #808080;
  998. height: 55px;
  999. &:nth-child(2n) {
  1000. background: #e6e6e6 !important;
  1001. }
  1002. }
  1003. .name {
  1004. color: #000 !important;
  1005. }
  1006. .col {
  1007. padding: 3px 0;
  1008. line-height: 23px;
  1009. display: flex;
  1010. justify-content: center;
  1011. align-items: center;
  1012. color: #000;
  1013. }
  1014. .symbol-name {
  1015. font-family: Microsoft YaHei, Arial, Helvetica, sans-serif;
  1016. font-size: 30rpx;
  1017. color: #ff0000;
  1018. }
  1019. .symbole-price {
  1020. width: 100%;
  1021. font-size: 30rpx;
  1022. }
  1023. }
  1024. .btn-container {
  1025. display: flex;
  1026. align-items: center;
  1027. justify-content: center;
  1028. height: 60rpx;
  1029. width: 40%;
  1030. font-size: 30rpx;
  1031. background-color: #cc9931;
  1032. color: #ffffff;
  1033. border-radius: 100rpx;
  1034. margin: 60rpx auto 20rpx;
  1035. .btn-image {
  1036. width: 30rpx;
  1037. margin-left: 10rpx;
  1038. }
  1039. /* 移除button默认样式 */
  1040. button::after {
  1041. border: none;
  1042. }
  1043. /* 自定义按钮样式 */
  1044. .btn {
  1045. -webkit-appearance: none;
  1046. width: 164rpx;
  1047. height: 60rpx;
  1048. font-size: 26rpx;
  1049. display: flex;
  1050. align-items: center;
  1051. justify-content: center;
  1052. background-color: #cc9931;
  1053. color: #fff;
  1054. border: none;
  1055. /* 移除点击后的轮廓线 */
  1056. outline: none;
  1057. ::after {
  1058. border: 0rpx solid #cc9931;
  1059. /* 移除点击后的轮廓线 */
  1060. outline: none;
  1061. }
  1062. }
  1063. button[open-type="contact"] {
  1064. outline: none;
  1065. border: none;
  1066. box-shadow: none;
  1067. }
  1068. }
  1069. /* 价格变动颜色(上升红、下降绿,优先级确保覆盖默认色) */
  1070. .symbol-price-rise {
  1071. color: #ff0000 !important;
  1072. }
  1073. .symbol-price-fall {
  1074. color: #33cc33 !important;
  1075. }
  1076. .fall {
  1077. border-top: 2rpx solid #999;
  1078. }
  1079. .pageFooter {
  1080. background: #2c3031 !important;
  1081. padding: 35rpx 50rpx 50rpx 50rpx;
  1082. font-size: 28rpx;
  1083. }
  1084. </style>