feat:小程序首页白屏问题
This commit is contained in:
1 parent
b22de4d6b2
commit
6412d3be5c
10 files changed
+209
-84
No files matched your search
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="通知公告" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="通知公告" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<view class="notice-detail">
|
||||
<view class="detail-header">
|
||||
<view class="title">
|
||||
@@ -66,8 +66,36 @@ const goGetCoupon = () => {
|
||||
uni.navigateTo({ url: `/pages/merchant/merchant-activity?actId=${actDetail.value.actId}&actType=${actDetail.value.actType}` })
|
||||
}
|
||||
|
||||
const normalizeRichText = (html: string) => {
|
||||
const origin = "https://stgl.pj.gov.cn"
|
||||
return html.replace(/<img\b[^>]*>/gi, (imgTag) => {
|
||||
let next = imgTag
|
||||
|
||||
next = next.replace(/\bsrc\s*=\s*(['"])(.*?)\1/i, (_m, quote: string, src: string) => {
|
||||
let resolved = src
|
||||
if (resolved?.startsWith("/api")) resolved = `${origin}${resolved}`
|
||||
if (resolved?.startsWith("//")) resolved = `https:${resolved}`
|
||||
return `src=${quote}${resolved}${quote}`
|
||||
})
|
||||
|
||||
const styleMatch = next.match(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i)
|
||||
const required = "max-width: 100%; height: auto; display: block;"
|
||||
if (styleMatch) {
|
||||
const quote = styleMatch[1]
|
||||
const styleValue = styleMatch[2] ?? ""
|
||||
if (styleValue.includes("max-width") || styleValue.includes("width")) return next
|
||||
const merged = styleValue.trim().length ? `${styleValue.replace(/;?\s*$/, "; ")}${required}` : required
|
||||
return next.replace(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i, `style=${quote}${merged}${quote}`)
|
||||
}
|
||||
|
||||
return next.replace(/<img\b/i, `<img style="${required}"`)
|
||||
})
|
||||
}
|
||||
|
||||
const nodes = computed(() => {
|
||||
return detail.value.description?.replaceAll(`<img src="/api`, `<img src="https://stgl.pj.gov.cn/api`)
|
||||
const html = detail.value.description
|
||||
if (!html) return ""
|
||||
return normalizeRichText(html)
|
||||
})
|
||||
|
||||
function getTypeLabel(type: string) {
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
<template>
|
||||
<view class="banner-detail">
|
||||
<view class="detail-header">
|
||||
<view class="title">{{ detail.title || "加载中..." }}</view>
|
||||
<crud-layout title="详情" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<view class="banner-detail">
|
||||
<view class="detail-header">
|
||||
<view class="title">{{ detail.title || "加载中..." }}</view>
|
||||
</view>
|
||||
<view v-if="loading" class="loading-tip">加载中...</view>
|
||||
<view v-else-if="error" class="error-tip">{{ error }}</view>
|
||||
<view v-else class="detail-content">
|
||||
<rich-text :nodes="richTextNodes || ''" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="loading" class="loading-tip">加载中...</view>
|
||||
<view v-else-if="error" class="error-tip">{{ error }}</view>
|
||||
<view v-else class="detail-content">
|
||||
<rich-text :nodes="richTextNodes || ''" />
|
||||
</view>
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import sysBannerApi from "@/sheep/api/sys-banner"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
import { filePath, parseHtml } from "@/sheep/utils/file"
|
||||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||||
|
||||
const detail = ref<{ title?: string; richTextContent?: string }>({})
|
||||
const loading = ref(false)
|
||||
@@ -31,11 +33,7 @@ const toAbsoluteUrl = (url?: string | null) => {
|
||||
const richTextNodes = computed(() => {
|
||||
const html = detail.value.richTextContent
|
||||
if (!html) return ""
|
||||
return html.replace(/<img\s+[^>]*src=["']([^"']+)["']/gi, (match, src) => {
|
||||
const fullSrc = toAbsoluteUrl(src)
|
||||
if (!fullSrc) return match
|
||||
return match.replace(src, fullSrc)
|
||||
})
|
||||
return parseHtml(html)
|
||||
})
|
||||
|
||||
onLoad(async (options: any) => {
|
||||
@@ -66,12 +64,6 @@ onLoad(async (options: any) => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.banner-detail {
|
||||
padding: 32rpx;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view v-if="state.actId" class="px-16rpx py-32rpx">
|
||||
<crud-layout title="商户活动" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<view v-if="state.actId" class="py-32rpx">
|
||||
<view v-if="state.actType == 'CANCEL_ACT'"
|
||||
class="card rounded-lb-0! rounded-rb-0! w-full h-400rpx relative activity-card overflow-hidden">
|
||||
<view class="ribbon">兑换券</view>
|
||||
@@ -12,10 +12,11 @@
|
||||
</text>
|
||||
</view>
|
||||
<view class="w-4/5 px-64rpx pt-32rpx text-28rpx c-#fff">{{ state.actDetail.actTitle }}</view>
|
||||
<view class="absolute bottom-100 left-60 text-40 italic">
|
||||
<view class="absolute bottom-100rpx left-60rpx text-40rpx italic">
|
||||
<text class="color-red mr-16rpx">¥{{ hooks.useMoney(state.actDetail.activeCancelPrice) }}</text>
|
||||
<text class="text-30rpx line-through color-red">¥{{ hooks.useMoney(state.actDetail.activeOrgPrice)
|
||||
}}</text>
|
||||
<text class="text-30rpx line-through color-red">
|
||||
¥{{ hooks.useMoney(state.actDetail.activeOrgPrice) }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="absolute bottom-40 left-60 text-28rpx bg-#eeeeee44 c-#fff px-16rpx rounded-full">限量领取 先领先得
|
||||
</view>
|
||||
@@ -69,10 +70,6 @@
|
||||
<text>天内使用</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="state.actDetail.description"
|
||||
class="m-l-20rpx m-y-20rpx w-55% text-28rpx bg-#eeeeee44 c-#fff p-16rpx rounded-16rpx">
|
||||
{{ state.actDetail.description }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="state.couponInfo.actStatus == '2'"
|
||||
class="text-center card rounded-lt-0! rounded-rt-0! p-24rpx sub-text-30">
|
||||
@@ -87,6 +84,9 @@
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<view class="detail-content">
|
||||
<rich-text :nodes="nodes || ''"></rich-text>
|
||||
</view>
|
||||
<template #main-bottom>
|
||||
<view class="w-full flex-col-center">
|
||||
<tm-button class="px-256rpx m-16rpx" width="90%" @click="doQrcode">我的礼券</tm-button>
|
||||
@@ -98,12 +98,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, nextTick } from "vue"
|
||||
import { reactive, ref, nextTick, computed } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
|
||||
import { actCancel, actComApi, actCouponApi, userApi } from "@/sheep/api"
|
||||
import { hooks, router } from "@/sheep"
|
||||
import { serviceEnum, storageConstant } from "@@/constant"
|
||||
import { serviceEnum, storageConstant } from "@@/constant";
|
||||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
import ModifyUser from "@@/components/modify-user.vue"
|
||||
|
||||
@@ -119,6 +121,10 @@ const state = reactive<any>({
|
||||
userDetail: {},
|
||||
})
|
||||
|
||||
const nodes = computed(() => {
|
||||
return state.actDetail.description?.replaceAll(`<img src="/api`, `<img src="https://stgl.pj.gov.cn/api`)
|
||||
})
|
||||
|
||||
onLoad((option: any) => {
|
||||
const { actId, actType } = option
|
||||
if (!actId || !actType) return uni.showToast({ title: "参数错误", icon: "error" })
|
||||
@@ -258,8 +264,17 @@ const modifyUserClose = () => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.detail-content {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.activity-card {
|
||||
background-image: url("../../static/page/activity-card-bg.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: 130%;
|
||||
|
||||
@@ -9,7 +9,8 @@ import * as CryptoJS from "crypto-js"
|
||||
|
||||
import { actCancel, actComApi, actCouponApi, applyApi } from "@@/api"
|
||||
import { hooks } from "@/sheep"
|
||||
import { serviceEnum } from "@@/constant"
|
||||
import { serviceEnum, SERVICE_IMAGE } from "@@/constant"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
|
||||
@@ -159,7 +160,7 @@ const genVerificationCode = async (params: Record<string, any>) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<crud-layout title="我的礼券" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="dynamicPageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { ref, reactive, computed, nextTick, onMounted } from "vue"
|
||||
import { onHide, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { router, constant } from "@@/index"
|
||||
import { router } from "@@/index"
|
||||
import { noticeApi, appApi } from "@@/api/index"
|
||||
import { getAppInfo } from "@@/utils/app"
|
||||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||||
@@ -48,7 +48,9 @@ onShow(() => {
|
||||
if (!ceheckLogin()) {
|
||||
uni.showToast({ title: "登录已过期,请重新登录", icon: "none" })
|
||||
uni.navigateTo({ url: "/pages/root/login" })
|
||||
return
|
||||
}
|
||||
getSwiperList()
|
||||
getNoticeList()
|
||||
getAppMenuList()
|
||||
})
|
||||
@@ -72,6 +74,20 @@ const doMenu = async (v: any) => {
|
||||
tabbarStore.jumpFirstTabbar()
|
||||
}
|
||||
|
||||
// 获取轮播图
|
||||
const getSwiperList = async () => {
|
||||
try {
|
||||
const { data, code }: any = await noticeApi.getSwiperList()
|
||||
console.log("获取轮播图,code:", code);
|
||||
if (code != 0) {
|
||||
throw new Error()
|
||||
}
|
||||
state.swiperList = (data || []).filter(Boolean)
|
||||
} catch (error) {
|
||||
console.log("获取轮播图意外的错误error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取通知公告列表
|
||||
const getNoticeList = async () => {
|
||||
try {
|
||||
@@ -79,6 +95,7 @@ const getNoticeList = async () => {
|
||||
current: 1,
|
||||
size: 9
|
||||
})
|
||||
console.log("获取通知公告列表,code:", code);
|
||||
if (code != 0) {
|
||||
throw new Error()
|
||||
}
|
||||
@@ -97,7 +114,10 @@ const getAppMenuList = async () => {
|
||||
platformEnum: platform
|
||||
}
|
||||
const { data, code }: any = await appApi.appList(params)
|
||||
if (code != 0) {
|
||||
console.log("获取应用菜单列表,code:", code);
|
||||
if (code == 424) {
|
||||
|
||||
} else if (code != 0) {
|
||||
throw new Error()
|
||||
}
|
||||
state.appMenuList = (data || []).filter(Boolean)
|
||||
@@ -105,6 +125,12 @@ const getAppMenuList = async () => {
|
||||
console.log("获取应用菜单列表意外的错误error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const doSwiper = async (v: any) => {
|
||||
if (!v) return
|
||||
const target = (v.jumpValue || "").replace(/\s+/g, "")
|
||||
uni.navigateTo({ url: target })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -112,8 +138,8 @@ const getAppMenuList = async () => {
|
||||
<view class="h-20rpx" />
|
||||
<swiper class="w-full h-280rpx rounded-16rpx overflow-hidden" circular :indicator-dots="true"
|
||||
indicator-active-color="#0779FD" indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in state?.swiperList" :key="i">
|
||||
<image class="w-full h-full" :src="v.image" mode="aspectFill" />
|
||||
<swiper-item v-for="(v, i) in state?.swiperList" :key="v.id" @tap="doSwiper(v)">
|
||||
<image class="w-full h-full" :src="v.imageUrl" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="h-20rpx" />
|
||||
@@ -135,7 +161,8 @@ const getAppMenuList = async () => {
|
||||
<view class="w-full">
|
||||
<view
|
||||
class="h-100rpx flex justify-between items-center p-x-16rpx p-y-20rpx border-b-1 border-color-#f0f0f0"
|
||||
v-for="(v, idx) in group" :key="idx">
|
||||
v-for="(v, idx) in group" :key="idx"
|
||||
@tap="() => router.jump('/pages/integrated/notice/detail', { id: v?.id })">
|
||||
<view class="flex-1 sub-text-26 font-normal! truncate">{{ v.title }}</view>
|
||||
<view class="w-250rpx second-text-24 m-l-10rpx">{{ v.createTime }}</view>
|
||||
</view>
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
// ========== 轮播图相关接口 ==========
|
||||
/**
|
||||
* 获取轮播图列表
|
||||
*/
|
||||
getSwiperList: () =>
|
||||
request({
|
||||
url: "/integrated/sysBanner/app/slides",
|
||||
method: "GET",
|
||||
}),
|
||||
|
||||
// 公告分页列表
|
||||
getNoticePage: (params: { current: number; size: number }) =>
|
||||
request({
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
import { throttle } from "radash"
|
||||
|
||||
function normalizePath(path = "") {
|
||||
if (!path) return ""
|
||||
const purePath = path.split("?")[0] || ""
|
||||
if (!purePath) return ""
|
||||
return purePath.startsWith("/") ? purePath : `/${purePath}`
|
||||
}
|
||||
|
||||
function getCurrentPagePath() {
|
||||
const currentPage = getCurrentPage()
|
||||
return normalizePath(currentPage?.route || "")
|
||||
}
|
||||
|
||||
function paramsToQuery(params: { [key: string]: string }) {
|
||||
let query = []
|
||||
for (let key in params) {
|
||||
@@ -14,6 +26,10 @@ function _jump(path = "", params = {}, type = 1) {
|
||||
if (!path) {
|
||||
console.error("router::jump>>path 不能为空")
|
||||
}
|
||||
const targetPath = normalizePath(path)
|
||||
if (targetPath && getCurrentPagePath() === targetPath) {
|
||||
return
|
||||
}
|
||||
if (hasTabbar(path)) {
|
||||
uni.switchTab({ url: path })
|
||||
return
|
||||
|
||||
@@ -22,3 +22,29 @@ export const filePath = (path?: string | null) => {
|
||||
|
||||
return `${base}${ensureLeadingSlash(rawPath)}`
|
||||
}
|
||||
|
||||
export const parseHtml = (html: string) => {
|
||||
const origin = "https://stgl.pj.gov.cn"
|
||||
return html.replace(/<img\b[^>]*>/gi, (imgTag) => {
|
||||
let next = imgTag
|
||||
|
||||
next = next.replace(/\bsrc\s*=\s*(['"])(.*?)\1/i, (_m, quote: string, src: string) => {
|
||||
let resolved = src
|
||||
if (resolved?.startsWith("/api")) resolved = `${origin}${resolved}`
|
||||
if (resolved?.startsWith("//")) resolved = `https:${resolved}`
|
||||
return `src=${quote}${resolved}${quote}`
|
||||
})
|
||||
|
||||
const styleMatch = next.match(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i)
|
||||
const required = "max-width: 100%; height: auto; display: block;"
|
||||
if (styleMatch) {
|
||||
const quote = styleMatch[1]
|
||||
const styleValue = styleMatch[2] ?? ""
|
||||
if (styleValue.includes("max-width") || styleValue.includes("width")) return next
|
||||
const merged = styleValue.trim().length ? `${styleValue.replace(/;?\s*$/, "; ")}${required}` : required
|
||||
return next.replace(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i, `style=${quote}${merged}${quote}`)
|
||||
}
|
||||
|
||||
return next.replace(/<img\b/i, `<img style="${required}"`)
|
||||
})
|
||||
}
|
||||
+51
-41
@@ -4,7 +4,7 @@ import { isEmpty } from "radash"
|
||||
|
||||
import * as router from "@@/router"
|
||||
import * as constant from "@@/constant"
|
||||
import { createCooldown, getBaseApiUrl } from "@@/utils/app"
|
||||
import { getBaseApiUrl } from "@@/utils/app"
|
||||
|
||||
const TOKEN_KEY = constant.storageConstant.TOKEN
|
||||
const USER_INFO_KEY = constant.storageConstant.USERINFO
|
||||
@@ -18,8 +18,13 @@ const SKIP_AUTH_URLS = [
|
||||
const SKIP_REFRESH_TOKEN = ["/sys/auth/refresh-token", "/auth/token/check_token"]
|
||||
|
||||
let refreshTokenLock = true
|
||||
const runLoginRedirect = createCooldown(1500)
|
||||
let refreshTokenPromise: Promise<any> | null = null
|
||||
const BASIC_AUTH = "Basic " + base64.encode(import.meta.env.VITE_OAUTH2_APP_CLIENT)
|
||||
const buildErrorResponse = (error: any, fallbackMsg: string = "请求失败") => ({
|
||||
code: error?.statusCode || -1,
|
||||
data: error?.data ?? null,
|
||||
msg: error?.data?.msg || error?.errMsg || error?.message || fallbackMsg,
|
||||
})
|
||||
|
||||
const https = new Request({
|
||||
baseURL: getBaseApiUrl(),
|
||||
@@ -58,13 +63,21 @@ https.interceptors.request.use(async (config) => {
|
||||
// 过期,刷新token
|
||||
const newTokenStorage = await refreshToken()
|
||||
if (newTokenStorage) {
|
||||
const tokenValue = getTokenValue(newTokenStorage)
|
||||
tokenValue = getTokenValue(newTokenStorage)
|
||||
if (tokenValue) config_header.Authorization = tokenValue
|
||||
} else {
|
||||
return Promise.reject({
|
||||
statusCode: 424,
|
||||
errMsg: "refresh token failed",
|
||||
data: { msg: "登录已过期,请重新登录" },
|
||||
config,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
config_header["Authorization"] = tokenValue
|
||||
}
|
||||
config.header = config_header
|
||||
return config
|
||||
}, Promise.reject)
|
||||
|
||||
@@ -79,7 +92,6 @@ https.interceptors.response.use(
|
||||
msg: null,
|
||||
})
|
||||
}
|
||||
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
async (error) => {
|
||||
@@ -87,23 +99,16 @@ https.interceptors.response.use(
|
||||
// 处理 424 错误(token过期)
|
||||
if (error.statusCode === 424) {
|
||||
// 判断是否在登录页面
|
||||
const currentPage = router.getCurrentPage()
|
||||
const currentRoute = currentPage?.route
|
||||
if (currentRoute === "pages/root/login" || currentRoute === "/pages/root/login") {
|
||||
return
|
||||
}
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
runLoginRedirect(() => {
|
||||
uni.showToast({ title: "登录已过期,请重新登录", icon: "none" })
|
||||
uni.navigateTo({ url: "/pages/root/login" })
|
||||
})
|
||||
uni.showToast({ title: "登录已过期,请重新登录", icon: "none" })
|
||||
router.jump("/pages/root/login")
|
||||
}
|
||||
// 显示错误信息
|
||||
else if (error?.data?.msg) {
|
||||
uni.showToast({ title: error.data.msg, icon: "none", mask: true })
|
||||
}
|
||||
return Promise.resolve(error.data)
|
||||
return Promise.resolve(buildErrorResponse(error))
|
||||
},
|
||||
)
|
||||
|
||||
@@ -120,34 +125,39 @@ const isTokenExpires = (tokenStorage: GlobalSetting.TokenStorage): boolean => {
|
||||
}
|
||||
|
||||
async function refreshToken(): Promise<any> {
|
||||
refreshTokenLock = false
|
||||
try {
|
||||
const tokenStorage = uni.getStorageSync(TOKEN_KEY) as GlobalSetting.TokenStorage
|
||||
const res: any = await https.middleware({
|
||||
url: "/auth/oauth2/token",
|
||||
header: {
|
||||
skipToken: "true",
|
||||
Authorization: BASIC_AUTH,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
method: "POST",
|
||||
params: { refresh_token: tokenStorage.refreshToken, grant_type: "refresh_token", scope: "server" },
|
||||
})
|
||||
const { data } = res || {}
|
||||
if (data) {
|
||||
tokenStorage.accessToken = data?.accessToken?.tokenValue
|
||||
tokenStorage.refreshToken = data?.refreshToken?.tokenValue
|
||||
tokenStorage.accessTokenExpiresIn = data?.accessToken?.expiresAt
|
||||
tokenStorage.refreshTokenExpiresIn = data?.refreshToken?.expiresAt
|
||||
uni.setStorageSync(TOKEN_KEY, tokenStorage)
|
||||
return tokenStorage
|
||||
if (refreshTokenPromise) return refreshTokenPromise
|
||||
refreshTokenPromise = (async () => {
|
||||
refreshTokenLock = false
|
||||
try {
|
||||
const tokenStorage = uni.getStorageSync(TOKEN_KEY) as GlobalSetting.TokenStorage
|
||||
const res: any = await https.middleware({
|
||||
url: "/auth/oauth2/token",
|
||||
header: {
|
||||
skipToken: "true",
|
||||
Authorization: BASIC_AUTH,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
method: "POST",
|
||||
params: { refresh_token: tokenStorage.refreshToken, grant_type: "refresh_token", scope: "server" },
|
||||
})
|
||||
const { data } = res || {}
|
||||
if (data) {
|
||||
tokenStorage.accessToken = data?.accessToken?.tokenValue
|
||||
tokenStorage.refreshToken = data?.refreshToken?.tokenValue
|
||||
tokenStorage.accessTokenExpiresIn = data?.accessToken?.expiresAt
|
||||
tokenStorage.refreshTokenExpiresIn = data?.refreshToken?.expiresAt
|
||||
uni.setStorageSync(TOKEN_KEY, tokenStorage)
|
||||
return tokenStorage
|
||||
}
|
||||
return null
|
||||
} catch (error) {
|
||||
return false
|
||||
} finally {
|
||||
refreshTokenLock = true
|
||||
refreshTokenPromise = null
|
||||
}
|
||||
return null
|
||||
} catch (error) {
|
||||
return false
|
||||
} finally {
|
||||
refreshTokenLock = true
|
||||
}
|
||||
})()
|
||||
return refreshTokenPromise
|
||||
}
|
||||
|
||||
// 请求函数
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Reference in new issue
Block a user