소스 검색

基础框架补充

zuy 1 년 전
부모
커밋
fb279d6be1
7개의 변경된 파일981개의 추가작업 그리고 23개의 파일을 삭제
  1. 12 2
      src/App.vue
  2. 67 21
      src/pages.json
  3. 35 0
      src/utils/common.ts
  4. 17 0
      src/utils/device.ts
  5. 200 0
      src/utils/https.js
  6. 538 0
      src/utils/mixin.js
  7. 112 0
      src/utils/storage.ts

+ 12 - 2
src/App.vue

@@ -1,6 +1,5 @@
 <script setup lang="ts">
-import {onHide, onLaunch, onReady, onShow} from "@dcloudio/uni-app";
-import {getCurrentInstance} from 'vue';
+import {onHide, onLaunch, onShow} from "@dcloudio/uni-app";
 
 /*const {ctx} = getCurrentInstance();
 onReady(() => {
@@ -10,8 +9,19 @@ onReady(() => {
 })
 console.log(uni.$uv.os())*/
 
+const globalData = {
+  device: {},
+  token: "",
+  userInfo: {}
+}
+
 onLaunch(() => {
   console.log("App Launch");
+  uni.getSystemInfo({
+    success: (res) => {
+      globalData.device = res;
+    },
+  });
 });
 onShow(() => {
   console.log("App Show");

+ 67 - 21
src/pages.json

@@ -1,23 +1,69 @@
 {
-	"easycom": {
-		"autoscan": true,
-		"custom": {
-			"^uv-(.*)": "@climblee/uv-ui/components/uv-$1/uv-$1.vue"
-		}
-	},
-	//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
-	"pages": [
-		{
-			"path": "pages/index/index",
-			"style": {
-				"navigationBarTitleText": "uni-app"
-			}
-		}
-	],
-	"globalStyle": {
-		"navigationBarTextStyle": "black",
-		"navigationBarTitleText": "uni-app",
-		"navigationBarBackgroundColor": "#F8F8F8",
-		"backgroundColor": "#F8F8F8"
-	},
+  "easycom": {
+    "autoscan": true,
+    "custom": {
+      "^uv-(.*)": "@climblee/uv-ui/components/uv-$1/uv-$1.vue"
+    }
+  },
+  //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+  "pages": [
+    {
+      "path": "pages/index/index",
+      "style": {
+        "navigationBarTitleText": "uni-app"
+      }
+    },
+    {
+      "path": "pages/map/map",
+      "style": {
+        "disableScroll": true
+      }
+    },
+    {
+      "path": "pages/user/user"
+    }
+  ],
+  "subPackages": {
+    "root": "pages-common",
+    "pages": [
+      {
+        "path": "profile/index",
+        "style": {
+          "navigationStyle": "default",
+          "navigationBarTitleText": "我的信息",
+          "navigationBarBackgroundColor": "#ffffff"
+        }
+      },
+      {
+        "path": "contact/index",
+        "style": {
+          "navigationStyle": "default",
+          "navigationBarTitleText": "联系我们",
+          "navigationBarBackgroundColor": "#ffffff"
+        }
+      },
+      {
+        "path": "faq/index",
+        "style": {
+          "navigationStyle": "default",
+          "navigationBarTitleText": "常见问题",
+          "navigationBarBackgroundColor": "#ffffff"
+        }
+      },
+      {
+        "path": "fav/index",
+        "style": {
+          "navigationStyle": "default",
+          "navigationBarTitleText": "我的收藏",
+          "navigationBarBackgroundColor": "#ffffff"
+        }
+      }
+    ]
+  },
+  "globalStyle": {
+    "navigationBarTextStyle": "black",
+    "navigationBarTitleText": "uni-app",
+    "navigationBarBackgroundColor": "#F8F8F8",
+    "backgroundColor": "#F8F8F8"
+  }
 }

+ 35 - 0
src/utils/common.ts

@@ -0,0 +1,35 @@
+// -防抖
+export function debounce(fn: Function, wait: number) {
+    let delay = wait || 500
+    let timer: any = null;
+    return function () {
+        let args = arguments;
+        if (timer) {
+            clearTimeout(timer)
+            console.log('debounce')
+        }
+        let callNow = !timer
+        timer = setTimeout(() => {
+            console.log('debounce send')
+            timer = null
+        }, delay)
+        if (callNow) fn.apply(null, args)
+    }
+}
+
+// -节流
+export function throttle(fn: Function, wait: number) {
+    let delay = wait || 500
+    let timer: any = null;
+    return function () {
+        if (timer) {
+            console.log('throttle');
+            return
+        }
+        timer = setTimeout(() => {
+            console.log('throttle send');
+            fn.apply(null, arguments)
+            timer = null
+        }, delay)
+    }
+}

+ 17 - 0
src/utils/device.ts

@@ -0,0 +1,17 @@
+export function rpxToPx(rpx: number): number {
+  if (getApp<any>().globalData.device) {
+    return (rpx * getApp<any>().globalData.device.windowWidth) / 750;
+  }
+  return rpx;
+}
+
+export function pxToRpx(px: number): number {
+  if (getApp<any>().globalData.device) {
+    return (750 * px) / getApp<any>().globalData.device.windowWidth;
+  }
+  return px;
+}
+
+export const isDevTool =
+  getApp<any>().globalData.device &&
+  getApp<any>().globalData.device.platform === "devtools";

+ 200 - 0
src/utils/https.js

@@ -0,0 +1,200 @@
+const env = process.env.NODE_ENV==="development"?"dev":"prd";
+let apis = {
+    dev: {
+        serverUrl: "http://localhost:10086/cms/",
+        fileUrl: "https://zyp-1258963180.cos.ap-guangzhou.myqcloud.com/"
+    },
+    uat: {
+        serverUrl: "http://npt.free.idcfengye.com/",
+        fileUrl: "https://zyp-1258963180.cos.ap-guangzhou.myqcloud.com/"
+    },
+    prd: {
+        serverUrl: "https://npww.net.cn/cms/",
+        fileUrl: "https://zyp-1258963180.cos.ap-guangzhou.myqcloud.com/",
+    },
+};
+const cfg = {
+    key: {
+        token: 'npt.token'
+    },
+    env: env,
+    api: {
+        serverUrl: apis[env].serverUrl,
+        fileUrl: apis[env].fileUrl,
+        uploadUrl: apis[env].serverUrl + "file/upload"
+    }
+};
+
+const serverUrl = cfg.api.serverUrl;
+const fileUrl = cfg.api.fileUrl;
+
+let source = -1;
+// #ifdef APP-PLUS
+source = 5;
+// #endif
+// #ifdef H5
+source = 3;
+// #endif
+// #ifdef MP-WEIXIN
+source = 2;
+// #endif
+// #ifdef MP-ALIPAY
+source = 7;
+// #endif
+// #ifdef MP-BAIDU
+source = 6;
+// #endif
+// #ifdef MP-QQ
+source = 9;
+// #endif
+// #ifdef MP-TOUTIAO
+source = 8;
+// #endif
+
+const isEmptyOrNull = function (exp) {
+    return !exp || typeof (exp) == "undefined" || exp.length === 0 || exp === '' || JSON.stringify(exp) === "{}";
+};
+
+
+/**
+ * get请求封装
+ * @param url
+ * @param param
+ */
+const get = (url, param = {}) => {
+    let token = uni.getStorageSync(cfg.key.token) || "";
+    if (!isEmptyOrNull(param)) {
+        var params = [];
+        for (var key in param) {
+            params.push(encodeURIComponent(key) + "=" + encodeURIComponent(param[key]));
+        }
+        param = params.join("&")
+    }
+    let options = {
+        url: fillUrl(url) + (isEmptyOrNull(param) ? "" : "?" + param),
+        data: param,
+        method: 'GET',
+        header: {
+            "Accept": "application/json",
+            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
+            "X-Token": token,
+            "X-Client-Type": source
+        },
+    };
+    return request(options)
+};
+
+
+const post = (url, param = {}) => {
+    let token = uni.getStorageSync(cfg.key.token) || "";
+    let options = {
+        url: fillUrl(url),
+        data: param,
+        method: 'POST',
+        header: {
+            'X-Requested-With': 'XMLHttpRequest',
+            "Accept": "application/json",
+            "Content-Type": "application/json; charset=UTF-8",
+            "X-Token": token,
+            "X-Client-Type": source
+        },
+        dataType: 'json'
+    };
+    return request(options);
+};
+
+
+const request = (options) => {
+    return new Promise((resolve, reject) => {
+        uni.request({
+            url: options.url,
+            data: options.data,
+            method: options.method,
+            header: options.header,
+            dataType: options.dataType
+        }).then(res => {
+            let response = res[1].data;
+            if (response.code !== 200) {
+                if (response.code == 92213 || response.code == 92305) {
+                    uni.showToast({
+                        title: response.msg,
+                        icon: 'none'
+                    });
+                    setTimeout(() => {
+                        uni.navigateTo({
+                            url: `/pages/login/login`
+                        })
+                    }, 300)
+
+                } else {
+                    let errMsg = response.msg || '网络异常,请稍后重试';
+                    uni.showToast({
+                        title: errMsg,
+                        icon: 'none'
+                    });
+                    reject(errMsg);
+                }
+            } else {
+                resolve(response.data);
+            }
+        }).catch(error => {
+            uni.hideLoading();
+            uni.showToast({
+                title: '网络异常,请稍后重试',
+                icon: 'none'
+            });
+            console.error("error=>", error);
+            reject(error.msg);
+        })
+    });
+};
+
+const upload = opt => {
+    opt = opt || {};
+    opt.url = opt.url || '';
+    opt.filePath = opt.filePath || null;//要上传文件资源的路径。
+    opt.name = opt.name || null;//文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
+
+    opt.filePath = opt.filePath || null;
+    opt.success = opt.success || function () {
+    };
+
+
+    uni.uploadFile({
+        url: fillUrl(opt.url),
+        filePath: opt.filePath,
+        name: opt.name,
+        success: function (res) {
+            console.log("upload file=>", res)
+            opt.success(res);
+        },
+        fail: function () {
+            uni.showToast({
+                title: '请稍后重试'
+            });
+        }
+    })
+};
+
+
+const fillUrl = function (url) {
+    if (url.indexOf("http") === 0) {
+        return url;
+    } else {
+        return serverUrl + url;
+    }
+};
+
+const formatUrl = v => {
+    if (v == null || v == "") {
+        return "/static/missing-face.png";
+    }
+    if (v.indexOf("http") === 0) {
+        return v;
+    }
+    return fileUrl + v.replace(/\\/g, "/");
+};
+
+export {
+    get, post, upload, cfg, serverUrl, fileUrl,formatUrl
+}

+ 538 - 0
src/utils/mixin.js

@@ -0,0 +1,538 @@
+import {isIos, judgeIosPermission, requestAndroidPermission, gotoAppPermissionSetting} from "./permission"
+import {cfg, fileUrl, serverUrl} from "./https";
+
+
+const msg = (title, icon = 'none', duration = 1800, mask = false) => {
+    //统一提示方便全局修改
+    if (Boolean(title) === false) {
+        return;
+    }
+    uni.showToast({
+        title,
+        duration,
+        mask,
+        icon
+    });
+};
+
+const isEmptyOrNull = function (exp) {
+    return !exp || typeof (exp) == "undefined" || exp.length === 0 || exp == '' || JSON.stringify(exp) == "{}";
+};
+
+
+const fillUrl = function (url) {
+    if (!url) {
+        return "";
+    }
+    if (url.indexOf("http") === 0) {
+        return url;
+    } else {
+        return fileUrl + url;
+    }
+};
+
+const getData = function (key, callback) {
+    uni.getStorage({
+        key: key,
+        success: function (res) {
+            if (!!callback) {
+                callback(null, [res.data]);
+            }
+        }
+    });
+};
+
+const formatDateTime = date => {
+    if (!date) {
+        return "";
+    }
+    if (!date instanceof Number && !date instanceof Date) {
+        return date;
+    }
+    date = new Date(date);
+    const year = date.getFullYear();
+    const month = date.getMonth() + 1;
+    const day = date.getDate();
+    const hour = date.getHours();
+    const minute = date.getMinutes();
+    const second = date.getSeconds();
+
+    return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
+};
+
+const formatDate = date => {
+    if (!date) {
+        return "";
+    }
+    if (!date instanceof Number && !date instanceof Date) {
+        return date;
+    }
+    date = new Date(date);
+    const year = date.getFullYear();
+    const month = date.getMonth() + 1;
+    const day = date.getDate();
+    const hour = date.getHours();
+    const minute = date.getMinutes();
+    const second = date.getSeconds();
+
+    return [year, month, day].map(formatNumber).join('-');
+};
+
+const formatNumber = n => {
+    n = n.toString();
+    return n[1] ? n : '0' + n
+};
+
+const fmtMoney = v => {
+    let value = v || 0;
+    return (Number(value) / 100).toFixed(2);
+};
+
+/**
+ * 根据key查找数据中对应角标
+ */
+const getDataIndex = (key, data) => {
+    var value = '';
+    var i = 0;
+    while (i < data.length) {
+        if (key == data[i].key) {
+            value = i;
+            break;
+        } else {
+            i++;
+        }
+    }
+    return value;
+};
+
+const getDictValue = (type, code, dict) => {
+    if (!dict || !code) {
+        return "";
+    }
+    let dictList = dict[type];
+    if (!isEmptyOrNull(dictList)) {
+        for (let i = 0; i < dictList.length; i++) {
+            if (dictList[i].code == code) {
+                return dictList[i].value;
+            }
+        }
+    }
+    return "";
+};
+
+const contains = (array, element, key) => {
+    if (!isEmptyOrNull(array)) {
+        for (let i = 0; i < array.length; i++) {
+            if (!key) {
+                if (array[i] == element) {
+                    return true;
+                }
+            } else if (key) {
+                if (element.constructor != Object && array[i][key] == element) {
+                    return true;
+                } else if (element.constructor == Object && array[i][key] == element[key]) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+};
+
+const gm = {
+    data() {
+        return {
+            shareOptions: {}
+        }
+    },
+    onShareAppMessage() {
+        return {
+            title: this.shareOptions.title,
+            path: this.shareOptions.path,
+            imageUrl: this.shareOptions.imageUrl,
+            success: function (res) {
+                console.log("share success", res)
+            }
+        }
+    },
+    filters: {
+        fmtUrl(url) {
+            return fillUrl(url);
+        },
+        fmtDate(date) {
+            return formatDate(date);
+        },
+        fmtDateTime(date) {
+            return formatDateTime(date);
+        },
+        fmtMoney(money) {
+            return fmtMoney(money);
+        },
+        fmtDict(code, type) {
+            var dataList = uni.getStorage("dataList");
+            return getDictValue(type, code, dataList);
+        },
+        fmtHisDate(t) {
+            if (t === null || t === undefined) {
+                return '';
+            }
+            const date = new Date(t * 1000);
+            const year = date.getFullYear();
+            const month = date.getMonth() + 1;
+            const day = date.getDate();
+            const hour = date.getHours();
+            const minute = date.getMinutes();
+
+            const today = new Date();
+            const ty = today.getFullYear();
+            const tm = today.getMonth() + 1;
+            const td = today.getDate();
+            if (year === ty && month === tm && day === td) {
+                return [hour, minute].map(n => {
+                    n = n.toString();
+                    return n[1] ? n : '0' + n;
+                }).join(':');
+            }
+            return [month, day].map(n => {
+                n = n.toString();
+                return n[1] ? n : '0' + n;
+            }).join('-') + "  " + [hour, minute].map(n => {
+                n = n.toString();
+                return n[1] ? n : '0' + n;
+            }).join(':');
+        },
+    },
+    methods: {
+        toPage(url){
+            var tabPages =["pages/index/index","pages/category/category","pages/cart/cart","pages/account/center"]
+            if(tabPages.findIndex(item=>url.indexOf(item)>-1)>-1){
+                uni.switchTab({url:url});
+            }else{
+                uni.navigateTo({url:url});
+            }
+        },
+        copy(obj) {
+            var newobj = obj.constructor === Array ? [] : {};
+            if (typeof obj !== 'object') {
+                return;
+            }
+            for (var i in obj) {
+                newobj[i] = typeof obj[i] === 'object' ? this.copy(obj[i]) : obj[i];
+            }
+            return newobj
+        },
+        getPrePage(delta=1) {
+            let pages = getCurrentPages();
+            pages.forEach(item=>console.log("route--->",item.route))
+
+            let prePage = pages[pages.length - (delta+1)];
+            // #ifdef H5
+            return prePage;
+            // #endif
+            return prePage.$vm;
+        },
+        getUrl(url) {
+            if (url.indexOf("http") === 0) {
+                return url;
+            } else {
+                return serverUrl + url;
+            }
+        },
+        isNull(val) {
+            return isEmptyOrNull(val);
+        },
+        contains(array, element, key) {
+            return contains(array, element, key);
+        },
+        stopEvent(e) {
+            console.log("stop event")
+            e.stopPrevent();
+        },
+        uploadImages(count, scallback, fcallback) {
+            let result = [];
+            this.checkPermission("camera", () => {
+                this.checkPermission("storage", () => {
+                    uni.chooseImage({
+                        count: count, //默认9
+                        sizeType: ['original', 'compressed'],
+                        sourceType: ['album'],
+                        success: (res) => {
+                            uni.showLoading({title: "图片上传中"});
+                            const files = res.tempFilePaths;
+                            let length = files.length;
+                            for (let i = 0; i < files.length; i++) {
+                                let fp = files[i];
+                                const formData = {
+                                    thumb_mode: 1,
+                                    'X-Token': uni.getStorageSync(cfg.key.token) || ""
+                                };
+                                uni.uploadFile({
+                                    url: cfg.api.uploadUrl,
+                                    filePath: fp,
+                                    name: 'file',
+                                    formData: formData,
+                                    success: (uploadFileRes) => {
+                                        result.unshift(JSON.parse(uploadFileRes.data).result.uuid);
+                                    },
+                                    complete: () => {
+                                        length--;
+                                        if (length <= 0) {
+                                            uni.hideLoading();
+                                            setTimeout(() => {
+                                                if (scallback) {
+                                                    console.log(result)
+                                                    scallback.call(null, result);
+                                                }
+                                            }, 100)
+                                        }
+                                    }
+                                });
+                            }
+                        }
+                    });
+                });
+            })
+        },
+        uploadVideo(callback) {
+            this.checkPermission("camera", () => {
+                this.checkPermission("storage", () => {
+                    uni.chooseVideo({
+                        count: 1, //默认9
+                        sourceType: ['camera', 'album'],
+                        maxDuration: 30,
+                        success: (res) => {
+                            if (res.size > 51200000) {
+                                this.$dialog.success("只能上传小于50M的视频!");
+                                return;
+                            }
+                            uni.showLoading({
+                                title: '视频上传中'
+                            });
+                            const formData = {
+                                thumb_mode: 1,
+                                'X-Token': uni.getStorageSync(cfg.key.token) || ""
+                            };
+                            uni.uploadFile({
+                                url: cfg.api.uploadUrl,
+                                filePath: res.tempFilePath,
+                                name: 'file',
+                                formData: formData,
+                                success: (uploadFileRes) => {
+                                    callback(uploadFileRes);
+                                    uni.hideLoading();
+                                },
+                                complete: () => {
+                                    uni.hideLoading();
+                                }
+                            });
+                        }
+                    });
+                })
+            })
+        },
+        payRequest(payType, payInfo, scallback, fcallback) {
+            let _this = this;
+            //1微信 2-支付宝
+            if (payType === 1) {
+                // fcallback.apply();
+                uni.requestPayment({
+                    provider: 'wxpay',
+                    orderInfo: payInfo.wxpay,
+                    success: function (res) {
+                        scallback.apply();
+                    },
+                    fail: function (err) {
+                        console.log('fail:' + JSON.stringify(err));
+                        fcallback.apply();
+                    }
+                });
+            } else if (payType === 2) {
+                uni.requestPayment({
+                    provider: 'alipay',
+                    orderInfo: payInfo.alipay.orderString,
+                    success: function (res) {
+                        scallback.apply();
+                    },
+                    fail: function (err) {
+                        console.log('fail:' + JSON.stringify(err));
+                        fcallback.apply();
+                    }
+                });
+            }
+        },
+        getDate(date, type) {
+            let year = date.getFullYear();
+            let month = date.getMonth() + 1;
+            let day = date.getDate();
+
+            if (type === 'start') {
+                year = year - 60;
+            } else if (type === 'end') {
+                year = year + 2;
+            }
+            month = month > 9 ? month : '0' + month;
+            day = day > 9 ? day : '0' + day;
+            return `${year}年${month}月`;
+        },
+        getTimestamp(timestamp) {
+            function zeroize(num) {
+                return (String(num).length === 1 ? '0' : '') + num;
+            }
+
+            var curTimestamp = parseInt(new Date().getTime() / 1000); //当前时间戳
+
+            var curDate = new Date(curTimestamp * 1000); // 当前时间日期对象
+            var tmDate = new Date(timestamp);  // 参数时间戳转换成的日期对象
+
+            var Y = tmDate.getFullYear(), m = tmDate.getMonth() + 1, d = tmDate.getDate();
+
+            if (curDate.getFullYear() == Y && curDate.getMonth() + 1 == m && curDate.getDate() == d) {
+                return '今天';
+            } else {
+                var newDate = new Date((curTimestamp - 86400) * 1000); // 参数中的时间戳加一天转换成的日期对象
+                if (newDate.getFullYear() == Y && newDate.getMonth() + 1 == m && newDate.getDate() == d) {
+                    return '昨天';
+                } else if (curDate.getFullYear() == Y) {
+                    return zeroize(m) + '月' + zeroize(d) + '日 ';
+                } else {
+                    return Y + '年' + zeroize(m) + '月' + zeroize(d) + '日 ';
+                }
+            }
+        },
+        isPhoneNumber(phone) {
+            const reg = /^((0\d{2,3}-?\d{7,8})|(1\d{10}))$/; //校验手机号和固定电话
+            return reg.test(phone);
+        },
+        isBankCardNo(bankNo) {
+            var num = /^\d*$/;
+            return !(bankNo.length < 16 || bankNo.length > 19 || !num.test(bankNo));
+        },
+        throttle(fn, wait = 500, isImmediate = false) {
+            let flag = true;
+            if (isImmediate) {
+                return function () {
+                    if (flag) {
+                        fn.apply(this, arguments);
+                        flag = false;
+                        setTimeout(() => {
+                            flag = true
+                        }, wait)
+                    }
+                }
+            }
+            return function () {
+                if (flag == true) {
+                    flag = false
+                    setTimeout(() => {
+                        fn.apply(this, arguments)
+                        flag = true
+                    }, wait)
+                }
+            }
+        },
+        debounce(fn, wait = 500, isImmediate = false) {
+            let timerId = null;
+            let flag = true;
+            if (isImmediate) {
+                return function () {
+                    clearTimeout(timerId);
+                    if (flag) {
+                        fn.apply(this, arguments);
+                        flag = false
+                    }
+                    timerId = setTimeout(() => {
+                        flag = true
+                    }, wait)
+                }
+            }
+            return function () {
+                clearTimeout(timerId);
+                timerId = setTimeout(() => {
+                    fn.apply(this, arguments)
+                }, wait)
+            }
+        },
+        /**
+         * APP权限校验 https://ext.dcloud.net.cn/plugin?id=594
+         * @param permissionId
+         * @param scallback
+         * @param fcallback
+         */
+        checkPermission(permissionId, scallback, fcallback) {
+            let _this = this;
+            //location	位置
+            // push	推送(限iOS,注意Android上推送并不是一个权限)
+            // camera	摄像头
+            // photoLibrary	相册
+            // record	麦克风
+            // contact	通讯录
+            // calendar	日历
+            // memo	备忘录
+
+            //#ifdef APP-PLUS
+            let msg = "";
+            if (isIos) {
+                let ret = judgeIosPermission(permissionId);
+                if (ret) {
+                    if (scallback) {
+                        scallback.apply();
+                    }
+                } else {
+                    _this.askToPermission(msg, fcallback);
+                }
+            } else {
+                if (permissionId == 'camera') {
+                    msg = "相机";
+                    permissionId = "android.permission.CAMERA";
+                }
+                if (permissionId == 'storage') {
+                    msg = "存储";
+                    permissionId = "android.permission.READ_EXTERNAL_STORAGE";
+                }
+                if (permissionId == 'location') {
+                    msg = "定位";
+                    permissionId = "android.permission.ACCESS_FINE_LOCATION";
+                }
+                requestAndroidPermission(permissionId).then(res => {
+                    console.log("android permission resp:" + JSON.stringify(res))
+                    if (res == 1) {
+                        if (scallback) {
+                            scallback.apply();
+                        }
+                    } else {
+                        _this.askToPermission(msg, fcallback);
+                    }
+                })
+            }
+            //#endif
+
+            //#ifndef APP-PLUS
+            if (scallback) {
+                scallback.apply();
+            }
+            //#endif
+        },
+        askToPermission(msg, fcallback) {
+            uni.showModal({
+                content: "您未授予应用" + msg + "相关权限,是否前往APP设置?",
+                success: ms => {
+                    if (ms.confirm) {
+                        try {
+                            gotoAppPermissionSetting();
+                        } catch (e) {
+                            console.error(e)
+                        }
+                    } else if (ms.cancel) {
+                        //do nothing
+                        if (fcallback) {
+                            fcallback.apply();
+                        }
+                    }
+                }
+            });
+        },
+    }
+
+};
+
+export {gm, msg};

+ 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