personalCenter.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. <template>
  2. <view class="app-container">
  3. <view class="container-mine">
  4. <uv-navbar
  5. title="个人中心"
  6. placeholder
  7. :bgColor="tabBg"
  8. leftIconSize="0"
  9. titleStyle="font-weight: 700;"
  10. />
  11. <view class="mine-top u-flex-center-sb">
  12. <view
  13. class="mine-top-user u-flex-center"
  14. @click.stop="goJump('/pages/setup/edit', true)"
  15. >
  16. <!-- src="/personalCenter/avatar.png" -->
  17. <image
  18. v-if="userInformation && userInformation.headPhoto"
  19. :src="userInformation.headPhoto"
  20. alt=""
  21. class="top-user-avatar"
  22. />
  23. <image
  24. class="top-user-avatar"
  25. v-else
  26. :src="$defaultAvatar"
  27. mode=""
  28. ></image>
  29. <view class="top-user-info" v-if="userInformation.id">
  30. <view class="top-user-name">{{ userInformation.nickname }}</view>
  31. <view class="top-user-phone u-flex-center">
  32. <image
  33. class="top-user-phone-img"
  34. :src="$handleImageUrl('/personalCenter/icon_phone.png')"
  35. alt=""
  36. />
  37. <text>{{ userInformation.mobile }}</text>
  38. </view>
  39. </view>
  40. <view class="top-user-info" v-else>
  41. <view class="top-user-name">登录/注册</view>
  42. </view>
  43. </view>
  44. <view
  45. class="mine-top-QRcode"
  46. v-if="userInformation.id"
  47. @click="showMembershipCode"
  48. >
  49. <image
  50. :src="$handleImageUrl('/personalCenter/icon_QR.png')"
  51. alt=""
  52. class="top-QRcode-img"
  53. />
  54. <view class="top-QRcode-text">会员码</view>
  55. </view>
  56. </view>
  57. <view class="mine-content">
  58. <view class="mine-content-item u-flex-center-sb">
  59. <view class="mine-content-item-view" @click="goToMyWallet">
  60. <image
  61. :src="$handleImageUrl('/personalCenter/bg_icon2.png')"
  62. alt=""
  63. class="mine-content-item-img"
  64. />
  65. <view class="mine-content-item-view">
  66. <view class="mine-content-item-title">我的余额</view>
  67. <view class="mine-content-item-value">{{
  68. $addDecimals(userInformation.balance || 0, 2)
  69. }}</view>
  70. <view class="mine-content-item-unit">元</view>
  71. </view>
  72. </view>
  73. <view class="mine-content-item-view" @click="goMypoints">
  74. <image
  75. :src="$handleImageUrl('/personalCenter/bg_icon1.png')"
  76. alt=""
  77. class="mine-content-item-img"
  78. />
  79. <view class="mine-content-item-view">
  80. <view class="mine-content-item-title">我的积分</view>
  81. <view class="mine-content-item-value">{{
  82. integralAble || 0
  83. }}</view>
  84. <view class="mine-content-item-unit">积分</view>
  85. </view>
  86. </view>
  87. </view>
  88. <view class="mine-content-order">
  89. <view class="mine-content-order-title">我的订单</view>
  90. <view class="mine-content-order-list">
  91. <view
  92. class="mine-content-order-item"
  93. @click.stop="goJump('/pages/order/mallOrder/orderList', true)"
  94. >
  95. <image
  96. class="mine-content-order-item-img1"
  97. :src="$handleImageUrl('/personalCenter/icon_mall.png')"
  98. alt=""
  99. />
  100. <view class="mine-content-order-item-title">商城订单</view>
  101. </view>
  102. <!-- <view class="order-item-line"> </view>
  103. <view
  104. class="mine-content-order-item"
  105. @click.stop="goJump('/pages/order/onlineOrder/list', true)"
  106. >
  107. <image
  108. class="mine-content-order-item-img1"
  109. :src="$handleImageUrl('/personalCenter/icon_online.png')"
  110. alt=""
  111. />
  112. <view class="mine-content-order-item-title">在线订单</view>
  113. </view>
  114. <view class="order-item-line"> </view>
  115. <view
  116. class="mine-content-order-item"
  117. @click.stop="goJump('/pages/order/queuingOrders/list', true)"
  118. >
  119. <image
  120. class="mine-content-order-item-img2"
  121. :src="$handleImageUrl('/personalCenter/icon_queue.png')"
  122. alt=""
  123. />
  124. <view class="mine-content-order-item-title">排队订单</view>
  125. </view> -->
  126. </view>
  127. </view>
  128. </view>
  129. <view class="app-center">
  130. <view class="app-center-title">
  131. <text>应用中心</text>
  132. </view>
  133. <view class="app-center-list">
  134. <view
  135. class="app-center-item"
  136. v-for="(item, index) in toolsList"
  137. :key="index"
  138. @click.stop="goSublevelPage(item)"
  139. >
  140. <template v-if="item.key == 'kf'">
  141. <!-- #ifdef MP-WEIXIN -->
  142. <button open-type="contact" class="app-center-item-button">
  143. <image
  144. :src="$handleImageUrl(item.icon)"
  145. alt=""
  146. class="app-center-item-img"
  147. />
  148. <view class="app-center-item-text">{{ item.label }}</view>
  149. </button>
  150. <!-- #endif -->
  151. <!-- #ifndef MP-WEIXIN -->
  152. <image
  153. :src="$handleImageUrl(item.icon)"
  154. alt=""
  155. class="app-center-item-img"
  156. />
  157. <view class="app-center-item-text">{{ item.label }}</view>
  158. <!-- #endif -->
  159. </template>
  160. <template v-else>
  161. <image
  162. :src="$handleImageUrl(item.icon)"
  163. alt=""
  164. class="app-center-item-img"
  165. />
  166. <view class="app-center-item-text">{{ item.label }}</view>
  167. </template>
  168. </view>
  169. </view>
  170. </view>
  171. <!-- 商家工作台 -->
  172. <image
  173. v-if="shopInfo.businessId && shopInfo.shelvedStatus"
  174. @click.stop="
  175. goSublevelPage({
  176. url: '/pages/shop/content/index',
  177. idNeedLogin: true,
  178. })
  179. "
  180. :src="$handleImageUrl('/personalCenter/img_workbench.png')"
  181. class="workbench"
  182. alt=""
  183. />
  184. </view>
  185. <!-- 会员码 -->
  186. <membershipCode ref="membershipCodeRef" />
  187. </view>
  188. </template>
  189. <script setup>
  190. import { ref } from "vue";
  191. import {
  192. onLoad,
  193. onShow,
  194. onPullDownRefresh,
  195. onPageScroll,
  196. } from "@dcloudio/uni-app";
  197. import { userInfo } from "@/api/login.js";
  198. import {
  199. messageUnreadNum_Api,
  200. totalIntegral_Api,
  201. businessUserInfo_Api,
  202. } from "@/api/userInfo.js";
  203. import utils from "@/util/index.js";
  204. const membershipCodeRef = ref(null);
  205. const userInformation = ref({});
  206. const myMsg = ref(0);
  207. const shopInfo = ref({}); // 商家信息
  208. const integralAble = ref(0); // 用户积分数据
  209. const toolsList = ref([
  210. {
  211. label: "收货地址",
  212. icon: "/personalCenter/app_icon1.png",
  213. url: "/pages/user/address/addressList?formType=mine",
  214. idNeedLogin: true,
  215. isPage: true,
  216. },
  217. {
  218. label: "个人信息",
  219. icon: "/personalCenter/app_icon2.png",
  220. url: "/pages/setup/edit",
  221. idNeedLogin: true,
  222. isPage: true,
  223. },
  224. {
  225. label: "我的优惠券",
  226. icon: "/personalCenter/app_icon3.png",
  227. url: "/pages/couponCenter/index?isMyCoupon=true",
  228. idNeedLogin: true,
  229. isPage: true,
  230. },
  231. {
  232. label: "优惠券中心",
  233. icon: "/personalCenter/app_icon12.png",
  234. url: "/pages/couponCenter/index",
  235. idNeedLogin: true,
  236. isPage: true,
  237. },
  238. {
  239. label: "我的收藏",
  240. icon: "/personalCenter/app_icon4.png",
  241. url: "/pages/user/collection",
  242. idNeedLogin: true,
  243. isPage: true,
  244. },
  245. {
  246. label: "商家入驻",
  247. icon: "/personalCenter/app_icon5.png",
  248. url: "/pages/user/merchant/settleIn?type=tenants_agreement",
  249. idNeedLogin: true,
  250. isPage: true,
  251. },
  252. // {
  253. // label: "代理中心",
  254. // icon: "/personalCenter/app_icon6.png",
  255. // url: "/pages/agencyCenter/index",
  256. // idNeedLogin: true,
  257. // isPage: true,
  258. // isAgent: true, // 是否为代理商才显示
  259. // },
  260. {
  261. label: "官方客服",
  262. icon: "/personalCenter/app_icon7.png",
  263. url: "",
  264. key: "kf",
  265. idNeedLogin: false,
  266. isPage: false,
  267. },
  268. {
  269. label: "常见问题",
  270. icon: "/personalCenter/app_icon8.png",
  271. url: "/pages/user/faq",
  272. idNeedLogin: false,
  273. isPage: true,
  274. },
  275. {
  276. label: "消息通知",
  277. icon: "/personalCenter/app_icon9.png",
  278. url: "/pages/user/myMsg",
  279. idNeedLogin: true,
  280. isPage: true,
  281. },
  282. {
  283. label: "投诉建议",
  284. icon: "/personalCenter/app_icon10.png",
  285. url: "/pages/set/feedback/index",
  286. idNeedLogin: true,
  287. isPage: true,
  288. },
  289. {
  290. label: "设置",
  291. icon: "/personalCenter/app_icon11.png",
  292. url: "/pages/set/index",
  293. idNeedLogin: true,
  294. isPage: true,
  295. },
  296. ]);
  297. const isSign = ref(false);
  298. const tabBg = ref("none");
  299. onPageScroll((e) => {
  300. // console.log(e.scrollTop)
  301. if (e.scrollTop > 10) {
  302. tabBg.value = "#ffffff";
  303. } else {
  304. tabBg.value = "none";
  305. }
  306. });
  307. // 获取商家信息
  308. const getbusinessUserInfo = () => {
  309. businessUserInfo_Api().then((res) => {
  310. if (res && res.code == 200) {
  311. shopInfo.value = res.data || {};
  312. }
  313. });
  314. };
  315. // 跳转我的积分
  316. function goMypoints() {
  317. if (!utils.isLoginTo(true)) {
  318. uni.navigateTo({
  319. url: "/pages/user/pointsList",
  320. });
  321. }
  322. }
  323. async function getAll() {
  324. await judgeLogin(); //判断是否登录
  325. if (utils.isLoginTo(true)) {
  326. getTotalIntegral();
  327. getbusinessUserInfo();
  328. await getUnreadNum(); //未读消息
  329. await getMyStatistics(); //登录消息
  330. uni.$forceUpdate();
  331. }
  332. }
  333. //获取未读消息
  334. function getUnreadNum() {
  335. messageUnreadNum_Api()
  336. .then((res) => {
  337. uni.stopPullDownRefresh();
  338. if (res && res.code == 200) {
  339. myMsg.value = res.data || 0;
  340. } else {
  341. myMsg.value = 0;
  342. }
  343. })
  344. .catch((err) => {
  345. myMsg.value = 0;
  346. });
  347. }
  348. //前往我的钱包
  349. function goToMyWallet() {
  350. if (utils.isLoginTo(true)) return;
  351. uni.navigateTo({
  352. url: "/pages/user/wallet/index",
  353. });
  354. }
  355. //判断是否登录
  356. async function judgeLogin() {
  357. // if (shop) {
  358. // return;
  359. userInfo().then((res) => {
  360. uni.stopPullDownRefresh();
  361. if (res && res.code == 200) {
  362. userInformation.value = res.data;
  363. isSign.value = res.data.sign_in;
  364. uni.setStorageSync("personal", res.data);
  365. }
  366. });
  367. }
  368. // 跳转子级页面
  369. const goSublevelPage = (item) => {
  370. if (item.idNeedLogin) {
  371. let url = item.url;
  372. if (item.isAgent && !userInformation.value.isAgent) {
  373. url = "/pages/agencyCenter/regionalAgent";
  374. }
  375. if (!utils.isLoginTo()) {
  376. uni.navigateTo({
  377. url,
  378. });
  379. } else {
  380. uni.$uv.toast("请先登录");
  381. }
  382. } else {
  383. if (item.key == "kf") {
  384. customerService();
  385. } else {
  386. uni.navigateTo({
  387. url: item.url,
  388. });
  389. }
  390. }
  391. };
  392. // 跳转页面
  393. const goJump = (url = "", isLogin = false) => {
  394. console.log("goJump", url, isLogin);
  395. if (!url) return;
  396. if (isLogin && utils.isLoginTo(isLogin)) return;
  397. uni.navigateTo({
  398. url,
  399. });
  400. };
  401. // 查询总积分
  402. const getTotalIntegral = () => {
  403. totalIntegral_Api().then((res) => {
  404. // console.log(res)
  405. if (res.code == 200) {
  406. integralAble.value = res.data || 0;
  407. }
  408. });
  409. };
  410. // 显示会员码
  411. const showMembershipCode = () => {
  412. membershipCodeRef.value.open();
  413. };
  414. // 客服
  415. const customerService = () => {
  416. // #ifdef APP-PLUS
  417. let sweixin;
  418. plus.share.getServices(
  419. (res) => {
  420. sweixin = res.find((i) => i.id === "weixin");
  421. if (sweixin) {
  422. sweixin.openCustomerServiceChat(
  423. {
  424. corpid: "wxf4cb2367022f4941",
  425. url: "https://work.weixin.qq.com/kfid/kfcfa748e7c99d682b8",
  426. },
  427. (suc) => {
  428. console.log("success", JSON.stringify(suc));
  429. },
  430. (err) => {
  431. console.log("error", JSON.stringify(err));
  432. }
  433. );
  434. } else {
  435. plus.nativeUI.alert("当前环境不支持微信操作!");
  436. }
  437. },
  438. function (e) {
  439. uni.showToast({
  440. title: "获取服务失败,不支持该操作。" + JSON.stringify(e),
  441. icon: "error",
  442. });
  443. }
  444. );
  445. // #endif
  446. };
  447. onLoad(() => {});
  448. //清空数据
  449. //显示弹出框
  450. onShow(async () => {
  451. let token = uni.getStorageSync("apiToken");
  452. if (token) {
  453. getTotalIntegral();
  454. getbusinessUserInfo();
  455. await judgeLogin()
  456. .then((res) => {
  457. // console.log('judgeLogin = res', res)
  458. })
  459. .catch((err) => {});
  460. await getUnreadNum();
  461. } else {
  462. integralAble.value = 0;
  463. shopInfo.value = {};
  464. myMsg.value = 0;
  465. userInformation.value = {};
  466. isSign.value = false;
  467. // uni.setStorageSync("personal", '');
  468. }
  469. });
  470. onPullDownRefresh(() => {
  471. let token = uni.getStorageSync("apiToken");
  472. if (!token) {
  473. uni.stopPullDownRefresh();
  474. } else {
  475. getAll();
  476. }
  477. });
  478. </script>
  479. <style scoped lang="scss">
  480. .app-container {
  481. background-color: #f7f8fa;
  482. }
  483. .container-mine {
  484. min-height: 100vh;
  485. box-sizing: border-box;
  486. padding: 23rpx;
  487. // background: url("/personalCenter/bg_icon.png");
  488. // 背景图片
  489. background: url("http://sly2020.oss-cn-beijing.aliyuncs.com/2025/11/25/040000f4d9254462bd559f27181bb7db.png");
  490. background-size: 100% 742rpx;
  491. background-repeat: no-repeat;
  492. .mine-top {
  493. padding-right: 60rpx;
  494. .mine-top-user {
  495. flex: 1;
  496. .top-user-avatar {
  497. width: 140rpx;
  498. height: 140rpx;
  499. border: 4rpx solid #ffffff;
  500. border-radius: 50%;
  501. flex-shrink: 0;
  502. }
  503. .top-user-info {
  504. margin-left: 20rpx;
  505. flex: 1;
  506. .top-user-name {
  507. font-size: 50rpx;
  508. color: #1a1a1a;
  509. font-weight: 700;
  510. }
  511. .top-user-phone {
  512. margin-top: 10rpx;
  513. .top-user-phone-img {
  514. width: 26rpx;
  515. height: 26rpx;
  516. }
  517. text {
  518. font-size: 28rpx;
  519. color: #1a1a1a;
  520. }
  521. }
  522. }
  523. }
  524. .mine-top-QRcode {
  525. flex-shrink: 0;
  526. margin-left: 20rpx;
  527. text-align: center;
  528. .top-QRcode-img {
  529. width: 57rpx;
  530. height: 57rpx;
  531. border-radius: 10rpx;
  532. margin: 0;
  533. }
  534. .top-QRcode-text {
  535. font-size: 24rpx;
  536. color: #1a1a1a;
  537. // margin-top: 10rpx;
  538. }
  539. }
  540. }
  541. .mine-content {
  542. margin-top: 30rpx;
  543. min-height: 447rpx;
  544. // opacity: 0.71;
  545. background: linear-gradient(180deg, #ffd0cc, #fbf3f3);
  546. border-radius: 20rpx;
  547. padding: 30rpx 24rpx;
  548. box-sizing: border-box;
  549. .mine-content-item {
  550. // background: #ffffff;
  551. border-radius: 20px;
  552. .mine-content-item-view {
  553. position: relative;
  554. width: 318rpx;
  555. height: 180rpx;
  556. .mine-content-item-img {
  557. position: absolute;
  558. left: 0;
  559. top: 0;
  560. width: 318rpx;
  561. height: 180rpx;
  562. z-index: 1;
  563. }
  564. .mine-content-item-view {
  565. position: relative;
  566. z-index: 2;
  567. display: flex;
  568. flex-direction: column;
  569. // align-items: center;
  570. justify-content: space-between;
  571. padding: 10rpx 20rpx 14rpx 20rpx;
  572. box-sizing: border-box;
  573. .mine-content-item-title {
  574. font-size: 30rpx;
  575. font-weight: 700;
  576. color: #1a1a1a;
  577. }
  578. .mine-content-item-value {
  579. font-size: 40rpx;
  580. font-weight: normal;
  581. color: #da4f4f;
  582. }
  583. .mine-content-item-unit {
  584. font-size: 28rpx;
  585. color: #666666;
  586. }
  587. }
  588. }
  589. }
  590. .mine-content-order {
  591. margin-top: 40rpx;
  592. .mine-content-order-title {
  593. font-size: 30rpx;
  594. font-weight: 600;
  595. color: #1a1a1a;
  596. margin-bottom: 15rpx;
  597. }
  598. .mine-content-order-list {
  599. display: flex;
  600. justify-content: space-around;
  601. align-items: center;
  602. .order-item-line {
  603. width: 1rpx;
  604. height: 85rpx;
  605. background: #e1d7d7;
  606. }
  607. .mine-content-order-item {
  608. text-align: center;
  609. .mine-content-order-item-img1 {
  610. width: 60rpx;
  611. height: 58rpx;
  612. }
  613. .mine-content-order-item-img2 {
  614. width: 48rpx;
  615. height: 58rpx;
  616. }
  617. .mine-content-order-item-title {
  618. margin-top: 13rpx;
  619. font-size: 24rpx;
  620. font-weight: 400;
  621. color: #1a1a1a;
  622. }
  623. }
  624. }
  625. }
  626. }
  627. .app-center {
  628. margin-top: 30rpx;
  629. padding: 38rpx 24rpx 12rpx 24rpx;
  630. box-sizing: border-box;
  631. min-height: 468rpx;
  632. background: #ffffff;
  633. border-radius: 20rpx;
  634. .app-center-title {
  635. font-size: 30rpx;
  636. font-weight: 600;
  637. color: #1a1a1a;
  638. margin-bottom: 34rpx;
  639. }
  640. .app-center-list {
  641. display: grid;
  642. grid-template-columns: repeat(4, 1fr);
  643. /* 创建4列,每列占据可用空间 */
  644. gap: 10rpx;
  645. /* 可选,设置网格之间的间隔 */
  646. text-align: center;
  647. .app-center-item-button {
  648. line-height: initial;
  649. background-color: #ffffff !important;
  650. border: 1rpx solid #ffffff !important;
  651. padding: 0;
  652. &:after {
  653. border: none !important;
  654. }
  655. }
  656. .app-center-item-img {
  657. width: 47rpx;
  658. height: 47rpx;
  659. }
  660. .app-center-item-text {
  661. font-size: 26rpx;
  662. font-weight: 400;
  663. color: #1a1a1a;
  664. margin-top: 10rpx;
  665. margin-bottom: 26rpx;
  666. }
  667. }
  668. }
  669. .workbench {
  670. width: 704rpx;
  671. height: 197rpx;
  672. border-radius: 20rpx;
  673. margin-top: 30rpx;
  674. }
  675. }
  676. </style>