dapan.vue 34 KB

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