Преглед изворни кода

tabbar feeback profile map

zuy пре 1 година
родитељ
комит
c46805b2f5

+ 27 - 31
src/App.vue

@@ -1,34 +1,30 @@
-<script setup lang="ts">
-import {onHide, onLaunch, onShow} from "@dcloudio/uni-app";
-
-/*const {ctx} = getCurrentInstance();
-onReady(() => {
-  ctx.$uv.getRect('.demo').then(res => {
-    console.log(res)
-  })
-})
-console.log(uni.$uv.os())*/
-
-const globalData = {
-  device: {},
-  token: "",
-  userInfo: {}
-}
-
-onLaunch(() => {
-  console.log("App Launch");
-  uni.getSystemInfo({
-    success: (res) => {
-      globalData.device = res;
-    },
-  });
-});
-onShow(() => {
-  console.log("App Show");
-});
-onHide(() => {
-  console.log("App Hide");
-});
+<script lang="ts">
+import { fetchToken } from "./utils/auth";
+export default <any>{
+  globalData: {
+    token: "",
+    lastData: {},
+    stations: [],
+    normalCode: "",
+  },
+  onLaunch() {
+    uni.getSystemInfo({
+      success: (res) => {
+        this.globalData.device = res;
+      },
+    });
+    return fetchToken().then((cache) => {
+      if (cache) {
+        this.globalData.token = cache;
+      }
+    });
+  },
+  onPageNotFound() {
+    uni.switchTab({
+      url: "/pages/map/map",
+    });
+  },
+};
 </script>
 </script>
 <style lang="scss">
 <style lang="scss">
 @import '@climblee/uv-ui/index.scss';
 @import '@climblee/uv-ui/index.scss';

+ 34 - 8
src/components/tab-bar/index.vue

@@ -1,17 +1,37 @@
 <template>
 <template>
-  <uv-tabbar :value="value" @change="index=>value = index" :border="false" :fixed="true">
-    <uv-tabbar-item text="首页" icon="home" @tap.stop="handleTabbarClick('index')"></uv-tabbar-item>
-    <uv-tabbar-item text="优惠" icon="photo" @tap.stop="handleTabbarClick('coupon')"></uv-tabbar-item>
-    <uv-tabbar-item text="" icon="scan" :iconSize="40" @tap.stop="handleTabbarClick('map')"></uv-tabbar-item>
-    <uv-tabbar-item text="订单" icon="play-right" @tap.stop="handleTabbarClick('order')"></uv-tabbar-item>
-    <uv-tabbar-item text="我的" icon="account" @tap.stop="handleTabbarClick('user')"></uv-tabbar-item>
-  </uv-tabbar>
+  <view class="tabbar">
+    <uv-tabbar :value="value" :fixed="true" @change="index=>value = index">
+      <uv-tabbar-item text="首页" icon="home" @tap.stop="handleTabbarClick('index')"></uv-tabbar-item>
+      <uv-tabbar-item text="优惠" icon="photo" @tap.stop="handleTabbarClick('coupon')"></uv-tabbar-item>
+      <uv-tabbar-item text="" icon="scan" :iconSize="40" @tap.stop="handleTabbarClick('map')" style="margin-top: -25px">
+        <template #text>
+
+        </template>
+      </uv-tabbar-item>
+      <uv-tabbar-item text="订单" icon="play-right" @tap.stop="handleTabbarClick('order')"></uv-tabbar-item>
+      <uv-tabbar-item text="我的" icon="account" @tap.stop="handleTabbarClick('user')"></uv-tabbar-item>
+    </uv-tabbar>
+  </view>
+
 </template>
 </template>
 <script setup lang="ts" name="TabBar">
 <script setup lang="ts" name="TabBar">
 import {ref} from 'vue'
 import {ref} from 'vue'
+import {onLoad, onTabItemTap} from "@dcloudio/uni-app";
 
 
+const props = defineProps({
+  index: {
+    type: Number,
+    default: 0
+  }
+})
 const value = ref(0)
 const value = ref(0)
 
 
+
+onLoad(() => {
+  console.log("tabbar onshow", props.index, value.value)
+  value.value = props.index;
+})
+
 const handleTabbarClick = (tab: string) => {
 const handleTabbarClick = (tab: string) => {
   uni.switchTab({
   uni.switchTab({
     url: `/pages/${tab}/index`,
     url: `/pages/${tab}/index`,
@@ -23,4 +43,10 @@ const handleTabbarClick = (tab: string) => {
     }
     }
   })
   })
 }
 }
-</script>
+</script>
+
+<style lang="scss" scoped>
+.tabbar {
+  background-image: url("../../static/tabbar/bg.png");
+}
+</style>

+ 94 - 0
src/custom.scss

@@ -148,3 +148,97 @@
     margin: #{$i}px #{$i}px !important;
     margin: #{$i}px #{$i}px !important;
   }
   }
 }
 }
+
+
+@for $i from 2 to 100 {
+  .fs-#{$i} {
+    font-size: #{$i}rpx;
+  }
+  .lh-#{$i} {
+    line-height: #{$i}rpx;
+  }
+}
+
+.fs-0 {
+  font-size: 0px;
+}
+
+.fw-500 {
+  font-weight: 500;
+}
+
+.fw-600 {
+  font-weight: 600;
+}
+
+.fw-bold {
+  font-weight: bold;
+}
+
+.lh-0 {
+  line-height: 0px;
+}
+
+.lh-normal {
+  line-height: normal;
+}
+
+.text-center {
+  text-align: center;
+}
+
+
+$position: top, right, bottom, left;
+
+@each $item in $position {
+  .m#{str-slice($item, 0, 1)}-auto {
+    margin-#{$item}: auto;
+  }
+  .m#{str-slice($item, 0, 1)}-0 {
+    margin-#{$item}: 0px;
+  }
+}
+
+@for $i from 2 to 100 {
+  @each $item in $position {
+    .m#{str-slice($item, 0, 1)}-#{$i} {
+      margin-#{$item}: #{$i}rpx;
+    }
+    .p#{str-slice($item, 0, 1)}-#{$i} {
+      padding-#{$item}: #{$i}rpx;
+    }
+  }
+  .height-#{$i} {
+    height: #{$i}rpx;
+  }
+  .width-#{$i} {
+    width: #{$i}rpx;
+  }
+  .br-#{$i} {
+    border-radius: #{$i}rpx;
+  }
+}
+
+.br-round {
+  border-radius: 50%;
+}
+
+.mb-0 {
+  margin-bottom: 0px;
+}
+
+.ml-auto {
+  margin-left: auto;
+}
+
+.mt-auto {
+  margin-top: auto;
+}
+
+.width-168 {
+  width: 168rpx;
+}
+
+.width-half {
+  width: 50%;
+}

+ 0 - 0
src/pages/sub-order/detail/index.vue → src/pages-order/detail/index.vue


+ 0 - 0
src/pages/sub-order/pay/index.vue → src/pages-order/pay/index.vue


+ 0 - 0
src/pages/sub-order/process/index.vue → src/pages-order/process/index.vue


+ 0 - 0
src/pages/sub-user/account/index.vue → src/pages-user/account/index.vue


+ 0 - 0
src/pages/sub-user/contact/index.vue → src/pages-user/contact/index.vue


+ 0 - 0
src/pages/sub-user/faq/index.vue → src/pages-user/faq/index.vue


+ 24 - 0
src/pages-user/fav/index.vue

@@ -0,0 +1,24 @@
+<template>
+  <view class="pl-20 pr-20" v-if="list && list.length">
+    <view class="mt-20" v-for="(item, index) in list" :key="index">
+
+    </view>
+  </view>
+
+  <uv-empty text="暂无收藏"></uv-empty>
+
+</template>
+
+<script setup lang="ts">
+import { onLoad } from "@dcloudio/uni-app";
+import { ref } from "vue";
+const list = ref<any[]>();
+onLoad(() => {
+});
+</script>
+
+<style lang="scss">
+page {
+  background-color: #f5f5f5;
+}
+</style>

