Sfoglia il codice sorgente

chore:配置迁移

needcode 2 anni fa
parent
commit
6c8d77c853

+ 1 - 1
package.json

@@ -64,7 +64,7 @@
     "@dcloudio/uni-stacktracey": "3.0.0-3080720230703001",
     "@dcloudio/vite-plugin-uni": "3.0.0-3080720230703001",
     "@vue/tsconfig": "^0.1.3",
-    "typescript": "^4.9.4",
+    "typescript": "^5.1.6",
     "vite": "4.0.4",
     "vue-tsc": "^1.0.24"
   }

+ 38 - 11
src/App.vue

@@ -1,17 +1,44 @@
-<script setup lang="ts">
-import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
-onLaunch(() => {
-  console.log("App Launch");
-});
-onShow(() => {
-  console.log("App Show");
-});
-onHide(() => {
-  console.log("App Hide");
-});
+<script lang="ts">
+import { fetchToken } from "./api/auth";
+export default <any>{
+  globalData: {
+    token: "",
+    lastData: {},
+    stations: [],
+    normalCode: "",
+  },
+  onLaunch() {
+    return fetchToken().then((cache) => {
+      if (cache) {
+        this.globalData.token = cache;
+      }
+    });
+  },
+};
 </script>
 <style lang="scss">
 @import "./styles/flex.scss";
 @import "./styles/font.scss";
 @import "./styles/layout.scss";
+
+view {
+  box-sizing: border-box;
+}
+
+image {
+  width: 20rpx;
+  height: 20rpx;
+}
+
+.color-fff {
+  color: #fff;
+}
+
+.color-000 {
+  color: #000;
+}
+
+.transition {
+  transition: all 0.3s;
+}
 </style>

+ 7 - 0
src/App.wxs

@@ -0,0 +1,7 @@
+{/* <script module="utils" lang="wxs" src="./utils.wxs"></script> */}
+
+module.exports.formatPrice = formatPrice
+
+function formatPrice(price) {
+  return (price / 100).toFixed(2)
+}

+ 175 - 0
src/api/auth.ts

@@ -0,0 +1,175 @@
+import { host } from "../utils/constant";
+import Storage from "../utils/storage";
+
+const _tokenStorage = new Storage("AUTH");
+
+const _tokenQueue: {
+  pending: boolean;
+  list: {
+    resolve: (value: string) => void;
+    reject: (err: any) => void;
+  }[];
+} = {
+  pending: false,
+  list: [],
+};
+
+let _onTokenListener: {
+  cb: (token: string) => void;
+}[] = [];
+
+const _resolveTokenQueue = function (res: any) {
+  _tokenQueue.pending = false;
+  uni.hideLoading();
+  if (res.errMsg) {
+    console.log(res);
+    uni.showModal({
+      title: "登录失败",
+      content: `${res.errMsg}`,
+    });
+    _tokenQueue.list.forEach((item) => {
+      item.reject(res);
+    });
+  } else {
+    uni.showToast({
+      icon: "success",
+      title: "登陆成功",
+    });
+    setToken(res as string);
+    _onTokenListener.forEach((item) => {
+      item.cb(res as string);
+    });
+    _tokenQueue.list.forEach((item) => {
+      item.resolve(res as string);
+    });
+  }
+  _onTokenListener = [];
+  _tokenQueue.list = [];
+};
+
+export function login(e: any): Promise<string> {
+  return new Promise((resolve, reject) => {
+    if (/deny|cancel/.test(e.detail.errMsg)) {
+      reject();
+      return;
+    }
+    if (!e.detail.code) {
+      uni.showModal({
+        title: `${e.detail.errMsg},请重试`,
+      });
+      reject();
+      return;
+    }
+    _tokenQueue.list.push({
+      resolve,
+      reject,
+    });
+    if (_tokenQueue.pending) {
+      return;
+    }
+    _tokenQueue.pending = true;
+    uni.showLoading({
+      title: "登录中",
+      mask: true,
+    });
+    uni.login({
+      success: (res) => {
+        uni.request<any>({
+          url: `${host}/user/login`,
+          method: "POST",
+          dataType: "json",
+          data: {
+            phone_code: e.detail.code,
+            code: res.code,
+          },
+          success: (res: any) => {
+            const { statusCode, data } = res;
+            if (
+              statusCode === 200 &&
+              data &&
+              data.msg === "OK" &&
+              data.code === 200
+            ) {
+              _resolveTokenQueue(data.data.access_token);
+            } else {
+              _resolveTokenQueue({
+                errMsg: data.msg ? data.msg : `${JSON.stringify(res)}`,
+              });
+            }
+          },
+          fail: _resolveTokenQueue,
+        });
+      },
+      fail: _resolveTokenQueue,
+    });
+  });
+}
+
+export function refresh(): Promise<string> {
+  return new Promise((resolve, reject) => {
+    _tokenStorage.get("token").then((token) => {
+      if (!token) {
+        clearToken();
+        reject({
+          errMsg: "请登录",
+        });
+        uni.reLaunch({
+          url: "/pages/map/map",
+        });
+      } else {
+        getApp().globalData.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 (
+              statusCode === 200 &&
+              data &&
+              data.msg === "OK" &&
+              data.code === 200
+            ) {
+              resolve(data.data.access_token);
+            } else {
+              if (data.code === 21005) {
+                uni.reLaunch({
+                  url: "/pages/map/map",
+                });
+              }
+              reject({
+                errMsg: `${JSON.stringify(res)}`,
+              });
+            }
+          },
+          fail: reject,
+        });
+      }
+    });
+  });
+}
+
+export function onLogin(cb: (token: string) => void) {
+  _onTokenListener.push({
+    cb,
+  });
+}
+
+export function fetchToken() {
+  return _tokenStorage.get("token");
+}
+
+export function setToken(token: string) {
+  getApp().globalData.token = token;
+  return _tokenStorage.set("token", token);
+}
+
+export function clearToken() {
+  getApp().globalData.token = "";
+  return _tokenStorage.clear("token");
+}

