feat: 端点登录

This commit is contained in:
caijun
2026-01-25 20:22:58 +08:00
parent f9e1a0cc18
commit f43f2ff3c2
12 changed files with 551 additions and 444 deletions

View File

@@ -90,6 +90,15 @@ export function getAdapterUserList(data, options) {
} }
}) })
} }
// 社交授权的跳转
export function socialAuthRedirect(type, redirectUri) {
return request({
url: '/admin-api/system/auth/social-auth-redirect?type=' + type + '&redirectUri=' + redirectUri,
method: 'GET'
})
}
// 获取人员角色 // 获取人员角色
export function getAdapterRoleList() { export function getAdapterRoleList() {
return request({ return request({
@@ -239,13 +248,18 @@ export function getPermissionInfo() {
} }
// 获取token // 获取token
export function socialLogin(token) { export function socialLogin(type, code, state) {
console.log(type,code,state,'data数据---')
return request({ return request({
url: '/admin-api/system/auth/social-login', url: '/admin-api/system/auth/social-login',
method: 'post', method: 'post',
token, data: {
type,
code,
state
},
header: { header: {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/json',
} }
}) })
} }

View File

@@ -1,6 +1,6 @@
{ {
"name" : "jnpf java vue3版", "name" : "jnpf java vue3版",
"appid": "__UNI__663111E", "appid" : "__UNI__55507A7",
"description" : "专注信息化平台、软件开发、app开发", "description" : "专注信息化平台、软件开发、app开发",
"versionName" : "1.0.0", "versionName" : "1.0.0",
"versionCode" : "100", "versionCode" : "100",
@@ -235,3 +235,4 @@
} }
} }
/* 5+App */ /* 5+App */

View File

@@ -56,13 +56,16 @@
</view> </view>
<!-- 底部操作按钮区域 --> <!-- 底部操作按钮区域 -->
<view v-if="!loading && (!(dataForm.approveStatus == 1 || dataForm.approveStatus == 2 || dataForm.approveStatus == 4) || !dataForm.id || config.current && config.current == 2)" class="buttom-actions"> <view v-if="!loading && (dataForm.approveStatus != 4 || !dataForm.id || config.current && config.current == 2) && !isProcess" class="buttom-actions">
<u-button v-if="(!dataForm.approveStatus && dataForm.id) || dataForm.approveStatus == 3" class="buttom-btn launch-flow-btn" type="primary" @click.stop="handleLaunchFlow" :disabled="idDsabled" :loading="btnLoading"> <u-button v-if="(!dataForm.approveStatus && dataForm.id) || dataForm.approveStatus == 3" class="buttom-btn launch-flow-btn" type="primary" @click.stop="handleLaunchFlow" :disabled="idDsabled" :loading="btnLoading">
发起流程 发起流程
</u-button> </u-button>
<u-button v-if="!config.current" class="buttom-btn" type="primary" @click.stop="submit" :disabled="idDsabled" :loading="btnLoading"> <u-button v-if="!config.current && !dataForm.approveStatus" class="buttom-btn" type="primary" @click.stop="submit" :disabled="idDsabled" :loading="btnLoading">
保存 保存
</u-button> </u-button>
<u-button v-if="!config.current && (dataForm.approveStatus == 1 || dataForm.approveStatus == 2)" class="buttom-btn" type="primary" @click.stop="goProcess">
查看流程
</u-button>
<u-button v-if="config.current == 2" class="buttom-btn" type="error" @click.stop="handleFail" :disabled="idDsabled" :loading="btnLoading"> <u-button v-if="config.current == 2" class="buttom-btn" type="error" @click.stop="handleFail" :disabled="idDsabled" :loading="btnLoading">
不通过 不通过
</u-button> </u-button>
@@ -344,6 +347,7 @@
currentProcessId: '', currentProcessId: '',
selectedCandidates: {}, selectedCandidates: {},
approvalData: [], // 存储审批记录 approvalData: [], // 存储审批记录
isProcess: false, // 点击查看流程
//审批意见弹窗相关数据 //审批意见弹窗相关数据
showApprovalReasonDialog: false, // 弹窗显示状态 showApprovalReasonDialog: false, // 弹窗显示状态
@@ -381,7 +385,7 @@
}, },
isApproval(){ isApproval(){
const {current} = this.config const {current} = this.config
return !!current return !!current || this.isProcess
} }
}, },
onLoad(option) { onLoad(option) {
@@ -426,7 +430,7 @@
const getNavigationTitle = () =>{ const getNavigationTitle = () =>{
let titleName = '' let titleName = ''
if(this.config.current){ if(this.config.current || this.isProcess){
titleName = this.config.name + '详情' titleName = this.config.name + '详情'
}else { }else {
const name = this.dataForm.id ? this.$t('common.editText') : this.$t('common.addText') const name = this.dataForm.id ? this.$t('common.editText') : this.$t('common.addText')
@@ -483,8 +487,19 @@
getListCreateData(params){ getListCreateData(params){
getListCreate(params,this.modelId).then(res=>{ getListCreate(params,this.modelId).then(res=>{
if(res.code == 0) { if(res.code == 0) {
// const name = this.approvalType == 'through' ? '申请通过成功' '发起成功'
let name = '发起成功'
switch(this.approvalType){
case 'through':
name = '审批通过成功'
break;
case 'fail':
name = '审批不通过成功'
break;
}
uni.showToast({ uni.showToast({
title: '发起成功', title: name,
icon: 'success' icon: 'success'
}) })
setTimeout(() => { setTimeout(() => {
@@ -743,6 +758,14 @@
this.approvalReason = '' // 清空之前的意见 this.approvalReason = '' // 清空之前的意见
this.showApprovalReasonDialog = true this.showApprovalReasonDialog = true
}, },
// 查看流程
goProcess(){
this.isProcess = true
console.log(this.config,'config-')
uni.setNavigationBarTitle({
title: `${this.config.name}流程详情`
})
},
// 提交审批结果(通过/不通过) // 提交审批结果(通过/不通过)
async submitApprovalResult() { async submitApprovalResult() {

View File

@@ -94,6 +94,10 @@
</view> </view>
</view> </view>
</view> </view>
<view v-if="todoList.length > 2" class="todo-more" @click="openToDoPage">
更多
<u-icon name="arrow-down" class="u-p-r-10"color="#666"></u-icon>
</view>
</scroll-view> </scroll-view>
<view class="empty-container" v-else> <view class="empty-container" v-else>
<view> <view>
@@ -398,7 +402,7 @@
getDonePage() { getDonePage() {
const params = { const params = {
pageNo:1, pageNo:1,
pageSize: 3 pageSize: 2000
} }
getDonePage(params).then(res=>{ getDonePage(params).then(res=>{
const {code,data} = res const {code,data} = res
@@ -408,7 +412,7 @@
index: 1, // 待办任务的tab索引 index: 1, // 待办任务的tab索引
text: res.data.total.toString() // 角标数字 text: res.data.total.toString() // 角标数字
}); });
this.todoList = data.list || [] this.todoList = data.list.slice(0,3) || []
} }
}) })
}, },
@@ -585,7 +589,7 @@
/* 滚动容器样式 */ /* 滚动容器样式 */
.todo-scroll-container { .todo-scroll-container {
width: 100%; width: 100%;
max-height: 680rpx !important; max-height: 780rpx !important;
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 4rpx; width: 4rpx;
} }
@@ -594,6 +598,12 @@
border-radius: 2rpx; border-radius: 2rpx;
} }
} }
.todo-more {
text-align: center;
color: #666;
font-size: 28rpx;
margin-top: 5rpx;
}
.todo-item { .todo-item {
// display: flex; // display: flex;
align-items: flex-start; align-items: flex-start;
@@ -652,7 +662,7 @@
} }
.title-right { .title-right {
align-items: center; align-items: center;
font-size: 24rpx; font-size: 28rpx;
color: #666; color: #666;
} }
/* 滚动容器 */ /* 滚动容器 */

View File

@@ -267,7 +267,7 @@
userStore.logout().then(() => { userStore.logout().then(() => {
uni.closeSocket() uni.closeSocket()
uni.reLaunch({ uni.reLaunch({
url: '/pages/login/index' url: '/pages/login/index?socialLogin=true'
}) })
}) })
this.removeAccount() this.removeAccount()

View File

@@ -17,7 +17,7 @@
</view> </view>
<view class="logo-hd u-flex-col"> <view class="logo-hd u-flex-col">
<view class="loginSwitch u-flex-col"> <view class="loginSwitch u-flex-col">
<view class="loginInputBox u-flex-col" v-show="!isSso && !ssoLoading"> <view class="loginInputBox u-flex-col" v-show=" true || !isSso && !ssoLoading">
<u-form :model="formData" :rules="rules" ref="dataForm" :errorType="['toast']" label-position="left" <u-form :model="formData" :rules="rules" ref="dataForm" :errorType="['toast']" label-position="left"
label-width="150" label-align="left"> label-width="150" label-align="left">
<u-form-item v-show="false" prop="account" :borderBottom="false"> <u-form-item v-show="false" prop="account" :borderBottom="false">
@@ -49,9 +49,9 @@
<view class="remember-wrap"> <view class="remember-wrap">
<u-checkbox v-model="remember"><span class="remember-text">记住账号密码</span></u-checkbox> <u-checkbox v-model="remember"><span class="remember-text">记住账号密码</span></u-checkbox>
</view> </view>
<view class="remember-wrap"> <!-- <view class="remember-wrap">
<u-checkbox v-model="isCertify"><span class="remember-text">是否认证</span></u-checkbox> <u-checkbox v-model="isCertify"><span class="remember-text">是否认证</span></u-checkbox>
</view> </view> -->
<view class="loginBtnBox"> <view class="loginBtnBox">
<u-button @click="login" type="primary" :loading="loading">{{ loading ? "登录中...":"登录"}} <u-button @click="login" type="primary" :loading="loading">{{ loading ? "登录中...":"登录"}}
</u-button> </u-button>
@@ -130,7 +130,8 @@
getLoginConfig, getLoginConfig,
getSocialsUserList, getSocialsUserList,
socialsLogin, socialsLogin,
getTicket getTicket,
socialAuthRedirect
} from '@/api/common.js' } from '@/api/common.js'
import md5Libs from "@/uni_modules/vk-uview-ui/libs/function/md5"; import md5Libs from "@/uni_modules/vk-uview-ui/libs/function/md5";
import resources from '@/libs/resources' import resources from '@/libs/resources'
@@ -171,7 +172,7 @@
}, },
sysConfigInfo: {}, sysConfigInfo: {},
appIcon: '', appIcon: '',
sysName: '', sysName: '综合监控系统',
copyright: '综合监控系统', copyright: '综合监控系统',
socialsList: [], socialsList: [],
show: false, show: false,
@@ -183,7 +184,8 @@
preUrl: '', preUrl: '',
ticketParams: "", ticketParams: "",
loginCode: '', loginCode: '',
isKeyUp: true isKeyUp: true,
ssoOptions: {} // 端点登录参数
} }
}, },
watch: { watch: {
@@ -209,43 +211,59 @@
this.$refs.dataForm.setRules(this.rules); this.$refs.dataForm.setRules(this.rules);
}, },
onLoad(options) { onLoad(options) {
if (options?.JNPF_TICKET) { this.ssoOptions = options
this.ssoTicket = options.JNPF_TICKET if(options.code){
uni.navigateTo({ this.exchangeToken(options)
url: `/pages/login/otherLogin?ssoTicket=${this.ssoTicket}` }else if(options.socialLogin){
}) this.getLogin()
} }
this.ssoTicket = uni.getStorageSync('ssoTicket') else{
this.sysConfigInfo = uni.getStorageSync('sysConfigInfo') this.certifyLogin()
console.log(this.define,'define-------------') }
this.appIcon = !!this.sysConfigInfo.appIcon ? this.baseURL + this.sysConfigInfo.appIcon :
logoImg // if(JSON.stringify(options) == '{}'){
this.sysName = !!this.sysConfigInfo.companyName ? this.sysConfigInfo.sysName : // // 端点登录
'JNPF快速开发平台' // this.certifyLogin()
// this.copyright = !!this.sysConfigInfo.copyright ? this.sysConfigInfo.copyright : // }else {
// this.define.copyright // this.getLogin()
// this.copyright = !!this.sysConfigInfo.copyright && this.sysConfigInfo.copyright // }
// if (options?.JNPF_TICKET) {
// this.ssoTicket = options.JNPF_TICKET
// uni.navigateTo({
// url: `/pages/login/otherLogin?ssoTicket=${this.ssoTicket}`
// })
// }
// this.ssoTicket = uni.getStorageSync('ssoTicket')
// this.sysConfigInfo = uni.getStorageSync('sysConfigInfo')
// console.log(this.define,'define-------------')
// this.appIcon = !!this.sysConfigInfo.appIcon ? this.baseURL + this.sysConfigInfo.appIcon :
// logoImg
// this.sysName = !!this.sysConfigInfo.companyName ? this.sysConfigInfo.sysName :
// '综合监控系统'
// // this.copyright = !!this.sysConfigInfo.copyright ? this.sysConfigInfo.copyright :
// // this.define.copyright
// // this.copyright = !!this.sysConfigInfo.copyright && this.sysConfigInfo.copyright
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: this.sysName title: this.sysName
}) })
let needCode = uni.getStorageSync('app_loginNeedCode') // let needCode = uni.getStorageSync('app_loginNeedCode')
this.isCode = needCode // this.isCode = needCode
this.changeCode() // this.changeCode()
// this.getLoginConfig() // this.getLoginConfig()
this.formData.password = ''; // this.formData.password = '';
if (options.data) { // if (options.data) {
this.tenantUserInfo = JSON.parse(options.data) // this.tenantUserInfo = JSON.parse(options.data)
// if (this.tenantUserInfo) this.show = true // // if (this.tenantUserInfo) this.show = true
} // }
this.initAccount() // this.initAccount()
// #ifndef H5 // // #ifndef H5
uni.onKeyboardHeightChange(res => { // uni.onKeyboardHeightChange(res => {
this.isKeyUp = res.height == 0 ? true : false // this.isKeyUp = res.height == 0 ? true : false
return this.isKeyUp // return this.isKeyUp
}) // })
// #endif // // #endif
this.initLoginConfig() // this.initLoginConfig()
}, },
methods: { methods: {
initAccount() { initAccount() {
@@ -499,30 +517,18 @@
this.imgUrl = `/api/oauth/ImageCode/${this.codeLength || 4}/${timestamp}` this.imgUrl = `/api/oauth/ImageCode/${this.codeLength || 4}/${timestamp}`
}, },
login() { login() {
if(this.ssoOptions.socialLogin){
this.$refs.dataForm.validate(valid => { this.$refs.dataForm.validate(valid => {
if (valid) { if (valid) {
this.loading = true this.loading = true
const password = md5Libs.md5(this.formData.password); const password = md5Libs.md5(this.formData.password);
const encryptPassword = this.jnpf.aesEncryption.encrypt(password); const encryptPassword = this.jnpf.aesEncryption.encrypt(password);
// let query = {
// account: this.formData.account,
// password: encryptPassword,
// timestamp: this.timestamp,
// code: this.formData.code,
// origin: this.formData.origin,
// jnpf_ticket: this.ssoTicket,
// grant_type: 'password',
// }
if(this.isCertify){
// 认证登录
this.certifyLogin()
}else {
this.getLogin() this.getLogin()
} }
}
}); });
return
}
this.certifyLogin()
}, },
// 普通登录 // 普通登录
getLogin(){ getLogin(){
@@ -540,8 +546,9 @@
// query.Client_Id = uni.getStorageSync('cid') // query.Client_Id = uni.getStorageSync('cid')
// #endif // #endif
login(query).then(res => { login(query).then(res => {
let token = res.data.accessToken const {accessToken,refreshToken} = res.data
userStore.setToken(token) userStore.setToken(accessToken)
userStore.setRefreshToken(refreshToken)
this.rememberAccount() this.rememberAccount()
if(res.code == 0){ if(res.code == 0){
getPermissionInfo().then(res=>{ getPermissionInfo().then(res=>{
@@ -576,33 +583,24 @@
}) })
}, },
// 认证登录 // 认证登录
certifyLogin(){ async certifyLogin(){
lx.biz.getAuthCode({ let type = '100'
appId: "8889088-16130048", // AppID let redirectUri = location.origin + '/pages/login/index?' + encodeURIComponent(`type=${type}&redirect=/`)
success: (res) => { const res = await socialAuthRedirect(type,encodeURIComponent(redirectUri))
console.log('免登授权码:', res.authCode) console.log(res,'res-------')
this.exchangeToken(res.authCode) window.location.href = res.data
}, },
fail: (err) => { async exchangeToken(options) {
console.error('获取免登授权码失败:', err)
uni.showToast({
title: '免登失败,请重试',
icon: 'none'
})
this.loading = false
}
})
},
async exchangeToken(authCode) {
try { try {
const type = '110' const type = '100'
const code = authCode const code = '1222' || options?.code
const state = this.uuid() const state = this.uuid() || options?.state
const res = await socialLogin(type, code, state) const res = await socialLogin(type, code, state)
const {accessToken,refreshToken} = res.data
const userStore = useUserStore() const userStore = useUserStore()
// 存储Token和用户信息 // 存储Token和用户信息
userStore.setToken(res) userStore.setToken(accessToken)
userStore.setRefreshToken(refreshToken)
uni.switchTab({ uni.switchTab({
url: '/pages/index/indexWork' url: '/pages/index/indexWork'
}); });

View File

@@ -10,9 +10,7 @@
</view> </view>
<view class="content u-p-l-32 u-p-r-32 u-p-t-30 u-font-28"> <view class="content u-p-l-32 u-p-r-32 u-p-t-30 u-font-28">
<text>引迈信息技术有限公司是一家做快速开发平台的企业针对软件传统开发遇到招人难留人难用人成本高技术更新换代快等一系列问题只需要一套JNPF平台您遇到的一系列问题就依然而解 <text>软通动力</text>
JNPF采用主流的两大技术Java/.Net开发是一套低代码开发平台可视化开发环境有拖拽式的代码生成器灵活的权限配置SaaS服务强大的接口对接随心可变的工作流引擎一站式开发多端使用WebAndroidIOS微信小程序并且有以构建业务流程逻辑和数据模型等所需的功能为企业项目节省80%的重回工作让开发者将重心放在业务逻辑不必烦恼底层架构设计可短时间开发出如ERPOACRMHRMIS以及电信银行政府企业等各行业的企业应用系统
引迈信息技术有限公司以诚信为根本服务为基础理念通过持续不断地研发技术创新强化平台质量和颜值为企业保驾护航</text>
</view> </view>
<view class="copyright">{{copyright}}</view> <view class="copyright">{{copyright}}</view>
</view> </view>

BIN
static/image/logoT.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 835 KiB

View File

@@ -12,6 +12,7 @@ export const useUserStore = defineStore({
id: 'user', id: 'user',
state: () => ({ state: () => ({
token: "", token: "",
refreshToken: "",
userInfo: {}, userInfo: {},
menuList: [], menuList: [],
tenantId: '', tenantId: '',
@@ -38,6 +39,10 @@ export const useUserStore = defineStore({
this.token = token this.token = token
uni.setStorageSync('token', token) uni.setStorageSync('token', token)
}, },
setRefreshToken(refreshToken) {
this.refreshToken = refreshToken
uni.setStorageSync('refreshToken', refreshToken)
},
setCid(cid) { setCid(cid) {
this.cid = cid this.cid = cid
uni.setStorageSync('cid', cid) uni.setStorageSync('cid', cid)

View File

@@ -1,10 +1,10 @@
/* process.env.NODE_ENV设置生产环境模式 */ /* process.env.NODE_ENV设置生产环境模式 */
// #ifndef MP // #ifndef MP
const baseURL = process.env.NODE_ENV === "production" ? "http://10.0.64.25:48080" : "http://10.28.117.48:48080" const baseURL = process.env.NODE_ENV === "production" ? "http://10.0.64.25:48080" : "http://10.0.64.25:48080"
const webSocketUrl = process.env.NODE_ENV === "production" ? "http://10.0.64.25:48080" : const webSocketUrl = process.env.NODE_ENV === "production" ? "http://10.0.64.25:48080" :
"ws://10.28.117.183:30000/api/message/websocket" "ws://10.0.64.25:48080/api/message/websocket"
const report = process.env.NODE_ENV === 'production' ? 'http://10.0.64.25:48080' : 'http://10.28.117.183:8200' const report = process.env.NODE_ENV === 'production' ? 'http://10.0.64.25:48080' : 'http://10.0.64.25:48080'
const pcURL = process.env.NODE_ENV === 'production' ? 'http://10.0.64.25:48080' : 'http://10.28.117.183:3000' const pcURL = process.env.NODE_ENV === 'production' ? 'http://10.0.64.25:48080' : 'http://10.0.64.25:48080'
// #endif // #endif
// #ifdef MP // #ifdef MP
@@ -15,7 +15,7 @@ const pcURL = process.env.NODE_ENV === 'production' ? 'http://10.0.64.25:48080'
// #endif // #endif
console.log(process.env.NODE_ENV === "production",'判断环境----------') console.log(process.env.NODE_ENV === "production",'判断环境----------')
const define = { const define = {
copyright: "Copyright @ 2025 引迈信息技术有限公司版权所有", copyright: "Copyright @ 2026 软通动力",
sysVersion: "V6.0", sysVersion: "V6.0",
baseURL, // 接口前缀 baseURL, // 接口前缀
report, report,

View File

@@ -1,36 +1,26 @@
import define from './define' import define from './define'
import { import { useLocale } from '@/locale/useLocale';
useLocale
} from '@/locale/useLocale';
const { const { getBackLocale } = useLocale();
getBackLocale
} = useLocale();
let host = define.baseURL let host = define.baseURL
const defaultOpt = { const defaultOpt = { load: true }
load: true
}
// 示例 // ------------- token刷新核心配置 -------------
// async xxxx(code) { const whiteList = ['/login', '/system/auth/refresh-token']
// var res = await this.request({ let requestQueue = []
// url: '/api/System/DictionaryData/All', let isRefreshingToken = false
// method: 'GET', const isRelogin = { show: false }
// data,
// options: {
// load: false
// }
// })
// if (!res) return
// console.log(res)
// }
// ------------- 核心request方法 -------------
function request(config) { function request(config) {
config.options = Object.assign(defaultOpt, config.options) config.options = Object.assign(defaultOpt, config.options)
const token = uni.getStorageSync('token') || '' const token = uni.getStorageSync('token') || ''
const tenantId = uni.getStorageSync('tenantId') || '' const refreshToken = uni.getStorageSync('refreshToken') || ''
const tenantId = '1' || uni.getStorageSync('tenantId')
const systemCode = uni.getStorageSync('systemCode') || '' const systemCode = uni.getStorageSync('systemCode') || ''
const locale = getBackLocale() const locale = getBackLocale()
// 构建请求头
let header = { let header = {
"accept": 'application/json, text/plain, */*', "accept": 'application/json, text/plain, */*',
"App-Code": systemCode, "App-Code": systemCode,
@@ -43,33 +33,89 @@ function request(config) {
} }
header['App-Code'] = encodeURIComponent(header['App-Code']) header['App-Code'] = encodeURIComponent(header['App-Code'])
if (token) header['Authorization'] = token if (token) header['Authorization'] = token
// 测试 todo // let url = config.url.indexOf('http') > -1 ? config.url : host + config.url
console.log(config.url,config.url.includes('admin-api'),'config.url.includes---') let url = host + config.url
if(config.url.includes('admin-api')){ console.log(url,'url---')
host = 'http://10.28.117.48:48080' // 3. 显示加载中
}else {
host = define.baseURL
}
let url = config.url.indexOf('http') > -1 ? config.url : host + config.url
if (config.options.load) { if (config.options.load) {
uni.showLoading({ uni.showLoading({ title: config.options.loadText || '正在加载' })
title: config.options.loadText || '正在加载'
})
} }
// 4. 返回Promise核心改造逻辑
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 封装核心请求逻辑
const coreRequest = () => {
uni.request({ uni.request({
url: url, url: url,
data: config.data || {}, data: config.data || {},
method: config.method || 'GET', method: config.method || 'GET',
header: header, header: header,
timeout: define.timeout, timeout: define.timeout,
success: res => { success: async (res) => {
uni.hideLoading();
if (res.statusCode === 200) { if (res.statusCode === 200) {
if (res.data.code == 200 || res.data.code == 0) { if (res.data.code == 200 || res.data.code == 0) {
resolve(res.data) resolve(res.data)
} else if ([401, 600, 601, 602].includes(res.data.code)) {
// 白名单接口不处理
const isWhiteList = whiteList.some(v => config.url.includes(v))
if (isWhiteList) {
ajaxError(res.data)
reject(res.data.msg)
return
}
// ------------- 核心调整刷新token请求改为问号拼接参数 -------------
if (!refreshToken) {
await handleAuthorized()
reject(res.data.msg)
return
}
if (isRefreshingToken) {
requestQueue.push(() => coreRequest())
return
}
isRefreshingToken = true
try {
// 拼接URL参数和PC端一致POST方法 + ?refreshToken=xxx
const refreshUrl = `${host}/admin-api/system/auth/refresh-token?refreshToken=${encodeURIComponent(refreshToken)}`
// 调用刷新token接口POST方法 + URL参数无请求体
const refreshRes = await uni.request({
url: refreshUrl, // 带参数的URL
method: 'POST', // 保持POST方法
header: {
'tenant-id': tenantId, // 携带租户ID
'Content-Type': 'application/json'
},
data: {} // 无请求体参数全在URL上
})
// 刷新成功处理
if (refreshRes.statusCode === 200 && refreshRes.data.code === 200) {
const newTokenData = refreshRes.data.data
// 存储新token建议用项目封装的setToken方法
uni.setStorageSync('token', newTokenData.token)
uni.setStorageSync('refreshToken', newTokenData.refreshToken)
// 更新请求头
header['Authorization'] = newTokenData.token
// 重试当前请求
coreRequest()
// 执行队列请求
requestQueue.forEach(cb => cb())
requestQueue = []
} else {
await handleAuthorized()
reject('刷新token失败' + (refreshRes.data?.msg || '接口返回异常'))
}
} catch (err) {
await handleAuthorized()
reject('刷新token异常' + err.errMsg)
} finally {
isRefreshingToken = false
requestQueue = []
}
} else { } else {
ajaxError(res.data) ajaxError(res.data)
reject(res.data.msg) reject(res.data.msg)
@@ -78,42 +124,54 @@ function request(config) {
ajaxError(res.data) ajaxError(res.data)
reject(res.errMsg) reject(res.errMsg)
} }
uni.hideLoading();
}, },
fail: err => { fail: (err) => {
uni.showToast({
title: '连接服务器失败',
icon: 'none',
})
setTimeout(function () {
uni.hideLoading(); uni.hideLoading();
}, 2000); uni.showToast({ title: '连接服务器失败', icon: 'none' })
reject(err) reject(err)
} }
}) })
}
coreRequest()
}) })
} }
// ------------- 辅助函数 -------------
function ajaxError(data) { function ajaxError(data) {
uni.showToast({ uni.showToast({
title: data.msg || '请求出错,请重试', title: data.msg || '请求出错,请重试',
icon: 'none', icon: 'none',
complete() { complete() {
if (data.code === 600 || data.code === 601 || data.code === 602 || data.code === 401) { if ([600, 601, 602, 401].includes(data.code) && !isRefreshingToken) {
setTimeout(() => { setTimeout(() => handleAuthorized(), 1500)
uni.removeStorageSync('token')
uni.removeStorageSync('cid')
uni.removeStorageSync('userInfo')
uni.removeStorageSync('permissionList')
uni.removeStorageSync('sysVersion')
uni.removeStorageSync('dynamicModelExtra')
uni.reLaunch({
url: '/pages/login/index'
})
}, 1500)
} }
} }
}) })
} }
async function handleAuthorized() {
if (!isRelogin.show) {
isRelogin.show = true
const res = await uni.showModal({
title: '登录过期',
content: '您的登录已过期,请重新登录',
showCancelButton: false,
confirmText: '重新登录'
})
if (res.confirm) {
// 清除缓存建议用项目封装的removeToken方法
uni.removeStorageSync('token')
uni.removeStorageSync('refreshToken')
uni.removeStorageSync('cid')
uni.removeStorageSync('userInfo')
uni.removeStorageSync('permissionList')
uni.removeStorageSync('sysVersion')
uni.removeStorageSync('dynamicModelExtra')
uni.reLaunch({ url: '/pages/login/index' })
}
isRelogin.show = false
}
}
export default request export default request