needcode преди 2 години
родител
ревизия
7bda220bee
променени са 2 файла, в които са добавени 289 реда и са изтрити 33 реда
  1. 16 8
      src/pages/map/index.vue
  2. 273 25
      src/pages/user/index.vue

+ 16 - 8
src/pages/map/index.vue

@@ -70,8 +70,12 @@
         <image src="/static/images/map-location.png" mode="widthFix" />
       </view>
     </view>
-    <view class="dialog" v-if="filterDialog.visible">
-      <view class="filter-dialog">
+    <view
+      class="dialog"
+      v-if="filterDialog.visible"
+      @click="toggleDialogVisible"
+    >
+      <view class="filter-dialog" @click.stop="emptyTap">
         <view :style="filterDialog.style"></view>
         <view class="pl-40 pr-40">
           <view class="pt-20 pb-20">
@@ -125,11 +129,9 @@
     </view>
   </view>
   <view class="login-mask" v-if="!token">
-    <button
-      open-type="getPhoneNumber"
-      bindgetphonenumber="login"
-      class="full"
-    >登陆按钮</button>
+    <button open-type="getPhoneNumber" @getphonenumber="loginMask" class="full">
+      登陆按钮
+    </button>
   </view>
 </template>
 
@@ -148,7 +150,7 @@ const pointSize = {
   androidX: -14,
   androidCurrentX: -20,
 };
-import { onLogin } from "@/api/auth";
+import { fetchToken, login, onLogin } from "@/api/auth";
 import { fetchStations } from "@/api/charge";
 import { fetchCollectList } from "@/api/user";
 import { fetchLocation } from "@/utils/location";
@@ -362,6 +364,8 @@ const refresh = () => {
 };
 
 onLoad((query: any) => {
+  // 只为了打包进tab-bar使用
+  console.log(fetchToken, login, onLogin);
   // 扫普通码
   if (query.q) {
     getApp<any>().globalData.normalCode = decodeURIComponent(query.q); // 获取到二维码原始链接内容
@@ -528,6 +532,10 @@ const search = () => {
     url: "/pages-charge/search/search",
   });
 };
+const loginMask = (e: any) => {
+  login(e);
+};
+const emptyTap = () => {};
 </script>
 
 <style lang="scss">

+ 273 - 25
src/pages/user/index.vue

@@ -1,41 +1,289 @@
 <template>
-  <view class="content">
-    <image class="logo" src="/static/logo.png" />
-    <view class="text-area">
-      <text class="title">{{ title }}</text>
+  <navigation-bar title="个人中心"></navigation-bar>
+
+  <image src="/static/images/user-bg.png" mode="widthFix" class="bg" />
+
+  <block v-if="user && user.phone">
+    <view class="container" :style="containerStyle">
+      <view class="header flex-column">
+        <view class="flex-grow flex-center">
+          <image
+            src="/static/images/user/round.png"
+            mode="heightFix"
+            style="height: 100%"
+          />
+        </view>
+        <view class="main flex-shrink">
+          <view
+            class="avatar"
+            @click="toPage(3)"
+            :style="{
+              'background-image': `url(${user.avatar})`,
+            }"
+          ></view>
+          <view class="phone fs-40 fw-500">{{ user.phone }}</view>
+          <view class="money flex-align-center">
+            <view class="fs-40 fw-500" style="margin-top: 10rpx">¥</view>
+            <view class="fw-500 ml-12" style="font-size: 60rpx">{{
+              user.balance
+            }}</view>
+            <view class="ml-auto" style="width: 140rpx" @click="toPage(0)">
+              <style-button size="small" type="primary" height="70"
+                >充值</style-button
+              >
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <view class="body">
+        <view
+          class="menu flex-align-center"
+          v-for="(item, index) in menu"
+          :key="index"
+          @click="toPage(index)"
+        >
+          <image src="/static/images/user/{{index + 1}}.png"></image>
+          <view>{{ item.title }}</view>
+          <view class="ml-auto">
+            <uni-icons
+              type="right"
+              size="12"
+              color="rgba(0,0,0,0.4)"
+            ></uni-icons>
+          </view>
+        </view>
+      </view>
+    </view>
+  </block>
+
+  <view
+    class="dialog flex-align-end"
+    style="z-index: 999999"
+    v-if="contactDialogVisible"
+    @click="close"
+  >
+    <view class="contact-dialog" @click.stop="emptyTap">
+      <view class="flex-center fs-32 fw-600 pb-40">联系我们</view>
+      <!-- <view class="code" v-if="menu[4].code">
+        <image-proxy
+          style="width: 100%"
+          :src="menu[4].code"
+          mode="widthFix"
+          menu
+        ></image-proxy>
+      </view>
+      <view
+        v-if="menu[4].code"
+        class="fs-22 mt-16"
+        style="color: rgba(0, 0, 0, 0.4)"
+        >长按识别二维码</view
+      > -->
+      <view class="phone flex-align-center flex-between" @click.stop="call">
+        <view class="fs-26 fw-500">联系方式:{{ menu[4].mobile }}</view>
+        <view class="flex-center btn">拨打电话</view>
+      </view>
     </view>
   </view>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