+ 310 - 0
src/api/charge.ts

@@ -0,0 +1,310 @@
+// import Http, { http } from '../utils/http'
+// import { host } from '../utils/constant'
+// const cHttp = new Http(host)
+
+// export function startCharge(sn: string) {
+//   return cHttp.get<{
+//     ConnectorID: string
+//     FailReason: number
+//     StartChargeSeq: string
+//     StartChargeSeqStat: number
+//     SuccStat: number
+//   }>(`/charge/startCharge?connector_id=${sn}`, {
+//     statusCodeHandle: false
+//   })
+// }
+
+// export function fetchStationPriceDesc(ConnectorID: string, StationID?: string) {
+//   return cHttp.get(`/charge/businessPolicy?connector_id=${ConnectorID}`).then(res => {
+//     const nowHour = new Date().getHours()
+//     let currentPrice = 0
+//     let currentTime = '00:00~24:00'
+//     if (res && res.PolicyInfos && res.PolicyInfos.length) {
+//       res.PolicyInfos.forEach((item: any, index: number) => {
+//         const hour = item.StartTime.substring(0, 2)
+//         const min = item.StartTime.substring(2, 4)
+//         if (index >= res.PolicyInfos.length - 1) {
+//           // 最后一个
+//           item.StartTimeFormat = `${hour}:${min}~24:00`
+//           if (Number(hour) <= nowHour) {
+//             currentPrice = Number(Number(item.ElecPrice + item.SevicePrice).toFixed(2))
+//             currentTime = `${hour}:${min}~24:00`
+//           }
+//         } else {
+//           const nhour = res.PolicyInfos[index + 1].StartTime.substring(0, 2)
+//           const nmin = res.PolicyInfos[index + 1].StartTime.substring(2, 4)
+//           item.StartTimeFormat = `${hour}:${min}~${nhour}:${nmin}`
+//           if (nowHour >= Number(hour) && nowHour < Number(nhour)) {
+//             currentPrice = Number(Number(item.ElecPrice + item.SevicePrice).toFixed(2))
+//             currentTime = `${hour}:${min}~${nhour}:${nmin}`
+//           }
+//         }
+//       })
+//     }
+//     res.CurrentPrice = currentPrice
+//     res.CurrentTime = currentTime
+//     if (StationID) {
+//       res.StationID = StationID
+//     }
+//     return res
+//   })
+// }
+
+// export function cancelCharge(sn: string) {
+//   return cHttp.get(`/charge/stopCharge?connector_id=${sn}`, {
+//     statusCodeHandle: false
+//   })
+// }
+
+// export function fetchChargeStatus() {
+//   return cHttp.get('/charge/chargeStatus', {
+//     statusCodeHandle: false
+//   })
+// }
+
+// export function fetchStations(
+//   page: number,
+//   pageSize: number,
+//   latitude?: number,
+//   longitude?: number,
+//   baseLatitude?: number,
+//   baseLongitude?: number,
+//   options?: {
+//     distance?: number
+//     status?: number
+//   }
+// ): Promise<ChongDian.Entity.Station[]> {
+//   return fetchAllStations()
+//     .then(res => {
+//       // console.log(latitude, longitude);
+//       let list = JSON.parse(JSON.stringify(res))
+//       const data: ChongDian.Entity.Station[] = []
+//       const start = (page - 1) * pageSize
+//       const end = start + pageSize
+//       if (latitude && longitude) {
+//         list.forEach((item: ChongDian.Entity.Station) => {
+//           item.StationLatDistance = _getDistance(latitude, longitude, item.StationLat, item.StationLng)
+//         })
+//         list.sort((item1: ChongDian.Entity.Station, item2: ChongDian.Entity.Station) => {
+//           return item1.StationLatDistance - item2.StationLatDistance
+//         })
+//       }
+//       if (options) {
+//         if (options.distance) {
+//           list = list.filter((item: ChongDian.Entity.Station) => item.StationLatDistance <= (options.distance || 20))
+//         }
+//       }
+//       list.forEach((item: ChongDian.Entity.Station, index: number) => {
+//         if (index >= start && index < end) {
+//           data.push(item)
+//         }
+//       })
+//       if (baseLatitude && baseLongitude) {
+//         data.forEach((item: ChongDian.Entity.Station) => {
+//           item.StationLatDistance = _getDistance(baseLatitude, baseLongitude, item.StationLat, item.StationLng)
+//         })
+//       }
+//       return _fetchStationStatus(data)
+//     })
+//     .then(list => {
+//       if (options && options.status) {
+//         let res = false
+//         list = list.filter((item: ChongDian.Entity.Station) => {
+//           res = false
+//           item.EquipmentInfos.forEach((eqInfo: any) => {
+//             eqInfo.ConnectorInfos.forEach((coInfo: any) => {
+//               if (
+//                 !res &&
+//                 options.status === 1 &&
+//                 coInfo.ConnectorStatusInfo &&
+//                 coInfo.ConnectorStatusInfo.Status === 1
+//               ) {
+//                 res = true
+//               }
+//               if (
+//                 !res &&
+//                 options.status === 2 &&
+//                 coInfo.ConnectorStatusInfo &&
+//                 coInfo.ConnectorStatusInfo.Status !== 1
+//               ) {
+//                 res = true
+//               }
+//             })
+//           })
+//           return res
+//         })
+//       }
+//       return list
+//     })
+// }
+
+// export function fetchStation(id: number) {
+//   return fetchAllStations()
+//     .then(res => {
+//       const findIndex = res.findIndex(item => Number(item.StationID) === id)
+//       if (findIndex < 0) {
+//         throw {
+//           errMsg: 'not found'
+//         }
+//       }
+//       return _fetchStationStatus([res[findIndex]])
+//     })
+//     .then(list => {
+//       return list[0]
+//     })
+// }
+
+// export function fetchStationByIds(ids: number[]) {
+//   return fetchAllStations().then(res => {
+//     const list = res.filter(item => ids.includes(Number(item.StationID)))
+//     return _fetchStationStatus(list)
+//   })
+// }
+
+// export function searchStation(keyword: string) {
+//   return fetchAllStations().then(res => {
+//     const reg = new RegExp(keyword, 'ig')
+//     const list = res.filter(item => reg.test(item.StationName) || reg.test(item.Address))
+//     return _fetchStationStatus(list)
+//   })
+// }
+
+// export function fetchAllStations(): Promise<ChongDian.Entity.Station[]> {
+//   if (getApp<ChongDian.App>().globalData.stations.length > 0) {
+//     return Promise.resolve(getApp<ChongDian.App>().globalData.stations)
+//   }
+//   const page = 1
+//   const page_size = 99
+//   return new Promise((resolve, reject) => {
+//     _fetchAllStations(page, page_size, [])
+//       .then(list => {
+//         // if (!isProduction) {
+//         //   list.push({
+//         //     ...list[0],
+//         //     StationName: '这是模拟数据,不要使用充电',
+//         //     Address: '这是模拟数据,测试一下附近的点',
+//         //     StationLat: 22.540545,
+//         //     StationLng: 113.942695,
+//         //     StationID: '0000'
+//         //   })
+//         // }
+//         getApp<ChongDian.App>().globalData.stations = list
+//         resolve(list)
+//       })
+//       .catch(reject)
+//   })
+// }
+
+// function _fetchAllStations(
+//   page: number,
+//   pageSize: number,
+//   list: ChongDian.Entity.Station[]
+// ): Promise<ChongDian.Entity.Station[]> {
+//   return _fetchStations(page, pageSize).then(res => {
+//     list = list.concat(res)
+//     if (res.length >= pageSize) {
+//       return _fetchAllStations(page + 1, pageSize, list)
+//     } else {
+//       // eslint-disable-next-line promise/no-return-wrap
+//       return Promise.resolve(list)
+//     }
+//   })
+// }
+
+// function _fetchStations(page: number, pageSize: number) {
+//   return cHttp
+//     .get<{
+//       StationInfos: ChongDian.Entity.Station[]
+//     }>(`/charge/stationList?page_no=${page}&page_size=${pageSize}`)
+//     .then(res => {
+//       res.StationInfos &&
+//         res.StationInfos.forEach(item => {
+//           item.fastEquipmentInfos = []
+//           item.slowEquipmentInfos = []
+//           item.TotalFee = Number(
+//             Number(Number(item.ElectricityFee) + Number(item.ParkFee) + Number(item.ServiceFee)).toFixed(2)
+//           )
+//         })
+
+//       return (res.StationInfos || []).filter((item: any) => {
+//         return !['1657'].includes(item.StationID)
+//       })
+//     })
+// }
+
+// function _getDistance(lat1: number, lng1: number, lat2: number, lng2: number) {
+//   var radLat1 = (lat1 * Math.PI) / 180.0
+//   var radLat2 = (lat2 * Math.PI) / 180.0
+//   var a = radLat1 - radLat2
+//   var b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
+//   var s =
+//     2 *
+//     Math.asin(
+//       Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))
+//     )
+//   s = s * 6378.137 // EARTH_RADIUS;
+//   s = Math.round(s * 10000) / 10000
+//   return s
+// }
+
+// function _fetchStationStatus(list: ChongDian.Entity.Station[]) {
+//   if (list.length <= 0) {
+//     return Promise.resolve([])
+//   }
+//   let _list: ChongDian.Entity.Station[] = []
+//   return cHttp
+//     .get(`/charge/stationStatus?station_ids=${list.filter(item => item.StationID !== '0000').map(item => item.StationID).join(',')}`)
+//     .then(res => {
+//       const StationStatusInfos = res.StationStatusInfos || []
+//       const ConnectorIDs: string[] = []
+//       const StationIDs: string[] = []
+//       list.forEach((item: ChongDian.Entity.Station) => {
+//         item.fastEquipmentInfos = []
+//         item.slowEquipmentInfos = []
+//         const StationStatusInfo = StationStatusInfos.find((status: any) => status.StationID === Number(item.StationID))
+//         let ConnectorID = ''
+//         item.EquipmentInfos.forEach((eqInfo: any) => {
+//           eqInfo.ConnectorInfos.forEach((coInfo: any) => {
+//             if (StationStatusInfo) {
+//               const ConnectorStatusInfo = StationStatusInfo.ConnectorStatusInfos.find(
+//                 (costatus: any) => costatus.ConnectorID === coInfo.ConnectorID
+//               )
+//               if (ConnectorStatusInfo) {
+//                 coInfo.ConnectorStatusInfo = ConnectorStatusInfo
+//               }
+//             }
+//             if (!ConnectorID) {
+//               ConnectorID = coInfo.ConnectorID
+//             }
+//           })
+//           if ([1].includes(Number(eqInfo.EquipmentType))) {
+//             item.fastEquipmentInfos.push(eqInfo)
+//           } else {
+//             item.slowEquipmentInfos.push(eqInfo)
+//           }
+//         })
+//         if (ConnectorID) {
+//           ConnectorIDs.push(ConnectorID)
+//           StationIDs.push(item.StationID)
+//         }
+//       })
+//       _list = list
+//       return Promise.all(
+//         ConnectorIDs.map((cid, cindex) => {
+//           return fetchStationPriceDesc(cid, StationIDs[cindex])
+//         })
+//       )
+//     })
+//     .then(res => {
+//       // console.log('我要看的数据', res)
+//       if (res && res.length) {
+//         _list.forEach(item => {
+//           const i = res.findIndex(r => r.StationID === item.StationID)
+//           if (i >= 0) {
+//             item.TotalFee = res[i].CurrentPrice
+//           }
+//         })
+//       }
+//       return _list
+//     })
+// }

