tangning 2 vuotta sitten
vanhempi
commit
fb19cb470f

+ 2 - 2
.env

@@ -1,4 +1,4 @@
-VITE_TOKEN_KEY=tokenKey
+VITE_TOKEN_KEY=token
 
-VITE_URL_PREFIX=/api
+VITE_URL_PREFIX=/service
 

+ 27 - 0
components.d.ts

@@ -0,0 +1,27 @@
+// generated by unplugin-vue-components
+// We suggest you to commit this file into source control
+// Read more: https://github.com/vuejs/core/pull/3399
+import '@vue/runtime-core'
+
+export {}
+
+declare module '@vue/runtime-core' {
+  export interface GlobalComponents {
+    RouterLink: typeof import('vue-router')['RouterLink']
+    RouterView: typeof import('vue-router')['RouterView']
+    TitleBar: typeof import('./src/components/TitleBar/index.vue')['default']
+    VanButton: typeof import('vant/es')['Button']
+    VanCellGroup: typeof import('vant/es')['CellGroup']
+    VanDivider: typeof import('vant/es')['Divider']
+    VanField: typeof import('vant/es')['Field']
+    VanForm: typeof import('vant/es')['Form']
+    VanIcon: typeof import('vant/es')['Icon']
+    VanList: typeof import('vant/es')['List']
+    VanRadio: typeof import('vant/es')['Radio']
+    VanRadioGroup: typeof import('vant/es')['RadioGroup']
+    VanRate: typeof import('vant/es')['Rate']
+    VanTab: typeof import('vant/es')['Tab']
+    VanTabs: typeof import('vant/es')['Tabs']
+    VanUploader: typeof import('vant/es')['Uploader']
+  }
+}

+ 1 - 1
package.json

@@ -27,7 +27,7 @@
     "pinia": "^2.0.28",
     "pinia-plugin-persistedstate": "^3.0.1",
     "universal-cookie": "^4.0.4",
-    "vant": "^4.0.3",
+    "vant": "^4.0.11",
     "vue": "^3.2.45",
     "vue-i18n": "^9.2.2",
     "vue-router": "^4.1.6"

+ 7 - 7
pnpm-lock.yaml

@@ -49,7 +49,7 @@ specifiers:
   universal-cookie: ^4.0.4
   unplugin-auto-import: ^0.12.1
   unplugin-vue-components: ^0.22.12
-  vant: ^4.0.3
+  vant: ^4.0.11
   vite: ^4.0.2
   vite-plugin-compression: ^0.5.1
   vite-plugin-eruda: ^1.0.1
@@ -78,7 +78,7 @@ dependencies:
   pinia: 2.0.28_typescript@4.9.4+vue@3.2.45
   pinia-plugin-persistedstate: 3.0.1_pinia@2.0.28
   universal-cookie: 4.0.4
-  vant: 4.0.3_vue@3.2.45
+  vant: 4.0.11_vue@3.2.45
   vue: 3.2.45
   vue-i18n: 9.2.2_vue@3.2.45
   vue-router: 4.1.6_vue@3.2.45
@@ -1146,8 +1146,8 @@ packages:
     resolution: {integrity: sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==}
     dev: false
 
-  /@vant/use/1.4.3:
-    resolution: {integrity: sha512-rSnETN7P9qT1WbItMpQxBqe3cHeK2ZFYp1sCxWUXaTeI71TqA8sOdzC36ledZ36NQgFNTch9fsRPYOkrCgZfQA==}
+  /@vant/use/1.5.0:
+    resolution: {integrity: sha512-Dk7aMn7gLpoDew2tix/mjXpP0PoERWcxWh+pRY4xxl0MG4eeByAAyZSE6PgMpof4Yorqn7yq8KmeQcaVnxq2cg==}
     dev: false
 
   /@varlet/icons/2.4.2:
@@ -7754,13 +7754,13 @@ packages:
       spdx-correct: 3.1.1
       spdx-expression-parse: 3.0.1
 
-  /vant/4.0.3_vue@3.2.45:
-    resolution: {integrity: sha512-rBQCSdMyYxO9I3weQmdTxY28OkVLM7MSIjMx3qwMTsFONek6bodVGEYXF0+mzh/5EBMVXjqtHj6CvD6QphKkCg==}
+  /vant/4.0.11_vue@3.2.45:
+    resolution: {integrity: sha512-axVP6eHH4vGb5FQ2hqNhB5DykMSBQb0KK97HT4bVVFTYM81EJq1YImqOglzsVt3OC98NRoT01DIwt4y2n1iwVw==}
     peerDependencies:
       vue: ^3.0.0
     dependencies:
       '@vant/popperjs': 1.3.0
-      '@vant/use': 1.4.3
+      '@vant/use': 1.5.0
       vue: 3.2.45
     dev: false
 

+ 1 - 1
postcss.config.js

@@ -1,7 +1,7 @@
 const path = require('path');
 
 const judgeComponent = (file) => {
-  const ignore = ['vant', '@nutui', '@varlet'];
+  const ignore = ['@nutui', '@varlet'];
   return ignore.some((item) => path.join(file).includes(path.join('node_modules', item)));
 };
 

+ 35 - 2
src/App.vue

@@ -1,8 +1,38 @@
 <template>
   <router-view />
 </template>
-<script setup lang="ts"></script>
-
+<script setup lang="ts">
+import 'vant/lib/index.css'
+import { onMounted, computed } from 'vue'
+import { useUserStore } from '/@/store/modules/user';
+const userStore = useUserStore();
+const wxOpenId = computed(() => {
+  return userStore.getWxOpenId;
+});
+onMounted(async ()=>{
+  
+  let code=getUrlKey("code");//获取url参数code
+  if(wxOpenId.value){//
+    console.log('已登录',wxOpenId.value)
+  }else if(code){//存在code
+    userStore.setWxOpenId(code)
+    let { openid } = await wxLogin(code)
+  }else{//进行微信登录
+    getCodeApi(123)
+  }
+  // getCodeApi()
+})
+function getUrlKey(name){//获取url 参数
+   return decodeURIComponent((new RegExp('[?|&]'+name+'='+'([^&;]+?)(&|#|;|$)').exec(location.href)||[,""])[1].replace(/\+/g,'%20'))||null;
+ }
+function getCodeApi(state){//获取code   
+     let urlNow=encodeURIComponent(window.location.href);
+     let scope='snsapi_base';    //snsapi_userinfo   //静默授权 用户无感知
+     let appid='wxac3d59ea82d9b82a';
+     let url=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
+     window.location.replace(url);
+}
+</script>
 <style>
   #app {
     font-family: PingFang SC-Regular, PingFang SC;
@@ -11,4 +41,7 @@
     color: #2c3e50;
     background-color: var(--color-bg-1);
   }
+  .van-toast{
+    background:rgba(0, 0, 0, 0.7) !important
+  }
 </style>

+ 127 - 0
src/api/index.ts

@@ -1,4 +1,5 @@
 import useAxiosApi from '/@/utils/useAxiosApi';
+import request from "/@/utils/request";
 
 /**
  * 账号密码登录
@@ -10,3 +11,129 @@ export function loginPassword() {
     data: { name: '123' },
   });
 }
+
+/**
+ * 上传文件
+ * @returns UseAxiosReturn
+ */
+ export const uploadFiles = (param) =>
+   useAxiosApi(`/service/sale/sale/upload/file`, {
+    method: 'POST',
+    formData: param,
+  });
+
+/**
+ * 备报修
+ * @returns UseAxiosReturn
+ */
+ export const cameraRepair = (param) =>
+   useAxiosApi(`/service/sale/customer/cameraRepair`, {
+    method: 'POST',
+    data: param,
+  });
+
+/**
+ * 列表
+ * @returns UseAxiosReturn
+ */
+export function repairList(params) {
+  return request({
+    url: "/service/sale/customer/getRepairByOpenId",
+    method: "get",
+    data: params,
+    params,
+  });
+}
+  
+/**
+ * 工单详情
+ * @returns UseAxiosReturn
+ */
+ export const repairDetails = (repairId) =>
+ useAxiosApi(`/service/sale/repairInfo/details`, {
+  method: 'GET',
+  params:{repairId},
+});
+
+/**
+ * 工单流程
+ * @returns UseAxiosReturn
+ */
+ export const repairProcess = (repairId) =>
+   useAxiosApi(`/service/sale/repairInfo/process`, {
+    method: 'GET',
+    params:{repairId},
+  });
+  
+/**
+ * 确认维修
+ * @returns UseAxiosReturn
+ */
+//  export const confirmRepair = (param) =>
+//  useAxiosApi(`/service/sale/customer/confirmRepair`, {
+//   method: 'POST',    
+//   data: param,
+// });
+
+  
+/**
+ * 确认维修
+ * @returns UseAxiosReturn
+ */
+//  export const commentApi = (param) =>
+//  useAxiosApi(`/service/sale/customer/comment`, {
+//   method: 'POST',    
+//   data: param,
+// });
+
+// 注册
+export function confirmRepair(params) {
+  return request({
+    url: "/service/sale/customer/confirmRepair",
+    method: "post",
+    data: params,
+  });
+}
+
+// 注册
+export function commentApi(params) {
+  return request({
+    url: "/service/sale/customer/comment",
+    method: "post",
+    data: params,
+  });
+}
+
+// 获取用户信息
+export function getUserInfo() {
+  return request({
+    url: "/user/get",
+    method: "get",
+  });
+}
+
+// 获取工单收货地址
+export function getInvoiceAddress(repairId) {
+  return request({
+    url: "/service/sale/customer/getInvoiceAddress",
+    method: "get",
+    params:{repairId},
+});
+}
+
+// 申请开票
+export function invoiceApply(params) {
+  return request({
+    url: "/service/sale/customer/invoiceApply",
+    method: "post",
+    data: params,
+  });
+}
+// 获取工单收货地址
+export function wxLogin(code) {
+  return request({
+    url: "/service/sale/customer/wxLogin",
+    method: "get",
+    params:{code},
+});
+}

