diff --git a/pages.json b/pages.json index 79e10aa..26b4e5a 100644 --- a/pages.json +++ b/pages.json @@ -63,6 +63,57 @@ } } ], + "subPackages": [ + { + "root": "pages/public", + "pages": [{ + "path": "setting", + "style": { + "navigationBarTitleText": "系统设置" + }, + "meta": { + "sync": true, + "title": "系统设置", + "group": "通用" + } + }, + { + "path": "richtext", + "style": { + "navigationBarTitleText": "富文本" + }, + "meta": { + "sync": true, + "title": "富文本", + "group": "通用" + } + }, + { + "path": "faq", + "style": { + "navigationBarTitleText": "常见问题" + }, + "meta": { + "sync": true, + "title": "常见问题", + "group": "通用" + } + }, + { + "path": "error", + "style": { + "navigationBarTitleText": "错误页面" + } + }, + { + "path": "webview", + "style": { + "navigationBarTitleText": "" + } + } + ] + } + ], "tabBar": { "list": [ { diff --git a/pages/public/error.vue b/pages/public/error.vue new file mode 100644 index 0000000..ef0ab9c --- /dev/null +++ b/pages/public/error.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/peach/request/index.js b/peach/request/index.js index dcfede9..0fba3b3 100644 --- a/peach/request/index.js +++ b/peach/request/index.js @@ -3,34 +3,34 @@ * @description api 模块管理,loading 配置,请求拦截,错误处理 */ -import Request from 'luch-request' -import { baseUrl, apiPath } from '@/peach/config' -import $store from '@/peach/store' -import { showAuthModal } from '@/peach/hooks/useModal' -import AuthUtil from '@/peach/api/member/auth' +import Request from "luch-request"; +import { baseUrl, apiPath } from "@/peach/config"; +import peach from "@/peach"; +import $store from "@/peach/store"; +import AuthUtil from "@/peach/api/member/auth"; const options = { - // 显示操作成功消息 默认不显示 - showSuccess: false, - // 成功提醒 默认使用后端返回值 - successMsg: '', - // 显示失败消息 默认显示 - showError: true, - // 失败提醒 默认使用后端返回信息 - errorMsg: '', - // 显示请求时loading模态框 默认显示 - showLoading: true, - // loading提醒文字 - loadingMsg: '加载中', - // 需要授权才能请求 默认放开 - auth: false, -} + // 显示操作成功消息 默认不显示 + showSuccess: false, + // 成功提醒 默认使用后端返回值 + successMsg: "", + // 显示失败消息 默认显示 + showError: true, + // 失败提醒 默认使用后端返回信息 + errorMsg: "", + // 显示请求时loading模态框 默认显示 + showLoading: true, + // loading提醒文字 + loadingMsg: "加载中", + // 需要授权才能请求 默认放开 + auth: false, +}; // Loading全局实例 let LoadingInstance = { - target: null, - count: 0, -} + target: null, + count: 0, +}; /** * @author Ankkaya @@ -39,21 +39,21 @@ let LoadingInstance = { * @returns {Type} */ function closeLoading() { - if (LoadingInstance.count > 0) LoadingInstance.count-- - if (LoadingInstance.count === 0) uni.hideLoading() + if (LoadingInstance.count > 0) LoadingInstance.count--; + if (LoadingInstance.count === 0) uni.hideLoading(); } // 请求实例 const http = new Request({ - baseUrl: baseUrl + apiPath, - timeout: 8000, - method: 'GET', - header: { - Accept: 'text/json', - 'Content-Type': 'application/json;charset=UTF-8', - }, - custom: options, -}) + baseUrl: baseUrl + apiPath, + timeout: 8000, + method: "GET", + header: { + Accept: "text/json", + "Content-Type": "application/json;charset=UTF-8", + }, + custom: options, +}); /** * @author Ankkaya @@ -63,39 +63,39 @@ const http = new Request({ */ http.interceptors.request.use( - (config) => { - // 自定义处理【auth 授权】:必须登录的接口,否则提示登录 - if (config.custom.auth && !$store('user').isLogin) { - // 处理登录 - showAuthModal() - return Promise.reject() - } - - // 自定义处理【loading 加载中】:如果需要显示 loading,则显示 loading - if (config.custom.showLoading) { - LoadingInstance.count++ - LoadingInstance.count === 1 && - uni.showLoading({ - title: config.custom.loadingMsg, - mask: true, - fail: () => { - uni.hideLoading() - }, - }) - } - - // 增加 token 令牌、terminal 终端、tenant 租户的请求头 - const token = getAccessToken() - if (token) { - config.header['Authorization'] = token - } - config.header['Accept'] = '*/*' - return config - }, - (error) => { - return Promise.reject(error) + (config) => { + // 自定义处理【auth 授权】:必须登录的接口,否则提示登录 + if (config.custom.auth && !$store("user").isLogin) { + // 处理登录 + peach.$router.go("/pages/index/login"); + return Promise.reject(); } -) + + // 自定义处理【loading 加载中】:如果需要显示 loading,则显示 loading + if (config.custom.showLoading) { + LoadingInstance.count++; + LoadingInstance.count === 1 && + uni.showLoading({ + title: config.custom.loadingMsg, + mask: true, + fail: () => { + uni.hideLoading(); + }, + }); + } + + // 增加 token 令牌、terminal 终端、tenant 租户的请求头 + const token = getAccessToken(); + if (token) { + config.header["Authorization"] = token; + } + config.header["Accept"] = "*/*"; + return config; + }, + (error) => { + return Promise.reject(error); + } +); /** * @author Ankkaya @@ -104,194 +104,202 @@ http.interceptors.request.use( * @returns {Type} */ http.interceptors.response.use( - (response) => { - console.log('response', response) - // 约定:如果是 /auth/ 下的 URL 地址,并且返回了 accessToken 说明是登录相关的接口,则自动设置登陆令牌 - if (response.config.url.indexOf('/member/auth/') >= 0 && response.data?.data?.accessToken) { - $store('user').setToken(response.data.data.accessToken, response.data.data.refreshToken) - } - - // 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading - response.config.custom.showLoading && closeLoading() - - // 自定义处理【error 错误提示】:如果需要显示错误提示,则显示错误提示 - if (response.data.code !== 0) { - // 特殊:如果 401 错误码,则跳转到登录页 or 刷新令牌 - if (response.data.code === 401) { - return refreshToken(response.config) - } - - // 错误提示 - if (response.config.custom.showError) { - uni.showToast({ - title: response.data.msg || '服务器开小差啦,请稍后再试~', - icon: 'none', - mask: true, - }) - return Promise.reject(false) - } - } - - // 自定义处理【showSuccess 成功提示】:如果需要显示成功提示,则显示成功提示 - if ( - response.config.custom.showSuccess && - response.config.custom.successMsg !== '' && - response.data.code === 0 - ) { - uni.showToast({ - title: response.config.custom.successMsg, - icon: 'none', - }) - } - - // 返回结果:包括 code + data + msg - return Promise.resolve(response.data) - }, - (error) => { - console.log('error', error) - const userStore = $store('user') - const isLogin = userStore.isLogin - let errorMessage = '网络请求出错' - if (error !== undefined) { - switch (error.statusCode) { - case 400: - errorMessage = '请求错误' - break - case 401: - errorMessage = isLogin ? '您的登陆已过期' : '请先登录' - // 正常情况下,后端不会返回 401 错误,所以这里不处理 handleAuthorized - break - case 403: - errorMessage = '拒绝访问' - break - case 404: - errorMessage = '请求出错' - break - case 408: - errorMessage = '请求超时' - break - case 429: - errorMessage = '请求频繁, 请稍后再访问' - break - case 500: - errorMessage = '服务器开小差啦,请稍后再试~' - break - case 501: - errorMessage = '服务未实现' - break - case 502: - errorMessage = '网络错误' - break - case 503: - errorMessage = '服务不可用' - break - case 504: - errorMessage = '网络超时' - break - case 505: - errorMessage = 'HTTP 版本不受支持' - break - } - if (error.errMsg.includes('timeout')) errorMessage = '请求超时' - // #ifdef H5 - if (error.errMsg.includes('Network')) - errorMessage = window.navigator.onLine ? '服务器异常' : '请检查您的网络连接' - // #endif - } - - if (error && error.config) { - if (error.config.custom.showError === true) { - uni.showToast({ - title: error.data?.msg || errorMessage, - icon: 'none', - mask: true, - }) - } - error.config.custom.showLoading && closeLoading() - } - - return Promise.reject(false) + (response) => { + console.log("response", response); + // 约定:如果是 /auth/ 下的 URL 地址,并且返回了 accessToken 说明是登录相关的接口,则自动设置登陆令牌 + if ( + response.config.url.indexOf("/member/auth/") >= 0 && + response.data?.data?.accessToken + ) { + $store("user").setToken( + response.data.data.accessToken, + response.data.data.refreshToken + ); } -) -let requestList = [] // 请求队列 -let isRefreshToken = false // 是否正在刷新中 + // 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading + response.config.custom.showLoading && closeLoading(); + + // 自定义处理【error 错误提示】:如果需要显示错误提示,则显示错误提示 + if (response.data.code !== 0) { + // 特殊:如果 401 错误码,则跳转到登录页 or 刷新令牌 + if (response.data.code === 401) { + return refreshToken(response.config); + } + + // 错误提示 + if (response.config.custom.showError) { + uni.showToast({ + title: response.data.msg || "服务器开小差啦,请稍后再试~", + icon: "none", + mask: true, + }); + return Promise.reject(false); + } + } + + // 自定义处理【showSuccess 成功提示】:如果需要显示成功提示,则显示成功提示 + if ( + response.config.custom.showSuccess && + response.config.custom.successMsg !== "" && + response.data.code === 0 + ) { + uni.showToast({ + title: response.config.custom.successMsg, + icon: "none", + }); + } + + // 返回结果:包括 code + data + msg + return Promise.resolve(response.data); + }, + (error) => { + console.log("error", error); + const userStore = $store("user"); + const isLogin = userStore.isLogin; + let errorMessage = "网络请求出错"; + if (error !== undefined) { + switch (error.statusCode) { + case 400: + errorMessage = "请求错误"; + break; + case 401: + errorMessage = isLogin ? "您的登陆已过期" : "请先登录"; + // 正常情况下,后端不会返回 401 错误,所以这里不处理 handleAuthorized + break; + case 403: + errorMessage = "拒绝访问"; + break; + case 404: + errorMessage = "请求出错"; + break; + case 408: + errorMessage = "请求超时"; + break; + case 429: + errorMessage = "请求频繁, 请稍后再访问"; + break; + case 500: + errorMessage = "服务器开小差啦,请稍后再试~"; + break; + case 501: + errorMessage = "服务未实现"; + break; + case 502: + errorMessage = "网络错误"; + break; + case 503: + errorMessage = "服务不可用"; + break; + case 504: + errorMessage = "网络超时"; + break; + case 505: + errorMessage = "HTTP 版本不受支持"; + break; + } + if (error.errMsg.includes("timeout")) errorMessage = "请求超时"; + // #ifdef H5 + if (error.errMsg.includes("Network")) + errorMessage = window.navigator.onLine + ? "服务器异常" + : "请检查您的网络连接"; + // #endif + } + + if (error && error.config) { + if (error.config.custom.showError === true) { + uni.showToast({ + title: error.data?.msg || errorMessage, + icon: "none", + mask: true, + }); + } + error.config.custom.showLoading && closeLoading(); + } + + return Promise.reject(false); + } +); + +let requestList = []; // 请求队列 +let isRefreshToken = false; // 是否正在刷新中 const refreshToken = async (config) => { - // 如果当前已经是 refresh-token 的 URL 地址,并且还是 401 错误,说明是刷新令牌失败了,直接返回 Promise.reject(error) - if (config.url.indexOf('/member/auth/refresh-token') >= 0) { - return Promise.reject('error') - } + // 如果当前已经是 refresh-token 的 URL 地址,并且还是 401 错误,说明是刷新令牌失败了,直接返回 Promise.reject(error) + if (config.url.indexOf("/member/auth/refresh-token") >= 0) { + return Promise.reject("error"); + } - // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了 - if (!isRefreshToken) { - isRefreshToken = true - // 1. 如果获取不到刷新令牌,则只能执行登出操作 - const refreshToken = getRefreshToken() - if (!refreshToken) { - return handleAuthorized() - } - // 2. 进行刷新访问令牌 - try { - const refreshTokenResult = await AuthUtil.refreshToken(refreshToken) - if (refreshTokenResult.code !== 0) { - // 如果刷新不成功,直接抛出 e 触发 2.2 的逻辑 - // noinspection ExceptionCaughtLocallyJS - throw new Error('刷新令牌失败') - } - // 2.1 刷新成功,则回放队列的请求 + 当前请求 - config.header.Authorization = 'Bearer ' + getAccessToken() - requestList.forEach((cb) => { - cb() - }) - requestList = [] - return request(config) - } catch (e) { - // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。 - // 2.2 刷新失败,只回放队列的请求 - requestList.forEach((cb) => { - cb() - }) - // 提示是否要登出。即不回放当前请求!不然会形成递归 - return handleAuthorized() - } finally { - requestList = [] - isRefreshToken = false - } - } else { - // 添加到队列,等待刷新获取到新的令牌 - return new Promise((resolve) => { - requestList.push(() => { - config.header.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改 - resolve(request(config)) - }) - }) + // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了 + if (!isRefreshToken) { + isRefreshToken = true; + // 1. 如果获取不到刷新令牌,则只能执行登出操作 + const refreshToken = getRefreshToken(); + if (!refreshToken) { + return handleAuthorized(); } -} + // 2. 进行刷新访问令牌 + try { + const refreshTokenResult = await AuthUtil.refreshToken(refreshToken); + if (refreshTokenResult.code !== 0) { + // 如果刷新不成功,直接抛出 e 触发 2.2 的逻辑 + // noinspection ExceptionCaughtLocallyJS + throw new Error("刷新令牌失败"); + } + // 2.1 刷新成功,则回放队列的请求 + 当前请求 + config.header.Authorization = "Bearer " + getAccessToken(); + requestList.forEach((cb) => { + cb(); + }); + requestList = []; + return request(config); + } catch (e) { + // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。 + // 2.2 刷新失败,只回放队列的请求 + requestList.forEach((cb) => { + cb(); + }); + // 提示是否要登出。即不回放当前请求!不然会形成递归 + return handleAuthorized(); + } finally { + requestList = []; + isRefreshToken = false; + } + } else { + // 添加到队列,等待刷新获取到新的令牌 + return new Promise((resolve) => { + requestList.push(() => { + config.header.Authorization = "Bearer " + getAccessToken(); // 让每个请求携带自定义token 请根据实际情况自行修改 + resolve(request(config)); + }); + }); + } +}; /** 处理 401 未登陆的错误 */ const handleAuthorized = () => { - const userStore = $store('user') - userStore.logout(true) - showAuthModal() - // 登录超时 - return Promise.reject({ - code: 401, - msg: userStore.isLogin ? '您的登陆已过期' : '请先登录', - }) -} + const userStore = $store("user"); + userStore.logout(true); + peach.$router.go("/pages/index/login"); + // 登录超时 + return Promise.reject({ + code: 401, + msg: userStore.isLogin ? "您的登陆已过期" : "请先登录", + }); +}; /** 获得访问令牌 */ const getAccessToken = () => { - return uni.getStorageSync('token') -} + return uni.getStorageSync("token"); +}; /** 获得刷新令牌 */ const getRefreshToken = () => { - return uni.getStorageSync('refresh-token') -} + return uni.getStorageSync("refresh-token"); +}; const request = (config) => { - return http.middleware(config) -} + return http.middleware(config); +}; -export default request +export default request; diff --git a/peach/store/app.js b/peach/store/app.js index 2b13618..0d3f507 100644 --- a/peach/store/app.js +++ b/peach/store/app.js @@ -1,181 +1,185 @@ -import { ref } from 'vue' -import { defineStore } from 'pinia' -import $platform from '@/peach/platform' -import $router from '@/peach/router' -import user from './user' -import useSysStore from './sys' +import { ref } from "vue"; +import { defineStore } from "pinia"; +import $platform from "@/peach/platform"; +import $router from "@/peach/router"; +import useUserStore from "./user"; +import useSysStore from "./sys"; const useAppStore = defineStore( - 'app', - () => { - /** - * @description 应用信息 - * @param string name 应用名称 - * @param string logo 应用logo - * @param string version 应用版本 - * @param string copyright 版权信息 - * @param string copyrightTime 版权时间 - * @param string cdnurl 静态资源域名 - * @param string filesystem 文件系统 - */ - const info = ref({ - name: '', - logo: '', - version: '', - copyright: '', - copytime: '', - cdnurl: '', - filesystem: '', - }) + "app", + () => { + /** + * @description 应用信息 + * @param string name 应用名称 + * @param string logo 应用logo + * @param string version 应用版本 + * @param string copyright 版权信息 + * @param string copyrightTime 版权时间 + * @param string cdnurl 静态资源域名 + * @param string filesystem 文件系统 + */ + const info = ref({ + name: "", + logo: "", + version: "", + copyright: "", + copytime: "", + cdnurl: "", + filesystem: "", + }); - /** - * @description 平台信息 - * @param Array share.methods 分享方式 - * @param Object share.forwardInfo 转发信息 - * @param Object share.posterInfo 海报信息 - * @param string share.linkAddress 分享链接地址 - * @param number bindMobile 绑定手机号提醒 0: 提醒 1: 不提醒 - */ - const platform = ref({ - share: { - methods: [], - forwardInfo: {}, - posterInfo: {}, - linkAddress: '', + /** + * @description 平台信息 + * @param Array share.methods 分享方式 + * @param Object share.forwardInfo 转发信息 + * @param Object share.posterInfo 海报信息 + * @param string share.linkAddress 分享链接地址 + * @param number bindMobile 绑定手机号提醒 0: 提醒 1: 不提醒 + */ + const platform = ref({ + share: { + methods: [], + forwardInfo: {}, + posterInfo: {}, + linkAddress: "", + }, + bindMobile: 0, + }); + + const chat = ref({}); + + /** + * @description 模板信息 + * @param Object basic 基础模板 + * @param Object tabbar 底部导航模板 + */ + const template = ref({ + basic: { + tabbar: { + items: [ + { + activeIconUrl: + "http://mall.yudao.iocoder.cn/static/images/1-002.png", + iconUrl: "http://mall.yudao.iocoder.cn/static/images/1-001.png", + text: "首页", + url: "/pages/index/index", }, - bindMobile: 0, - }) - - const chat = ref({}) - - /** - * @description 模板信息 - * @param Object basic 基础模板 - * @param Object tabbar 底部导航模板 - */ - const template = ref({ - basic: { - tabbar: { - items: [ - { - activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/1-002.png', - iconUrl: 'http://mall.yudao.iocoder.cn/static/images/1-001.png', - text: '首页', - url: '/pages/index/index', - }, - { - activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/2-002.png', - iconUrl: 'http://mall.yudao.iocoder.cn/static/images/2-001.png', - text: '产品', - url: '/pages/index/product', - }, - { - activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/3-002.png', - iconUrl: 'http://mall.yudao.iocoder.cn/static/images/3-001.png', - text: '订单', - url: '/pages/order/list', - }, - { - activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/4-002.png', - iconUrl: 'http://mall.yudao.iocoder.cn/static/images/4-001.png', - text: '我的', - url: '/pages/index/my', - }, - ], - style: { - activeColor: '#fc4141', - bgColor: '#fff', - bgType: 'color', - color: '#282828', - }, - theme: 'red', - }, + { + activeIconUrl: + "http://mall.yudao.iocoder.cn/static/images/2-002.png", + iconUrl: "http://mall.yudao.iocoder.cn/static/images/2-001.png", + text: "产品", + url: "/pages/index/product", }, - }) - - // 全局分享信息 - const shareInfo = ref({}) - - // 小程序发货信息管理 0: 没有 1:有 - const hasWechatTradeManaged = ref(0) - - /** - * @author Ankkaya - * @description 小程序初始化 - * @param {Type} - - * @returns {Type} - */ - async function init() { - // 检查网络 - const networkStatus = await $platform.checkNetwork() - if (!networkStatus) { - $router.error('NetworkError') - } - - if (true) { - this.info = { - name: '🍑商城', - logo: 'https://static.iocoder.cn/ruoyi-vue-pro-logo.png', - version: '1.0.0', - copyright: '全部开源,个人与企业可 100% 免费使用', - copytime: 'Copyright© 2018-2024', - - cdnurl: 'https://file.sheepjs.com', // 云存储域名 - filesystem: 'qcloud', // 云存储平台 - } - this.platform = { - share: { - methods: ['poster', 'link'], - linkAddress: 'https://shopro.sheepjs.com/#/', - posterInfo: { - user_bg: '/static/img/shop/config/user-poster-bg.png', - goods_bg: '/static/img/shop/config/goods-poster-bg.png', - groupon_bg: '/static/img/shop/config/groupon-poster-bg.png', - }, - }, - bind_mobile: 0, - } - this.chat = { - chat_domain: 'https://api.shopro.sheepjs.com/chat', - room_id: 'admin', - } - this.has_wechat_trade_managed = 0 - - // 加载主题 - const sysStore = useSysStore() - sysStore.setTheme() - - // 模拟用户登录 - const userStore = user() - if (userStore.isLogin) { - userStore.loginAfter() - } - return Promise.resolve(true) - } else { - $router.error('InitError', res.msg || '加载失败') - } - } - - return { - info, - platform, - chat, - template, - shareInfo, - hasWechatTradeManaged, - init, - } - }, - { - persist: { - enabled: true, - strategies: [ - { - key: 'app-store', - }, - ], + { + activeIconUrl: + "http://mall.yudao.iocoder.cn/static/images/3-002.png", + iconUrl: "http://mall.yudao.iocoder.cn/static/images/3-001.png", + text: "订单", + url: "/pages/order/list", + }, + { + activeIconUrl: + "http://mall.yudao.iocoder.cn/static/images/4-002.png", + iconUrl: "http://mall.yudao.iocoder.cn/static/images/4-001.png", + text: "我的", + url: "/pages/index/my", + }, + ], + style: { + activeColor: "#fc4141", + bgColor: "#fff", + bgType: "color", + color: "#282828", + }, + theme: "red", }, - } -) + }, + }); -export default useAppStore + // 全局分享信息 + const shareInfo = ref({}); + + // 小程序发货信息管理 0: 没有 1:有 + const hasWechatTradeManaged = ref(0); + + /** + * @author Ankkaya + * @description 小程序初始化 + * @param {Type} - + * @returns {Type} + */ + async function init() { + // 检查网络 + const networkStatus = await $platform.checkNetwork(); + if (!networkStatus) { + $router.error("NetworkError"); + } + + if (true) { + this.info = { + name: "🍑商城", + logo: "https://static.iocoder.cn/ruoyi-vue-pro-logo.png", + version: "1.0.0", + copyright: "全部开源,个人与企业可 100% 免费使用", + copytime: "Copyright© 2018-2024", + + cdnurl: "https://file.sheepjs.com", // 云存储域名 + filesystem: "qcloud", // 云存储平台 + }; + this.platform = { + share: { + methods: ["poster", "link"], + linkAddress: "https://shopro.sheepjs.com/#/", + posterInfo: { + user_bg: "/static/img/shop/config/user-poster-bg.png", + goods_bg: "/static/img/shop/config/goods-poster-bg.png", + groupon_bg: "/static/img/shop/config/groupon-poster-bg.png", + }, + }, + bind_mobile: 0, + }; + this.chat = { + chat_domain: "https://api.shopro.sheepjs.com/chat", + room_id: "admin", + }; + this.has_wechat_trade_managed = 0; + + // 加载主题 + const sysStore = useSysStore(); + sysStore.setTheme(); + + // 模拟用户登录 + const userStore = useUserStore(); + if (userStore.isLogin) { + userStore.loginAfter(); + } + return Promise.resolve(true); + } else { + $router.error("InitError", res.msg || "加载失败"); + } + } + + return { + info, + platform, + chat, + template, + shareInfo, + hasWechatTradeManaged, + init, + }; + }, + { + persist: { + enabled: true, + strategies: [ + { + key: "app-store", + }, + ], + }, + } +); + +export default useAppStore; diff --git a/peach/store/user.js b/peach/store/user.js index 31240a2..2197af1 100644 --- a/peach/store/user.js +++ b/peach/store/user.js @@ -1,30 +1,110 @@ -import { ref } from 'vue' -import { defineStore } from 'pinia' -import { isEmpty, cloneDeep, clone } from 'lodash' +import { ref } from "vue"; +import { defineStore } from "pinia"; +import $share from '@/peach/platform/share' +import { isEmpty, cloneDeep, clone } from "lodash"; -const useUserStore = defineStore('user', () => { - const userInfo = ref() - const isLogin = ref(!!uni.getStorageSync('token')) +// 默认用户信息 +const defaultUserInfo = { + avatar: "", // 头像 + nickname: "", // 昵称 + gender: 0, // 性别 + mobile: "", // 手机号 + point: 0, // 积分 +}; - function setToken(accessToken, refreshToken) { - if (token === '') { - isLogin.value = false - uni.removeStorageSync('token') - uni.removeStorageSync('refresh-token') - } else { - isLogin.value = true - uni.setStorageSync('token', token) - uni.setStorageSync('refresh-token', refreshToken) - // 成功后处理 - } - return isLogin.value +// 默认钱包信息 +const defaultWallet = { + balance: 0, // 余额 +}; + +// 默认订单信息 +const defaultNumData = { + unusedCouponCount: 0, + orderCount: { + allCount: 0, + unpaidCount: 0, + undeliveredCount: 0, + deliveredCount: 0, + uncommentedCount: 0, + afterSaleCount: 0, + }, +}; + +const useUserStore = defineStore( + "user", + () => { + const userInfo = ref(clone(defaultUserInfo)); + const userWallet = ref(clone(defaultWallet)); + const userNumData = ref(cloneDeep(defaultNumData)); + const isLogin = ref(!!uni.getStorageSync("token")); + const lastUpdateTime = ref(0) + + function getUserInfo() {} + + function getWallet() {} + + function getNumData() {} + + function setToken(token, refreshToken) { + if (token === "") { + isLogin.value = false; + uni.removeStorageSync("token"); + uni.removeStorageSync("refresh-token"); + } else { + isLogin.value = true; + uni.setStorageSync("token", token); + uni.setStorageSync("refresh-token", refreshToken); + // 成功后处理 + loginAfter(); + } + return isLogin.value; + } + + function resetUserData() { + setToken(""); + userInfo.value = clone(defaultUserInfo); + userWallet.value = clone(defaultWallet); + userNumData.value = cloneDeep(defaultNumData); + } + + function updateUserData() { + const nowTime = new Date().getTime() + if (lastUpdateTime.value + 5000 > nowTime) { + return + } + lastUpdateTime.value = nowTime + + await getUserInfo() + getWallet() + getNumData() + return userInfo.value + } + + function loginAfter() { + updateUserData() + $share.getShareInfo() + } + + function logOut() { + resetUserData(); + return !isLogin.value } return { - userInfo, - isLogin, - setToken, - } -}) + userInfo, + isLogin, + setToken, + logOut + }; + }, + { + persist: true, + strategies: [ + { + key: "user-store", + }, + ], + } +); -export default useUserStore +export default useUserStore; diff --git a/static/internet-empty.png b/static/internet-empty.png new file mode 100644 index 0000000..55ac2f6 Binary files /dev/null and b/static/internet-empty.png differ