+ 8 - 0
src/api/index.ts

@@ -0,0 +1,8 @@
+import Http from '../utils/http'
+import { host } from '../utils/constant'
+
+const indexHttp = new Http(host)
+
+export function fetchContact() {
+  return indexHttp.get('/common/contact')
+}

+ 105 - 0
src/api/user.ts

@@ -0,0 +1,105 @@
+// import Http from '../utils/http'
+// import { host } from '../utils/constant'
+
+// const userHttp = new Http(host)
+
+// export function fetchProfile() {
+//   return userHttp.get<ChongDian.Entity.User>('/user/me').then(res => {
+//     getApp<ChongDian.App>().globalData.user = res
+//     return res
+//   })
+// }
+
+// export function fetchCollectList() {
+//   if (getApp<ChongDian.App>().globalData.collectIds) {
+//     return Promise.resolve(getApp<ChongDian.App>().globalData.collectIds)
+//   }
+//   return userHttp.get<{
+//     data: {
+//       status: number
+//       station_id: number
+//     }[]
+//   }>('/user/collectList?page=1&page_size=999').then(res => {
+//     getApp<ChongDian.App>().globalData.collectIds = res.data ? res.data.filter(item => Number(item.status) === 1).map(item => {
+//       return Number(item.station_id)
+//     }) : []
+//     return getApp<ChongDian.App>().globalData.collectIds
+//   })
+// }
+
+// export function addCollectList(sid: number) {
+//   let ids = getApp<ChongDian.App>().globalData.collectIds ? getApp<ChongDian.App>().globalData.collectIds as number[] : []
+//   const status = ids.includes(sid) ? 2 : 1
+//   return userHttp.post('/user/addCollect', {
+//     data: {
+//       station_id: sid,
+//       status
+//     }
+//   }).then(() => {
+//     if (status === 1) {
+//       ids.push(sid)
+//     } else {
+//       ids = ids.filter(id => id !== sid)
+//     }
+//     getApp<ChongDian.App>().globalData.collectIds = ids
+//     return status === 1
+//   })
+// }
+
+// export function updateProfile(data: {
+//   nick_name?: string
+//   avatar?: string
+//   vin?: string
+//   license_plate?: string
+//   card_no?: string
+// }) {
+//   return userHttp.post('/user/update', {
+//     data
+//   })
+// }
+
+// export function insertMoney(amount: number) {
+//   return userHttp.post<{
+//     appId: string
+//     nonceStr: string
+//     package: string
+//     paySign: string
+//     signType: string
+//     timestamp: string
+//   }>('/payment/pay', {
+//     data: {
+//       amount: parseInt(`${amount * 100}`),
+//       openid: getApp<ChongDian.App>().globalData.user?.openid
+//     }
+//   }).then(res => {
+//     return new Promise((resolve, reject) => {
+//       wx.requestPayment({
+//         timeStamp: res.timestamp,
+//         nonceStr: res.nonceStr,
+//         package: res.package,
+//         signType: 'MD5',
+//         paySign: res.paySign,
+//         success(res) {
+//           resolve(res)
+//         },
+//         fail: reject
+//       })
+//     })
+//   })
+// }
+
+// export function logout() {
+//   return userHttp.get('/user/logout')
+// }
+
+// export function fetchWallet(type: number, page: number, pageSize: number) {
+//   return userHttp.get<{
+//     data: ChongDian.Entity.Wallet[]
+//   }>(`/account/wallet?page=${page}&page_size=${pageSize}&type=${type}`).then(res => {
+//     return res.data
+//   })
+// }
+
+// export function fetchOrder(orderid: string) {
+//   return userHttp.get(`/charge/orderInfo?order_id=${orderid}`)
+// }