+ 1 - 0
src/layout/basic/index.vue

@@ -19,6 +19,7 @@
 
 <script lang="ts" setup name="BasicLayoutPage">
   import { useRouter } from 'vue-router';
+  import { ref, onMounted } from 'vue';
 
   // const tabItem = [
   //   { key: 'home', icon: 'home' },

+ 4 - 4
src/main.ts

@@ -1,9 +1,9 @@
 import { createApp } from 'vue';
 import App from './App.vue';
-// import { nutUiComponents } from './plugins/nutUI';
+import { nutUiComponents } from './plugins/nutUI';
+import { Toast } from 'vant';
 import { i18n } from '/@/i18n';
 import router from '/@/router';
-
 // ① 引入createPinia方法从pinia
 import { createPinia } from 'pinia'
 // ② 拿到pinia实例
@@ -13,11 +13,11 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
 // 2 pinia使用数据持久化插件
 pinia.use(piniaPluginPersistedstate)
 
+// import 'vant/lib/index.css'
 import './assets/font/iconfont.css';
 import './assets/app.css';
-
 const app = createApp(App);
-
+app.use(Toast);
 // 路由
 app.use(router);
 

+ 51 - 26
src/store/modules/home.ts

@@ -2,56 +2,81 @@
 import { defineStore } from 'pinia'
 //引入接口
 // import { httpPost } from '../request/api'
- 
+
 // 官方建议取名遵从 useXXXStore 形式
 // 'home' 为当前store的唯一标识 类似ID 
 // 取名建议与文件名称一致 便于记忆和管理
 // pinia舍弃了冗长的mutations属性 
 // 以下是pinia的一种写法 因与vuex相似 便于学习和记忆