+ 169 - 0
src/pages-user/feedback/add.vue

@@ -0,0 +1,169 @@
+<template>
+  <view>
+    <uv-popup ref="popup_ref" mode="bottom" custom-style="min-height: 800rpx;padding:15rpx;" closeable round="10">
+      <view class="w100 flex-center">纠错上报</view>
+      <uv-form
+          labelPosition="top"
+          labelWidth="100"
+          :model="state.ruleForm"
+          :rules="state.rules"
+          ref="feedback_form_ref">
+        <uv-form-item label="概要描述" prop="title">
+          <uv-input required="true" type="text" :disabled="state.mode==='detail'" v-model="state.ruleForm.title" placeholder="请填写概要描述" clearable count
+                    maxlength="100">
+          </uv-input>
+        </uv-form-item>
+        <uv-form-item label="问题类别" prop="type" @click="handleShowAction">
+          <uv-input v-model="state.ruleForm.type" disabled disabledColor="#ffffff" placeholder="请选择" border="none">
+          </uv-input>
+          <template v-slot:right>
+            <uv-icon name="arrow-right"></uv-icon>
+          </template>
+        </uv-form-item>
+        <uv-form-item label="详细描述" prop="content">
+          <uv-textarea required="true" height="120"  :disabled="state.mode==='detail'"  v-model="state.ruleForm.content" placeholder="请填写详细描述信息" count
+                       maxlength="300">
+          </uv-textarea>
+        </uv-form-item>
+        <uv-form-item label="问题截图" prop="attachList">
+          <uv-upload
+              :fileList="state.ruleForm.attachList"
+              name="1"
+              multiple
+              :maxCount="9"
+              @delete="handleDelete"
+              @afterRead="handleUpload"
+              :previewFullImage="true"
+          ></uv-upload>
+        </uv-form-item>
+
+        <uv-form-item label="平台答复" prop="content" v-if="state.mode==='detail'">
+          <uv-textarea required="true" height="120" v-model="state.ruleForm.replay" placeholder="平台答复" >
+          </uv-textarea>
+        </uv-form-item>
+
+      </uv-form>
+
+      <view class="w100 flex-inline flex-justify-center">
+        <uv-button type="info" @click="close" hairline> 取 消</uv-button>
+        <uv-button type="primary" @click="handleSubmit" hairline class="ml10" customStyle="{'width':'120px','margin-left':'10px'}" v-if="state.mode==='add'">
+          提 交</uv-button>
+      </view>
+    </uv-popup>
+
+    <uv-action-sheet ref="type_select_ref" :actions="state.feedbackTypeList" title="请选择问题类型" description="选择本次上报问题的类型"
+                     @select="handleTypeSelect">
+    </uv-action-sheet>
+  </view>
+</template>
+<script setup lang="ts">
+import {reactive, ref} from "vue";
+import {onHide} from "@dcloudio/uni-app";
+import {body, formatUrl, upload} from "@/utils/https";
+
+const popup_ref = ref()
+const feedback_form_ref = ref()
+const type_select_ref = ref()
+
+const initState = () => ({
+  ruleForm: {
+    title: '',
+    content: '',
+    replay: '',
+    type: '',
+    attachList: [] as any[]
+  },
+  rules: {
+    'title': {
+      type: 'string',
+      required: true,
+      message: '请填写概要描述',
+      trigger: ['blur', 'change']
+    },
+  },
+  feedbackTypeList: [] as any[],
+  mode:'add'
+})
+
+const state = reactive(initState())
+
+onHide(() => {
+  Object.assign(state, initState());
+})
+
+const handleSubmit = () => {
+  feedback_form_ref.value?.validate().then((res: any) => {
+    uni.showToast({
+      icon: 'success',
+      title: '校验通过'
+    })
+
+    body(`feedback/add`, state.ruleForm).then(() => {
+      uni.showToast({
+        icon: 'success',
+        title: '提交成功,感谢您的反馈'
+      })
+    })
+  }).catch((errors: any) => {
+    uni.showToast({
+      icon: 'error',
+      title: '校验失败'
+    })
+  })
+}
+
+
+const handleUpload = (event: any) => {
+  let file = event.file;
+  upload(`file/upload`).then((res: any) => {
+    state.ruleForm.attachList.push({
+      name: file.name,
+      url: formatUrl(res.url)
+    })
+  })
+}
+
+const handleDelete = (event: any) => {
+  let {file, index, name} = event;
+  state.ruleForm.attachList.splice(index, 1);
+}
+
+const loadDict = () => {
+  body(`dict/list`, {type: 'Feedback.type'}).then((res: any) => {
+    state.feedbackTypeList = res.list;
+  })
+}
+
+const handleShowAction = () => {
+  type_select_ref.value?.open();
+  uni.hideKeyboard();
+}
+
+const handleTypeSelect = (e: any) => {
+  console.log(e)
+  state.ruleForm.type = e.value;
+}
+
+
+const close = () => {
+  Object.assign(state, initState());
+  popup_ref.value.close()
+}
+
+const open = (item:any,mode='add') => {
+  popup_ref.value.open();
+  state.mode=mode;
+  if(mode==='detail'){
+    state.ruleForm  = {...item}
+  }
+  loadDict();
+}
+
+defineExpose({
+  open
+})
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 186 - 0
src/pages-user/feedback/index.vue

