调整
This commit is contained in:
1 parent
bab4a4383b
commit
01b5f47f5c
3 files changed
+201
-225
No files matched your search
@@ -2,9 +2,7 @@
|
||||
<view
|
||||
:class="[props.mode == 'car' ? 'car_border' : '']"
|
||||
class="flex-row items-start card p-x-15rpx p-y-25rpx m-b-20rpx"
|
||||
@tap="
|
||||
props.productId && props.mode === 'default' && router.jump('/pages/shop/product-detail', { id: props.productId })
|
||||
"
|
||||
@tap="props.productId && props.mode === 'default' && router.jump('/pages/shop/product-detail', { id: props.productId })"
|
||||
>
|
||||
<image class="size-140rpx rounded-12rpx" :src="props.picUrl" mode="aspectFill" />
|
||||
<view class="flex-1 m-l-20rpx">
|
||||
@@ -32,10 +30,7 @@
|
||||
</view>
|
||||
|
||||
<view v-if="mode === 'car'" class="flex-row items-center justify-end m-t-20rpx">
|
||||
<view
|
||||
class="flex-row-center size-40rpx rounded-full border-1px border-solid border-color-#0094ff"
|
||||
@tap.stop="remove"
|
||||
>
|
||||
<view class="flex-row-center size-40rpx rounded-full border-1px border-solid border-color-#0094ff" @tap.stop="remove">
|
||||
<view class="iconfont icon-a--" />
|
||||
</view>
|
||||
<view class="sub-text-28 m-x-20rpx">{{ productCount }}</view>
|
||||
@@ -50,7 +45,7 @@
|
||||
<script setup lang="ts">
|
||||
import { hooks, router } from "@@/index"
|
||||
|
||||
const emit = defineEmits(["onClickAddToCar", "add", "remove"])
|
||||
const emit = defineEmits(["onClickAddToCart", "add", "remove"])
|
||||
|
||||
export type Props = {
|
||||
mode?: "default" | "car"
|
||||
@@ -65,7 +60,7 @@ export type Props = {
|
||||
stock?: number
|
||||
spec?: string
|
||||
unit?: string
|
||||
onClickAddToCar?: () => void
|
||||
onClickAddToCart?: () => void
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
mode: "default",
|
||||
@@ -84,7 +79,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
const handleClickAddToCar = () => {
|
||||
if (props.productId) {
|
||||
emit("onClickAddToCar", { ...props })
|
||||
emit("onClickAddToCart", { ...props })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
:productName="goodsItem.productName"
|
||||
:salesCount="goodsItem.salesCount"
|
||||
:stock="goodsItem.stock"
|
||||
@onClickAddToCar="onClickAddToCar"
|
||||
@onClickAddToCart="onClickAddToCart(goodsItem)"
|
||||
/>
|
||||
</view>
|
||||
</scroll-view>
|
||||
@@ -130,7 +130,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, nextTick, ref } from "vue"
|
||||
import { reactive, nextTick } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { router } from "@@/index"
|
||||
@@ -247,9 +247,9 @@ const doClassify = async (i: any) => {
|
||||
}
|
||||
|
||||
// 点击添加到购物车
|
||||
const onClickAddToCar = (productData: any) => {
|
||||
const onClickAddToCart = (goodsItem: any) => {
|
||||
state.curProductData = goodsItem
|
||||
state.showSkuDialog = true
|
||||
state.curProductData = productData
|
||||
}
|
||||
|
||||
// 加入到购物车时
|
||||
|
||||
+192
-211
@@ -1,20 +1,17 @@
|
||||
import Request from "luch-request"
|
||||
import { router, constant } from "@@/index"
|
||||
import { userApi } from "../api"
|
||||
import { isEmpty } from "radash"
|
||||
import { isDevEnv } from "./app"
|
||||
import { getAppInfo } from "@@/utils/app"
|
||||
import { getAppInfo, isDevEnv } from "@@/utils/app"
|
||||
import { userApi } from "../api"
|
||||
import showVerifyDeviceImpModel from "../components/verifyDeviceImpModel/verifyDeviceImpModel"
|
||||
|
||||
const TOKEN_KEY = constant.storageConstant.TOKEN
|
||||
const USER_INFO_KEY = constant.storageConstant.USERINFO
|
||||
const SKIP_AUTH_URLS = ["/thirdparty/thirdPartyOAth2", "/sys/auth/refresh-token", "/auth/oauth2/token"]
|
||||
|
||||
let isRefreshing = false
|
||||
// 队列存储发送失败的请求
|
||||
let failedQueue: any[] = []
|
||||
// 存储刷新token的Promise
|
||||
let refreshTokenPromise: Promise<any> | null = null
|
||||
let refreshTokenPromise: Promise<any> | null = null // 存储刷新token的Promise
|
||||
let isRefreshing = false // 是否正在刷新
|
||||
let failedQueue: any[] = [] // 队列存储发送失败的请求
|
||||
|
||||
// 处理队列中的请求
|
||||
const processQueue = (error: any, token: any = null) => {
|
||||
@@ -30,116 +27,125 @@ const processQueue = (error: any, token: any = null) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 读取token并处理Authorization请求头
|
||||
const getAuthHeader = (tokenStorage: any) => {
|
||||
// 创建http请求实例
|
||||
const http = new Request({
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
timeout: 15000,
|
||||
method: "GET",
|
||||
header: {
|
||||
Accept: "*/*",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
},
|
||||
withCredentials: true,
|
||||
custom: {
|
||||
showSuccess: false, // 成功提醒 默认使用后端返回值
|
||||
successMsg: "", // 成功消息
|
||||
showError: true, // 显示失败消息 默认显示
|
||||
errorMsg: "", // 失败提醒 默认使用后端返回信息
|
||||
loadingMsg: "加载中", // loading提醒文字
|
||||
auth: false, // 需要授权才能请求 默认放开
|
||||
},
|
||||
})
|
||||
|
||||
http.interceptors.request.use(async (config) => {
|
||||
const tokenStorage = uni.getStorageSync(TOKEN_KEY)
|
||||
const config_header: any = config.header || {}
|
||||
|
||||
// 设置租户请求头
|
||||
config_header["TENANT-ID"] = "1"
|
||||
if (import.meta.env.VITE_IS_TOC === "true") config_header["CLIENT-TOC"] = "Y"
|
||||
|
||||
// 判断是否需要设置认证头
|
||||
if (!SKIP_AUTH_URLS.some((url) => config.url?.startsWith(url))) {
|
||||
if (!isEmpty(tokenStorage)) {
|
||||
// token存在,检查是否过期
|
||||
if (isTokenExpires(tokenStorage)) {
|
||||
// 过期,刷新token
|
||||
const newTokenStorage = await refreshToken()
|
||||
if (newTokenStorage) {
|
||||
const tokenValue = getTokenValue(newTokenStorage)
|
||||
if (tokenValue) config_header.Authorization = tokenValue
|
||||
}
|
||||
} else {
|
||||
const tokenValue = getTokenValue(tokenStorage)
|
||||
if (tokenValue) config_header.Authorization = tokenValue
|
||||
}
|
||||
} else {
|
||||
// token不存在,刷新token
|
||||
const newTokenStorage = await refreshToken()
|
||||
if (newTokenStorage) {
|
||||
const tokenValue = getTokenValue(newTokenStorage)
|
||||
if (tokenValue) config_header.Authorization = tokenValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config
|
||||
}, Promise.reject)
|
||||
|
||||
// 响应拦截器
|
||||
http.interceptors.response.use(
|
||||
async (response) => {
|
||||
// 账号密码登录响应结果特殊处理
|
||||
if (response.config.url === "/auth/oauth2/token") {
|
||||
return Promise.resolve({
|
||||
code: 0,
|
||||
data: response.data,
|
||||
msg: null,
|
||||
})
|
||||
}
|
||||
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
async (error) => {
|
||||
// 处理 424 错误(token过期)
|
||||
if (error.statusCode === 424) {
|
||||
if (isDevEnv()) {
|
||||
// 开发环境直接清除token并跳转登录
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
uni.showToast({ title: "登录已过期,请重新登录", icon: "none" })
|
||||
router.jump("/pages/user/login")
|
||||
} else {
|
||||
try {
|
||||
const newTokenStorage = await refreshToken()
|
||||
if (newTokenStorage) {
|
||||
const config = error.config
|
||||
const tokenValue = getTokenValue(newTokenStorage)
|
||||
if (tokenValue && config.header) config.header.Authorization = tokenValue
|
||||
return http.request(config)
|
||||
}
|
||||
} catch (err) {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 显示错误信息
|
||||
if (error?.data?.msg) {
|
||||
uni.showToast({ title: error.data.msg, icon: "none", mask: true })
|
||||
}
|
||||
return Promise.resolve(error.data)
|
||||
},
|
||||
)
|
||||
|
||||
// 从tokenStorage中读取tokenValue值
|
||||
const getTokenValue = (tokenStorage: any): string | null => {
|
||||
if (isDevEnv()) {
|
||||
return tokenStorage?.access_token ? `Bearer ${tokenStorage.access_token}` : null
|
||||
}
|
||||
return tokenStorage?.accessToken?.tokenValue ? `Bearer ${tokenStorage.accessToken.tokenValue}` : null
|
||||
}
|
||||
|
||||
// 浙政钉登录 登录成功返回true,否则返回false
|
||||
async function handleZzdLogin(): Promise<boolean> {
|
||||
try {
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
const token = new URL(window.location.href).searchParams.get("uabaseToken")
|
||||
|
||||
if (!token) {
|
||||
uni.showToast({ title: "用户凭证已失效,请重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
return false
|
||||
}
|
||||
|
||||
const res = await userApi.auth(token)
|
||||
if (res?.code == 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, res.data)
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(USER_INFO_KEY, userData)
|
||||
return true
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
if (res.msg == "token已失效") {
|
||||
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || "登录失败", icon: "none" })
|
||||
}
|
||||
return false
|
||||
}
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: error, icon: "none" })
|
||||
return false
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
// 检查tokenStorage中tokenValue是否过期
|
||||
const isTokenExpires = (tokenStorage: any): boolean => {
|
||||
const { accessToken } = tokenStorage
|
||||
const expiresDate = new Date(accessToken.expiresAt).getTime()
|
||||
return new Date().getTime() >= expiresDate
|
||||
}
|
||||
|
||||
// 诗画登录 登录成功返回true,否则返回false
|
||||
async function handleShLogin(): Promise<boolean> {
|
||||
try {
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
|
||||
const userInfo = await (window as any).CP2.getUserInfo()
|
||||
if (userInfo.code == 0 || !userInfo.data.accountId || !userInfo.data.sessionId) {
|
||||
uni.showToast({ title: "获取诗画用户信息失败", icon: "none" })
|
||||
return false
|
||||
}
|
||||
|
||||
const { accountId, sessionId } = userInfo.data
|
||||
const response = await userApi.authsh({ accountId, sessionId })
|
||||
// const response = await userApi.authsh({ accountId: "67e790d6a95d5a7b507e53dd", sessionId: "68215b03a95d5a4899d20cb4" }) // 测试
|
||||
|
||||
if (response.code == 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken })
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(USER_INFO_KEY, userData)
|
||||
uni.showToast({ title: "登录成功", icon: "none" })
|
||||
return true
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
if (response.msg == "token已失效") {
|
||||
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
return false
|
||||
}
|
||||
|
||||
// 如果是设备未验证,保存响应数据
|
||||
if (response.data == -1) {
|
||||
uni.setStorageSync(TOKEN_KEY, { data: -1 })
|
||||
}
|
||||
|
||||
uni.showToast({ title: response.msg || "登录失败", icon: "none" })
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "登录错误", icon: "none" })
|
||||
return false
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 根据应用环境自动登录 返回登录结果
|
||||
async function autoLogin(): Promise<boolean> {
|
||||
const appInfo = await getAppInfo()
|
||||
|
||||
// 浙政钉环境
|
||||
if (appInfo == "zzd") {
|
||||
return await handleZzdLogin()
|
||||
}
|
||||
// 诗画环境
|
||||
else if (appInfo == "sh") {
|
||||
return await handleShLogin()
|
||||
} else {
|
||||
uni.showToast({ title: "app环境错误", icon: "none" })
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// token刷新
|
||||
async function refreshToken(): Promise<any> {
|
||||
if (refreshTokenPromise) {
|
||||
return refreshTokenPromise
|
||||
}
|
||||
if (refreshTokenPromise) return refreshTokenPromise
|
||||
|
||||
if (!isRefreshing) {
|
||||
isRefreshing = true
|
||||
@@ -185,120 +191,95 @@ async function refreshToken(): Promise<any> {
|
||||
return refreshTokenPromise
|
||||
}
|
||||
|
||||
// token过期刷新检查
|
||||
async function checkAndRefreshToken(tokenStorage: any) {
|
||||
const { accessToken } = tokenStorage
|
||||
if (!accessToken) return
|
||||
// 根据应用环境自动登录 返回登录结果
|
||||
const autoLogin = async (): Promise<boolean> => {
|
||||
const appInfo = await getAppInfo()
|
||||
// 浙政钉环境
|
||||
if (appInfo == "zzd") return await loginByZzd()
|
||||
// 诗画环境
|
||||
if (appInfo == "sh") return await loginBySh()
|
||||
|
||||
const expiresDate = new Date(accessToken.expiresAt).getTime()
|
||||
uni.showToast({ title: "app环境错误", icon: "none" })
|
||||
return false
|
||||
}
|
||||
|
||||
// token已过期,尝试刷新
|
||||
if (new Date().getTime() >= expiresDate) {
|
||||
return await refreshToken()
|
||||
// 浙政钉登录
|
||||
async function loginByZzd(): Promise<boolean> {
|
||||
try {
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
const token = new URL(window.location.href).searchParams.get("uabaseToken")
|
||||
|
||||
if (!token) {
|
||||
uni.showToast({ title: "用户凭证已失效,请重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
return false
|
||||
}
|
||||
|
||||
const res = await userApi.auth(token)
|
||||
if (res?.code == 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, res.data)
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(USER_INFO_KEY, userData)
|
||||
return true
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
if (res.msg == "token已失效") {
|
||||
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
}
|
||||
return false
|
||||
}
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: error, icon: "none" })
|
||||
return false
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建请求实例
|
||||
const http = new Request({
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
timeout: 15000,
|
||||
method: "GET",
|
||||
header: {
|
||||
Accept: "*/*",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
},
|
||||
withCredentials: true,
|
||||
custom: {
|
||||
showSuccess: false, // 成功提醒 默认使用后端返回值
|
||||
successMsg: "", // 成功消息
|
||||
showError: true, // 显示失败消息 默认显示
|
||||
errorMsg: "", // 失败提醒 默认使用后端返回信息
|
||||
loadingMsg: "加载中", // loading提醒文字
|
||||
auth: false, // 需要授权才能请求 默认放开
|
||||
},
|
||||
})
|
||||
// 诗画登录
|
||||
async function loginBySh(): Promise<boolean> {
|
||||
try {
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
|
||||
// 请求拦截器
|
||||
http.interceptors.request.use(async (config) => {
|
||||
const tokenStorage = uni.getStorageSync(TOKEN_KEY)
|
||||
const config_header: any = config.header || {}
|
||||
const userInfo = await (window as any).CP2.getUserInfo()
|
||||
if (userInfo.code == 0 || !userInfo.data.accountId || !userInfo.data.sessionId) {
|
||||
uni.showToast({ title: "获取诗画用户信息失败", icon: "none" })
|
||||
return false
|
||||
}
|
||||
|
||||
// 设置租户请求头
|
||||
config_header["TENANT-ID"] = "1"
|
||||
if (import.meta.env.VITE_IS_TOC === "true") config_header["CLIENT-TOC"] = "Y"
|
||||
const { accountId, sessionId } = userInfo.data
|
||||
const response = await userApi.authsh({ accountId, sessionId })
|
||||
// const response = await userApi.authsh({ accountId: "67e790d6a95d5a7b507e53dd", sessionId: "68215b03a95d5a4899d20cb4" }) // 测试
|
||||
|
||||
// 判断是否需要设置认证头
|
||||
if (!SKIP_AUTH_URLS.some((url) => config.url?.startsWith(url))) {
|
||||
if (!isEmpty(tokenStorage)) {
|
||||
// token存在,token过期刷新检查
|
||||
const newTokenStorage = await checkAndRefreshToken(tokenStorage)
|
||||
if (newTokenStorage) {
|
||||
const authHeader = getAuthHeader(newTokenStorage)
|
||||
if (authHeader) config_header.Authorization = authHeader
|
||||
} else {
|
||||
const authHeader = getAuthHeader(tokenStorage)
|
||||
if (authHeader) config_header.Authorization = authHeader
|
||||
}
|
||||
if (response.code == 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken })
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(USER_INFO_KEY, userData)
|
||||
uni.showToast({ title: "登录成功", icon: "none" })
|
||||
return true
|
||||
} else {
|
||||
// token不存在,刷新token
|
||||
const newTokenStorage = await refreshToken()
|
||||
if (newTokenStorage) {
|
||||
const authHeader = getAuthHeader(newTokenStorage)
|
||||
if (authHeader) config_header.Authorization = authHeader
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
if (response.msg == "token已失效") {
|
||||
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
return false
|
||||
}
|
||||
|
||||
// 如果是设备未验证,保存响应数据
|
||||
if (response.data == -1) {
|
||||
uni.setStorageSync(TOKEN_KEY, { data: -1 })
|
||||
}
|
||||
|
||||
uni.showToast({ title: response.msg || "登录失败", icon: "none" })
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "登录错误", icon: "none" })
|
||||
return false
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
return config
|
||||
}, Promise.reject)
|
||||
|
||||
// 响应拦截器
|
||||
http.interceptors.response.use(
|
||||
async (response) => {
|
||||
// 账号密码登录响应结果特殊处理
|
||||
if (response.config.url === "/auth/oauth2/token") {
|
||||
return Promise.resolve({
|
||||
code: 0,
|
||||
data: response.data,
|
||||
msg: null,
|
||||
})
|
||||
}
|
||||
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
async (error) => {
|
||||
// 处理 424 错误(token过期)
|
||||
if (error.statusCode === 424) {
|
||||
if (isDevEnv()) {
|
||||
// 开发环境直接清除token并跳转登录
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
uni.showToast({ title: "登录已过期,请重新登录", icon: "none" })
|
||||
router.jump("/pages/user/login")
|
||||
} else {
|
||||
try {
|
||||
const newTokenStorage = await refreshToken()
|
||||
if (newTokenStorage) {
|
||||
// 重新发起失败的请求
|
||||
const config = error.config
|
||||
const authHeader = getAuthHeader(newTokenStorage)
|
||||
if (authHeader && config.header) config.header.Authorization = authHeader
|
||||
return http.request(config)
|
||||
}
|
||||
} catch (err) {
|
||||
// 错误已在refreshToken中处理
|
||||
return Promise.reject(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 显示错误信息
|
||||
if (error?.data?.msg) {
|
||||
uni.showToast({ title: error.data.msg, icon: "none", mask: true })
|
||||
}
|
||||
return Promise.resolve(error.data)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// 请求函数
|
||||
const request = (config: any) => {
|
||||
|
||||
Reference in new issue
Block a user