+ 66 - 62
src/custom-tab-bar/index.js

@@ -1,8 +1,4 @@
-// import {
-//   fetchToken,
-//   login,
-//   onLogin
-// } from '../api/auth'
+import { fetchToken, login, onLogin } from "../api/auth";
 // import {
 //   fetchChargeStatus
 // } from '../api/charge'
@@ -12,40 +8,47 @@ Component({
     hidden: false,
     dialog: false,
     tabIndex: -1,
-    tabs: [{
-      path: "/pages/map/index",
-      text: "充电地图"
-    }, {
-      path: "",
-      text: "扫码充电"
-    }, {
-      path: "/pages/list/index",
-      text: "电站列表"
-    }, {
-      path: "/pages/user/index",
-      text: "个人中心"
-    }],
-    charging: ''
+    tabs: [
+      {
+        path: "/pages/map/index",
+        text: "充电地图",
+      },
+      {
+        path: "",
+        text: "扫码充电",
+      },
+      {
+        path: "/pages/list/index",
+        text: "电站列表",
+      },
+      {
+        path: "/pages/user/index",
+        text: "个人中心",
+      },
+    ],
+    charging: "",
   },
   lifetimes: {
     ready() {
-      // fetchToken().then(token => {
-      //   const pages = getCurrentPages()
-      //   const index = this.data.tabs.findIndex(item => item.path === `/${pages[pages.length - 1].route}`)
-      //   this.setData({
-      //     hidden: false,
-      //     tabIndex: index,
-      //     token,
-      //   })
-      //   if (!token) {
-      //     onLogin((token) => {
-      //       this.setData({
-      //         token,
-      //       })
-      //     })
-      //   }
-      // })
-    }
+      fetchToken().then((token) => {
+        const pages = getCurrentPages();
+        const index = this.data.tabs.findIndex(
+          (item) => item.path === `/${pages[pages.length - 1].route}`
+        );
+        this.setData({
+          hidden: false,
+          tabIndex: index,
+          token,
+        });
+        if (!token) {
+          onLogin((token) => {
+            this.setData({
+              token,
+            });
+          });
+        }
+      });
+    },
   },
   methods: {
     switchTab(e) {
@@ -58,52 +61,53 @@ Component({
       //     charging: ''
       //   })
       // })
-      const data = e.currentTarget.dataset
-      const url = data.path
+      const data = e.currentTarget.dataset;
+      const url = data.path;
       if (!url) {
-        this.switchDialog()
-        return
+        this.switchDialog();
+        return;
       }
       this.setData({
-        dialog: false
-      })
-      wx.vibrateShort && wx.vibrateShort({
-        type: 'light'
-      })
+        dialog: false,
+      });
+      wx.vibrateShort &&
+        wx.vibrateShort({
+          type: "light",
+        });
       wx.switchTab({
-        url
-      })
+        url,
+      });
     },
     switchDialog() {
       this.setData({
-        dialog: !this.data.dialog
-      })
+        dialog: !this.data.dialog,
+      });
     },
     hiddenTab() {
       this.setData({
-        hidden: true
-      })
+        hidden: true,
+      });
     },
     showTab() {
       this.setData({
-        hidden: false
-      })
+        hidden: false,
+      });
     },
     login(e) {
-      login(e)
+      login(e);
     },
     scanCode() {
-      getApp().scanCode()
+      getApp().scanCode();
     },
     inputCode() {
       wx.navigateTo({
-        url: '/pages-charge/codeing/codeing'
-      })
+        url: "/pages-charge/codeing/codeing",
+      });
     },
     toCharging() {
       wx.navigateTo({
-        url: `/pages-charge/ordering/ordering?sn=${this.data.charging}`
-      })
-    }
-  }
-})
+        url: `/pages-charge/ordering/ordering?sn=${this.data.charging}`,
+      });
+    },
+  },
+});