@@ -0,0 +1,186 @@
+<template>
+  <view class="page">
+    <view v-if="state.faqList.length <= 0" class="flex-center mt40 animation-loading">
+      <uv-icon name="photo"></uv-icon>
+    </view>
+    <view class="sheet">
+      <uv-list border>
+        <uv-list-item
+            border
+            :title="item.title"
+            clickable
+            show-arrow
+            @click="handleClickFaq(item)"
+            :note="item.createTime"
+            v-for="(item, index) in state.faqList" :key="index">
+          <template #footer>
+            <uv-tags text="已反馈" plain size="mini" type="warning"></uv-tags>
+          </template>
+        </uv-list-item>
+      </uv-list>
+    </view>
+
+
+    <view
+        class="flex-center flex-column contact mt-20"
+        hover-class="hover-scale"
+        @click="call"
+        v-if="state.faqList.length">
+
+      <image
+          class="width-96"
+          mode="widthFix"
+          src="/static/images/contact-customer.png"/>
+
+      <view class="mt-16 color-666 fs-28">电话客服</view>
+    </view>
+
+    <view class="feedback-plus" @click="handleAddFeedback">
+      <uv-icon name="plus" color="#fff"></uv-icon>
+    </view>
+
+    <add ref="add_ref"></add>
+    <add ref="detail_ref"></add>
+  </view>
+</template>
+
+<script setup lang="ts">
+import {onHide, onShow} from "@dcloudio/uni-app";
+import {reactive, ref} from "vue";
+import {body} from "@/utils/https"
+
+import add from '@/pages-user/feedback/add'
+
+const add_ref = ref()
+const detail_ref = ref()
+
+const initState = () => ({
+  faqList: [
+    {
+      title: '洗车扣费异常问题',
+      status: 1,
+      createTime: '2022-09-01 10:00:00',
+    },
+    {
+      title: '洗车扣费异常问题',
+      status: 1,
+      createTime: '2022-09-01 10:00:00',
+    }
+  ] as any[],
+  servicerPhone: "",
+})
+
+const state = reactive(initState())
+
+const call = () => {
+  uni.makePhoneCall({
+    phoneNumber: state.servicerPhone,
+  });
+};
+
+const toggle = (index: number) => {
+  state.faqList = state.faqList.map((item, i) => {
+    return {
+      ...item,
+      open: item.open ? false : i === index,
+    };
+  });
+};
+
+onShow((options) => {
+  let gd = getApp<any>().globalData;
+  console.log(gd)
+  if (options) {
+    state.servicerPhone = options.service;
+  }
+  body(`faq/list`).then((res: any) => {
+    // state.faqList = res.list;
+  })
+});
+
+onHide(() => {
+  Object.assign(state, initState());
+})
+
+const handleClickFaq = (item: any) => {
+  detail_ref.value?.open(item,'detail')
+}
+
+const handleAddFeedback = () => {
+  add_ref.value?.open(null,'add');
+}
+</script>
+
+<style lang="scss">
+.page {
+  min-height: 100vh;
+  background: #f6f7fa;
+  box-sizing: border-box;
+  padding: 40rpx 32rpx;
+}
+
+.contact {
+  height: 216rpx;
+  border-radius: 24rpx;
+  background: #fff;
+}
+
+.sheet {
+  box-sizing: border-box;
+  border-radius: 24rpx;
+  background: #fff;
+  overflow: hidden;
+
+  &_bar {
+    .head {
+      padding: 0rpx 24rpx;
+      box-sizing: border-box;
+
+      & > view {
+        border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
+      }
+    }
+
+    .body {
+      box-sizing: border-box;
+      background-color: rgba(52, 125, 255, 0.06);
+      transition: all 0.3s;
+      padding: 0rpx 24rpx;
+    }
+
+    .body-hidden {
+      height: 0px;
+      overflow: hidden;
+    }
+
+    .body-open {
+      height: auto;
+      padding-top: 24rpx;
+      padding-bottom: 24rpx;
+    }
+
+    &:last-child {
+      .head {
+        & > view {
+          border-bottom: none;
+        }
+      }
+    }
+  }
+}
+
+.feedback-plus {
+  position: fixed;
+  bottom: 60rpx;
+  right: 60rpx;
+  width: 90rpx;
+  height: 90rpx;
+  background: $uni-color-primary;
+  border-radius: 50%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.1);
+  z-index: 9999;
+}
+</style>

+ 0 - 0
src/pages/sub-user/fav/index.vue → src/pages-user/message/index.vue


+ 99 - 112
src/pages/sub-wash/detail/index.vue → src/pages-user/profile/index.vue

@@ -3,8 +3,7 @@
     <button
     <button
         class="avatar"
         class="avatar"
         open-type="chooseAvatar"
         open-type="chooseAvatar"
-        @chooseavatar="chooseAvatar"
-    >
+        @chooseavatar="chooseAvatar">
       <image class="avatar_image" :src="avatar" @error="errorHandle"></image>
       <image class="avatar_image" :src="avatar" @error="errorHandle"></image>
       <view class="avatar_text flex-center">编辑</view>
       <view class="avatar_text flex-center">编辑</view>
     </button>
     </button>
@@ -13,39 +12,30 @@
   <view class="pl-50 pr-50">
   <view class="pl-50 pr-50">
     <view
     <view
         class="menu flex-align-center flex-between"
         class="menu flex-align-center flex-between"
-        v-for="(item, index) in state.menuList"
+        v-for="(item, index) in menu"
         :key="index"
         :key="index"
-        @click="edit(index)"
-    >
+        @click="edit(index)">
       <view class="fs-30">{{ item.title }}</view>
       <view class="fs-30">{{ item.title }}</view>
       <view class="flex">
       <view class="flex">
         <view
         <view
             :class="['fs-30', 'fw-500', `mr-${item.disabled ? '0' : '20'}`]"
             :class="['fs-30', 'fw-500', `mr-${item.disabled ? '0' : '20'}`]"
-            style="color: rgba(0, 0, 0, 0.8)"
-        >{{ item.value }}
-        </view
-        >
-        <uni-icons
-            type="right"
-            size="12"
-            color="rgba(0,0,0,0.4)"
-            v-if="!item.disabled"
-        ></uni-icons>
+            style="color: rgba(0, 0, 0, 0.8)">{{ item.value }}
+        </view>
+        <uv-icon name="right-arrow" v-if="!item.disabled" size="12" color="rgba(0,0,0,0.4)"></uv-icon>
       </view>
       </view>
     </view>
     </view>
   </view>
   </view>
 
 
-  <style-bottom-view>
-    <view class="pl-60 pr-60 pb-40">
-      <style-button type="primary" @click="logoutUser">退出登录</style-button>
-    </view>
-  </style-bottom-view>
+  <view class="pl-60 pr-60 pb-40">
+    <uv-button :custom-style="customStyle" type="error" @click="logoutUser">退出登录</uv-button>
+  </view>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import {onHide, onShow} from "@dcloudio/uni-app";
-import {reactive, ref} from "vue";
-import {body, get, upload} from "@/utils/https"
+import {onLoad, onShow} from "@dcloudio/uni-app";
+import {ref} from "vue";
+import {body, get, upload} from "@/utils/https";
+import {clearToken} from "@/utils/auth"
 
 
 const avatar = ref<string>();
 const avatar = ref<string>();
 const menu = ref<any[]>([]);
 const menu = ref<any[]>([]);
@@ -77,92 +67,84 @@ const MENU_TEMPLATE = [
   // },
   // },
 ];
 ];
 
 
-
-const initState = () => ({
-  user: {},
-  menuList: []
-})
-
-const state = reactive(initState())
+const customStyle = () => {
+  return {
+    height: '80rpx',
+    borderRadius: '40rpx',
+    fontSize: '30rpx',
+    lineHeight: '80rpx',
+    background: '#FF6D00',
+    color: '#fff',
+    fontWeight: '500',
+    width: '60%',
+  }
+}
 
 
 const refresh = () => {
 const refresh = () => {
   const _menu = [...MENU_TEMPLATE];
   const _menu = [...MENU_TEMPLATE];
-  get(`user/profile`).then(res => {
-    getApp<any>().globalData.user = res;
+  get(`user/profile`).then((res: any) => {
+    let {user, permission} = res;
+    getApp<any>().globalData.user = user;
+
+    if (user) {
+      _menu[0].value = user.nickname;
+      _menu[1].value = user.mobilePhone;
+      _menu[2].value = user.defaultPlateNo;
+      _menu[3].value = user.vin;
+      // _menu[4].value = user.card_no;
+      avatar.value =
+          user.avatar ||
+          "https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0";
+      menu.value = _menu;
+    }
   })
   })
-  // fetchProfile().then(() => {
-  //   const user = getApp<any>().globalData.user;
-  //   if (user) {
-  //     _menu[0].value = user.nickname;
-  //     _menu[1].value = user.mobilePhone;
-  //     _menu[2].value = user.defaultPlateNo;
-  //     _menu[3].value = user.vin;
-  //     // _menu[4].value = user.card_no;
-  //     avatar.value =
-  //         user.avatar ||
-  //         "https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0";
-  //     menu.value = _menu;
-  //   }
-  // });
 };
 };
 
 
 const save = (form: Record<string, any>) => {
 const save = (form: Record<string, any>) => {
+  console.log(form)
   uni.showLoading({
   uni.showLoading({
     title: "保存中",
     title: "保存中",
   });
   });
-  return body(`user/updateProfile`, form)
-      .then((res) => {
-        uni.hideLoading();
-        uni.showToast({
-          icon: "success",
-          title: "保存成功",
-        });
-        refresh();
-        return res;
-      })
-      .catch((err) => {
-        uni.hideLoading();
-        uni.showModal({
-          content: `${err.errMsg},请重试`,
-        });
-      });
+  body(`user/updateProfile`, form).then(() => {
+    uni.hideLoading();
+    uni.showToast({
+      icon: "success",
+      title: "保存成功",
+    });
+    refresh();
+  }).catch((err: any) => {
+    uni.hideLoading();
+  })
 };
 };
 
 
 const chooseAvatar = (e: any) => {
 const chooseAvatar = (e: any) => {
+  console.log(e)
   if (e.detail.avatarUrl) {
   if (e.detail.avatarUrl) {
     uni.showLoading({
     uni.showLoading({
       title: "上传中",
       title: "上传中",
     });
     });
-    let params = {
-      url: `file/upload`,
-      filePath: e.detail.avatarUrl,
-      success: (res) => {
-        body(`user/updateAvatar`, {
-          avatar: res.url,
-        })
-            .then(() => {
-              uni.hideLoading();
-              uni.showToast({
-                title: "已更新",
-                icon: "success",
-              });
-              avatar.value = res.url;
-            })
-            .catch((err) => {
-              uni.hideLoading();
-              uni.showModal({
-                content: `${err.errMsg},请重试`,
-              });
-            });
-      }
-    }
-    upload(params)
+
+    upload(`file/upload`, {filePath: e.detail.avatarUrl,name:'avatar.jpg'}).then((res: any) => {
+      body(`user/updateAvatar`, {avatar: res.url}).then(() => {
+        uni.hideLoading();
+        uni.showToast({
+          icon: "success",
+          title: "保存成功",
+        });
+        refresh();
+      }).catch((err: any) => {
+        console.error(err)
+        uni.hideLoading();
+      })
+    })
   } else {
   } else {
     uni.showModal({
     uni.showModal({
       content: `${e.detail.errMsg},请重试`,
       content: `${e.detail.errMsg},请重试`,
     });
     });
   }
   }
 };
 };