-const title = ref('Hello')
+import { fetchContact } from "@/api";
+import { fetchProfile } from "@/api/user";
+import { onLoad, onShow } from "@dcloudio/uni-app";
+import { ref } from "vue";
+const containerStyle = ref({});
+const user = ref<any>({
+  avatar: "",
+});
+const menu = ref([
+  {
+    title: "我的钱包",
+    path: "/pages-user/wallet/wallet",
+  },
+  {
+    title: "充电订单",
+    path: "/pages-charge/orders/orders",
+  },
+  {
+    title: "我的收藏",
+    path: "/pages-user/collect/collect",
+  },
+  {
+    title: "个人信息",
+    path: "/pages-user/profile/profile",
+  },
+  {
+    title: "联系我们",
+    path: "",
+    code: "",
+    mobile: "",
+  },
+]);
+const contactDialogVisible = ref(false);
+const toPage = (index: number) => {
+  const item = menu.value[index];
+  if (item.mobile) {
+    contactDialogVisible.value = true;
+    return;
+  }
+  uni.navigateTo({
+    url: item.path,
+  });
+};
+const close = () => {
+  contactDialogVisible.value = false;
+}
+const emptyTap = () => {};
+const call = () => {
+  uni.makePhoneCall({
+    phoneNumber: menu.value[4].mobile as string
+  });
+};
+onLoad(() => {
+  const bound = uni.getMenuButtonBoundingClientRect();
+  containerStyle.value = {
+    top: `${bound.bottom + 10}px`,
+  };
+  fetchContact().then((res) => {
+    if (res && res.mobile) {
+      menu.value[4].mobile = res.mobile;
+    }
+    if (res && res.code_url) {
+      menu.value[4].code = res.code_url;
+    }
+  });
+});
+onShow(() => {
+  fetchProfile().then((res) => {
+    res.balance = (Number(res.balance) / 100).toFixed(2);
+    res.avatar = res.avatar
+      ? res.avatar
+      : "https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0";
+    user.value = res;
+  });
+});
 </script>
 
-<style>
-.content {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
+<style lang="scss">
+@import "../../styles/dialog.scss";
+.bg {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 660rpx;
 }
 
-.logo {
-  height: 200rpx;
-  width: 200rpx;
-  margin-top: 200rpx;
-  margin-left: auto;
-  margin-right: auto;
-  margin-bottom: 50rpx;
+.container {
+  position: absolute;
+  left: 0;
+  top: 0;
+  height: 100vh;
+  width: 100%;
+  overflow-y: auto;
 }
 
-.text-area {
-  display: flex;
-  justify-content: center;
+.header {
+  height: 400rpx;
+  width: 100%;
+
+  .main {
+    height: 334rpx;
+    background: rgba(254, 255, 255, 0.7);
+    border-radius: 40rpx 40rpx 0 0;
+    position: relative;
+    text-align: center;
+
+    .avatar {
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+      top: -50rpx;
+      width: 110rpx;
+      height: 110rpx;
+      border: 2rpx solid #ffffff;
+      filter: drop-shadow(0px 4rpx 8rpx rgba(0, 24, 60, 0.1));
+      background-size: cover;
+      background-repeat: no-repeat;
+      border-radius: 50%;
+    }
+
+    .phone {
+      padding-top: 78rpx;
+      color: #000;
+    }
+
+    .money {
+      width: 690rpx;
+      height: 118rpx;
+      background: #feffff;
+      border-radius: 120rpx;
+      margin: 0 auto;
+      margin-top: 30rpx;
+      color: #000000;
+      padding: 0 24rpx 0 40rpx;
+    }
+  }
 }
 
-.title {
-  font-size: 36rpx;
-  color: #8f8f94;
+.body {
+  width: 100%;
+  background-color: #fff;
+  padding: 0rpx 30rpx;
+
+  .menu {
+    background-color: #fff;
+    height: 120rpx;
+    border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
+
+    image {
+      width: 52rpx;
+      height: 52rpx;
+      margin-right: 20rpx;
+    }
+
+    &:last-child {
+      border-bottom: none;
+    }
+  }
+}
+
+.contact-dialog {
+  width: 100%;
+  padding: 40rpx 30rpx 70rpx 30rpx;
+  padding-bottom: 70rpx;
+  background-color: #fff;
+  border-radius: 40rpx 40rpx 0rpx 0rpx;
+  text-align: center;
+
+  .icon {
+    width: 52rpx;
+  }
+
+  .code {
+    width: 320rpx;
+    min-height: 320rpx;
+    margin: 0 auto;
+    margin-bottom: 40rpx;
+  }
+
+  .phone {
+    height: 76rpx;
+    background: var(--color-sec);
+    border-radius: 76rpx;
+    padding: 0 30rpx;
+  }
+
+  .btn {
+    width: 144rpx;
+    height: 56rpx;
+    background: #ffffff;
+    border: 1rpx solid var(--color-primary);
+    border-radius: 56rpx;
+    font-size: 26rpx;
+    line-height: 56rpx;
+    color: var(--color-primary);
+  }
 }
 </style>