index.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <template>
  2. <uv-navbar leftIcon="" title="我的" bg-color="#C6171E"></uv-navbar>
  3. <view class="w100 bg" style="background-color:#C6171E "></view>
  4. <!-- <image src="/static/user/user-bg.png" mode="widthFix" class="bg"/>-->
  5. <block>
  6. <view class="container" :style="containerStyle">
  7. <view class="header flex-column">
  8. <view class="flex-grow flex-center">
  9. <image
  10. src="/static/user/round.png"
  11. mode="heightFix"
  12. style="width: 12orpx;height: 120rpx"/>
  13. </view>
  14. <view class="main flex-shrink">
  15. <image
  16. class="avatar"
  17. src='/static/iconfont/me.svg'>
  18. </image>
  19. <view class="phone fs-40 fw-500">{{ user.mobilePhone }}</view>
  20. <view class="money" @click="toPage({path: '/pages-user/wallet/index'})">
  21. <view class="money-left">
  22. <image src="/static/iconfont/chongzhi.svg" mode="widthFit" style="width: 40rpx;height: 40rpx"></image>
  23. <!-- <uv-icon name="red-packet" size="24" color="#C6171E"></uv-icon>-->
  24. <view style="font-size: 16px;margin-left: 10rpx;">钱包 | 充值</view>
  25. </view>
  26. <view class="money-right">
  27. <view class="money-right_balance">¥ {{ ((user.balance || 0) / 100).toFixed(2) }}</view>
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. <view class="body">
  33. <block v-for="(item, index) in menu" :key="index">
  34. <view
  35. class="menu-item"
  36. @click="toPage(item)">
  37. <view class="menu-item_left">
  38. <image :src="item.icon"></image>
  39. <view class="menu-item_left-title">{{ item.title }}</view>
  40. </view>
  41. <view class="menu-item_right">
  42. <uv-icon name="arrow-right" size="16"></uv-icon>
  43. </view>
  44. </view>
  45. </block>
  46. <view class="logout-btn" v-if="isLogin">
  47. <view class="mt20 logout-btn-wrap" type="error" @click="logoutUser">退出登录</view>
  48. </view>
  49. </view>
  50. </view>
  51. </block>
  52. <cover-view class="login_bar" v-if="!isLogin">
  53. <login-bar class="w100 text-center"></login-bar>
  54. </cover-view>
  55. <!-- <view class="logout-btn">
  56. <uv-button :custom-style="customStyle" type="error" @click="logoutUser">退出登录</uv-button>
  57. </view>-->
  58. <tab-bar :index="2"/>
  59. </template>
  60. <script setup lang="ts">
  61. import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
  62. import {computed, ref} from "vue";
  63. import TabBar from "@/components/tab-bar/index.vue";
  64. import LoginBar from "@/components/login-bar/index.vue";
  65. import {checkLogin, clearToken} from "@/utils/auth"
  66. import {get} from "@/utils/https";
  67. import {getServicePhone} from "@/utils/common";
  68. const containerStyle = ref({});
  69. const user = ref<any>({
  70. id: 0,
  71. avatar: "",
  72. mobilePhoneFormat: '',
  73. balance: 0,
  74. });
  75. const isLogin = ref(false)
  76. const service = ref("15012341234");
  77. const menu = ref([
  78. {
  79. title: "绑定车辆",
  80. path: "/pages-user/profile/index",
  81. icon: '/static/user/profile.png'
  82. },
  83. /* {
  84. title: "我的卡包",
  85. path: "/pages/coupon/index",
  86. icon: '/static/user/coupon.png'
  87. },*/
  88. {
  89. title: "我的订单",
  90. path: "/pages-order/list/index",
  91. icon: '/static/user/faq.png'
  92. },
  93. /* {
  94. title: "我的收藏",
  95. path: "/pages-user/fav/index",
  96. icon: '/static/user/fav.png'
  97. },*/
  98. {
  99. title: "联系我们",
  100. path: "/pages-user/contact/index",
  101. icon: '/static/user/contact.png'
  102. },
  103. {
  104. title: "洗车指导",
  105. path: "/pages-user/faq/index",
  106. icon: '/static/iconfont/default/guide.svg'
  107. },
  108. {
  109. title: "纠错上报",
  110. path: "/pages-user/feedback/index",
  111. icon: '/static/user/feedback.png'
  112. },
  113. ]);
  114. const toPage = (item: any) => {
  115. checkLogin().then(() => {
  116. let {title, path} = item;
  117. let servicePhone = getServicePhone();
  118. if (path.includes('contact')) {
  119. uni.makePhoneCall({
  120. phoneNumber: servicePhone,
  121. fail: (error) => {
  122. console.log(error)
  123. }
  124. });
  125. return;
  126. }
  127. uni.navigateTo({
  128. url: item.path,
  129. });
  130. })
  131. };
  132. const loginListen = () => {
  133. }
  134. const logoutUser = () => {
  135. uni.showModal({
  136. title: "温馨提示",
  137. content: "确定退出登录吗?",
  138. confirmColor: "#2d9e95",
  139. confirmText: "确定退出",
  140. cancelText: "手滑了",
  141. success: (res) => {
  142. if (res.confirm) {
  143. uni.showLoading({
  144. title: "退出中",
  145. });
  146. get(`/user/logout`).then(() => {
  147. uni.hideLoading();
  148. uni.showToast({
  149. icon: "success",
  150. title: "已退出",
  151. });
  152. getApp<any>().globalData.manualLogout = true;
  153. clearToken();
  154. setTimeout(() => {
  155. uni.exitMiniProgram()
  156. }, 1500);
  157. })
  158. }
  159. },
  160. });
  161. };
  162. onLoad(() => {
  163. uni.setNavigationBarTitle({title: '个人中心'})
  164. const bound = uni.getMenuButtonBoundingClientRect();
  165. containerStyle.value = {
  166. top: `${bound.bottom + 10}px`,
  167. };
  168. });
  169. const addListener = () => {
  170. uni.$on('login', function (data) {
  171. isLogin.value = data.isLogin;
  172. console.log("event>>>", data)
  173. if (data.isLogin) {
  174. user.value = getApp<any>().globalData.user;
  175. console.log("event1111>>>", user.value)
  176. }
  177. })
  178. uni.$on('logout', function (data) {
  179. isLogin.value = false;
  180. user.value = {}
  181. })
  182. }
  183. const removeListener = () => {
  184. uni.$off('logout');
  185. uni.$off('login');
  186. }
  187. onShow(() => {
  188. const userData = getApp<any>().globalData.user;
  189. if (userData && userData.id) {
  190. isLogin.value = true;
  191. user.value = userData;
  192. }
  193. // loginListen();
  194. addListener();
  195. });
  196. onHide(()=>{
  197. removeListener();
  198. })
  199. </script>
  200. <style lang="scss" scope>
  201. page{
  202. background-color: #fafafa;
  203. }
  204. .bg {
  205. position: absolute;
  206. left: 0;
  207. top: 0;
  208. width: 100%;
  209. height: 460rpx;
  210. }
  211. .container {
  212. position: absolute;
  213. left: 0;
  214. top: 0;
  215. height: 100vh;
  216. width: 100%;
  217. overflow-y: auto;
  218. }
  219. .header {
  220. //height: 400rpx;
  221. width: 100%;
  222. .main {
  223. //height: 234rpx;
  224. padding: 60rpx auto;
  225. background: rgba(254, 255, 255, 0.7);
  226. border-radius: 40rpx 40rpx 0 0;
  227. position: relative;
  228. text-align: center;
  229. .avatar {
  230. position: absolute;
  231. left: 50%;
  232. transform: translateX(-50%);
  233. top: -90rpx;
  234. width: 110rpx;
  235. height: 110rpx;
  236. border: 2rpx solid #ffffff;
  237. filter: drop-shadow(0px 4rpx 8rpx rgba(0, 24, 60, 0.1));
  238. background-size: cover;
  239. background-repeat: no-repeat;
  240. border-radius: 50%;
  241. }
  242. .phone {
  243. padding-top: 78rpx;
  244. color: #000;
  245. }
  246. .money {
  247. //position: absolute;
  248. //left: 0;
  249. //bottom: 0;
  250. width: 600rpx;
  251. //height: 98rpx;
  252. background: #feffff;
  253. border-radius: 120rpx;
  254. margin: 0 auto;
  255. margin-top: 60rpx;
  256. color: #000000;
  257. padding: 40rpx;
  258. display: flex;
  259. align-content: center;
  260. align-items: center;
  261. justify-content: space-between;
  262. &-left {
  263. color: $uni-color-primary;
  264. display: inline-flex;
  265. align-items: flex-end;
  266. }
  267. &-right {
  268. color: $uni-color-primary;
  269. display: inline-flex;
  270. align-items: flex-end;
  271. &_balance {
  272. font-weight: 600;
  273. font-size: 20px;
  274. margin-right: 10px;
  275. }
  276. }
  277. }
  278. }
  279. }
  280. .body {
  281. width: 100%;
  282. background-color: #fff;
  283. //border-top: 1px solid $uni-color-primary;
  284. //padding: 0rpx 30rpx;
  285. .menu-item {
  286. display: inline-flex;
  287. justify-content: space-between;
  288. background-color: #fff;
  289. height: 90rpx;
  290. border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
  291. align-items: center;
  292. width: 100%;
  293. &_left {
  294. display: flex;
  295. align-items: center;
  296. align-content: center;
  297. margin-left: 20rpx;
  298. image {
  299. width: 42rpx;
  300. height: 42rpx;
  301. margin-right: 20rpx;
  302. }
  303. &-title {
  304. font-size: 13px;
  305. }
  306. }
  307. &_right {
  308. text-align: right;
  309. width: 60rpx;
  310. }
  311. &:last-child {
  312. border-bottom: none;
  313. }
  314. }
  315. }
  316. .logout-btn {
  317. width: calc(100vw - 60rpx);
  318. margin: 60rpx auto;
  319. &-wrap{
  320. height: 80rpx;
  321. font-size: 28rpx;
  322. margin: 20px auto;
  323. width: 540rpx;
  324. text-align: center;
  325. background: #dd524d;
  326. color: white;
  327. border-radius: 10rpx;
  328. display: flex;
  329. align-items: center;
  330. align-content: center;
  331. justify-content: center;
  332. }
  333. }
  334. </style>