+
+
 const edit = (index: number) => {
 const edit = (index: number) => {
   const menuItem = menu.value[index];
   const menuItem = menu.value[index];
   if (menuItem.disabled) {
   if (menuItem.disabled) {
@@ -207,26 +189,22 @@ const logoutUser = () => {
         uni.showLoading({
         uni.showLoading({
           title: "退出中",
           title: "退出中",
         });
         });
-        logout()
-            .then(() => {
-              uni.hideLoading();
-              uni.showToast({
-                icon: "success",
-                title: "已退出",
-              });
-              clearToken();
-              setTimeout(() => {
-                uni.reLaunch({
-                  url: "/pages/map/map",
-                });
-              }, 1500);
-            })
-            .catch((err) => {
-              uni.hideLoading();
-              uni.showModal({
-                content: `${err.errMsg},请重试`,
-              });
+
+        get(`user/logout`).then(() => {
+          uni.hideLoading();
+          uni.showToast({
+            icon: "success",
+            title: "已退出",
+          });
+
+          clearToken();
+          setTimeout(() => {
+            uni.reLaunch({
+              url: "/pages/map/map",
             });
             });
+          }, 1500);
+
+        })
       }
       }
     },
     },
   });
   });
@@ -236,20 +214,29 @@ const errorHandle = (e: any) => {
   console.log(e);
   console.log(e);
 };
 };
 
 
+onLoad(() => {
+  if (getApp<any>().globalData.user) {
+    const user = getApp<any>().globalData.user;
+    const _menu = [...MENU_TEMPLATE];
+    _menu[0].value = user.nickname;
+    _menu[1].value = user.mobilePhone;
+    _menu[2].value = user.defaultPlateNo;
+    _menu[3].value = user.vin;
+    // _menu[4].value = user.card_no;
+    avatar.value =
+        user.avatar ||
+        "https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0";
+    menu.value = _menu;
+  }
+});
 onShow(() => {
 onShow(() => {
   if (getApp<any>().globalData.lastData.profile) {
   if (getApp<any>().globalData.lastData.profile) {
     const {key, value} = getApp<any>().globalData.lastData.profile;
     const {key, value} = getApp<any>().globalData.lastData.profile;
     save({
     save({
       [key]: value,
       [key]: value,
-    }).then(() => {
-      getApp<any>().globalData.lastData.profile = undefined;
-    });
+    })
   }
   }
 });
 });
-
-onHide(() => {
-  Object.assign(state, initState());
-})
 </script>
 </script>
 
 
 <style lang="scss">
 <style lang="scss">

+ 0 - 0
src/pages/sub-user/feedback/index.vue → src/pages-wash/detail/index.vue


+ 0 - 0
src/pages/sub-user/message/index.vue → src/pages-wash/price/index.vue


+ 0 - 0
src/pages/sub-user/profile/index.vue → src/pages-wash/process/index.vue


+ 11 - 3
src/pages.json

