index.vue 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. <template>
  2. <view class="container">
  3. <up-navbar class="inde-nav-bar" :bgColor="navBgColor">
  4. <template #left>
  5. <view></view>
  6. </template>
  7. <template #center>
  8. <view class="page-title">我的</view>
  9. </template>
  10. </up-navbar>
  11. <!-- 顶部用户信息 -->
  12. <view class="user-header">
  13. <view class="user-info">
  14. <view class="user-main">
  15. <view>
  16. <image
  17. class="avatar"
  18. :src="isHttpsImage(appStore.$userInfo?.avatar)"
  19. ></image>
  20. </view>
  21. <view class="user-detail">
  22. <view class="name-vip" v-if="appStore.isLogin">
  23. <text class="name">{{ appStore.$userInfo?.nickname }}</text>
  24. <image class="vip-tag" v-if="appStore.$userInfo?.svip" mode="widthFix" :src="HTTP_REQUEST_URL_IMG+'sviplogo.png'"></image>
  25. </view>
  26. <view
  27. class="name-vip"
  28. v-else
  29. @click="navigateTo('/pages/users/login/index')"
  30. >
  31. <text class="name">未登录</text>
  32. </view>
  33. <text class="vip-expire" v-if="appStore.$userInfo?.svip"
  34. >到期时间:{{ appStore.$userInfo?.svipExpireTime }}</text
  35. >
  36. </view>
  37. </view>
  38. <view class="btn-content" @click="handleEdit()">
  39. <image
  40. class="setting"
  41. :src="HTTP_REQUEST_URL_IMG + 'setting.png'"
  42. mode="widthFix"
  43. ></image>
  44. <text class="btn-text">编辑资料</text>
  45. </view>
  46. </view>
  47. <!-- 会员开通提示 v-if="!userInfo.isVip"-->
  48. <view class="vip-promote" v-if="useList&&useList.length>0&&showIcons">
  49. <image class="vipBG" :src="HTTP_REQUEST_URL_IMG+'vipBG.png'" mode="scaleToFill"></image>
  50. <view class="vip-text">
  51. <view class="title">
  52. <image class="vipIcon" :src="HTTP_REQUEST_URL_IMG+'setting/vipIcon.png'" mode="widthFix"></image>
  53. <text v-if="!appStore.$userInfo?.svip">开通<text class="bigText">会员</text>享受更多<text class="bigText">权益</text></text>
  54. <text v-else>前往查看<text class="bigText">权益</text></text>
  55. </view>
  56. <button class="open-vip" @click="goVIP">{{appStore.$userInfo?.svip ? '去查看':'去开通'}}<image class="bofang" :src="HTTP_REQUEST_URL_IMG+'setting/bofang.png'" mode="widthFix"></image></button>
  57. </view>
  58. </view>
  59. </view>
  60. <!-- 钱包余额 -->
  61. <view class="wallet-section">
  62. <view class="wallet-header">
  63. <view>
  64. <view class="wallet-title">钱包余额(元)</view>
  65. <view class="balance">{{ wallet.balance }}</view>
  66. </view>
  67. <view
  68. class="transaction-detail"
  69. @click="viewTransactionDetail"
  70. v-if="useList && useList.length > 0 && showIcons"
  71. >
  72. <text style="margin-right: 10rpx">交易明细</text>
  73. <uni-icons type="right" size="16" color="#666666"></uni-icons>
  74. </view>
  75. </view>
  76. <up-line color="#F1F3F8"></up-line>
  77. <view class="assets">
  78. <view
  79. v-for="(asset, index) in wallet.assets"
  80. :key="asset.name"
  81. class="asset-container"
  82. >
  83. <view class="asset-item">
  84. <text class="asset-name">{{ asset.name }}</text>
  85. <text class="asset-amount"
  86. >{{ asset.balance }}{{ asset.unit }}</text
  87. >
  88. </view>
  89. <!-- 在每个资产项后面添加垂直分隔线,除了最后一个 -->
  90. <up-line
  91. v-if="index < wallet.assets.length - 1"
  92. color="#F1F3F8"
  93. direction="col"
  94. length="80rpx"
  95. style="margin: 0 20rpx"
  96. ></up-line>
  97. </view>
  98. </view>
  99. <view
  100. class="wallet-actions"
  101. v-if="tradeList && tradeList.length > 0 && showIcons"
  102. >
  103. <view
  104. class="wallet-btn withdraw"
  105. @click="goDetail(tradeList[0].jumpUrl)"
  106. >{{ tradeList[0].iconName }}</view
  107. >
  108. <view
  109. class="wallet-btn recharge"
  110. @click="goDetail(tradeList[1].jumpUrl)"
  111. >{{ tradeList[1].iconName }}</view
  112. >
  113. </view>
  114. <view class="functions" v-if="useList&&useList.length>0&&showIcons">
  115. <view class="function-item" v-for="item in useList" :key="item.iconName" @click="goDetail(item.jumpUrl)">
  116. <view class="function-icon">
  117. <image class="img" :src="item.src" mode="widthFix"></image>
  118. </view>
  119. <text class="function-name">{{ item.iconName }}</text>
  120. </view>
  121. </view>
  122. </view>
  123. <!-- 最近访问 -->
  124. <view class="recent-visit" v-if="recentStores.length > 0">
  125. <view class="section-header">
  126. <text class="section-title">最近访问</text>
  127. <view class="more" @click="handleFunctionClick('/pages/users/browsing_history/index')">更多商家<uni-icons style="margin-left: 10rpx;" type="right" size="16" color="#666666"></uni-icons></view>
  128. </view>
  129. <view class="store-list">
  130. <template v-for="(store,storeIndex) in recentStores" :key="store.id">
  131. <view class="store-item" v-if="storeIndex == 0" @click="viewStore(store)">
  132. <view class="store-logo">
  133. <image class="img" :src="store.merchantLogo"></image>
  134. </view>
  135. <view class="store-info">
  136. <text class="store-name">{{ store.merchantName }}</text>
  137. <text class="store-desc">{{ store.merchantDescribe }}</text>
  138. </view>
  139. <uni-icons style="margin-left: auto;" type="right" size="16" color="#666666"></uni-icons>
  140. </view>
  141. </template>
  142. </view>
  143. </view>
  144. <!-- 订单状态 -->
  145. <view class="order-section">
  146. <view class="section-header">
  147. <text class="section-title">我的订单</text>
  148. <view class="more" @click="viewAllOrders"
  149. >全部订单<uni-icons
  150. style="margin-left: 10rpx"
  151. type="right"
  152. size="16"
  153. color="#666666"
  154. ></uni-icons
  155. ></view>
  156. </view>
  157. <view class="order-status">
  158. <view
  159. class="status-item"
  160. v-for="order in orderStatus"
  161. :key="order.name"
  162. @click="viewOrders(order.id)"
  163. >
  164. <view class="status-icon">
  165. <image class="img" :src="order.src" mode="widthFix"></image>
  166. </view>
  167. <text class="status-name">{{ order.name }}</text>
  168. </view>
  169. </view>
  170. </view>
  171. <!-- 常用功能 -->
  172. <view class="common-functions">
  173. <view class="section-header">
  174. <text class="section-title">常用功能</text>
  175. </view>
  176. <view class="functions">
  177. <template v-for="func in commonFunctions" :key="func.name">
  178. <view class="function-item" @click="handleFunctionClick(func.pageUrl)" v-if="func.show">
  179. <view class="function-icon">
  180. <image class="img" :src="func.src" mode="widthFix"></image>
  181. </view>
  182. <text class="function-name">{{ func.name }}</text>
  183. </view>
  184. </template>
  185. </view>
  186. </view>
  187. <!-- 企微客服弹窗 -->
  188. <up-popup
  189. :show="showCallList"
  190. closeOnClickOverlay
  191. mode="bottom"
  192. @close="showCallList = false"
  193. >
  194. <view class="callService">
  195. <view class="list-box">
  196. <view
  197. v-for="(item, index) in callList"
  198. :key="index"
  199. class="list-item"
  200. @click="callService(item)"
  201. >
  202. <view class="item-left">
  203. <view class="item-name">{{ item.serviceName }}</view>
  204. </view>
  205. </view>
  206. </view>
  207. </view>
  208. </up-popup>
  209. </view>
  210. </template>
  211. <script setup>
  212. import { ref, reactive, watch, computed } from "vue";
  213. import { onLoad, onShow, onPageScroll } from "@dcloudio/uni-app";
  214. import UniIcons from "../../uni_modules/uni-icons/components/uni-icons/uni-icons.vue";
  215. import { HTTP_REQUEST_URL_IMG } from "@/config/app";
  216. import { isHttpsImage } from "@/utils/util";
  217. import { useAppStore } from "@/stores/app";
  218. import { useToast } from "@/hooks/useToast";
  219. import { getMetalBalance } from "@/api/vault";
  220. import { footprintList } from "@/api/merchant.js";
  221. import { getCustomerServiceList } from "@/api/user";
  222. import { toLogin } from "@/libs/login.js";
  223. const showIcons = ref(false);
  224. const appStore = useAppStore();
  225. const { Toast } = useToast();
  226. const isLogin = appStore.isLogin;
  227. const callList = ref([]);
  228. const showCallList = ref(false);
  229. const navBgColor = ref("rgba(255,255,255,0)");
  230. // 钱包信息
  231. const wallet = ref({
  232. balance: appStore.userInfo?.nowMoney || "0.00",
  233. assets: [
  234. { name: "黄金资产", balance: "0.00", unit: "g", type: 1 },
  235. { name: "铂金资产", balance: "0.00", unit: "g", type: 2 },
  236. { name: "白银资产", balance: "0.00", unit: "g", type: 3 },
  237. ],
  238. });
  239. // 主要功能列表
  240. const mainFunctions = ref([
  241. {
  242. src: `${HTTP_REQUEST_URL_IMG}setting/mailiao.png`,
  243. name: "买料",
  244. pageUrl: "/pages/users/vault/rechargeGold",
  245. },
  246. {
  247. src: `${HTTP_REQUEST_URL_IMG}setting/mailiao2.png`,
  248. name: "卖料",
  249. pageUrl: "/pages/users/vault/storeMetal/index",
  250. },
  251. {
  252. src: `${HTTP_REQUEST_URL_IMG}setting/cunliao.png`,
  253. name: "存料",
  254. pageUrl: "/pages/users/vault/storeMetal/goldBullionStock",
  255. },
  256. {
  257. src: `${HTTP_REQUEST_URL_IMG}setting/tiliao.png`,
  258. name: "提料",
  259. pageUrl: "/pages/users/vault/storeMetal/metalExchange",
  260. },
  261. ]);
  262. // 最近访问的商家
  263. const recentStores = ref([]);
  264. // 订单状态
  265. const orderStatus = ref([
  266. {
  267. src: `${HTTP_REQUEST_URL_IMG}setting/daifukuan.png`,
  268. name: "待付款",
  269. id: 0,
  270. },
  271. { src: `${HTTP_REQUEST_URL_IMG}setting/daifahuo.png`, name: "待发货", id: 1 },
  272. {
  273. src: `${HTTP_REQUEST_URL_IMG}setting/daishouhuo.png`,
  274. name: "待收货",
  275. id: 2,
  276. },
  277. {
  278. src: `${HTTP_REQUEST_URL_IMG}setting/tuikuan.png`,
  279. name: "退款/换货",
  280. id: 5,
  281. },
  282. {
  283. src: `${HTTP_REQUEST_URL_IMG}setting/yiwancheng.png`,
  284. name: "已完成",
  285. id: 4,
  286. },
  287. ]);
  288. const merchantZYShow = ref(false);
  289. const lxsjShow = ref(false);
  290. const logoutShow = ref(false);
  291. // 常用功能
  292. const commonFunctions = computed(() => {
  293. const baseFunctions = [
  294. {
  295. src: `${HTTP_REQUEST_URL_IMG}setting/zuji.png`,
  296. name: "浏览足迹",
  297. pageUrl: "/pages/users/browsing_history/index",
  298. show: true,
  299. },
  300. {
  301. src: `${HTTP_REQUEST_URL_IMG}setting/shoucang.png`,
  302. name: "我的收藏",
  303. pageUrl: "/pages/users/user_goods_collection/index",
  304. show: true,
  305. },
  306. {
  307. src: `${HTTP_REQUEST_URL_IMG}setting/dingwei.png`,
  308. name: "收货地址",
  309. pageUrl: "/pages/users/user_address_list/index",
  310. show: true,
  311. },
  312. {
  313. src: `${HTTP_REQUEST_URL_IMG}setting/dianpu.png`,
  314. name: "联系商家",
  315. pageUrl: "/pages/users/my_merchant/index",
  316. show: lxsjShow.value,
  317. },
  318. {
  319. src: `${HTTP_REQUEST_URL_IMG}setting/dianpu.png`,
  320. name: "门店主页",
  321. pageUrl: "/pages/merchantCenter/index",
  322. show: merchantZYShow.value,
  323. },
  324. // { src: `${HTTP_REQUEST_URL_IMG}setting/xiazaiapp.png`, name: '下载APP', pageUrl: 'download', show: true },
  325. {
  326. src: `${HTTP_REQUEST_URL_IMG}setting/lianxikefu.png`,
  327. name: "平台客服",
  328. show: true,
  329. },
  330. {
  331. src: `${HTTP_REQUEST_URL_IMG}setting/logout.png`,
  332. name: "退出登录",
  333. pageUrl: "logout",
  334. show: logoutShow.value,
  335. },
  336. ];
  337. // 根据 show 值过滤
  338. return baseFunctions.filter((func) => func.show);
  339. });
  340. const params = ref({
  341. page: 1,
  342. limit: 10,
  343. });
  344. // 页面加载
  345. onShow(async () => {
  346. if (appStore.isLogin) {
  347. await appStore.USERINFO();
  348. logoutShow.value = true;
  349. wallet.value.balance = appStore.userInfo?.nowMoney || "0.00";
  350. if (appStore.userInfo?.merchant?.id) {
  351. merchantZYShow.value = true;
  352. } else {
  353. merchantZYShow.value = false;
  354. }
  355. if (appStore.merchantId || appStore.userInfo?.merchant?.id) {
  356. lxsjShow.value = true;
  357. } else {
  358. lxsjShow.value = false;
  359. }
  360. } else {
  361. logoutShow.value = false;
  362. }
  363. fetchMetalBalance();
  364. getHistoryList();
  365. });
  366. onLoad(async () => {
  367. await getServiceList();
  368. });
  369. onPageScroll((e) => {
  370. if (e.scrollTop > 0) {
  371. navBgColor.value = "#ffe079";
  372. } else {
  373. navBgColor.value = "rgba(252,255,255,0)";
  374. }
  375. });
  376. const wxConfig = ref({});
  377. const tradeList = ref([]);
  378. const useList = ref([]);
  379. watch(
  380. () => appStore.wxConfig,
  381. (newVal) => {
  382. const configDate = newVal || appStore.$wxConfig;
  383. wxConfig.value = configDate;
  384. const list = JSON.parse(configDate.essentialFunctions);
  385. if (list[0].status == false) {
  386. showIcons.value = false;
  387. } else {
  388. showIcons.value = true;
  389. }
  390. tradeList.value = [list[0], list[1]];
  391. useList.value = [
  392. {
  393. ...list[2],
  394. src: `${HTTP_REQUEST_URL_IMG}setting/mailiao.png`,
  395. },
  396. {
  397. ...list[3],
  398. src: `${HTTP_REQUEST_URL_IMG}setting/mailiao2.png`,
  399. },
  400. {
  401. ...list[4],
  402. src: `${HTTP_REQUEST_URL_IMG}setting/cunliao.png`,
  403. iconName: "存料",
  404. },
  405. {
  406. ...list[5],
  407. src: `${HTTP_REQUEST_URL_IMG}setting/tiliao.png`,
  408. },
  409. ];
  410. console.log(tradeList.value);
  411. },
  412. { deep: true, immediate: true }
  413. );
  414. // 编辑资料
  415. const editProfile = () => {
  416. uni.showToast({
  417. title: "编辑资料",
  418. icon: "none",
  419. });
  420. };
  421. // 开通会员
  422. const openVip = () => {
  423. uni.showToast({
  424. title: "开通会员",
  425. icon: "none",
  426. });
  427. };
  428. // 查看会员权益
  429. const goVIP = () => {
  430. uni.navigateTo({ url: "/pages/users/VIP/VIP" });
  431. };
  432. // 查看交易明细
  433. const viewTransactionDetail = () => {
  434. if (!isLogin) {
  435. toLogin();
  436. } else {
  437. uni.navigateTo({ url: "/pages/users/vault/index" });
  438. }
  439. };
  440. // 充值
  441. const recharge = () => {
  442. if (!isLogin) {
  443. toLogin();
  444. } else {
  445. uni.navigateTo({
  446. url: `/pages/webview/index?path=${"/pages/users/vault/rechargeRmb"}`,
  447. });
  448. }
  449. };
  450. // 提现
  451. const withdraw = () => {
  452. if (!isLogin) {
  453. toLogin();
  454. } else {
  455. uni.navigateTo({
  456. url: `/pages/webview/index?path=${"/pages/users/vault/withdraw"}`,
  457. });
  458. }
  459. };
  460. const goDetail = (url) => {
  461. console.log(url);
  462. const webviewPageUrl = `/pages/webview/index?path=${url}`;
  463. uni.navigateTo({
  464. url: webviewPageUrl,
  465. fail: (err) => {
  466. console.error("跳转到webview页面失败:", err);
  467. uni.showToast({
  468. title: "跳转失败,请重试",
  469. icon: "none",
  470. duration: 1500,
  471. });
  472. },
  473. });
  474. };
  475. function handleLogOut() {
  476. uni.showModal({
  477. title: "提示",
  478. content: "确认退出登录吗?",
  479. success: function (res) {
  480. if (res.confirm) {
  481. // 清除全局定时器
  482. if (getApp().globalData?.messageTimer) {
  483. clearInterval(getApp().globalData.messageTimer);
  484. getApp().globalData.messageTimer = null;
  485. }
  486. appStore.LOGOUT();
  487. uni.reLaunch({ url: "/pages/users/login/index" });
  488. }
  489. },
  490. });
  491. }
  492. // 功能点击
  493. const handleFunctionClick = (item) => {
  494. const url = item.url;
  495. // console.log(url);
  496. if (item.name === "平台客服") return (showCallList.value = true);
  497. if (!url) return;
  498. // 买料、卖料、消费需要通过webview跳转
  499. if (
  500. [
  501. "/pages/users/vault/rechargeGold",
  502. "/pages/users/vault/storeMetal/index",
  503. "/pages/users/vault/storeMetal/order",
  504. ].includes(url)
  505. ) {
  506. const webviewPageUrl = `/pages/webview/index?path=${url}`;
  507. uni.navigateTo({
  508. url: webviewPageUrl,
  509. fail: (err) => {
  510. console.error("跳转到webview页面失败:", err);
  511. uni.showToast({
  512. title: "跳转失败,请重试",
  513. icon: "none",
  514. duration: 1500,
  515. });
  516. },
  517. });
  518. return; // 阻止继续执行后续跳转逻辑
  519. } else if (url === "download") {
  520. uni.setClipboardData({
  521. data: "https://a.app.qq.com/o/simple.jsp?pkgname=uni.app.UNI9DE338F",
  522. showToast: false,
  523. success: function () {
  524. uni.showToast({
  525. title: "下载链接复制成功,请打开内置手机浏览器访问下载。",
  526. icon: "none",
  527. });
  528. console.log("success");
  529. },
  530. });
  531. return;
  532. } else if (url === "logout") {
  533. handleLogOut();
  534. } else {
  535. uni.navigateTo({ url });
  536. }
  537. };
  538. // 获取客服列表
  539. const getServiceList = async (url) => {
  540. const res = await getCustomerServiceList();
  541. callList.value = res.data.list;
  542. };
  543. // 跳转企微客服
  544. const callService = async (item) => {
  545. wx.openCustomerServiceChat({
  546. corpId: item.enterpriseId,
  547. extInfo: {
  548. url: item.serviceLink,
  549. },
  550. });
  551. };
  552. // 查看商家
  553. const viewStore = (store) => {
  554. if (!store.merchantId) {
  555. return;
  556. }
  557. uni.navigateTo({
  558. url: "/pages/merchantCenters/merchant?merchantId=" + store.merchantId,
  559. });
  560. };
  561. // 查看全部订单
  562. const viewAllOrders = () => {
  563. uni.navigateTo({ url: "/pages/order_list/index" });
  564. };
  565. // 查看订单
  566. const viewOrders = (status) => {
  567. uni.navigateTo({ url: "/pages/order_list/index?status=" + status });
  568. };
  569. const navigateTo = (url) => {
  570. if (!url) return;
  571. uni.navigateTo({ url });
  572. };
  573. // 用户面板事件处理
  574. function handleEdit() {
  575. // console.log("编辑资料");
  576. uni.navigateTo({ url: "/pages/users/personal_info/personal_info" });
  577. }
  578. async function fetchMetalBalance() {
  579. // 若appStore.uid为空,则请求失败
  580. if (!appStore?.uid) {
  581. // Toast({ title: "未登录,请前往登录后访问" });
  582. return;
  583. }
  584. const params = { userId: appStore.uid };
  585. const { data } = await getMetalBalance(params);
  586. wallet.value.assets = wallet.value.assets.map((metal) => {
  587. const metalValue = data[metal.type];
  588. return metalValue !== undefined ? { ...metal, balance: metalValue } : metal;
  589. });
  590. }
  591. const getHistoryList = async () => {
  592. const { data } = await footprintList(params.value);
  593. recentStores.value = data.records;
  594. };
  595. </script>
  596. <style scoped lang="scss">
  597. .container {
  598. background-color: #f5f5f5;
  599. min-height: 100vh;
  600. padding-bottom: 30rpx;
  601. }
  602. /* 顶部用户信息 */
  603. .user-header {
  604. height: 600rpx;
  605. background-image: linear-gradient(200deg, #fcd965 0%, #ffffff 90%) !important;
  606. background-size: 100% 100%;
  607. padding: 150rpx 20rpx 20rpx;
  608. color: #fff;
  609. border-radius: 0 0 20rpx 20rpx;
  610. box-sizing: border-box;
  611. }
  612. .user-info {
  613. display: flex;
  614. justify-content: space-between;
  615. align-items: center;
  616. margin-bottom: 30rpx;
  617. }
  618. .user-main {
  619. display: flex;
  620. align-items: center;
  621. }
  622. .avatar {
  623. width: 120rpx;
  624. height: 120rpx;
  625. border-radius: 50%;
  626. background-color: #fff;
  627. margin-right: 30rpx;
  628. }
  629. .name-vip {
  630. display: flex;
  631. align-items: center;
  632. margin-bottom: 16rpx;
  633. }
  634. .name {
  635. font-size: 32rpx;
  636. color: #333;
  637. }
  638. .vip-tag {
  639. width: 100rpx;
  640. margin-left: 16rpx;
  641. }
  642. .vip-expire,
  643. .login-tip {
  644. font-size: 28rpx;
  645. color: #666;
  646. }
  647. .btn-content {
  648. display: flex;
  649. flex-direction: column;
  650. align-items: center;
  651. justify-content: center;
  652. .setting {
  653. width: 40rpx;
  654. height: 40rpx;
  655. }
  656. .btn-text {
  657. font-size: 24rpx;
  658. color: #333;
  659. line-height: 1.5;
  660. }
  661. }
  662. /* 会员开通提示 */
  663. .vip-promote {
  664. height: 108rpx;
  665. width: 100%;
  666. height: 108rpx;
  667. padding: 0 30rpx;
  668. box-sizing: border-box;
  669. .vipBG {
  670. width: 100%;
  671. height: 100%;
  672. border-radius: 48rpx 48rpx 0 0;
  673. }
  674. .vip-text {
  675. margin-top: -108rpx;
  676. display: flex;
  677. width: 100%;
  678. justify-content: space-between;
  679. align-items: center;
  680. padding: 20rpx;
  681. box-sizing: border-box;
  682. .title {
  683. font-size: 28rpx;
  684. color: #bdad8e;
  685. display: flex;
  686. justify-content: flex-start;
  687. align-items: center;
  688. .vipIcon {
  689. width: 70rpx;
  690. height: 60rpx;
  691. margin-right: 10rpx;
  692. }
  693. .bigText {
  694. font-size: 32rpx;
  695. color: #facd8d;
  696. margin: 0 10rpx;
  697. }
  698. }
  699. .open-vip {
  700. width: 144rpx;
  701. height: 60rpx;
  702. line-height: 60rpx;
  703. font-size: 24rpx;
  704. color: #5d3d03;
  705. background: linear-gradient(270deg, #fee2a3 0%, #fdebcc 100%);
  706. border-radius: 16rpx 16rpx 16rpx 16rpx;
  707. .bofang {
  708. width: 24rpx;
  709. height: 24rpx;
  710. margin-left: 10rpx;
  711. }
  712. }
  713. }
  714. }
  715. .desc {
  716. font-size: 22rpx;
  717. opacity: 0.9;
  718. }
  719. /* 钱包余额 */
  720. .wallet-section {
  721. background: #fff;
  722. margin: -190rpx 20rpx 20rpx;
  723. border-radius: 24rpx;
  724. padding: 30rpx;
  725. }
  726. .wallet-header {
  727. display: flex;
  728. justify-content: space-between;
  729. align-items: center;
  730. margin-bottom: 20rpx;
  731. }
  732. .wallet-title {
  733. font-size: 28rpx;
  734. color: #333;
  735. }
  736. .transaction-detail {
  737. color: #666;
  738. font-size: 24rpx;
  739. display: flex;
  740. align-items: center;
  741. }
  742. .balance {
  743. font-size: 48rpx;
  744. font-weight: bold;
  745. text-align: center;
  746. margin: 10rpx 0;
  747. color: #333;
  748. }
  749. .assets {
  750. display: flex;
  751. justify-content: space-between;
  752. align-items: center;
  753. margin-top: 40rpx;
  754. flex-wrap: nowrap; /* 确保不换行 */
  755. }
  756. .asset-container {
  757. display: flex;
  758. align-items: center;
  759. flex: 1;
  760. justify-content: center;
  761. position: relative;
  762. }
  763. .asset-item {
  764. display: flex;
  765. flex-direction: column;
  766. align-items: center;
  767. flex: 1;
  768. padding: 0 20rpx;
  769. }
  770. .asset-name {
  771. font-size: 24rpx;
  772. color: #333;
  773. margin-bottom: 16rpx;
  774. text-align: center;
  775. }
  776. .asset-amount {
  777. font-size: 40rpx;
  778. font-weight: bold;
  779. color: #333;
  780. text-align: center;
  781. }
  782. .wallet-actions {
  783. display: flex;
  784. justify-content: space-between;
  785. margin-top: 50rpx;
  786. }
  787. .wallet-btn {
  788. flex: 1;
  789. text-align: center;
  790. height: 88rpx;
  791. line-height: 88rpx;
  792. margin: 0 10rpx;
  793. border-radius: 16rpx;
  794. font-size: 32rpx;
  795. }
  796. .recharge {
  797. background: #f8c008;
  798. color: #333;
  799. }
  800. .withdraw {
  801. background: rgba(248, 192, 8, 0.1);
  802. color: #333;
  803. }
  804. /* 功能入口 */
  805. .function-grid {
  806. background: #fff;
  807. margin: 30rpx;
  808. border-radius: 24rpx;
  809. padding: 40rpx;
  810. }
  811. .functions {
  812. display: grid;
  813. grid-template-columns: repeat(4, 1fr);
  814. gap: 40rpx;
  815. margin-top: 40rpx;
  816. }
  817. .function-item {
  818. text-align: center;
  819. }
  820. .function-icon {
  821. .img {
  822. width: 60rpx;
  823. height: 60rpx;
  824. }
  825. }
  826. .function-name {
  827. font-size: 24rpx;
  828. color: #333;
  829. }
  830. /* 最近访问 */
  831. .recent-visit,
  832. .order-section,
  833. .common-functions {
  834. background: #fff;
  835. margin: 20rpx;
  836. border-radius: 16rpx;
  837. padding: 30rpx;
  838. }
  839. .section-header {
  840. display: flex;
  841. justify-content: space-between;
  842. align-items: center;
  843. margin-bottom: 30rpx;
  844. }
  845. .section-title {
  846. font-size: 32rpx;
  847. color: #333;
  848. }
  849. .more {
  850. font-size: 24rpx;
  851. color: #666;
  852. }
  853. .store-item {
  854. display: flex;
  855. align-items: center;
  856. justify-content: flex-start;
  857. padding: 20rpx;
  858. border-bottom: 2rpx solid #f0f0f0;
  859. background-color: #f9f7f0;
  860. border-radius: 16rpx;
  861. }
  862. .store-item:last-child {
  863. border-bottom: none;
  864. }
  865. .store-logo {
  866. .img {
  867. width: 100rpx;
  868. height: 100rpx;
  869. border-radius: 16rpx;
  870. margin-right: 30rpx;
  871. }
  872. }
  873. .store-name {
  874. font-size: 32rpx;
  875. color: #333;
  876. margin-bottom: 20rpx;
  877. display: block;
  878. }
  879. .store-desc {
  880. font-size: 24rpx;
  881. color: #666;
  882. display: block;
  883. }
  884. /* 订单状态 */
  885. .order-status {
  886. display: flex;
  887. justify-content: space-between;
  888. }
  889. .status-item {
  890. text-align: center;
  891. flex: 1;
  892. }
  893. .status-icon {
  894. .img {
  895. width: 60rpx;
  896. height: 60rpx;
  897. }
  898. }
  899. .status-name {
  900. font-size: 24rpx;
  901. color: #333;
  902. }
  903. /* 常用功能 */
  904. .common-functions .functions {
  905. grid-template-columns: repeat(4, 1fr);
  906. }
  907. .page-title {
  908. font-size: 36rpx;
  909. color: #333;
  910. }
  911. .callService {
  912. padding: 20px 10px 0px;
  913. // background-color: #ddcca3;
  914. display: flex;
  915. justify-content: center;
  916. flex-direction: column;
  917. font-size: 16px;
  918. margin-bottom: 30rpx;
  919. .list-box {
  920. background: #fff;
  921. border-radius: 20px;
  922. .list-item {
  923. width: 100%;
  924. height: 100rpx;
  925. display: flex;
  926. justify-content: center;
  927. align-items: center;
  928. border-bottom: 1px solid #e1e1e1;
  929. }
  930. }
  931. }
  932. </style>