diff --git a/src/api/system/unitConverter/sysUnitConverter.js b/src/api/system/unitConverter/sysUnitConverter.js
index de425f6..45b20ea 100644
--- a/src/api/system/unitConverter/sysUnitConverter.js
+++ b/src/api/system/unitConverter/sysUnitConverter.js
@@ -4,9 +4,7 @@ import request from '@/utils/request'
export function listConvert(query) {
return request({
url: '/system/convert/list',
- headers: {
- isToken: false
- },
+
method: 'get',
params: query
})
@@ -16,9 +14,7 @@ export function listConvert(query) {
export function getConvert(id) {
return request({
url: '/system/convert/' + id,
- headers: {
- isToken: false
- },
+
method: 'get'
})
}
@@ -27,9 +23,7 @@ export function getConvert(id) {
export function addConvert(data) {
return request({
url: '/system/convert',
- headers: {
- isToken: false
- },
+
method: 'post',
data: data
})
@@ -39,9 +33,7 @@ export function addConvert(data) {
export function updateConvert(data) {
return request({
url: '/system/convert',
- headers: {
- isToken: false
- },
+
method: 'put',
data: data
})
@@ -51,9 +43,7 @@ export function updateConvert(data) {
export function delConvert(id) {
return request({
url: '/system/convert/' + id,
- headers: {
- isToken: false
- },
+
method: 'delete'
})
}
diff --git a/src/main.js b/src/main.js
index 021ac8f..50059f3 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,7 +1,6 @@
import App from './App.vue'
import plugins from './plugins'
-import store from './store'
-import uviewPlus from 'uview-plus'
+import store from './store'
import { createSSRApp } from 'vue'
@@ -14,8 +13,7 @@ import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, select
export function createApp() {
const app = createSSRApp(App)
- app.use(store)
- app.use(uviewPlus)
+ app.use(store)
app.use(plugins)
// #ifndef MP-WEIXIN
diff --git a/src/manifest.json b/src/manifest.json
index 00233f8..e844371 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -16,6 +16,9 @@
"autoclose" : true,
"delay" : 0
},
+ "compatible" : {
+ "ignoreVersion" : true // 忽略版本检查
+ },
/* 模块配置 */
"modules" : {
"OAuth" : {}
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 98c8b30..6594f0c 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -33,16 +33,22 @@
ref,
onMounted
} from "vue";
- import modal from "@/plugins/modal"
- import {
- storage
- } from '@/utils/storageUnit.ts';
+ import modal from "@/plugins/modal"
+
import {
extractModuleData
} from '@/utils/moudlesData.ts';
- import useUnitStore from '@/store/modules/unitData.ts';
+
+ import useUnitStore from '@/store/modules/unitData.ts';
+ import {
+ getToken,
+ setToken,
+ removeToken
+ } from "@/utils/auth";
+
const unitStore = useUnitStore();
+
const current = ref(0);
const swiperDotIndex = ref(0);
const data = ref([{
@@ -58,14 +64,60 @@
// 核心数据:计算分组和功能项定义
const moudlesGroups = ref([]);
-
- onMounted(async() => {
+
+ // 登录状态校验函数
+ const checkLoginStatus = () => {
+ // 1. 检查本地token是否存在
+ const token = getToken();
+
+ console.log(token)
+ // 2. 无token/用户信息,直接跳转登录
+ if (!token) {
+ uni.reLaunch({
+ url: '/pages/login'
+ });
+ return false; // 未登录
+ }
+ return true; // 已登录
+ };
+
+ onMounted(async () => {
+ // 第一步:优先校验登录状态(核心修复)
+ const isLogin = checkLoginStatus();
+ if (!isLogin) return; // 未登录则终止后续逻辑
moudlesGroups.value = extractModuleData(['流量计算', '参数计算'], false)
- // 优先从本地缓存恢复,再请求最新数据
- unitStore.restoreUnitDataFromLocal();
- await unitStore.getList();
-
- })
+ // 优先从本地缓存恢复,再请求最新数据
+ unitStore.restoreUnitDataFromLocal();
+ try {
+ await unitStore.getList();
+ } catch (error) {
+ console.error('获取单位数据失败:', error);
+
+ if (error.code === 401 ||
+ (error.message &&
+ (error.message.includes('会话过期') ||
+ error.message.includes('无效的会话')))) {
+
+ // 清除本地存储
+ uni.removeStorageSync('token');
+ uni.removeStorageSync('userInfo');
+
+ // 跳转到登录页
+ uni.reLaunch({
+ url: '/pages/login/'
+ });
+ } else {
+ // 其他错误:显示具体错误信息
+ const errorMsg = error.message || '数据加载失败,请稍后重试';
+ modal.showToast({
+ title: errorMsg,
+ mask: false,
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ }
+ });
function navigateToMoudles(item) {
console.log(item)
diff --git a/src/pages/login.vue b/src/pages/login.vue
index 34d7dc9..e639068 100644
--- a/src/pages/login.vue
+++ b/src/pages/login.vue
@@ -130,12 +130,17 @@
wxLogin,
wxAppLogin
} from '@/api/oauth'
- import useUserStore from '@/store/modules/user'
+
import {
setToken
} from '@/utils/auth'
import config from '@/config.js'
import request from '@/utils/request'
+
+ // 添加一个标志位,防止重复跳转
+ let isChecking = false;
+ let hasChecked = false;
+ import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const appName = config.appInfo.name || '天然气工具箱'
@@ -245,13 +250,18 @@
const res = await login(params.username, params.password, params.code, params.uuid)
+
if (res.token) {
setToken(res.token)
await userStore.getInfo()
- uni.switchTab({
- url: '/pages/index'
- });
+ // 添加延迟,确保状态更新完成
+ setTimeout(() => {
+ // 使用 reLaunch 关闭所有页面并跳转到首页
+ uni.reLaunch({
+ url: '/pages/index'
+ })
+ }, 300)
}
} catch (error) {
// 如果需要验证码,重新获取
@@ -348,7 +358,7 @@
if (platform === 'android' || platform === 'ios') {
// APP 端
- code = await wechatLoginApp();
+ code = await wechatLoginApp();
console.log(code);
@@ -405,15 +415,55 @@
getCaptcha()
})
- onLoad(() => {
- // 检查是否有token,如果有则直接跳转
- const token = uni.getStorageSync('token')
- if (token) {
- uni.reLaunch({
- url: '/pages/index'
- })
+ onLoad(async (options) => {
+ // === 新增:防止重复检查 ===
+ if (isChecking || hasChecked) return;
+ isChecking = true;
+
+ try {
+ const token = uni.getStorageSync('token');
+
+ if (!token) {
+ hasChecked = true;
+ isChecking = false;
+ getCaptcha(); // 确保验证码加载
+ return;
+ }
+
+ // 仅当明确要求跳过自动登录时才中断
+ if (options?.skipAutoLogin === 'true') {
+ hasChecked = true;
+ isChecking = false;
+ return;
+ }
+
+ // 验证 token 有效性(关键:使用安全的验证方式)
+ try {
+ await userStore.getInfo(); // 这会触发用户信息请求
+
+ // 成功获取用户信息,跳转首页
+ uni.reLaunch({
+ url: '/pages/index'
+ });
+ } catch (error) {
+ // === 重点修复:精确处理 token 失效 ===
+ if (error.code === 401 ||
+ (error.message &&
+ (error.message.includes('会话过期') ||
+ error.message.includes('无效的会话')))) {
+
+ // 清除失效 token
+ uni.removeStorageSync('token');
+ uni.removeStorageSync('userInfo');
+ modal.alert('登录已过期,请重新登录');
+ }
+ getCaptcha(); // 重新加载验证码
+ }
+ } finally {
+ isChecking = false;
+ hasChecked = true;
}
- })
+ });
\ No newline at end of file
diff --git a/src/utils/auth.ts b/src/utils/auth.ts
index 7a2d227..dec6eeb 100644
--- a/src/utils/auth.ts
+++ b/src/utils/auth.ts
@@ -1,13 +1,78 @@
const TokenKey = 'App-Token'
-export function getToken():string {
- return uni.getStorageSync(TokenKey)
+/**
+ * 获取Token(兼容多平台,带错误处理)
+ * @returns string 空字符串表示无Token
+ */
+export function getToken(): string {
+ try {
+ // 优先使用uniapp API
+ const token = uni.getStorageSync(TokenKey)
+ // 处理非字符串场景(如存入了null/undefined)
+ return token ? String(token) : ''
+ } catch (error) {
+ // 兼容H5隐私模式/localStorage不可用场景
+ console.warn('获取Token失败:', error)
+ return ''
+ }
}
-export function setToken(token:string) {
- return uni.setStorageSync(TokenKey, token)
+/**
+ * 设置Token(兼容多平台,带错误处理)
+ * @param token 必须为字符串,非字符串会自动转换
+ * @returns boolean 是否设置成功
+ */
+export function setToken(token: string): boolean {
+ try {
+ if (typeof token !== 'string') {
+ console.warn('Token必须为字符串,已自动转换')
+ token = String(token)
+ }
+ uni.setStorageSync(TokenKey, token)
+ return true
+ } catch (error) {
+ console.error('设置Token失败:', error)
+ // H5兜底:尝试直接操作localStorage
+ if (process.env.VUE_APP_PLATFORM === 'h5' && typeof localStorage !== 'undefined') {
+ try {
+ localStorage.setItem(TokenKey, token)
+ return true
+ } catch (e) {
+ console.error('H5 localStorage设置失败:', e)
+ }
+ }
+ return false
+ }
}
-export function removeToken() {
- return uni.removeStorageSync(TokenKey)
+/**
+ * 移除Token(兼容多平台,带错误处理)
+ * @returns boolean 是否移除成功
+ */
+export function removeToken(): boolean {
+ try {
+ uni.removeStorageSync(TokenKey)
+ return true
+ } catch (error) {
+ console.error('移除Token失败:', error)
+ // H5兜底
+ if (process.env.VUE_APP_PLATFORM === 'h5' && typeof localStorage !== 'undefined') {
+ try {
+ localStorage.removeItem(TokenKey)
+ return true
+ } catch (e) {
+ console.error('H5 localStorage移除失败:', e)
+ }
+ }
+ return false
+ }
}
+
+/**
+ * 检查Token是否有效(辅助函数)
+ * @returns boolean
+ */
+export function hasValidToken(): boolean {
+ const token = getToken()
+ return !!token && token.trim() !== ''
+}
\ No newline at end of file
diff --git a/src/utils/request.ts b/src/utils/request.ts
index 6c4660c..1d92123 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -8,103 +8,101 @@ import useUserStore from '@/store/modules/user'
let timeout = 10000
const baseUrl = config.baseUrl
-const request = (config: RequestConfig): Promise> => {
- // 是否需要设置 token
- const isToken = (config.headers || {}).isToken === false
- config.header = config.header || {}
- if (getToken() && !isToken) {
- config.header['Authorization'] = 'Bearer ' + getToken()
- }
- // get请求映射params参数
- if (config.params) {
- let url = config.url + '?' + tansParams(config.params)
- url = url.slice(0, -1)
- config.url = url
- }
- return new Promise((resolve, reject) => {
- uni.request({
- method: config.method || 'GET',
- timeout: config.timeout || timeout,
- url: (config.baseUrl || baseUrl) + config.url,
- data: config.data,
- header: config.header,
- dataType: 'json'
- }).then(response => {
- /* let [error, res] = response
- if (error) {
- toast('后端接口连接异常')
- reject('后端接口连接异常')
- return
- } */
- const res = response
- const data: ResponseData = res.data as ResponseData
- const code = data.code || 200
- // @ts-ignore
- const msg: string = errorCode[code] || data.msg || errorCode['default']
- if (code === 401) {
- showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
- if (res.confirm) {
- useUserStore().logOut().then(res => {
- uni.reLaunch({ url: '/pages/login' })
- })
- }
- })
- reject('无效的会话,或者会话已过期,请重新登录。')
- } else if (code === 500) {
- toast(msg)
- reject('500')
- } else if (code !== 200) {
- toast(msg)
- reject(code)
- }
- resolve(data)
- })
- .catch(error => {
- // === 修复这里的问题 ===
- let message = '网络请求失败'
-
- // 安全地获取错误信息
- if (error) {
- // 小程序环境错误对象可能有不同的结构
- if (error.errMsg) {
- message = error.errMsg
- } else if (error.message) {
- message = error.message
- } else if (typeof error === 'string') {
- message = error
- }
- }
-
- // 安全地使用 includes 方法 - 添加类型检查
- if (message && typeof message === 'string') {
- if (message.includes('Network Error')) {
- message = '后端接口连接异常'
- } else if (message.includes('timeout')) {
- message = '系统接口请求超时'
- } else if (message.includes('Request failed with status code')) {
- message = '系统接口' + message.substr(message.length - 3) + '异常'
- }
- } else {
- // 如果 message 不是字符串,转换为字符串
- message = String(message || '未知错误')
- }
- toast(message)
- reject(error)
- })
- })
+const request = (config : RequestConfig) : Promise> => {
+ // 是否需要设置 token
+ const isToken = (config.headers || {}).isToken === false
+ config.header = config.header || {}
+ if (getToken() && !isToken) {
+ config.header['Authorization'] = 'Bearer ' + getToken()
+ }
+ // get请求映射params参数
+ if (config.params) {
+ let url = config.url + '?' + tansParams(config.params)
+ url = url.slice(0, -1)
+ config.url = url
+ }
+ return new Promise((resolve, reject) => {
+ uni.request({
+ method: config.method || 'GET',
+ timeout: config.timeout || timeout,
+ url: (config.baseUrl || baseUrl) + config.url,
+ data: config.data,
+ header: config.header,
+ dataType: 'json'
+ }).then(response => {
+ /* let [error, res] = response
+ if (error) {
+ toast('后端接口连接异常')
+ reject('后端接口连接异常')
+ return
+ } */
+ const res = response
+ const data : ResponseData = res.data as ResponseData
+ const code = data.code || 200
+ // @ts-ignore
+ const msg : string = errorCode[code] || data.msg || errorCode['default']
+ if (code === 401) {
+ showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
+ if (res.confirm) {
+ useUserStore().logOut().then(res => {
+ uni.reLaunch({ url: '/pages/login' })
+ })
+ }
+ })
+ reject('无效的会话,或者会话已过期,请重新登录。')
+ } else if (code === 500) {
+ toast(msg)
+ reject('500')
+ } else if (code !== 200) {
+ toast(msg)
+ reject(code)
+ }
+ resolve(data)
+ })
+ .catch(error => {
+ // === 修复这里的问题 ===
+ let message = '网络请求失败'
+
+
+ // === 重点修复:安全提取错误信息 ===
+ if (error && typeof error === 'object') {
+ // 优先使用后端返回的错误消息
+ if (error.data?.msg) message = error.data.msg;
+ // 小程序特有的错误结构
+ else if (error.errMsg) message = error.errMsg;
+ // 常规错误消息
+ else if (error.message) message = error.message;
+ } else if (typeof error === 'string') {
+ message = error;
+ }
+
+ // 特殊错误处理
+ if (message.includes('Network Error')) {
+ message = '网络连接异常';
+ } else if (message.includes('timeout')) {
+ message = '请求超时,请检查网络';
+ }
+
+ toast(message);
+
+ // === 关键:返回带code的错误对象 ===
+ const err = new Error(message);
+ err.code = error.statusCode || 500; // 保留HTTP状态码
+ reject(err);
+ })
+ })
+}
+export function postAction(url : string, data ?: any, isToken : boolean = true) {
+ return request({ data, url, method: 'POST', headers: { isToken }, })
+}
+export function getAction(url : string, params ?: any, isToken : boolean = true) {
+ return request({ params, url, method: 'GET', headers: { isToken }, })
+}
+export function putAction(url : string, data ?: any, isToken : boolean = true) {
+ return request({ data, url, method: 'PUT', headers: { isToken }, })
+}
+export function deleteAction(url : string, data ?: any, isToken : boolean = true) {
+ return request({ data, url, method: 'DELETE', headers: { isToken }, })
}
-export function postAction(url: string, data?: any, isToken: boolean = true) {
- return request({ data, url, method: 'POST', headers: { isToken }, })
-}
-export function getAction(url: string, params?: any, isToken: boolean = true) {
- return request({ params, url, method: 'GET', headers: { isToken }, })
-}
-export function putAction(url: string, data?: any, isToken: boolean = true) {
- return request({ data, url, method: 'PUT', headers: { isToken }, })
-}
-export function deleteAction(url: string, data?: any, isToken: boolean = true) {
- return request({ data, url, method: 'DELETE', headers: { isToken }, })
-}
-
-export default request
+export default request
\ No newline at end of file
diff --git a/src/vite.config.js b/src/vite.config.js
index 1d873bb..e84266a 100644
--- a/src/vite.config.js
+++ b/src/vite.config.js
@@ -25,4 +25,23 @@ export default defineConfig(() => {
}
}
}
-})
\ No newline at end of file
+})
+
+module.exports = {
+ configureWebpack: {
+ optimization: {
+ splitChunks: {
+ chunks: 'async', // 仅异步代码抽离
+ minSize: 20000, // 大于20KB才抽离
+ cacheGroups: {
+ commons: {
+ name: 'commons',
+ chunks: 'initial',
+ minChunks: 2, // 被引用2次以上抽离
+ priority: -10
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file