@@ -9,7 +9,7 @@
     {
     {
       "path": "pages/index/index",
       "path": "pages/index/index",
       "style": {
       "style": {
-        "navigationBarTitleText": "Car-Wash"
+        "navigationBarTitleText": "洗车小程序"
       }
       }
     },
     },
     {
     {
@@ -37,7 +37,7 @@
   ],
   ],
   "subPackages": [
   "subPackages": [
     {
     {
-      "root": "pages/sub-user",
+      "root": "pages-user",
       "pages": [
       "pages": [
         {
         {
           "path": "profile/index",
           "path": "profile/index",
@@ -70,16 +70,24 @@
             "navigationBarTitleText": "我的收藏",
             "navigationBarTitleText": "我的收藏",
             "navigationBarBackgroundColor": "#ffffff"
             "navigationBarBackgroundColor": "#ffffff"
           }
           }
+        },
+        {
+          "path": "feedback/index",
+          "style": {
+            "navigationStyle": "default",
+            "navigationBarTitleText": "纠错上报",
+            "navigationBarBackgroundColor": "#ffffff"
+          }
         }
         }
       ]
       ]
     }
     }
   ],
   ],
   "tabBar": {
   "tabBar": {
+    "custom": true,
     "color": "#7A7E83",
     "color": "#7A7E83",
     "selectedColor": "#3cc51f",
     "selectedColor": "#3cc51f",
     "borderStyle": "black",
     "borderStyle": "black",
     "backgroundColor": "#ffffff",
     "backgroundColor": "#ffffff",
-    "backgroundImage": "static/tabbar/bg.png",
     "list": [
     "list": [
       {
       {
         "pagePath": "pages/index/index",
         "pagePath": "pages/index/index",

+ 3 - 0
src/pages/coupon/index.vue

@@ -54,6 +54,8 @@
 <!--    <view v-if="showClose" class="button-cancel" @click="handleClose">
 <!--    <view v-if="showClose" class="button-cancel" @click="handleClose">
       不使用
       不使用
     </view>-->
     </view>-->
+
+    <tab-bar :index="1"/>
   </view>
   </view>
 </template>
 </template>
 
 
@@ -61,6 +63,7 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import {reactive, ref} from 'vue'
 import {reactive, ref} from 'vue'
 import {onHide, onShow} from "@dcloudio/uni-app";
 import {onHide, onShow} from "@dcloudio/uni-app";
+import TabBar from "@/components/tab-bar";
 
 
 
 
 const props = defineProps({
 const props = defineProps({

+ 3 - 1
src/pages/index/index.vue

@@ -52,12 +52,14 @@
       </view>
       </view>
     </view>
     </view>
 
 
+    <tab-bar></tab-bar>
   </view>
   </view>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
 import {reactive, ref} from 'vue'
 import {reactive, ref} from 'vue'
 import {onHide, onShow} from "@dcloudio/uni-app";
 import {onHide, onShow} from "@dcloudio/uni-app";
+import TabBar from "@/components/tab-bar";
 
 
 const title = ref('Hello')
 const title = ref('Hello')
 const qrcode_ref = ref()
 const qrcode_ref = ref()
@@ -110,7 +112,7 @@ onHide(() => {
 const refreshQrcode = () => {
 const refreshQrcode = () => {
   qrcode_ref.value?.remake({
   qrcode_ref.value?.remake({
     success: () => {
     success: () => {
-      console.log("success")
+      // console.log("success")
     },
     },
     fail: () => {
     fail: () => {
       console.log("fail")
       console.log("fail")

+ 2 - 0
src/pages/map/index.vue

@@ -61,6 +61,7 @@
     </view>
     </view>
     <!--    站点清单  end-->
     <!--    站点清单  end-->
 
 
+    <tab-bar :index="2"/>
   </view>
   </view>
 </template>
 </template>
 
 
@@ -68,6 +69,7 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import {reactive, ref} from 'vue'
 import {reactive, ref} from 'vue'
 import {onHide, onShow} from "@dcloudio/uni-app";
 import {onHide, onShow} from "@dcloudio/uni-app";
+import TabBar from "@/components/tab-bar";
 
 
 const mapCtx = ref(); // 地图上下文
 const mapCtx = ref(); // 地图上下文
 
 

+ 2 - 1
src/pages/order/index.vue

@@ -42,13 +42,14 @@
         </view>
         </view>
       </view>
       </view>
     </scroll-view>
     </scroll-view>
+    <tab-bar :index="3"/>
   </view>
   </view>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
 import {reactive} from 'vue'
 import {reactive} from 'vue'
 import {onHide, onShow} from "@dcloudio/uni-app";
 import {onHide, onShow} from "@dcloudio/uni-app";
-
+import TabBar from "@/components/tab-bar";
 
 
 const initState = () => ({
 const initState = () => ({
   orderList: [{
   orderList: [{

+ 0 - 294
src/pages/sub-wash/price/index.vue

@@ -1,294 +0,0 @@
-<template>
-  <view class="pt-60 pb-20 flex-center">
-    <button
-        class="avatar"
-        open-type="chooseAvatar"
-        @chooseavatar="chooseAvatar"
-    >
-      <image class="avatar_image" :src="avatar" @error="errorHandle"></image>
-      <view class="avatar_text flex-center">编辑</view>
-    </button>
-  </view>
-
-  <view class="pl-50 pr-50">
-    <view
-        class="menu flex-align-center flex-between"
-        v-for="(item, index) in state.menuList"
-        :key="index"
-        @click="edit(index)"
-    >
-      <view class="fs-30">{{ item.title }}</view>
-      <view class="flex">
-        <view
-            :class="['fs-30', 'fw-500', `mr-${item.disabled ? '0' : '20'}`]"
-            style="color: rgba(0, 0, 0, 0.8)"
-        >{{ item.value }}
-        </view
-        >
-        <uni-icons
-            type="right"
-            size="12"
-            color="rgba(0,0,0,0.4)"
-            v-if="!item.disabled"
-        ></uni-icons>
-      </view>
-    </view>
-  </view>
-
-  <style-bottom-view>
-    <view class="pl-60 pr-60 pb-40">
-      <style-button type="primary" @click="logoutUser">退出登录</style-button>
-    </view>
-  </style-bottom-view>
-</template>
-
-<script setup lang="ts">
-import {onHide, onShow} from "@dcloudio/uni-app";
-import {reactive, ref} from "vue";
-import {body, get, upload} from "@/utils/https"
-
-const avatar = ref<string>();
-const menu = ref<any[]>([]);
-const MENU_TEMPLATE = [
-  {
-    title: "昵称",
-    key: "nickname",
-    value: "",
-  },
-  {
-    title: "电话",
-    key: "",
-    disabled: true,
-  },
-  {
-    title: "车牌号",
-    key: "defaultPlateNo",
-    value: "",
-  },
-  {
-    title: "VIN码",
-    key: "vin",
-    value: "",
-  },
-  // {
-  //   title: "充电卡",
-  //   key: "",
-  //   value: "",
-  // },
-];
-
-
-const initState = () => ({
-  user: {},
-  menuList: []
-})
-
-const state = reactive(initState())
-
-const refresh = () => {
-  const _menu = [...MENU_TEMPLATE];
-  get(`user/profile`).then(res => {
-    getApp<any>().globalData.user = res;
-  })
-  // fetchProfile().then(() => {
-  //   const user = getApp<any>().globalData.user;
-  //   if (user) {
-  //     _menu[0].value = user.nickname;
-  //     _menu[1].value = user.mobilePhone;
-  //     _menu[2].value = user.defaultPlateNo;
-  //     _menu[3].value = user.vin;
-  //     // _menu[4].value = user.card_no;
-  //     avatar.value =
-  //         user.avatar ||
-  //         "https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0";
-  //     menu.value = _menu;
-  //   }
-  // });
-};
-
-const save = (form: Record<string, any>) => {
-  uni.showLoading({
-    title: "保存中",
-  });
-  return body(`user/updateProfile`, form)
-      .then((res) => {
-        uni.hideLoading();
-        uni.showToast({
-          icon: "success",
-          title: "保存成功",
-        });
-        refresh();
-        return res;
-      })
-      .catch((err) => {
-        uni.hideLoading();
-        uni.showModal({
-          content: `${err.errMsg},请重试`,
-        });
-      });
-};
-
-const chooseAvatar = (e: any) => {
-  if (e.detail.avatarUrl) {
-    uni.showLoading({
-      title: "上传中",
-    });
-    let params = {
-      url: `file/upload`,
-      filePath: e.detail.avatarUrl,
-      success: (res) => {
-        body(`user/updateAvatar`, {
-          avatar: res.url,
-        })
-            .then(() => {
-              uni.hideLoading();
-              uni.showToast({
-                title: "已更新",
-                icon: "success",
-              });
-              avatar.value = res.url;
-            })
-            .catch((err) => {
-              uni.hideLoading();
-              uni.showModal({
-                content: `${err.errMsg},请重试`,
-              });
-            });
-      }
-    }
-    upload(params)
-  } else {
-    uni.showModal({
-      content: `${e.detail.errMsg},请重试`,
-    });
-  }
-};
-const edit = (index: number) => {
-  const menuItem = menu.value[index];
-  if (menuItem.disabled) {
-    return;
-  }
-  if (!menuItem.key) {
-    uni.showToast({
-      icon: "none",
-      title: "暂不支持修改",
-    });
-    return;
-  }
-  if (/车牌/.test(menuItem.title)) {
-    uni.chooseLicensePlate({
-      success: (res) => {
-        save({
-          defaultPlateNo: res.plateNumber,
-        });
-      },
-      fail: (err) => {
-        console.log(err);
-      },
-    });
-    return;
-  }
-  uni.navigateTo({
-    url: `/pages-user/profile-edit/profile-edit?key=${menuItem.key}&title=${
-        menuItem.title
-    }${menuItem.value ? `&value=${encodeURIComponent(menuItem.value)}` : ""}`,
-  });
-};
-
-const logoutUser = () => {
-  uni.showModal({
-    title: "温馨提示",
-    content: "确定退出登录吗?",
-    confirmColor: "#2d9e95",
-    confirmText: "确定退出",
-    cancelText: "手滑了",
-    success: (res) => {
-      if (res.confirm) {
-        uni.showLoading({
-          title: "退出中",
-        });
-        logout()
-            .then(() => {
-              uni.hideLoading();
-              uni.showToast({
-                icon: "success",
-                title: "已退出",
-              });
-              clearToken();
-              setTimeout(() => {
-                uni.reLaunch({
-                  url: "/pages/map/map",
-                });
-              }, 1500);
-            })
-            .catch((err) => {
-              uni.hideLoading();
-              uni.showModal({
-                content: `${err.errMsg},请重试`,
-              });
-            });
-      }
-    },
-  });
-};
-
-const errorHandle = (e: any) => {
-  console.log(e);
-};
-
-onShow(() => {
-  if (getApp<any>().globalData.lastData.profile) {
-    const {key, value} = getApp<any>().globalData.lastData.profile;
-    save({
-      [key]: value,
-    }).then(() => {
-      getApp<any>().globalData.lastData.profile = undefined;
-    });
-  }
-});
-
-onHide(() => {
-  Object.assign(state, initState());
-})
-</script>
-
-<style lang="scss">
-.avatar {
-  position: relative;
-  height: 116rpx !important;
-  width: 116rpx !important;
-  border-radius: 50%;
-  border: 2rpx solid rgba(0, 0, 0, 0.15);
-  overflow: hidden;
-
-  &_image {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    left: 0;
-    top: 0;
-    border-radius: 50%;
-  }
-
-  &_text {
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    width: 100%;
-    height: 40rpx;
-    background: rgba(0, 0, 0, 0.5);
-    color: #fff;
-    font-size: 24rpx;
-  }
-}
-
-.menu {
-  background-color: #fff;
-  height: 120rpx;
-  border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
-
-  &:last-child {
-    border-bottom: none;
-  }
-}
-</style>

+ 0 - 294
src/pages/sub-wash/process/index.vue

@@ -1,294 +0,0 @@
-<template>
-  <view class="pt-60 pb-20 flex-center">
-    <button
-        class="avatar"
-        open-type="chooseAvatar"
-        @chooseavatar="chooseAvatar"
-    >
-      <image class="avatar_image" :src="avatar" @error="errorHandle"></image>
-      <view class="avatar_text flex-center">编辑</view>
-    </button>
-  </view>
-
-  <view class="pl-50 pr-50">
-    <view
-        class="menu flex-align-center flex-between"
-        v-for="(item, index) in state.menuList"
-        :key="index"
-        @click="edit(index)"
-    >
-      <view class="fs-30">{{ item.title }}</view>
-      <view class="flex">
-        <view
-            :class="['fs-30', 'fw-500', `mr-${item.disabled ? '0' : '20'}`]"
-            style="color: rgba(0, 0, 0, 0.8)"
-        >{{ item.value }}
-        </view
-        >
-        <uni-icons
-            type="right"
-            size="12"
-            color="rgba(0,0,0,0.4)"
-            v-if="!item.disabled"
-        ></uni-icons>
-      </view>
-    </view>
-  </view>
-
-  <style-bottom-view>
-    <view class="pl-60 pr-60 pb-40">
-      <style-button type="primary" @click="logoutUser">退出登录</style-button>
-    </view>
-  </style-bottom-view>
-</template>
-
-<script setup lang="ts">
-import {onHide, onShow} from "@dcloudio/uni-app";
-import {reactive, ref} from "vue";
-import {body, get, upload} from "@/utils/https"
-
-const avatar = ref<string>();
-const menu = ref<any[]>([]);
-const MENU_TEMPLATE = [
-  {
-    title: "昵称",
-    key: "nickname",
-    value: "",
-  },
-  {
-    title: "电话",
-    key: "",
-    disabled: true,
-  },
-  {
-    title: "车牌号",
-    key: "defaultPlateNo",
-    value: "",
-  },
-  {
-    title: "VIN码",
-    key: "vin",
-    value: "",
-  },
-  // {
-  //   title: "充电卡",
-  //   key: "",
-  //   value: "",
-  // },
-];
-
-
-const initState = () => ({
-  user: {},
-  menuList: []
-})
-
-const state = reactive(initState())
-
-const refresh = () => {
-  const _menu = [...MENU_TEMPLATE];
-  get(`user/profile`).then(res => {
-    getApp<any>().globalData.user = res;
-  })
-  // fetchProfile().then(() => {
-  //   const user = getApp<any>().globalData.user;
-  //   if (user) {
-  //     _menu[0].value = user.nickname;
-  //     _menu[1].value = user.mobilePhone;
-  //     _menu[2].value = user.defaultPlateNo;
-  //     _menu[3].value = user.vin;
-  //     // _menu[4].value = user.card_no;
-  //     avatar.value =
-  //         user.avatar ||
-  //         "https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0";
-  //     menu.value = _menu;
-  //   }
-  // });
-};
-
-const save = (form: Record<string, any>) => {
-  uni.showLoading({
-    title: "保存中",
-  });
-  return body(`user/updateProfile`, form)
-      .then((res) => {
-        uni.hideLoading();
-        uni.showToast({
-          icon: "success",
-          title: "保存成功",
-        });
-        refresh();
-        return res;
-      })
-      .catch((err) => {
-        uni.hideLoading();
-        uni.showModal({
-          content: `${err.errMsg},请重试`,
-        });
-      });
-};
-
-const chooseAvatar = (e: any) => {
-  if (e.detail.avatarUrl) {
-    uni.showLoading({
-      title: "上传中",
-    });
-    let params = {
-      url: `file/upload`,
-      filePath: e.detail.avatarUrl,
-      success: (res) => {
-        body(`user/updateAvatar`, {
-          avatar: res.url,
-        })
-            .then(() => {
-              uni.hideLoading();
-              uni.showToast({
-                title: "已更新",
-                icon: "success",
-              });
-              avatar.value = res.url;
-            })
-            .catch((err) => {
-              uni.hideLoading();
-              uni.showModal({
-                content: `${err.errMsg},请重试`,
-              });
-            });
-      }
-    }
-    upload(params)
-  } else {
-    uni.showModal({
-      content: `${e.detail.errMsg},请重试`,
-    });
-  }
-};
-const edit = (index: number) => {
-  const menuItem = menu.value[index];
-  if (menuItem.disabled) {
-    return;
-  }
-  if (!menuItem.key) {
-    uni.showToast({
-      icon: "none",
-      title: "暂不支持修改",
-    });
-    return;
-  }
-  if (/车牌/.test(menuItem.title)) {
-    uni.chooseLicensePlate({
-      success: (res) => {
-        save({
-          defaultPlateNo: res.plateNumber,
-        });
-      },
-      fail: (err) => {
-        console.log(err);
-      },
-    });
-    return;
-  }
-  uni.navigateTo({
-    url: `/pages-user/profile-edit/profile-edit?key=${menuItem.key}&title=${
-        menuItem.title
-    }${menuItem.value ? `&value=${encodeURIComponent(menuItem.value)}` : ""}`,
-  });
-};
-
-const logoutUser = () => {
-  uni.showModal({
-    title: "温馨提示",
-    content: "确定退出登录吗?",
-    confirmColor: "#2d9e95",
-    confirmText: "确定退出",
-    cancelText: "手滑了",
-    success: (res) => {
-      if (res.confirm) {
-        uni.showLoading({
-          title: "退出中",
-        });
-        logout()
-            .then(() => {
-              uni.hideLoading();
-              uni.showToast({
-                icon: "success",
-                title: "已退出",
-              });
-              clearToken();
-              setTimeout(() => {
-                uni.reLaunch({
-                  url: "/pages/map/map",
-                });
-              }, 1500);
-            })
-            .catch((err) => {
-              uni.hideLoading();
-              uni.showModal({
-                content: `${err.errMsg},请重试`,
-              });
-            });
-      }
-    },
-  });
-};
-
-const errorHandle = (e: any) => {
-  console.log(e);
-};
-
-onShow(() => {
-  if (getApp<any>().globalData.lastData.profile) {
-    const {key, value} = getApp<any>().globalData.lastData.profile;
-    save({
-      [key]: value,
-    }).then(() => {
-      getApp<any>().globalData.lastData.profile = undefined;
-    });
-  }
-});
-
-onHide(() => {
-  Object.assign(state, initState());
-})
-</script>
-
-<style lang="scss">
-.avatar {
-  position: relative;
-  height: 116rpx !important;
-  width: 116rpx !important;
-  border-radius: 50%;
-  border: 2rpx solid rgba(0, 0, 0, 0.15);
-  overflow: hidden;
-
-  &_image {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    left: 0;
-    top: 0;
-    border-radius: 50%;
-  }
-
-  &_text {
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    width: 100%;
-    height: 40rpx;
-    background: rgba(0, 0, 0, 0.5);
-    color: #fff;
-    font-size: 24rpx;
-  }
-}
-
-.menu {
-  background-color: #fff;
-  height: 120rpx;
-  border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
-
-  &:last-child {
-    border-bottom: none;
-  }
-}
-</style>

+ 45 - 45
src/pages/user/index.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
 
 
-    <image src="/static/user/user-bg.png" mode="widthFix" class="bg" />
+  <image src="/static/user/user-bg.png" mode="widthFix" class="bg"/>
 
 
   <block>
   <block>
     <view class="container" :style="containerStyle">
     <view class="container" :style="containerStyle">
@@ -22,18 +22,9 @@
           ></view>
           ></view>
           <view class="phone fs-40 fw-500">{{ user.mobilePhoneFormat }}</view>
           <view class="phone fs-40 fw-500">{{ user.mobilePhoneFormat }}</view>
 
 
-          <view class="money flex-align-center" @click="toPage(-1)">
+          <view class="money" @click="toPage({path: '/pages-user/account/index'})">
             <uv-icon name="red-packet" size="24"></uv-icon>
             <uv-icon name="red-packet" size="24"></uv-icon>
-            <view>¥{{user.balance}}</view>
-<!--            <view class="color-primary ml-12" style="font-size: 16px"
-            >我的钱包
-            </view
-            >
-            <view class="fs-40 fw-500 ml-auto mt-12 color-primary"></view>
-            <view class="fs-60 fw-500 ml-12 mr-48 color-primary">{{
-                user.balance
-              }}
-            </view>-->
+            <view>¥{{ user.balance }}</view>
           </view>
           </view>
         </view>
         </view>
       </view>
       </view>
@@ -42,13 +33,9 @@
         <block v-for="(item, index) in menu" :key="index">
         <block v-for="(item, index) in menu" :key="index">
           <view
           <view
               class="menu-item"
               class="menu-item"
-              v-if="
-              index !== menu.length - 1
-            "
-              @click="toPage(index)"
-          >
+              @click="toPage(item)">
             <view class="menu-item_left">
             <view class="menu-item_left">
-              <image :src="'/static/user/'+index+'.png'"></image>
+              <image :src="item.icon"></image>
               <view class="menu-item_left-title">{{ item.title }}</view>
               <view class="menu-item_left-title">{{ item.title }}</view>
             </view>
             </view>
             <view class="menu-item_right">
             <view class="menu-item_right">
@@ -59,11 +46,13 @@
       </view>
       </view>
     </view>
     </view>
   </block>
   </block>
+  <tab-bar :index="4"/>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
 import {onLoad, onShow} from "@dcloudio/uni-app";
 import {onLoad, onShow} from "@dcloudio/uni-app";
 import {ref} from "vue";
 import {ref} from "vue";
+import TabBar from "@/components/tab-bar";
 
 
 const containerStyle = ref({});
 const containerStyle = ref({});
 const user = ref<any>({
 const user = ref<any>({
@@ -71,53 +60,62 @@ const user = ref<any>({
   mobilePhoneFormat: '15012341234',
   mobilePhoneFormat: '15012341234',
   balance: '2345.67',
   balance: '2345.67',
 });
 });
-const service = ref("");
+const service = ref("15012341234");
 const menu = ref([
 const menu = ref([
   {
   {
-    title: "我的卡包",
-    path: "/pages-charge/card/card",
+    title: "个人信息",
+    path: "/pages-user/profile/index",
+    icon: '/static/user/profile.png'
   },
   },
   {
   {
-    title: "充电订单",
-    path: "/pages-charge/orders/orders",
+    title: "我的卡包",
+    path: "/pages/coupon/index",
+    icon: '/static/user/coupon.png'
   },
   },
   {
   {
-    title: "我的收藏",
-    path: "/pages-user/collect/collect",
+    title: "洗车订单",
+    path: "/pages/order/index",
+    icon: '/static/user/order.png'
   },
   },
   {
   {
-    title: "个人信息",
-    path: "/pages-user/profile/profile",
+    title: "我的收藏",
+    path: "/pages-user/fav/index",
+    icon: '/static/user/fav.png'
   },
   },
+
   {
   {
     title: "联系我们",
     title: "联系我们",
-    path: "",
+    path: "/pages-user/contact/index",
+    icon: '/static/user/contact.png'
   },
   },
   {
   {
     title: "常见问题",
     title: "常见问题",
-    path: "/pages-common/faq/faq",
+    path: "/pages-user/faq/index",
+    icon: '/static/user/faq.png'
   },
   },
   {
   {
-    title: "电站列表",
-    path: "/pages/list/list",
+    title: "纠错上报",
+    path: "/pages-user/feedback/index",
+    icon: '/static/user/feedback.png'
   },
   },
 ]);
 ]);
-const toPage = (index: number) => {
-  if (index < 0) {
-    uni.navigateTo({
-      url: "/pages-user/wallet/wallet",
-    });
-    return;
-  }
-  if (index === 4) {
+const toPage = (item: any) => {
+  let {title, path} = item;
+  if (path.includes('contact')) {
     uni.makePhoneCall({
     uni.makePhoneCall({
       phoneNumber: service.value,
       phoneNumber: service.value,
+      fail: (error) => {
+        console.log(error)
+      }
     });
     });
     return;
     return;
+  }else if(path.includes("order")||path.includes("coupon")){
+    uni.switchTab({
+      url:path
+    })
   }
   }
-  const item = menu.value[index];
   uni.navigateTo({
   uni.navigateTo({
-    url: item.path + (index === 5 ? `?service=${service.value}` : ""),
+    url: item.path,
   });
   });
 };
 };
 
 
@@ -178,7 +176,7 @@ onShow(() => {
       position: absolute;
       position: absolute;
       left: 50%;
       left: 50%;
       transform: translateX(-50%);
       transform: translateX(-50%);
-      top: -50rpx;
+      top: -90rpx;
       width: 110rpx;
       width: 110rpx;
       height: 110rpx;
       height: 110rpx;
       border: 2rpx solid #ffffff;
       border: 2rpx solid #ffffff;
@@ -209,6 +207,7 @@ onShow(() => {
       display: flex;
       display: flex;
       align-content: center;
       align-content: center;
       align-items: center;
       align-items: center;
+      justify-content: space-between;
 
 
     }
     }
   }
   }
@@ -217,12 +216,11 @@ onShow(() => {
 .body {
 .body {
   width: 100%;
   width: 100%;
   background-color: #fff;
   background-color: #fff;
-  padding: 0rpx 30rpx;
+  //padding: 0rpx 30rpx;
 
 
   .menu-item {
   .menu-item {
     display: inline-flex;
     display: inline-flex;
     justify-content: space-between;
     justify-content: space-between;
-    padding: 4rpx 10rpx;
     background-color: #fff;
     background-color: #fff;
     height: 90rpx;
     height: 90rpx;
     border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
     border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
@@ -233,6 +231,7 @@ onShow(() => {
       display: flex;
       display: flex;
       align-items: center;
       align-items: center;
       align-content: center;
       align-content: center;
+      margin-left: 20rpx;
 
 
       image {
       image {
         width: 42rpx;
         width: 42rpx;
@@ -246,7 +245,8 @@ onShow(() => {
     }
     }
 
 
     &_right {
     &_right {
-      width: 120rpx;
+      text-align: right;
+      width: 60rpx;
     }
     }
 
 
 
 

+ 0 - 0
src/static/user/4.png → src/static/user/contact.png


+ 0 - 0
src/static/user/0.png → src/static/user/coupon.png


BIN
src/static/user/faq.png


+ 0 - 0
src/static/user/2.png → src/static/user/fav.png


+ 0 - 0
src/static/user/5.png → src/static/user/feedback.png


+ 0 - 0
src/static/user/1.png → src/static/user/order.png


+ 0 - 0
src/static/user/3.png → src/static/user/profile.png


+ 37 - 48
src/utils/auth.ts

@@ -1,5 +1,5 @@
-import { host } from "../utils/constant";
 import Storage from "../utils/storage";
 import Storage from "../utils/storage";
+import {body, get} from "@/utils/https";
 
 
 const _tokenStorage = new Storage("AUTH");
 const _tokenStorage = new Storage("AUTH");
 
 
@@ -74,33 +74,29 @@ export function login(e: any): Promise<string> {
     });
     });
     uni.login({
     uni.login({
       success: (res) => {
       success: (res) => {
-        uni.request<any>({
-          url: `${host}/user/wxLogin`,
-          method: "POST",
-          dataType: "json",
-          data: {
-            phoneCode: e.detail.code,
-            code: res.code,
-            avatar: "",
-            nickname: "",
-          },
-          success: (res: any) => {
-            const { statusCode, data } = res;
-            if (
+        let data = {
+          phoneCode: e.detail.code,
+          code: res.code,
+          avatar: "",
+          nickname: "",
+        }
+        body(`/user/wxLogin`,data).then((res:any)=>{
+          const { statusCode, data } = res;
+          if (
               statusCode === 200 &&
               statusCode === 200 &&
               data &&
               data &&
               data.message === "ok" &&
               data.message === "ok" &&
               data.code === 200
               data.code === 200
-            ) {
-              _resolveTokenQueue(data.data.satoken);
-            } else {
-              _resolveTokenQueue({
-                errMsg: data.msg ? data.msg : `${JSON.stringify(res)}`,
-              });
-            }
-          },
-          fail: _resolveTokenQueue,
-        });
+          ) {
+            _resolveTokenQueue(data.data.satoken);
+          } else {
+            _resolveTokenQueue({
+              errMsg: data.msg ? data.msg : `${JSON.stringify(res)}`,
+            });
+          }
+        }).catch(e=>{
+          _resolveTokenQueue
+        })
       },
       },
       fail: _resolveTokenQueue,
       fail: _resolveTokenQueue,
     });
     });
@@ -121,36 +117,29 @@ export function refresh(): Promise<string> {
       } else {
       } else {
         getApp<any>().globalData.token = "";
         getApp<any>().globalData.token = "";
         _tokenStorage.clear("token");
         _tokenStorage.clear("token");
-        uni.request({
-          url: `${host}/user/refresh`,
-          method: "GET",
-          dataType: "json",
-          header: {
-            Authorization: token,
-          },
-          success: (res: any) => {
-            console.log("refresh返回", res);
-            const { statusCode, data } = res;
-            if (
+        get(`/user/refresh`).then((res:any)=>{
+          console.log("refresh返回", res);
+          const { statusCode, data } = res;
+          if (
               statusCode === 200 &&
               statusCode === 200 &&
               data &&
               data &&
               data.msg === "OK" &&
               data.msg === "OK" &&
               data.code === 200
               data.code === 200
-            ) {
-              resolve(data.data.access_token);
-            } else {
-              if (data.code === 21005) {
-                uni.reLaunch({
-                  url: "/pages/map/map",
-                });
-              }
-              reject({
-                errMsg: `${JSON.stringify(res)}`,
+          ) {
+            resolve(data.data.access_token);
+          } else {
+            if (data.code === 21005) {
+              uni.reLaunch({
+                url: "/pages/map/map",
               });
               });
             }
             }
-          },
-          fail: reject,
-        });
+            reject({
+              errMsg: `${JSON.stringify(res)}`,
+            });
+          }
+        }).catch(()=>{
+          reject()
+        })
       }
       }
     });
     });
   });
   });

+ 52 - 7
src/utils/https.ts

@@ -1,8 +1,11 @@
 // @ts-ignore
 // @ts-ignore
-const env = process?.env.NODE_ENV === "development" ? "dev" : "prd";
-let apis = {
+import {fetchToken} from "@/utils/auth"
+
+let isDevelopment = process.env.NODE_ENV === "development";
+const env: string = isDevelopment ? "dev" : "prd";
+const apis = {
     dev: {
     dev: {
-        serverUrl: "http://localhost:10086/cms/",
+        serverUrl: "https://dev.kuaiyuman.cn/api/",
         fileUrl: "https://zyp-1258963180.cos.ap-guangzhou.myqcloud.com/"
         fileUrl: "https://zyp-1258963180.cos.ap-guangzhou.myqcloud.com/"
     },
     },
     uat: {
     uat: {
@@ -40,7 +43,7 @@ const isEmptyOrNull = function (exp: any) {
  * @param param
  * @param param
  */
  */
 const get = (url: string, param = {}) => {
 const get = (url: string, param = {}) => {
-    let token = uni.getStorageSync(cfg.key.token) || "";
+    let token = fetchToken() || ""
     if (!isEmptyOrNull(param)) {
     if (!isEmptyOrNull(param)) {
         var params = [];
         var params = [];
         for (var key in param) {
         for (var key in param) {
@@ -64,7 +67,7 @@ const get = (url: string, param = {}) => {
 
 
 
 
 const body = (url: string, param = {}) => {
 const body = (url: string, param = {}) => {
-    let token = uni.getStorageSync(cfg.key.token) || "";
+    let token = fetchToken() || ""
     let options = {
     let options = {
         url: fillUrl(url),
         url: fillUrl(url),
         data: param,
         data: param,
@@ -127,7 +130,49 @@ const request = (options: any) => {
     });
     });
 };
 };
 
 
-const upload = (opt: any) => {
+const upload = (url: string, param: any = {}) => {
+    let token = fetchToken() || ""
+    console.log("upload", url, param, token)
+    return new Promise((resolve, reject) => {
+        uni.uploadFile({
+            url: fillUrl(url),
+            filePath: param.filePath,
+            name: param.name,
+            header: {
+                token
+            },
+            success: function (res) {
+                console.log("upload file=>", res)
+                let response = JSON.parse(res.data);
+                if (response.code === 200) {
+                    resolve(response);
+                }else if (response.code === 500) {
+                    uni.showToast({
+                        title: '系统繁忙,请稍后重试',
+                        icon: 'none'
+                    });
+                    reject();
+                } else {
+                    console.error()
+                    uni.showToast({
+                        title: response.message
+                    });
+                    reject();
+                }
+
+            },
+            fail: function (e) {
+                console.error(e)
+                uni.showToast({
+                    title: '请稍后重试'
+                });
+                reject();
+            }
+        });
+    })
+}
+
+const uploadV2 = (opt: any) => {
     opt = opt || {};
     opt = opt || {};
     opt.url = opt.url || '';
     opt.url = opt.url || '';
     opt.filePath = opt.filePath || null;//要上传文件资源的路径。
     opt.filePath = opt.filePath || null;//要上传文件资源的路径。
@@ -174,5 +219,5 @@ const formatUrl = (v: string) => {
 };
 };
 
 
 export {
 export {
-    get, body, upload, cfg, serverUrl, fileUrl, formatUrl
+    get, body, upload, uploadV2, cfg, serverUrl, fileUrl, formatUrl
 }
 }