+ 77 - 67
src/manifest.json

@@ -1,72 +1,82 @@
 {
-    "name" : "",
-    "appid" : "",
-    "description" : "",
-    "versionName" : "1.0.0",
-    "versionCode" : "100",
-    "transformPx" : false,
-    /* 5+App特有相关 */
-    "app-plus" : {
-        "usingComponents" : true,
-        "nvueStyleCompiler" : "uni-app",
-        "compilerVersion" : 3,
-        "splashscreen" : {
-            "alwaysShowBeforeRender" : true,
-            "waiting" : true,
-            "autoclose" : true,
-            "delay" : 0
-        },
-        /* 模块配置 */
-        "modules" : {},
-        /* 应用发布信息 */
-        "distribute" : {
-            /* android打包配置 */
-            "android" : {
-                "permissions" : [
-                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
-                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
-                ]
-            },
-            /* ios打包配置 */
-            "ios" : {},
-            /* SDK配置 */
-            "sdkConfigs" : {}
-        }
+  "name": "",
+  "appid": "",
+  "description": "",
+  "versionName": "1.0.0",
+  "versionCode": "100",
+  "transformPx": false,
+  /* 5+App特有相关 */
+  "app-plus": {
+    "usingComponents": true,
+    "nvueStyleCompiler": "uni-app",
+    "compilerVersion": 3,
+    "splashscreen": {
+      "alwaysShowBeforeRender": true,
+      "waiting": true,
+      "autoclose": true,
+      "delay": 0
     },
-    /* 快应用特有相关 */
-    "quickapp" : {},
-    /* 小程序特有相关 */
-    "mp-weixin" : {
-        "appid" : "wx369fcff95d387bde",
-        "setting" : {
-            "urlCheck" : false
-        },
-        "usingComponents" : true
+    /* 模块配置 */
+    "modules": {},
+    /* 应用发布信息 */
+    "distribute": {
+      /* android打包配置 */
+      "android": {
+        "permissions": [
+          "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+          "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+          "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+          "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+          "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+          "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+          "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+          "<uses-feature android:name=\"android.hardware.camera\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+        ]
+      },
+      /* ios打包配置 */
+      "ios": {},
+      /* SDK配置 */
+      "sdkConfigs": {}
+    }
+  },
+  "quickapp": {},
+  "mp-weixin": {
+    "appid": "wx369fcff95d387bde",
+    "setting": {
+      "urlCheck": false
     },
-    "mp-alipay" : {
-        "usingComponents" : true
+    "useExtendedLib": {
+      "weui": true
     },
-    "mp-baidu" : {
-        "usingComponents" : true
-    },
-    "mp-toutiao" : {
-        "usingComponents" : true
-    },
-    "uniStatistics": {  
-        "enable": false
-    },
-    "vueVersion" : "3"
+    "style": "v2",
+    "darkmode": false,
+    "resizable": false,
+    "usingComponents": true,
+    "requiredPrivateInfos": ["getLocation"],
+    "permission": {
+      "scope.userLocation": {
+        "desc": "你的位置信息将用于获取附近充电桩位置"
+      }
+    }
+  },
+  "mp-alipay": {
+    "usingComponents": true
+  },
+  "mp-baidu": {
+    "usingComponents": true
+  },
+  "mp-toutiao": {
+    "usingComponents": true
+  },
+  "uniStatistics": {
+    "enable": false
+  },
+  "vueVersion": "3"
 }

+ 6 - 4
src/pages/map/index.vue

@@ -1,11 +1,13 @@
 <template>
-  <view class="map">
-  </view>
+  <view class="map"></view>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
-const title = ref('Hello')
+import { login, onLogin } from '../../api/auth'
+import { onShow } from "@dcloudio/uni-app";
+onShow(()=> {
+  console.log(login, onLogin)
+})
 </script>
 
 <style>

+ 1 - 0
src/types/index.d.ts

@@ -0,0 +1 @@
+declare const getApp: any

+ 32 - 0
src/utils/code.ts

@@ -0,0 +1,32 @@
+export function scanCode() {
+  uni.scanCode({
+    scanType: ["qrCode"],
+    success: (res) => {
+      console.log(res);
+      if (res.scanType === "QR_CODE" && res.result) {
+        deCode(res.result);
+      }
+    },
+  });
+}
+
+export function deCode(url: string) {
+  // 线上 https://www.kuaiyuman.cn/#001091
+  if (
+    /h5\.en-plus\.com/.test(url) ||
+    /www.en-plus.cn/.test(url) ||
+    /dev\.en-plus\.com\.cn/.test(url) ||
+    /www\.kuaiyuman\.cn/.test(url)
+  ) {
+    const split = url.split("/");
+    const sn = split[split.length - 1].replace("#", "");
+    uni.navigateTo({
+      url: `/pages-charge/ordering/ordering?sn=${sn}`,
+    });
+  } else {
+    uni.showModal({
+      content: "输扫描正确的二维码",
+      showCancel: false,
+    });
+  }
+}

+ 1 - 0
src/utils/constant.ts

@@ -0,0 +1 @@
+export const host = 'https://www.kuaiyuman.cn/api'

+ 166 - 0
src/utils/http.ts

@@ -0,0 +1,166 @@
+import { setToken, clearToken } from "../api/auth";
+
+interface IOptions {
+  data?: any;
+  params?: any;
+  header?: any;
+  statusCodeHandle?: boolean;
+}
+
+interface IResponse<T> {
+  code: number;
+  data: T;
+  msg: string;
+}
+
+class Http {
+  private baseUrl: string;
+  private header?: any;
+
+  constructor(baseUrl?: string, header?: any) {
+    this.baseUrl = baseUrl || "";
+    if (header) {
+      this.header = header;
+    }
+  }
+
+  request<R = any>(
+    method: "GET" | "POST",
+    api: string,
+    options?: IOptions
+  ): Promise<R> {
+    return new Promise((resolve, reject) => {
+      if (!options) {
+        options = {
+          statusCodeHandle: true,
+        };
+      }
+      const url = this.baseUrl + api;
+      const urlHasParams = url.indexOf("?") >= 0;
+      const header = {
+        // 'content-type': 'application/json',
+        Authorization: getApp().globalData.token || "",
+        ...(this.header || {}),
+        ...(options.header || {}),
+      };
+      const data = options.data || {};
+      const params = options.params || {};
+      const query = Object.keys(params)
+        .map(
+          (key) =>
+            `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
+        )
+        .join("&");
+
+      WxRequest<IResponse<R>>({
+        url: `${url}${query ? (urlHasParams ? "&" : "?") : ""}${query}`,
+        method,
+        data,
+        header,
+      })
+        .then((res) => {
+          if (res.code === 888) {
+            // eslint-disable-next-line promise/no-nesting
+            return WxRequest<IResponse<R>>({
+              url: `${url}${query ? (urlHasParams ? "&" : "?") : ""}${query}`,
+              method,
+              data,
+              header: {
+                ...header,
+                Authorization: getApp().globalData.token || "",
+              },
+            });
+          }
+          if (res.code === 21005 || res.code === 21000) {
+            clearToken();
+            setTimeout(() => {
+              uni.reLaunch({
+                url: "/pages/map/map",
+              });
+            }, 1000);
+            throw {
+              errMsg: "请重新登录",
+            };
+            // Token过期 废弃
+            // eslint-disable-next-line promise/no-nesting
+            // return refresh().then((token) => {
+            //   return WxRequest<IResponse<R>>({
+            //     url: `${url}${query ? (urlHasParams ? '&' : '?') : ''}${query}`,
+            //     method,
+            //     data,
+            //     header: {
+            //       ...header,
+            //       Authorization: token
+            //     }
+            //   })
+            // })
+          }
+          return res;
+        })
+        .then((res) => {
+          // eslint-disable-next-line no-console
+          console.log("接口返回", res);
+          const { msg } = res || {
+            msg: "出现错误",
+          };
+          if (res && msg === "OK") {
+            resolve(res.data);
+          } else {
+            throw {
+              errMsg: msg,
+            };
+          }
+        })
+        .catch((err) => {
+          if (err && err.errMsg && options && options.statusCodeHandle) {
+            uni.showToast({
+              title: `${err.errMsg}`,
+              icon: "none",
+            });
+          }
+          reject(err);
+        });
+    });
+  }
+
+  get<R = any>(api: string, options?: IOptions) {
+    return this.request<R>("GET", api, options);
+  }
+
+  post<R = any>(api: string, options?: IOptions) {
+    return this.request<R>("POST", api, options);
+  }
+}
+
+export function WxRequest<T = any>(
+  option: UniNamespace.RequestOptions
+): Promise<T> {
+  return new Promise((resolve, reject) => {
+    uni.request({
+      ...option,
+      success(res: any) {
+        // console.log('微信返回', res)
+        const { statusCode, header } = res;
+        if (header["Authorization"]) {
+          setToken(header["Authorization"]);
+          resolve({
+            ...res.data,
+            code: 888,
+          });
+          return;
+        }
+        if (statusCode > 200) {
+          reject({
+            errMsg: `${option.url}:${statusCode}`,
+          });
+        }
+        resolve(res.data);
+      },
+      fail: reject,
+    });
+  });
+}
+
+export default Http;
+
+export const http = new Http();

+ 112 - 0
src/utils/storage.ts

@@ -0,0 +1,112 @@
+class Storage {
+  private namespace: string
+
+  constructor(namespace?: string) {
+    this.namespace = `CHONGDIAN_${namespace || 'DEFAULT'}`
+  }
+
+  set<T = any>(key: string, data: T, expire?: number): Promise<void> {
+    const now = new Date().getTime()
+    const _d = {
+      data,
+      expire: expire ? now + expire : 0
+    }
+    return new Promise((resolve, reject) => {
+      uni.setStorage({
+        key: `${this.namespace}_${key}`,
+        data: JSON.stringify(_d),
+        success() {
+          resolve()
+        },
+        fail(err) {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  get<T = any>(key: string, defaultValue?: T): Promise<T | undefined> {
+    return new Promise(resolve => {
+      const _key = `${this.namespace}_${key}`
+      uni.getStorage({
+        key: _key,
+        success(res) {
+          if (res && res.data) {
+            try {
+              const data = JSON.parse(res.data)
+              if (!data.expire) {
+                resolve(data.data)
+                return
+              }
+              const now = new Date().getTime()
+              if (now <= data.expire) {
+                resolve(data.data)
+                return
+              }
+            } catch (error) {
+              // eslint-disable-next-line no-console
+              console.log(error)
+            }
+          }
+          uni.removeStorage({
+            key: _key
+          })
+          resolve(defaultValue ? defaultValue : undefined)
+        },
+        fail(err) {
+          resolve(defaultValue ? defaultValue : undefined)
+          return err
+        }
+      })
+    })
+  }
+
+  clear(key?: string): Promise<void> {
+    if (key) {
+      const _key = `${this.namespace}_${key}`
+      return this.rm(_key)
+    }
+    return new Promise((resolve, reject) => {
+      uni.getStorageInfo({
+        success: res => {
+          if (res.keys && res.keys.length) {
+            const reg = new RegExp(`^${this.namespace.replace(/\^/gi, '\\^')}.+`)
+            const ps: Promise<void>[] = []
+            res.keys.forEach(key => {
+              if (reg.test(key)) {
+                ps.push(this.rm(key))
+              }
+            })
+            Promise.all(ps)
+              .then(() => {
+                resolve()
+                return true
+              })
+              .catch(reject)
+            return
+          }
+          resolve()
+        },
+        fail: err => {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  private rm(key: string): Promise<void> {
+    return new Promise((resolve, reject) => {
+      uni.removeStorage({
+        key,
+        success() {
+          resolve()
+        },
+        fail(err) {
+          reject(err)
+        }
+      })
+    })
+  }
+}
+
+export default Storage

+ 1 - 0
tsconfig.json

@@ -1,6 +1,7 @@
 {
   "extends": "@vue/tsconfig/tsconfig.json",
   "compilerOptions": {
+    "ignoreDeprecations": "5.0",
     "sourceMap": true,
     "baseUrl": ".",
     "paths": {