-export const useHomeStore = defineStore('home',{
-    state:()=>{
-        return{
-            num:0,
-            token:''
+export const useHomeStore = defineStore('home', {
+    id: 'home',
+    state: () => {
+        return {
+            num: 0,
+            token: '',
+            statusList: {
+                '-1': '全部',
+                0: '待接单',
+                1: '待检测',
+                2: '待报价',
+                3: '待确认',
+                4: '已取消',
+                5: '待备料',
+                6: '维修中',
+                7: '待回收',
+                8: '待测试',
+                9: '待支付',
+                10: '待发货',
+                11: '已发货',
+                12: '已评价',
+                13: '待评价',
+                21: '待跟进',
+                22: '维修完成',
+                23: '已完结',
+                24: '待备料',
+                25: '已备料',
+                26: '待测试',
+                27: '测试完成',
+            }
         }
     },
     //state也可写成这样
     // state:()=>({
     //     num:0
     // }),
-    actions:{
-        changeNum(){
-        //这里可以使用this去拿到state里定义的变量 下面同理
-            this.num ++
+    actions: {
+        changeNum() {
+            //这里可以使用this去拿到state里定义的变量 下面同理
+            this.num++
         },
-        changeToken(){
-        // ts 实在学的不咋地 这里就先any了
-        // httpPost().then((res:any)=>{
-        //     this.token = res.data.data.token
-        //     })
+        changeToken() {
+            // ts 实在学的不咋地 这里就先any了
+            // httpPost().then((res:any)=>{
+            //     this.token = res.data.data.token
+            //     })
         }
     },
-    getters:{
+    getters: {
         // 这里取名不可与state里的变量一致 所以取名getNum
         //简写
-        getNum:state=>state.num,
+        getNum: state => state.num,
         //全写
-        // getNum:(state)=>{
-        //     return state.num
-        // }
-        getToken:state=>state.token,
+        getStatus:(state)=>{
+            return state.statusList
+        },
+        getToken: state => state.token,
     },
     //数据持久化配置 这里是当前所有变量都持久化
     // persist:true
-     
+
     //按需配置数据持久化 这里指定变量num保持持久化
-    persist:{
+    persist: {
         //默认名称为当前store唯一标识 这里即home
-        key:'storeHomeNum',
+        key: 'storeHomeNum',
         //默认localStorage 本地储存 
         //这里建议临时储存sessionStorage 也可写成window.sessionStorage
-        storage:sessionStorage,
+        storage: sessionStorage,
         //默认当前store里的所有变量都持久化
-        paths:['num']
+        paths: ['num']
     }
 })

+ 17 - 0
src/store/modules/user.ts

@@ -1,12 +1,14 @@
 import { loginPassword } from '/@/api';
 import { useCookies } from '@vueuse/integrations/useCookies';
 import { defineStore } from 'pinia';
+import { wxLogin } from '/@/api'
 
 const { VITE_TOKEN_KEY } = import.meta.env;
 const token = useCookies().get(VITE_TOKEN_KEY as string);
 
 interface StoreUser {
   token: string;
+  wxOpenId: string;
   info: Record<any, any>;
 }
 
@@ -14,19 +16,34 @@ export const useUserStore = defineStore('user',{
   id: 'user',
   state: (): StoreUser => ({
     token: token,
+    wxOpenId:'',
     info: {
       name:'test',
+      wxOpenId:'test1',
     },
   }),
   getters: {
     getUserInfo(): any {
       return this.info || {};
     },
+    getWxOpenId(): any {
+      return this.wxOpenId || useCookies().get('wxOpenId');
+    },
   },
   actions: {
     setInfo(info: any) {
       this.info = info ? info : '';
     },
+    setWxOpenId(code: string){
+      wxLogin(code).the(res => {
+        console.log('wxlogin',res)
+        let { openid } = res 
+        this.wxOpenId = openid ? openid : '';
+        if(openid){
+          useCookies.set('wxOpenId', openid)
+        }
+      })
+    },
     login() {
       return new Promise((resolve) => {
         const { execute } = loginPassword();

+ 85 - 0
src/utils/request.ts

@@ -0,0 +1,85 @@
+import axios, { AxiosResponse, AxiosRequestConfig } from "axios";
+import { showLoadingToast, closeToast, showFailToast  } from 'vant';
+import { useCookies } from '@vueuse/integrations/useCookies';
+const { VITE_TOKEN_KEY } = import.meta.env;
+const token = useCookies().get(VITE_TOKEN_KEY as string);
+interface ResponseData<T = any> {
+  code: number;
+  message: string;
+  data: T;
+}
+let loadingCount = 0
+const MODE = import.meta.env.MODE; // 环境变量
+console.log("MODE: ", MODE);
+const service = axios.create({
+  // 开发环境请求本地代理,生产环境请求域名
+  // 开发环境在接口面前自动加上 api,配合 本地代理使用,无需在每个接口前写 /api
+//   baseURL: MODE === "development" ? "/service" : "http://ab.svip52.com/api",
+  headers: {
+    "X-Requested-With": "XMLHttpRequest",
+    "Content-Type": "application/json",
+  },
+});
+// 两层泛型,一层是 axios 提供的,AxiosRequestConfig
+// 一层是自定义的,ResponseData<T>
+// 实现响应的 data 以及 data.data 的类型提示
+// request 函数传入一个 data.data 的类型
+const request = async <T = any>(
+  config: AxiosRequestConfig
+): Promise<ResponseData<T>> => {
+  // 请求前加上 token
+  service.interceptors.request.use((config) => {
+    addToast()
+    console.log('confige',config)
+    if (config?.headers) {
+      config.headers.Authorization = localStorage.getItem("token") || "";
+    }
+    return config;
+  });
+    //response拦截器
+    service.interceptors.response.use(
+    response => {
+        reduce()
+        return response;
+    },
+    error => {
+        reduce()
+        return Promise.reject(error)
+    }
+    );
+  const { data } = await service.request<ResponseData<T>>(config);
+  // 请求失败
+  console.log('request',data)
+//   reduce()
+  if (typeof data !== "object") {
+    showFailToast('服务器错误,请联系管理员');
+    return Promise.reject(data);
+  }
+  if (data.code != 200) {
+    if (data.message) showFailToast(data.message);
+    // 401,token 过期
+    if (data.code == 401) {
+      localStorage.removeItem("token");
+      location.href = "#/login";
+    }
+    return Promise.reject(data);
+  }
+  return data.data || data;
+};
+function addToast(){
+    showLoadingToast({
+      message: '加载中...',
+      forbidClick: true,
+      duration: 0,
+    });
+    loadingCount++
+    console.log('loadingCount+',loadingCount)
+  }
+function reduce(){
+    loadingCount--
+    if (loadingCount == 0) {
+      closeToast()
+    }
+    console.log('loadingCount-',loadingCount)
+}
+export default request;

+ 26 - 18
src/utils/useAxiosApi.ts

@@ -1,7 +1,7 @@
 import { useAxios } from '@vueuse/integrations/useAxios';
 import axios, { AxiosRequestConfig } from 'axios';
-import { showToast } from 'vant/lib/toast';
-
+import { showLoadingToast, closeToast, showFailToast  } from 'vant';
+let loadingCount = 0
 // create an axios instance
 const instance = axios.create({
   withCredentials: false,
@@ -11,16 +11,18 @@ const instance = axios.create({
 // request interceptor
 instance.interceptors.request.use(
   (config) => {
-    // do something before request is sent
     // const token = store.state.user.token;
-
     // if (token) {
-    //   // let each request carry token
     //   config.headers = {
     //     ...config.headers,
-    //     Authorization: `Bearer ${token}`
     //   };
     // }
+    showLoadingToast({
+      message: '加载中...',
+      forbidClick: true,
+      duration: 0,
+    });
+    loadingCount++
     return config;
   },
   (error) => {
@@ -43,23 +45,28 @@ instance.interceptors.response.use(
    * You can also judge the status by HTTP Status Code
    */
   (response) => {
+    console.log('response',response);
+    loadingCount--
+    if (loadingCount == 0) {
+      closeToast()
+    }
     const res = response.data;
     // if the custom code is not 200, it is judged as an error.
     if (res.code !== 200) {
-      showToast(res.msg);
-      // 412: Token expired;
-      if (res.code === 412) {
-        // store.dispatch('user/userLogout');
-      }
-      return Promise.reject(res.msg || 'Error');
+      showFailToast(res.message);
+      return Promise.reject(res || 'Error');
     } else {
-      return res;
+      return Promise.resolve(res); //进行中 
     }
   },
   (error) => {
-    console.log('err' + error);
-    showToast(error.message);
-    return Promise.reject(error.message);
+    console.log('error',error.response);
+    loadingCount--
+    if (loadingCount == 0) {
+      closeToast()
+    }
+    showFailToast('服务器错误,请联系管理员');
+    return Promise.reject(error.response);
   },
 );
 
@@ -67,6 +74,7 @@ instance.interceptors.response.use(
  * reactive useFetchApi
  */
 
-export default function useAxiosApi(url: string, config: AxiosRequestConfig) {
+
+export default function useAxiosApi(url: string, config?: any): any {
   return useAxios(url, config, instance);
-}
+ }

+ 35 - 18
src/views/detail/evaluate.vue

@@ -3,7 +3,7 @@
   <div class="evaluate">
     <div class="evaluate_top">
       <van-field
-        v-model="evaluate.message"
+        v-model="evaluate.comment"
         rows="3"
         autosize
         :border="false"
@@ -14,41 +14,58 @@
       />
       <div class="star">
         <span class="text">本次服务</span>
-        <van-rate v-model="evaluate.value" :size="25" color="#ffd21e" void-icon="star" void-color="#eee" />
+        <van-rate v-model="evaluate.starRank" :size="25" color="#ffd21e" void-icon="star" void-color="#eee" />
       </div>
     </div>
     <div class="but">
-      <van-button type="primary" block>块级元素</van-button>
+      <van-button type="primary" @click="handlComment" block>提交</van-button>
     </div>
   </div>
 </template>
   
   <script lang="ts" setup name="detailPage">
-import { reactive } from 'vue';
+import { ref, unref  } from 'vue';
+import { showToast } from 'vant';
+import { commentApi } from '/@/api';
+import { useRouter } from 'vue-router';
+const router = useRouter();
+const { id } = unref(router.currentRoute)?.params;
 const evaluate = ref({
-  message: '',
-  value: 2.5,
+  comment: '',
+  starRank: 2.5,
 });
+async function handlComment() {
+  const { comment, starRank} = evaluate.value
+  if(!comment){
+    return showToast('请输入您的评论')
+  }
+  const res = await commentApi({
+    repairId: id,
+    comment,
+    starRank,
+  });
+  console.log('evaluate', res);
+}
 </script>
  <style lang="scss" >
 .evaluate {
   min-height: 100vh;
   background-color: #f5f5f5;
-  .evaluate_top{
+  .evaluate_top {
     background-color: #fff;
-    .star{
-        line-height: 25px;
-        padding: 11px 16px;
-        border-top: 1px solid #E7E7E7;
-        .text{
-            margin-right: 15px;
-            font-family: PingFang SC-Regular, PingFang SC;
-            font-weight: 400;
-            color: #333333;
-        }
+    .star {
+      line-height: 25px;
+      padding: 11px 16px;
+      border-top: 1px solid #e7e7e7;
+      .text {
+        margin-right: 15px;
+        font-family: PingFang SC-Regular, PingFang SC;
+        font-weight: 400;
+        color: #333333;
+      }
     }
   }
-  .but{
+  .but {
     padding: 25px 15px;
   }
 }

+ 157 - 140
src/views/detail/index.vue

@@ -1,57 +1,66 @@
 // 评价页面
 <template>
   <div class="page">
-    <div class="stepList item_content" :key="stepShow">
-      <div class="stepList_title">维修单号 2022101200001</div>
+    <div class="stepList item_content" :key="stepShow+'123'">
+      <div class="item_content_top">
+        <div class="stepList_title">维修单号 {{id}}</div>
+        <!-- <van-button class="top_but" type="primary" size="small">去支付</van-button> -->
+        <van-button v-if="detailData.repairerVo?.status == 3" size="small" @click="goRoute(`/repair/${id}`)" type="primary" >待确认</van-button>
+        <van-button v-if="detailData.repairerVo?.status == 9" size="small" @click="goRoute(`/payment/${id}`)" type="primary" >支付</van-button>
+        <van-button v-if="detailData.repairerVo?.status == 13" size="small" @click="goRoute(`/evaluate/${id}`)" type="primary" >评价</van-button>
+        <van-button v-if="detailData.repairerVo?.status == 10" size="small" @click="goRoute(`/invoice/${id}`)" type="primary" >申请开票</van-button>
+      </div>
       <transition-group name="van-fade">
-      <!-- <div v-show="stepShow">Slide Right</div> -->
-      <div class="border stepItem" v-for="(item, index) in 3" :key="index+stepShow" v-show="stepShow?true: index<1">
-        <div class="step">
-            <div class="step_title">维修完毕</div>
-            <div>前台取回 / 快递寄回  SF151315352892</div>
-            <div>检测结果: 镜头失焦</div>
-            <div>所需备件: 镜头x2、电池x1</div>
-            <div>机器外观: 外壳有轻微划痕</div>
+        <!-- <div v-show="stepShow">Slide Right</div> -->
+        <div class="border stepItem" v-for="(item, index) in processList" :key="index + stepShow" v-show="stepShow ? true : index < 1">
+          <div class="step">
+            <div class="step_title">{{item.remark}}</div>
+            <div v-if="item.customerAddress">{{item.customerAddress.sendType == 0?' 前台送修':`快递寄送 ${item.customerAddress?.sendTrackingNum}`}}</div>
+            <div v-if="item.customerAddress">{{item.customerAddress.getType == 0?' 前台取回':`快递寄回 ${item.customerAddress?.getTrackingNum}`}}</div>
+            <div v-if="item.customerAddress">前台取回 </div>
+            <div v-if="item.repairRegisterVo?.checkResult">检测结果: {{item.repairRegisterVo?.checkResult}}</div>
+            <div v-if="item.repairRegisterVo?.partNamesStr">所需备件: {{item.repairRegisterVo?.partNamesStr}}</div>
+            <div v-if="item.repairRegisterVo?.orderFaultMsg">机器外观: {{item.orderReceiving?.orderFaultMsg}}</div>
             <div class="imgList">
-              <img src="../../assets/image/case1.jpg" v-for="imgItem in 6" :key="imgItem" alt="">
+              <img :src="imgItem" v-for="imgItem in item.imagesInfo" :key="imgItem + index" alt="" />
             </div>
-            <div class="step_time">10-14 12:30</div>
-            <div class="doct" :class="index == 0?'oneSpot':'Spot'"></div>
+            <div class="step_time">{{dayjs(item.createTime).format('MM-DD hh:mm')}}</div>
+            <div class="doct" :class="index == 0 ? 'oneSpot' : 'Spot'"></div>
+          </div>
         </div>
-      </div>
-    </transition-group>
-      <van-divider>
+      </transition-group>
+      <van-divider v-if="processList?.length >1">
         <div @click="handleShow">
-          <van-icon :name="stepShow?'arrow-down':'arrow-up'" />
-          {{stepShow?"展开":"收起"}}
+          <van-icon :name="stepShow ? 'arrow-down' : 'arrow-up'" />
+          {{ stepShow ? '展开' : '收起' }}
         </div>
       </van-divider>
     </div>
-    <div class="page_top item_content">
+    <div class="page_top item_content" v-if="detailData.customer">
       <div class="title">客户信息</div>
       <div class="content">
         <div class="cost_list" style="border-bottom: none">
           <div class="item">
             <span>公司名称</span>
-            <span>某某某某公司</span>
+            <span>{{detailData.customer?.companyName}}</span>
           </div>
           <div class="item">
             <span>联系人</span>
-            <span>老王</span>
+            <span>{{detailData.customer?.customerName}}</span>
           </div>
           <div class="item">
             <span>联系电话</span>
-            <span>110</span>
+            <span>{{detailData.customer?.phone}}</span>
           </div>
         </div>
       </div>
     </div>
-    <div class="page_top item_content">
+    <div class="page_top item_content" v-if="detailData.orderReceivingVo">
       <div class="title">故障信息</div>
       <div class="content">
-        <div class="text">四维看看 FJ6OA4W89H 镜头拆坏、底盖脱落、</div>
-        <div class="imgList">
-          <img src="../../assets/image/case1.jpg" v-for="imgItem in 6" :key="imgItem" alt="">
+        <div class="text">{{cameraType[detailData.repairerVo?.cameraType]}} {{detailData.repairerVo?.cameraSnCode}} {{detailData.repairerVo?.faultMsg}}</div>
+        <div class="imgList" v-if="detailData.repairerVo">
+          <img :src="imgItem" v-for="imgItem in detailData.repairerVo.faultImg" :key="imgItem" alt="" />
         </div>
       </div>
     </div>
@@ -59,123 +68,126 @@
       <div class="title">费用明细</div>
       <div class="content">
         <div class="cost_list">
-          <div class="item" v-for="item in repair.costList" :key="item.name">
+          <div class="item" v-for="item in detailData.priceList" :key="item.name">
             <span>{{ item.name }}</span>
-            <span>¥{{ item.value }} x{{ item.count }}</span>
+            <span>¥{{ item.price }} x{{ item.count }}</span>
           </div>
         </div>
         <div class="cell" style="border: none">
           <span>维修费用</span>
-          <span class="colortext">¥1000.00</span>
+          <span class="colortext">¥{{ priceCount(detailData?.priceList || []) }}</span>
         </div>
       </div>
     </div>
-    <div class="page_top item_content">
+    <div class="page_top item_content" v-if="detailData.customerAddress">
       <div class="title">运输信息</div>
       <div class="content">
         <div class="cost_list">
           <div class="item">
             <span>送修方式</span>
-            <span>快递寄送</span>
+            <span>{{detailData.customerAddress.sendType == 0 ?'前台送修':'快递寄送'}}</span>
           </div>
-          <div class="item">
+          <div class="item" v-if="detailData.customerAddress.sendType != 0">
             <span>快递单号</span>
-            <span>SF473827489237</span>
-          </div>
-          <div class="item">
-            <span>送修方式</span>
-            <span>快递寄送</span>
+            <span>{{detailData.customerAddress.sendTrackingNum}}</span>
           </div>
           <div class="item">
             <span>取回方式</span>
-            <span>快递寄送</span>
+            <span>{{detailData.customerAddress.getType == 0 ?'前台取回':'快递寄回'}}</span>
           </div>
-          <div class="item">
+          <div class="item" v-if="detailData.customerAddress.getType != 0">
             <span>快递单号</span>
-            <span>SF1513153523892</span>
+            <span>{{detailData.customerAddress.getTrackingNum}}</span>
           </div>
-          <div class="item">
+          <div class="item" v-if="detailData.customerAddress.getType != 0">
             <span>收件人</span>
-            <span>老王</span>
+            <span>{{detailData.customerAddress.getAddrName}}</span>
           </div>
-          <div class="item">
+          <div class="item" v-if="detailData.customerAddress.getType != 0">
             <span>收件人电话</span>
-            <span>138 2222 5555</span>
+            <span>{{detailData.customerAddress.getAddrPhone}}</span>
           </div>
-          <div class="item">
+          <div class="item" v-if="detailData.customerAddress.getType != 0">
             <span>收件地址</span>
-            <span>广东省广州市越秀区某大厦某某公司</span>
+            <span>{{detailData.customerAddress.getAddress}}</span>
           </div>
         </div>
       </div>
     </div>
 
-    <div class="page_top item_content">
+    <div class="page_top item_content" v-if="detailData.RepairComment">
       <div class="title">评价信息</div>
       <div class="content">
         <div class="cost_list" style="border-bottom: none">
           <div class="item">
             <span>内容</span>
-            <span>整体态度和效率都不错</span>
+            <span>{{detailData.RepairComment?.comment}}</span>
           </div>
           <div class="item">
             <span>评分</span>
-            <span>4.5分</span>
+            <span>{{detailData.RepairComment?.starRank}}分</span>
           </div>
         </div>
       </div>
     </div>
-    <!-- <div class="but">
-      <span class="tips">确认维修后,将直接开始维修。维修费用待维修完成后支付</span>
-      <van-button type="primary" color="#00B3EC" block>块级元素</van-button>
-      <van-button type="primary" color="#00B3EC" plain block>块级元素</van-button>
-    </div> -->
   </div>
 </template>
   
-  <script lang="ts" setup name="detailPage">
-import { reactive } from 'vue';
-const stepShow = ref(true)
-const repair = reactive({
-  info: [
-    {
-      name: '维修单号',
-      value: '2022101200001',
-    },
-    {
-      name: '设备信息',
-      value: '四维看看 FJ6OA4W89H',
-    },
-    {
-      name: '检测结果',
-      value: '3号镜头失焦',
-    },
-  ],
-  evaluate:{
-    message:'haisuanbucuo',
-    value:5,
-  },
-  costList: [
-    {
-      name: '镜头模组',
-      value: 700.0,
-      count: 1,
-    },
-    {
-      name: '镜头模组',
-      value: 700.0,
-      count: 1,
-    },
-    {
-      name: '镜头模组',
-      value: 700.0,
-      count: 1,
-    },
-  ],
+<script lang="ts" setup name="detailPage">
+import { useRouter } from 'vue-router';
+import { reactive, ref, onMounted, unref } from 'vue';
+import { repairProcess, repairDetails } from '/@/api';
+import * as dayjs from 'dayjs'
+const { currentRoute } = useRouter();
+const router = useRouter();
+const { id } = unref(currentRoute)?.params
+const stepShow = ref<boolean>(true);
+const cameraType = {
+    0:'四维看看',
+    1:'四维看见',
+    2:'四维深时',
+  }
+let detailData = ref({
+  customer:{},
+  customerAddress:{},
+  repairerVo:{},
+  RepairTestVo:{},
+  repairRegisterVo:{},
+  orderReceivingVo:{},
+  repairPay:{},
+  RepairComment:{},
+  priceList:[],
 });
-const handleShow = () => {
-  stepShow.value = !stepShow.value
+let processList = ref([])
+onMounted(() => {
+  console.log('onMounted',id)
+  getDetaile();
+});
+function priceCount(list){
+  let price = 0
+  list.map(ele => {
+    price = (ele.price * ele.count) + price
+  })
+  return price
 }
+const getDetaile = async () => {
+  const { response } = await repairDetails(id);
+  let detaile = unref(response)?.data;
+  detailData.value = detaile
+  const resProcess = await repairProcess(id);
+  console.log('resProcess',resProcess)
+  let process = unref(resProcess?.response)?.data;
+  processList.value = process
+  console.log('getDetaile',detaile,process)
+};
+const handleShow = () => {
+  stepShow.value = !stepShow.value;
+};
+const goRoute = (path) => {
+  console.log('goRoute',path)
+  if (!path) return;
+  router.push(path);
+};
 </script>
  <style lang="scss" >
 .page {
@@ -192,10 +204,10 @@ const handleShow = () => {
       font-weight: 500;
       color: #000000;
       padding: 15px 0;
-      margin:  0 15px;
+      margin: 0 15px;
       border-bottom: 1px solid #e7e7e7;
     }
-    .content{
+    .content {
       padding: 24px 15px;
     }
     .item {
@@ -203,42 +215,48 @@ const handleShow = () => {
       justify-content: space-between;
       align-items: center;
       line-height: 30px;
+      font-size: 14px;
       // margin-bottom: 8px;
     }
-    
-    .imgList{
-      img{
+
+    .imgList {
+      img {
         height: 64px;
         width: 64px;
         padding: 0 8px 0 0;
       }
     }
   }
-  .stepList{
+  .stepList {
     padding: 24px 16px;
-    &_title{
+    .item_content_top{
+      padding-bottom: 15px;
+      margin-bottom: 24px;
+      border-bottom: 1px solid #f5f5f5;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+    &_title {
       font-size: 14px;
       font-family: PingFang SC-Medium, PingFang SC;
       font-weight: 500;
       color: #000000;
-      padding-bottom: 15px;
-      margin-bottom: 24px;
-      border-bottom: 1px solid #F5F5F5;
     }
-    .stepItem{
+    .stepItem {
       transition: all 3s 2s linear;
     }
-    .step{
-      &:last-child{
+    .step {
+      &:last-child {
         // border: none;
       }
       padding: 0 15px;
-      border-left: 1px solid #F5F5F5;
-      &_title{
+      border-left: 1px solid #f5f5f5;
+      &_title {
         font-size: 14px;
         line-height: 22px;
       }
-      &_time{
+      &_time {
         font-size: 10px;
         font-family: PingFang SC-Regular, PingFang SC;
         font-weight: 400;
@@ -246,34 +264,33 @@ const handleShow = () => {
         line-height: 14px;
         padding-bottom: 24px;
       }
-    font-size: 12px;
-    font-family: PingFang SC-Regular, PingFang SC;
-    font-weight: 400;
-    color: #333333;
-    line-height: 30px;
-    position: relative;
-    .doct{
-      display: inline-block;
-      position: absolute;
-      left: 0;
-      top: 0;
-      width: 8px;
-      height: 8px;
-      border-radius: 50%;
-      transform: translat(-50%,-50%);
-    }
-    .oneSpot{
-      border: 4px solid #00B3EC;
-      left: -8px;
-      top: 4px;
-      background: #fff;
-    }
-    .Spot{
-      background: #CCCCCC;
-      left: -4px;
-      top: 8px;
-    }
-
+      font-size: 12px;
+      font-family: PingFang SC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #333333;
+      line-height: 30px;
+      position: relative;
+      .doct {
+        display: inline-block;
+        position: absolute;
+        left: 0;
+        top: 0;
+        width: 8px;
+        height: 8px;
+        border-radius: 50%;
+        transform: translat(-50%, -50%);
+      }
+      .oneSpot {
+        border: 4px solid #00b3ec;
+        left: -8px;
+        top: 4px;
+        background: #fff;
+      }
+      .Spot {
+        background: #cccccc;
+        left: -4px;
+        top: 8px;
+      }
     }
   }
   .colortext {
@@ -312,7 +329,7 @@ const handleShow = () => {
         // bottom: 1px solid #e7e7e7;
       }
     }
-    .text{
+    .text {
       line-height: 30px;
     }
   }

+ 91 - 31
src/views/detail/invoice.vue

@@ -7,30 +7,22 @@
       </div>
       <div class="cell">
         <span>开票金额</span>
-        <span class="colortext">¥1000.00</span>
+        <span class="colortext">¥{{ formData.invoiceAmount }}</span>
       </div>
     </div>
     <div class="form invoiceForm">
       <van-form @submit="onSubmit" style="margin-top: 10px; background: #fff">
-        <van-cell-group inset>
-          <van-field
-            input-align="right"
-            v-model="formData.nameL"
-            name="用户名"
-            label="公司名称"
-            placeholder="请填写公司名称"
-            :rules="[{ required: true, message: '请填写公司名称' }]"
-          />
-          <van-field name="radio" label="单选框" input-align="right">
+          <van-field name="radio" label="发票类型" input-align="right">
           <template #input>
-            <van-radio-group v-model="formData.checkeds" direction="horizontal">
-              <van-radio name="1">前台送修</van-radio>
-              <van-radio name="2">快递寄送</van-radio>
+            <van-radio-group v-model="formData.invoiceType" direction="horizontal">
+              <van-radio :name="0">普通发票</van-radio>
+              <van-radio :name="1">专用发票</van-radio>
             </van-radio-group>
           </template>
         </van-field>
+        <van-cell-group inset>
           <van-field
-            v-model="formData.nameL"
+            v-model="formData.invoiceHead"
             input-align="right"
             name="发票抬头"
             label="发票抬头"
@@ -38,7 +30,7 @@
             :rules="[{ required: true, message: '请填写发票抬头' }]"
           />
           <van-field
-            v-model="formData.nameL"
+            v-model="formData.invoiceNum"
             input-align="right"
             name="税号"
             label="税号"
@@ -46,55 +38,123 @@
             :rules="[{ required: true, message: '请填写税号' }]"
           />
           <van-field
-            v-model="formData.nameL"
+            v-model="formData.bank"
             input-align="right"
             name="开户银行"
             label="开户银行"
             placeholder="请填写开户银行"
+            :rules="[{ required: true, message: '请填写开户银行' }]"
           />
           <van-field
-            v-model="formData.nameL"
+            v-model="formData.bankAccount"
             input-align="right"
             name="银行账户"
             label="银行账户"
             placeholder="请填写银行账户"
+            :rules="[{ required: true, message: '请填写银行账户' }]"
           />
           <van-field
-            v-model="formData.nameL"
+            v-model="formData.address"
             input-align="right"
             name="企业地址"
             label="企业地址"
             placeholder="请填写企业地址"
+            :rules="[{ required: true, message: '请填写企业地址' }]"
           />
           <van-field
-            v-model="formData.nameL"
+            v-model="formData.phone"
             input-align="right"
             name="企业电话"
             label="企业电话"
             placeholder="请填写企业电话"
+            :rules="[{ required: true, message: '请填写企业电话' }]"
+          />
+          <van-field v-if="formData.invoiceType == 0"
+            v-model="formData.invoiceEmail"
+            input-align="right"
+            name="电子邮箱"
+            label="电子邮箱"
+            placeholder="请填写接收发票邮箱"
+            :rules="[{ required: true, message: '请填写接收发票邮箱' }]"
+          />
+          <van-field v-if="formData.invoiceType == 1"
+            v-model="formData.getAddress"
+            input-align="right"
+            name="收件地址"
+            label="收件地址"
+            placeholder="请填写收件地址"
+            :rules="[{ required: true, message: '请填写收件地址' }]"
+          />
+          <van-field  v-if="formData.invoiceType == 1"
+            v-model="formData.getAddrName"
+            input-align="right"
+            name="收件人"
+            label="收件人"
+            placeholder="请填写收件人姓名"
+            :rules="[{ required: true, message: '请填写收件人姓名' }]"
+          />
+          <van-field v-if="formData.invoiceType == 1"
+            v-model="formData.getAddrPhone"
+            input-align="right"
+            name="收件人电话"
+            label="收件人电话"
+            placeholder="请填写收件人电话"
+            :rules="[{ required: true, message: '请填写手机号' }, rulesMobile]"
           />
         </van-cell-group>
-      </van-form>
       <div class="but">
-          <van-button type="primary" block native-type="submit">提交</van-button>
+          <van-button round block type="primary" native-type="submit"> 提交 </van-button>
         </div>
+      </van-form>
     </div>
   </div>
 </template>
   
   <script lang="ts" setup name="detailPage">
-import { reactive } from 'vue';
-const formData = reactive({
-  nameL: '',
-  lxr: '',
-  lxdh: '',
-  sncode: '',
-  gzms: '',
-  message: '',
-  file: [],
+import { ref, onMounted, unref } from 'vue';
+import { getInvoiceAddress, invoiceApply } from '/@/api'
+import { useRouter } from 'vue-router';
+const router = useRouter();
+const { id } = unref(router.currentRoute)?.params;
+const rulesMobile = {
+  // 自定义校验规则
+  validator: (value) => {
+    return /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/.test(value);
+  },
+  message: '请输入正确格式的手机号码',
+  trigger: 'onBlur',
+};
+const formData = ref({
+  address: '',
+  bankAccount: '',
+  bank: '',
+  invoiceEmail: '',
+  invoiceNum: '',
+  invoiceHead: '',
   checked: '1',
   checkeds: '1',
+  invoiceAmount:0,
+  invoiceType:0,
+  phone:'',
+  getAddrName:'',
+  getAddrPhone:'',
+  getAddress:'',
 });
+onMounted( async ()=>{
+  let { data } = await getInvoiceAddress('20230227175908840')
+  console.log('payAmount',data)
+  formData.value.invoiceAmount = data.payAmount
+  formData.value.getAddrName = data.getAddrName
+  formData.value.getAddrPhone = data.getAddrPhone
+  formData.value.getAddress = data.getAddress
+})
+async function onSubmit() {
+  const res = await invoiceApply({
+    ...formData.value,
+    repairId:id,
+  })
+  console.log(res)
+}
 </script>
  <style lang="scss" >
  .van-cell-group{

+ 47 - 31
src/views/detail/payment.vue

@@ -1,53 +1,69 @@
 <template>
   <div class="evaluate">
     <div class="evaluate_top">
-        <div class="cell">
-            <span>维修费用</span>
-            <span class="colortext">¥1000.00</span>
-        </div>
-        <div class="cell border">
-            <span>单位</span>
-            <span>四维时代</span>
-        </div>
+      <div class="cell">
+        <span>维修费用</span>
+        <span class="colortext">¥{{detail.amount}}</span>
+      </div>
+      <div class="cell border">
+        <span>单位</span>
+        <span>四维时代</span>
+      </div>
     </div>
     <div class="but">
-      <van-button type="primary" block>块级元素</van-button>
+      <van-button type="primary"  block>支付</van-button>
     </div>
   </div>
 </template>
   
-  <script lang="ts" setup name="detailPage">
-import { reactive } from 'vue';
-const evaluate = ref({
-  message: '',
-  value: 2.5,
-});
+<script lang="ts" setup name="detailPage">
+  import { reactive, ref, onMounted, unref } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { repairDetails } from '/@/api';
+  const router = useRouter();
+  const { id } = unref(router.currentRoute)?.params;
+  const detail = ref({
+    // priceList: [],
+    amount: 0,
+  });
+  onMounted(async () => {
+    const { response } = await repairDetails(id);
+    let detaile = unref(response)?.data,amount = 0;
+    // detail.value.priceList = 
+    detaile.priceList.map(ele =>{
+      amount = amount + (ele.price * ele.count)
+      // return ele
+    })
+    detail.value.amount = amount
+  });
+   // 判断是否在微信浏览器  1为微信浏览器 2为其他  这个方法定义在外面,后面也会用到
+
 </script>
  <style lang="scss" >
 .evaluate {
   min-height: 100vh;
   background-color: #f5f5f5;
-  .evaluate_top{
+  .evaluate_top {
     background-color: #fff;
-    .border{
-        border-top: 1px solid #E7E7E7;
+    .border {
+      border-top: 1px solid #e7e7e7;
     }
-    .colortext{
-        color: #E34D59;
+    .colortext {
+      color: #e34d59;
     }
-    .cell{
-        height: 48px;
-        padding: 0 15px;
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        font-size: 14px;
-        font-family: PingFang SC-Regular, PingFang SC;
-        font-weight: 400;
-        color: #333333;
+    .cell {
+      height: 48px;
+      padding: 0 15px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      font-size: 14px;
+      font-family: PingFang SC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #333333;
     }
   }
-  .but{
+  .but {
     padding: 25px 15px;
   }
 }

+ 104 - 90
src/views/detail/repair.vue

@@ -2,125 +2,139 @@
 <template>
   <div class="page">
     <div class="repairInfo">
-        <div class="cell border" v-for="item in repair.info" :key="item.name">
-            <span>{{item.name}}</span>
-            <span>{{item.value}}</span>
-        </div>
+      <div class="cell border">
+        <span>维修单号</span>
+        <span>{{ id }}</span>
+      </div>
+      <div class="cell border">
+        <span>设备信息</span>
+        <span>{{ detail.repairerVo?.cameraSnCode }}</span>
+      </div>
+      <div class="cell border">
+        <span>检测结果</span>
+        <span>{{ detail.repairRegisterVo?.checkResult }}</span>
+      </div>
     </div>
     <div class="page_top">
-        <div class="title">费用明细</div>
-        <div class="cost_list">
-            <div class="item"  v-for="item in repair.costList" :key="item.name">
-                <span>{{item.name}}</span>
-                <span>¥{{ item.value }} x{{ item.count }}</span>
-            </div>
-        </div>
-        <div class="cell" style="border:none">
-            <span>维修费用</span>
-            <span class="colortext">¥1000.00</span>
+      <div class="title">费用明细</div>
+      <div class="cost_list">
+        <div class="item" v-for="item in detail.priceList" :key="item.name">
+          <span>{{ item.name }}</span>
+          <span>¥{{ item.price }} x{{ item.count }}</span>
         </div>
+      </div>
+      <div class="cell" style="border: none">
+        <span>维修费用</span>
+        <span class="colortext">¥{{ detail.amount }}</span>
+      </div>
     </div>
     <div class="but">
       <span class="tips">确认维修后,将直接开始维修。维修费用待维修完成后支付</span>
-      <van-button type="primary" color="#00B3EC" block>块级元素</van-button>
-      <van-button type="primary" color="#00B3EC" plain  block>块级元素</van-button>
+      <van-button type="primary" color="#00B3EC" @click="hanldConfirm(0)" block>确认维修</van-button>
+      <van-button type="primary" color="#00B3EC" @click="hanldConfirm(1)" plain block>取消维修</van-button>
     </div>
   </div>
 </template>
   
   <script lang="ts" setup name="detailPage">
-import { reactive } from 'vue';
-const repair = reactive({
-    info:[{
-        name:'维修单号',
-        value:'2022101200001',
-    },{
-        name:'设备信息',
-        value:'四维看看 FJ6OA4W89H',
-    },{
-        name:'检测结果',
-        value:'3号镜头失焦',
-    }],
-    costList:[{
-        name:'镜头模组',
-        value:700.00,
-        count:1,
-    },{
-        name:'镜头模组',
-        value:700.00,
-        count:1,
-    },{
-        name:'镜头模组',
-        value:700.00,
-        count:1,
-    }]
+import { reactive, ref, onMounted, unref } from 'vue';
+import { useRouter } from 'vue-router';
+import { showToast } from 'vant';
+import { repairDetails, confirmRepair } from '/@/api';
+const router = useRouter();
+const { id } = unref(router.currentRoute)?.params;
+const detail = ref({
+  amount: 0,
+  priceList: [],
+  repairerVo: {},
+  repairRegisterVo: {},
+});
+onMounted(async () => {
+  const { response } = await repairDetails(id);
+  let detaile = unref(response)?.data,
+    amount = 0;
+  detail.value.repairerVo = detaile.repairerVo;
+  detail.value.repairRegisterVo = detaile.repairRegisterVo;
+  detail.value.priceList = detaile.priceList.map((ele) => {
+    amount = amount + ele.price * ele.count;
+    return ele;
+  });
+  detail.value.amount = amount;
 });
+const hanldConfirm = async (confirm) => {
+  const {code} = await confirmRepair({ repairId: id, confirm });
+  if (code == 200 || !code) {
+    showToast('操作成功');
+    setTimeout(() => {
+      router.go(-1);
+    }, 500);
+  }
+};
 </script>
  <style lang="scss" >
 .page {
   min-height: 100vh;
   background-color: #f5f5f5;
-  
-    .title{
-        font-size: 14px;
-        font-family: PingFang SC-Medium, PingFang SC;
-        font-weight: 500;
-        color: #000000;
-        padding: 15px;
-    }
-    .colortext{
-        color: #E34D59;
-    }
-    .cell{
-        border-top: 1px solid #E7E7E7; 
-        &:first-child{
-            border-top: none; 
-        }
-        height: 48px;
-        padding: 0 15px;
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        font-size: 14px;
-        font-family: PingFang SC-Regular, PingFang SC;
-        font-weight: 400;
-        color: #333333;
+
+  .title {
+    font-size: 14px;
+    font-family: PingFang SC-Medium, PingFang SC;
+    font-weight: 500;
+    color: #000000;
+    padding: 15px;
+  }
+  .colortext {
+    color: #e34d59;
+  }
+  .cell {
+    border-top: 1px solid #e7e7e7;
+    &:first-child {
+      border-top: none;
     }
+    height: 48px;
+    padding: 0 15px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 14px;
+    font-family: PingFang SC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #333333;
+  }
   .page_top {
     background-color: #fff;
     border-radius: 4px 4px 4px 4px;
-    .cost_list{
-        margin: 0 15px;
-        padding-top: 24px;
-        border: {
-            top:1px solid #E7E7E7; 
-            bottom:1px solid #E7E7E7; 
-        }
-        .item{
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            margin-bottom: 8px;
-        }
+    .cost_list {
+      margin: 0 15px;
+      padding-top: 24px;
+      border: {
+        top: 1px solid #e7e7e7;
+        bottom: 1px solid #e7e7e7;
+      }
+      .item {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 8px;
+      }
     }
-
   }
-  .repairInfo{
+  .repairInfo {
     background-color: #fff;
     margin-bottom: 12px;
     border-radius: 4px 4px 4px 4px;
   }
-  .but{
+  .but {
     padding: 25px 15px;
-    .tips{
-        font-size: 12px;
-        font-family: PingFang SC-Regular, PingFang SC;
-        font-weight: 400;
-        color: #999999;
-        margin-bottom: 10px;
+    .tips {
+      font-size: 12px;
+      font-family: PingFang SC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #999999;
+      margin-bottom: 10px;
     }
-    button{
-        margin-top: 16px;
+    button {
+      margin-top: 16px;
     }
   }
 }

+ 7 - 18
src/views/home/index.vue

@@ -2,18 +2,17 @@
   <div class="page">
     <van-tabs v-model:active="active" @click-tab="onClickTab">
       <van-tab title="设备报修">
-        <div></div>
-        <SubmitPage/>
+        <SubmitPage @setActive="changeActive"/>
       </van-tab>
       <van-tab title="报修记录">
-        <List/>
+        <List :active="active" @setActive="changeActive"/>
       </van-tab>
     </van-tabs>
   </div>
 </template>
 
 <script lang="ts" setup name="HomePage">
-import { computed } from 'vue';
+import { computed, ref, reactive } from 'vue';
 import { useUserStore } from '/@/store/modules/user';
 import { setLang } from '/@/i18n';
 import store from '/@/store';
@@ -27,26 +26,16 @@ const getUserInfo = computed(() => {
   const { name = '' } = userStore.getUserInfo || {};
   return name;
 });
-const formData = reactive({
-  nameL: '',
-  lxr: '',
-  lxdh: '',
-  sncode: '',
-  gzms: '',
-  message: '',
-  file: [],
-  checked: '1',
-  checkeds: '1',
-});
 const onSubmit = () => {
   console.log('onSubmit');
 };
 const onClickTab = (title) => {
-  console.log('title',title)
+  console.log('title',title,active.value)
   console.log('store',userStore,getUserInfo)
 }
-const changeLang = (type) => {
-  setLang(type);
+const changeActive = (type) => {
+  document.documentElement.scrollTo({ top: 0, behavior: 'smooth' });
+  active.value = type
 };
 </script>
 <style lang="scss" scoped>

+ 80 - 40
src/views/home/list.vue

@@ -1,43 +1,80 @@
 <template>
   <div class="list">
-    <van-list style="overflow: hidden;" v-model:loading="loading" v-model:error="error" error-text="请求失败,点击重新加载" @load="onLoad">
+    <van-list style="overflow: hidden" :finished="loading" finished-text="没有更多了">
       <!-- <van-cell v-for="item in list" :key="item" :title="item" /> -->
-      
-    <div class="item" v-for="item in 5" :key="item" @click="goRoute(`detail/${item}`)">
-      <div class="item_top padddiv">
-        <div class="orderSn">工单号: <span>2022101100001</span></div>
-        <div class="state">待接单</div>
-      </div>
-      <div class="content padddiv">
-        <div class="camera">
-          <img src="../../assets/image/tips/kj.png" />
-          <span>{{ myData.name }}</span>
+      <div class="item" v-for="item in list" :key="item" @click="goRoute(`detail/${item.repairId}`)">
+        <div class="item_top padddiv">
+          <div class="orderSn">工单号: <span>{{item.repairId}}</span></div>
+          <div class="state">{{status[item.status]}}</div>
         </div>
-        <div class="camera_text">镜头摔坏、底盖脱落、
-           其它待检
+        <div class="content padddiv">
+          <div class="camera">
+            <img src="../../assets/image/tips/kj.png" />
+            <span>{{ myData.cameraType[item.cameraType] }}  {{ item.cameraSnCode }}</span>
+          </div>
+          <div class="camera_text">{{item.faultMsg}} </div>
         </div>
-      </div>
-      <div class="item_buttom padddiv">
-        <div class="time">报修日期 2022-10-11</div>
-        <div class="butList">
-          <!-- <van-button @click.stop="goRoute(`payment/${item}`)" hairline size="small" type="primary" >支付</van-button> -->
-          <van-button  @click.stop="goRoute(`evaluate/${item}`)" plain hairline  size="small" >评价</van-button>
-          <van-button @click.stop="goRoute(`invoice/${item}`)"  plain hairline  size="small" >申请开票</van-button>
+        <div class="item_buttom padddiv">
+          <div class="time">报修日期 {{ dayjs(item.createTime).format('YYYY-MM-DD') }}</div>
+          <div class="butList">
+            <!-- <van-button @click.stop="goRoute(`payment/${item}`)" hairline size="small" type="primary" >支付</van-button> -->
+            <van-button v-if="item.status == 3" @click.stop="goRoute(`payment/${item.repairId}`)" plain hairline size="small">支付</van-button>
+            <van-button v-if="item.status == 9" @click.stop="goRoute(`repair/${item.repairId}`)" plain hairline size="small">待确认</van-button>
+            <van-button v-if="item.status == 13" @click.stop="goRoute(`evaluate/${item.repairId}`)" plain hairline size="small">评价</van-button>
+            <van-button v-if="item.status == 23" @click.stop="goRoute(`invoice/${item.repairId}`)" plain hairline size="small">申请开票</van-button>
+          </div>
         </div>
       </div>
-    </div>
     </van-list>
   </div>
 </template>
 <script lang="ts" setup name="HomeList">
+import { reactive, ref, toRefs, watch, computed, unref, onMounted } from 'vue';
+import { useRouter } from 'vue-router';
+import { useUserStore } from '/@/store/modules/user';
+import { useHomeStore } from '/@/store/modules/home';
+import { repairList } from '/@/api';
+import * as dayjs from 'dayjs'
+const userStore = useUserStore();
+const userHome = useHomeStore();
 const router = useRouter();
 import sw from '/@/assets/image/tips/l-sh.png';
 import ss from '/@/assets/image/tips/ss.png';
 import kk from '/@/assets/image/tips/kk.png';
 import kj from '/@/assets/image/tips/kj.png';
-import { reactive } from 'vue';
+const props = defineProps({
+  active: Number,
+});
+const { active } = toRefs(props);
+const list = ref([]);
+const error = ref(false);
+const loading = ref(false);
+const wxOpenId = computed(() => {
+  return userStore.getWxOpenId;
+});
+const status = computed(() => {
+  return userHome.getStatus || {};
+});
+console.log(props, active)
+watch(
+  () => active.value,
+  (val) => {
+    //val为修改后的值,preVal为修改前的值
+    if(val==1){
+      onLoad()
+    }
+  }
+);
+onMounted(()=>{
+  onLoad()
+})
 const myData = reactive({
-  name: 'text',
+  cameraType:{
+    0:'四维看看',
+    1:'四维看见',
+    2:'四维深时',
+  },
+  
   imgObj: {
     1: sw,
     2: kk,
@@ -45,50 +82,53 @@ const myData = reactive({
     4: ss,
   },
 });
-const list = ref([]);
-const error = ref(false);
-const loading = ref(false);
-const onLoad = () => {
-  //   fetchSomeThing().catch(() => {
-  //     error.value = true;
-  //   });
+const onLoad = async () => {
+  loading.value = false;
+  const data = await repairList({wxOpenId:wxOpenId.value});
+  console.log('data',data)
+  list.value = data
+  loading.value = true;
 };
 // const onDetail = (item) => {
 //     console.log('onDetail',item)
 //     router.push(`detail/${item}`);
 // }
 const goRoute = (path) => {
-    if(!path) return
-    router.push(path);
-
-}
+  if (!path) return;
+  router.push(path);
+};
 </script>
 <style lang="scss" scoped>
 .list {
-    background-color: #F5F5F5;
+  background-color: #f5f5f5;
   .item {
     margin: 10px 0;
     background-color: #fff;
-    .padddiv{
-        padding: 0 16px;
+    .padddiv {
+      padding: 0 16px;
     }
     .item_top {
       display: flex;
       justify-content: space-between;
       align-items: center;
       padding: 13px 16px;
-      .orderSn{
+      .orderSn {
         font-size: 14px;
         font-family: PingFang SC-Regular, PingFang SC;
         font-weight: 400;
-        color: rgba(102,102,102,0.6);
+        color: rgba(102, 102, 102, 0.6);
       }
     }
     .content {
       .camera {
         margin: 12px 0;
+        img{
+          position: relative;
+          top: 6px;
+          margin-right: 10px;
+        }
       }
-      .camera_text{
+      .camera_text {
         margin-bottom: 20px;
       }
     }

+ 118 - 44
src/views/home/submit.vue

@@ -1,8 +1,8 @@
 <template>
-  <van-form @submit="onSubmit" style="margin-top:10px;background:#fff">
+  <van-form @submit="onSubmit" style="margin-top: 10px; background: #fff">
     <van-cell-group inset>
       <van-field
-        v-model="formData.nameL"
+        v-model="formData.companyName"
         label-align="top"
         name="用户名"
         label="公司名称"
@@ -10,7 +10,7 @@
         :rules="[{ required: true, message: '请填写公司名称' }]"
       />
       <van-field
-        v-model="formData.nameL"
+        v-model="formData.customerName"
         label-align="top"
         name="联系人"
         label="联系人"
@@ -18,15 +18,15 @@
         :rules="[{ required: true, message: '请填写姓名' }]"
       />
       <van-field
-        v-model="formData.nameL"
+        v-model="formData.phone"
         label-align="top"
         name="联系电话"
         label="联系电话"
         placeholder="请填写手机号"
-        :rules="[{ required: true, message: '请填写手机号' }]"
+        :rules="[{ required: true, message: '请填写手机号' }, rulesMobile]"
       />
       <van-field
-        v-model="formData.nameL"
+        v-model="formData.cameraSnCode"
         label-align="top"
         name="产品SN码"
         label="产品SN码"
@@ -34,29 +34,33 @@
         :rules="[{ required: true, message: '请填写密码' }]"
       />
       <van-field
-        v-model="formData.nameL"
+        v-model="formData.faultMsg"
         label-align="top"
-        name="障描述"
-        label="障描述"
+        name="故障描述"
+        label="故障描述"
+        rows="2"
+        autosize
+        type="textarea"
+        maxlength="500"
+        show-word-limit
         placeholder="请具体描述故障现象,相关操作等。"
-        :rules="[{ required: true, message: '请填写密码' }]"
       />
       <van-field name="uploader" label="文件上传" label-align="top">
         <template #input>
-          <van-uploader v-model="formData.file" />
+          <van-uploader v-model="formData.faultImg" :before-read="beforeRead" :after-read="clzpAfterRead" @delete="deleteFile" />
         </template>
       </van-field>
-      <van-field name="radio" label="单选框" label-align="top">
+      <van-field name="radio" label="送修方式" label-align="top">
         <template #input>
-          <van-radio-group v-model="formData.checked" direction="horizontal">
-            <van-radio name="1">前台送修</van-radio>
-            <van-radio name="2">快递寄送</van-radio>
+          <van-radio-group v-model="formData.sendType" direction="horizontal">
+            <van-radio :name="0">前台送修</van-radio>
+            <van-radio :name="1">快递寄送</van-radio>
           </van-radio-group>
         </template>
       </van-field>
-
       <van-field
-        v-model="formData.nameL"
+        v-if="formData.sendType == 1"
+        v-model="formData.sendTrackingNum"
         label-align="top"
         name="快递单号"
         label="快递单号"
@@ -64,17 +68,18 @@
         :rules="[{ required: true, message: '请填写快递单号' }]"
       />
 
-      <van-field name="radio" label="单选框" label-align="top">
+      <van-field name="radio" label="取回方式" label-align="top">
         <template #input>
-          <van-radio-group v-model="formData.checkeds" direction="horizontal">
-            <van-radio name="1">前台送修</van-radio>
-            <van-radio name="2">快递寄送</van-radio>
+          <van-radio-group v-model="formData.getType" direction="horizontal">
+            <van-radio :name="0">前台送修</van-radio>
+            <van-radio :name="1">快递寄送</van-radio>
           </van-radio-group>
         </template>
       </van-field>
 
       <van-field
-        v-model="formData.nameL"
+        v-if="formData.getType == 1"
+        v-model="formData.getAddress"
         label-align="top"
         name="收件地址"
         label="收件地址"
@@ -82,7 +87,8 @@
         :rules="[{ required: true, message: '请填写收件地址' }]"
       />
       <van-field
-        v-model="formData.nameL"
+        v-if="formData.getType == 1"
+        v-model="formData.getAddrName"
         label-align="top"
         name="收件人"
         label="收件人"
@@ -90,12 +96,13 @@
         :rules="[{ required: true, message: '请填写收件人' }]"
       />
       <van-field
-        v-model="formData.nameL"
+        v-if="formData.getType == 1"
+        v-model="formData.getAddrPhone"
         label-align="top"
         name="收件人电话"
         label="收件人电话"
         placeholder="请填写收件人电话"
-        :rules="[{ required: true, message: '请填写收件人电话' }]"
+        :rules="[{ required: true, message: '请填写收件人电话' }, rulesMobile]"
       />
 
       <van-field
@@ -111,40 +118,107 @@
       />
     </van-cell-group>
     <div style="margin: 16px">
+      <nut-icon name="JD"></nut-icon>
+      <nut-icon
+        size="40"
+        name="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png"
+      ></nut-icon>
       <van-button round block type="primary" native-type="submit"> 提交 </van-button>
     </div>
   </van-form>
 </template>
   
 <script lang="ts" setup name="HomeSubmit">
-import { computed } from 'vue';
+import { computed, reactive, unref } from 'vue';
 import { useUserStore } from '/@/store/modules/user';
-import { showToast } from 'vant';
+import { showToast, showSuccessToast  } from 'vant';
+import axios from 'axios';
+import useAxiosApi from '/@/utils/useAxiosApi';
+// import { Toast } from '@nutui/nutui';
+import { cameraRepair } from '/@/api';
 import { setLang } from '/@/i18n';
 import { useI18n } from 'vue-i18n';
+const emit = defineEmits(['setActive'])
 const { locale } = useI18n();
 const userStore = useUserStore();
-const getUserInfo = computed(() => {
-  const { name = '' } = userStore.getUserInfo || {};
-  return name;
+const wxOpenId = computed(() => {
+  return userStore.getWxOpenId;
 });
 const formData = reactive({
-  nameL: '',
-  lxr: '',
-  lxdh: '',
-  sncode: '',
-  gzms: '',
-  message: '',
-  file: [],
-  checked: '1',
-  checkeds: '1',
+  companyName: '',
+  customerName: '',
+  phone: '',
+  cameraSnCode: '',
+  faultMsg: '',
+  faultImg: [],
+  sendType: 0,
+  sendTrackingNum: '',
+  getAddress: '',
+  getAddrName: '',
+  getAddrPhone: '',
+  getType: 0,
+  wxOpenId: wxOpenId.value,
 });
-const onSubmit = () => {
-  console.log('onSubmit');
-};
-const changeLang = (type) => {
-  setLang(type);
+const rulesMobile = {
+  // 自定义校验规则
+  validator: (value) => {
+    return /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/.test(value);
+  },
+  message: '请输入正确格式的手机号码',
+  trigger: 'onBlur',
 };
+function changeActive(){
+  emit('setActive',1)
+}
+async function onSubmit() {
+  // return new Promise((resolve) => {
+  let apiData = {
+    ...formData,
+    faultImg:formData.faultImg.map(ele => ele.url)
+  }
+  const { response } = await cameraRepair(apiData);
+  let data = unref(response)
+  console.log('onSubmit', formData, data);
+  if(data.code == 200){
+    showSuccessToast('提交成功')
+    emit('setActive',1)
+  }
+
+}
+//校验图片的格式
+function beforeRead(file) {
+  if (!/(jpg|jpeg|png|JPG|PNG)/i.test(file.type)) {
+    showToast('请上传正确格式的图片');
+    return false;
+  }
+  return true;
+}
+//照片上传事件方法
+function clzpAfterRead(file) {
+  // 上传状态提示开启
+  file.status = 'uploading';
+  file.message = '上传中...';
+  // 创建一个空对象实例
+  let formData = new FormData();
+  // 调用append()方法添加数据
+  formData.append('file', file.file);
+  axios({
+    url:'/service/sale/upload/file',
+    method: 'POST',
+    data:formData,
+    headers:{
+      'Content-Type': 'multipart/form-data'
+    }
+  }).then(res => {
+    let { data } = res
+    if (data.code == 200) {
+      // 上传状态提示关闭
+      file.url = data.data
+      file.status = 'done';
+      showToast('上传成功!');
+    }
+  });
+}
 </script>
   <style lang="scss">
 .header {

+ 0 - 6
types/components.d.ts

@@ -11,20 +11,14 @@ declare module '@vue/runtime-core' {
     RouterView: typeof import('vue-router')['RouterView']
     TitleBar: typeof import('./../src/components/TitleBar/index.vue')['default']
     VanButton: typeof import('vant/es')['Button']
-    VanCell: typeof import('vant/es')['Cell']
     VanCellGroup: typeof import('vant/es')['CellGroup']
-    VanDivider: typeof import('vant/es')['Divider']
     VanField: typeof import('vant/es')['Field']
     VanForm: typeof import('vant/es')['Form']
-    VanIcon: typeof import('vant/es')['Icon']
     VanList: typeof import('vant/es')['List']
     VanRadio: typeof import('vant/es')['Radio']
     VanRadioGroup: typeof import('vant/es')['RadioGroup']
-    VanRate: typeof import('vant/es')['Rate']
     VanTab: typeof import('vant/es')['Tab']
     VanTabs: typeof import('vant/es')['Tabs']
     VanUploader: typeof import('vant/es')['Uploader']
-    VarButton: typeof import('@varlet/ui')['_ButtonComponent']
-    VarSpace: typeof import('@varlet/ui')['_SpaceComponent']
   }
 }

+ 17 - 5
vite.config.ts

@@ -1,8 +1,10 @@
 import { createVitePlugins } from './build/vite/plugins';
 import { resolve } from 'path';
-import { ConfigEnv, loadEnv, UserConfig } from 'vite';
+import { ConfigEnv, loadEnv, UserConfig, defineConfig } from 'vite';
 import { wrapperEnv } from './build/utils';
-
+import Components from 'unplugin-vue-components/vite'
+import { VantResolver } from 'unplugin-vue-components/resolvers'
+import vue from '@vitejs/plugin-vue';
 const pathResolve = (dir: string) => {
   return resolve(process.cwd(), '.', dir);
 };
@@ -35,10 +37,20 @@ export default function ({ command, mode }: ConfigEnv): UserConfig {
       ],
     },
     server: {
-      host: true,
-      hmr: true,
+      proxy: {
+        "/service": {
+          target: "https://v4-uat.4dkankan.com/",
+          changeOrigin: true,
+          rewrite: (path) => path.replace(/^\/api/, ""),
+        },
+      },
     },
-    plugins: createVitePlugins(viteEnv, isProduction),
+    plugins: [
+      vue(),
+      Components({
+        resolvers: [VantResolver()]
+      })
+    ],
     build: {
       minify: 'terser',
       terserOptions: {

+ 15 - 10
yarn.lock

@@ -858,10 +858,10 @@
   resolved "https://registry.yarnpkg.com/@vant/popperjs/-/popperjs-1.3.0.tgz#e0eff017124b5b2352ef3b36a6df06277f4400f2"
   integrity sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==
 
-"@vant/use@^1.4.3":
-  version "1.4.3"
-  resolved "https://registry.yarnpkg.com/@vant/use/-/use-1.4.3.tgz#0c542fe01a1439878e4aa8779d1791e189610d30"
-  integrity sha512-rSnETN7P9qT1WbItMpQxBqe3cHeK2ZFYp1sCxWUXaTeI71TqA8sOdzC36ledZ36NQgFNTch9fsRPYOkrCgZfQA==
+"@vant/use@^1.5.0":
+  version "1.5.0"
+  resolved "http://192.168.0.47:4873/@vant/use/-/use-1.5.0.tgz#ea1d6ab866ac54cfe410667fce96293c44fbcc7d"
+  integrity sha512-Dk7aMn7gLpoDew2tix/mjXpP0PoERWcxWh+pRY4xxl0MG4eeByAAyZSE6PgMpof4Yorqn7yq8KmeQcaVnxq2cg==
 
 "@varlet/icons@2.4.2":
   version "2.4.2"
@@ -2131,11 +2131,16 @@ cwebp-bin@^5.0.0:
     bin-wrapper "^4.0.1"
     logalot "^2.1.0"
 
-dayjs@^1.10.4, dayjs@^1.11.7:
+dayjs@^1.10.4:
   version "1.11.7"
   resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2"
   integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
 
+dayjs@^1.11.7:
+  version "1.11.7"
+  resolved "http://192.168.0.47:4873/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2"
+  integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
+
 de-indent@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
@@ -7523,13 +7528,13 @@ validate-npm-package-license@^3.0.1:
     spdx-correct "^3.0.0"
     spdx-expression-parse "^3.0.0"
 
-vant@^4.0.3:
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/vant/-/vant-4.0.3.tgz#ec5fb0b1b694f2c3ca2e9bc1ca2345c6abebfbec"
-  integrity sha512-rBQCSdMyYxO9I3weQmdTxY28OkVLM7MSIjMx3qwMTsFONek6bodVGEYXF0+mzh/5EBMVXjqtHj6CvD6QphKkCg==
+vant@^4.0.11:
+  version "4.0.11"
+  resolved "http://192.168.0.47:4873/vant/-/vant-4.0.11.tgz#c26dc1a0828987d94fe96a6cef8b1c92bd7245f2"
+  integrity sha512-axVP6eHH4vGb5FQ2hqNhB5DykMSBQb0KK97HT4bVVFTYM81EJq1YImqOglzsVt3OC98NRoT01DIwt4y2n1iwVw==
   dependencies:
     "@vant/popperjs" "^1.3.0"
-    "@vant/use" "^1.4.3"
+    "@vant/use" "^1.5.0"
 
 varstream@^0.3.2:
   version "0.3.2"