角色 保存
This commit is contained in:
@@ -44,13 +44,14 @@ function isLoginApi(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置全局 uni.request 拦截器,自动添加 X-Tenant-Id header
|
* 设置全局 uni.request 拦截器,自动添加 X-Tenant-Id header 和 Authorization token
|
||||||
|
* 确保每次请求后端都携带 token 进行身份验证
|
||||||
*/
|
*/
|
||||||
function setupRequestInterceptor() {
|
function setupRequestInterceptor() {
|
||||||
// 保存原始的 uni.request
|
// 保存原始的 uni.request
|
||||||
const originalRequest = uni.request
|
const originalRequest = uni.request
|
||||||
|
|
||||||
// 重写 uni.request,自动添加 tenantId
|
// 重写 uni.request,自动添加 tenantId 和 token
|
||||||
uni.request = function(options = {}) {
|
uni.request = function(options = {}) {
|
||||||
const { url, header = {}, method = 'GET', ...restOptions } = options
|
const { url, header = {}, method = 'GET', ...restOptions } = options
|
||||||
|
|
||||||
@@ -81,18 +82,37 @@ function setupRequestInterceptor() {
|
|||||||
newHeader['X-Tenant-Id'] = tenantId
|
newHeader['X-Tenant-Id'] = tenantId
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加 token(如果存在且未设置)
|
// 每次请求都自动添加 token(登录接口除外)
|
||||||
if (!newHeader['Authorization']) {
|
// 全局拦截器确保所有通过 uni.request 的请求都携带 token
|
||||||
|
if (!isLoginApi(url)) {
|
||||||
try {
|
try {
|
||||||
const token = uni.getStorageSync('backend-token') || ''
|
const token = uni.getStorageSync('backend-token') || ''
|
||||||
if (token) {
|
if (token) {
|
||||||
|
// 每次请求都添加 token 到 Authorization header
|
||||||
newHeader['Authorization'] = `Bearer ${token}`
|
newHeader['Authorization'] = `Bearer ${token}`
|
||||||
|
} else {
|
||||||
|
// 如果没有 token,移除可能存在的旧 Authorization header
|
||||||
|
delete newHeader['Authorization']
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('获取 token 失败:', e)
|
console.error('获取 token 失败:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加 roleName 和 scenario 到 header(从登录响应中获取)
|
||||||
|
try {
|
||||||
|
const roleName = uni.getStorageSync('backend-role-name') || ''
|
||||||
|
if (roleName) {
|
||||||
|
newHeader['X-Role-Name'] = roleName
|
||||||
|
}
|
||||||
|
const scenario = uni.getStorageSync('backend-scenario') || ''
|
||||||
|
if (scenario) {
|
||||||
|
newHeader['X-Scenario'] = scenario
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取 roleName 或 scenario 失败:', e)
|
||||||
|
}
|
||||||
|
|
||||||
// 统一使用 Promise 方式,确保正确返回响应
|
// 统一使用 Promise 方式,确保正确返回响应
|
||||||
// 这样无论调用方使用 await 还是回调,都能正常工作
|
// 这样无论调用方使用 await 还是回调,都能正常工作
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -132,7 +152,7 @@ function setupRequestInterceptor() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全局请求拦截器已设置,所有 uni.request 调用将自动添加 X-Tenant-Id header
|
// 全局请求拦截器已设置,所有 uni.request 调用将自动添加 X-Tenant-Id header 和 Authorization token
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function() {
|
export default async function() {
|
||||||
|
|||||||
@@ -61,6 +61,30 @@ function getToken() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 roleName(从本地存储)
|
||||||
|
*/
|
||||||
|
function getRoleName() {
|
||||||
|
try {
|
||||||
|
return uni.getStorageSync('backend-role-name') || ''
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取 roleName 失败:', e)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 scenario(从本地存储)
|
||||||
|
*/
|
||||||
|
function getScenario() {
|
||||||
|
try {
|
||||||
|
return uni.getStorageSync('backend-scenario') || ''
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取 scenario 失败:', e)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一的请求方法
|
* 统一的请求方法
|
||||||
* @param {Object} options - uni.request 的配置选项
|
* @param {Object} options - uni.request 的配置选项
|
||||||
@@ -99,16 +123,29 @@ export function request(options = {}) {
|
|||||||
...header
|
...header
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加 token(如果需要)
|
// 每次请求都自动添加 token(登录接口除外)
|
||||||
if (needToken) {
|
// 确保所有后端请求都携带 token 进行身份验证
|
||||||
|
if (needToken && !isLoginApi(fullUrl)) {
|
||||||
const token = getToken()
|
const token = getToken()
|
||||||
if (token) {
|
if (token) {
|
||||||
|
// 每次请求都添加 token 到 Authorization header
|
||||||
requestHeader['Authorization'] = `Bearer ${token}`
|
requestHeader['Authorization'] = `Bearer ${token}`
|
||||||
// 或者使用其他 header 名称,根据后端要求调整
|
} else {
|
||||||
// requestHeader['X-Token'] = token
|
// 如果没有 token,移除可能存在的旧 Authorization header
|
||||||
|
delete requestHeader['Authorization']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加 roleName 和 scenario 到 header(从登录响应中获取)
|
||||||
|
const roleName = getRoleName()
|
||||||
|
if (roleName) {
|
||||||
|
requestHeader['X-Role-Name'] = roleName
|
||||||
|
}
|
||||||
|
const scenario = getScenario()
|
||||||
|
if (scenario) {
|
||||||
|
requestHeader['X-Scenario'] = scenario
|
||||||
|
}
|
||||||
|
|
||||||
// 处理请求数据
|
// 处理请求数据
|
||||||
let requestData = { ...data }
|
let requestData = { ...data }
|
||||||
|
|
||||||
|
|||||||
@@ -52,9 +52,6 @@
|
|||||||
</view>
|
</view>
|
||||||
<text class="customer-name">{{ item.customerName }}</text>
|
<text class="customer-name">{{ item.customerName }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="ai-tag">
|
|
||||||
<text>以上内容由AI生成</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1635,7 +1635,8 @@
|
|||||||
// 构建查询参数对象(后端使用 @RequestParam,参数需要作为 URL 查询参数传递)
|
// 构建查询参数对象(后端使用 @RequestParam,参数需要作为 URL 查询参数传递)
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
current: this.serviceListPage.current,
|
current: this.serviceListPage.current,
|
||||||
size: this.serviceListPage.size
|
size: this.serviceListPage.size,
|
||||||
|
serviceStatus: '服务结束' // 默认搜索条件:服务结束
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加查询参数:所属销售姓名和客户姓名
|
// 添加查询参数:所属销售姓名和客户姓名
|
||||||
@@ -1654,17 +1655,40 @@
|
|||||||
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`)
|
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`)
|
||||||
.join('&');
|
.join('&');
|
||||||
|
|
||||||
|
// 调试:打印请求参数
|
||||||
|
console.log('服务记录查询参数:', JSON.stringify(queryParams));
|
||||||
|
console.log('查询字符串:', queryString);
|
||||||
|
|
||||||
// 后端使用 @RequestParam,参数需要作为 URL 查询参数传递
|
// 后端使用 @RequestParam,参数需要作为 URL 查询参数传递
|
||||||
const baseUrl = getApiUrl('/api/audioManagement/list');
|
const baseUrl = getApiUrl('/api/audioManagement/list');
|
||||||
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
||||||
|
|
||||||
|
// 获取认证信息
|
||||||
|
let tenantId = '';
|
||||||
|
let token = '';
|
||||||
|
try {
|
||||||
|
tenantId = uni.getStorageSync('backend-tenant-id') || '';
|
||||||
|
token = uni.getStorageSync('backend-token') || '';
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取认证信息失败:', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建请求头(参考接待页面的实现方式)
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
};
|
||||||
|
if (token) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
if (tenantId) {
|
||||||
|
headers['X-Tenant-Id'] = tenantId;
|
||||||
|
}
|
||||||
|
|
||||||
const res = await uni.request({
|
const res = await uni.request({
|
||||||
url,
|
url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {}, // POST 请求体为空,参数都在 URL 查询字符串中
|
data: {}, // POST 请求体为空,参数都在 URL 查询字符串中
|
||||||
header: {
|
header: headers,
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -75,9 +75,9 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 密码登录(改为调用后端 /api/sys/auth/login 接口)
|
* 密码登录(调用后端 /api/sys/auth/login 接口)
|
||||||
*/
|
*/
|
||||||
pwdLogin() {
|
async pwdLogin() {
|
||||||
if (!this.password.length) {
|
if (!this.password.length) {
|
||||||
this.focusPassword = true
|
this.focusPassword = true
|
||||||
return uni.showToast({
|
return uni.showToast({
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
return this.$refs.agreements.popup(this.pwdLogin)
|
return this.$refs.agreements.popup(this.pwdLogin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组装后端登录参数(根据后端 LoginRequest 约定,这里假定为 userName + password)
|
// 组装后端登录参数
|
||||||
const payload = {
|
const payload = {
|
||||||
userName: this.username,
|
userName: this.username,
|
||||||
password: this.password
|
password: this.password
|
||||||
@@ -109,79 +109,100 @@
|
|||||||
mask: true
|
mask: true
|
||||||
})
|
})
|
||||||
|
|
||||||
uni.request({
|
try {
|
||||||
url: getApiUrl('/api/sys/auth/login'),
|
// 使用 uni.request 直接调用登录接口(登录接口不需要 token)
|
||||||
method: 'POST',
|
const res = await new Promise((resolve, reject) => {
|
||||||
header: {
|
uni.request({
|
||||||
'Content-Type': 'application/json'
|
url: getApiUrl('/api/sys/auth/login'),
|
||||||
},
|
method: 'POST',
|
||||||
data: payload,
|
header: {
|
||||||
success: (res) => {
|
'Content-Type': 'application/json'
|
||||||
const body = res.data || {}
|
},
|
||||||
if (!body.success || !body.data) {
|
data: payload,
|
||||||
return uni.showToast({
|
success: resolve,
|
||||||
title: body.message || '登录失败',
|
fail: reject
|
||||||
icon: 'none',
|
|
||||||
duration: 3000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const loginData = body.data
|
|
||||||
// 持久化后端登录态,供后续接口使用
|
|
||||||
try {
|
|
||||||
uni.setStorageSync('backend-login-response', loginData)
|
|
||||||
uni.setStorageSync('backend-token', loginData.token || '')
|
|
||||||
uni.setStorageSync('backend-user-id', loginData.userId)
|
|
||||||
|
|
||||||
// 保存 tenantId(从 LoginResponse 中获取,后端 UserServiceImpl.login 从 user.getTenantId() 赋值)
|
|
||||||
// 后续所有请求会自动在 X-Tenant-Id header 中携带此值
|
|
||||||
if (loginData.tenantId) {
|
|
||||||
uni.setStorageSync('backend-tenant-id', loginData.tenantId)
|
|
||||||
console.log('[Login] tenantId 已保存:', loginData.tenantId)
|
|
||||||
} else {
|
|
||||||
console.warn('[Login] 登录响应中未包含 tenantId,后续请求可能失败')
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('缓存登录信息失败:', e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同步更新前端 store,保证“我的”页等能识别为已登录状态
|
|
||||||
try {
|
|
||||||
mutations.setUserInfo({
|
|
||||||
username: loginData.userName,
|
|
||||||
mobile: loginData.phone,
|
|
||||||
email: loginData.email,
|
|
||||||
avatar_file: loginData.avatar ? { url: loginData.avatar } : undefined
|
|
||||||
}, { cover: true })
|
|
||||||
} catch (e) {
|
|
||||||
console.error('更新本地用户信息失败:', e)
|
|
||||||
}
|
|
||||||
|
|
||||||
uni.showToast({
|
|
||||||
title: body.message || '登录成功',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 800
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// 登录成功后跳转到 tabBar 首页(接待页)
|
const body = res.data || {}
|
||||||
setTimeout(() => {
|
if (!body.success || !body.data) {
|
||||||
uni.switchTab({
|
return uni.showToast({
|
||||||
url: '/pages/reception/reception'
|
title: body.message || '登录失败',
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('调用登录接口失败:', err)
|
|
||||||
uni.showToast({
|
|
||||||
title: '网络异常,登录失败',
|
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
duration: 3000
|
duration: 3000
|
||||||
})
|
})
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
uni.hideLoading()
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
const loginData = body.data
|
||||||
|
|
||||||
|
// 保存 token(重要:后续所有请求会自动在 header 中携带此 token)
|
||||||
|
if (loginData.token) {
|
||||||
|
uni.setStorageSync('backend-token', loginData.token)
|
||||||
|
console.log('[Login] token 已保存,后续请求将自动在 header 中携带')
|
||||||
|
} else {
|
||||||
|
console.warn('[Login] 登录响应中未包含 token')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 持久化其他登录信息
|
||||||
|
try {
|
||||||
|
uni.setStorageSync('backend-login-response', loginData)
|
||||||
|
uni.setStorageSync('backend-user-id', loginData.userId)
|
||||||
|
|
||||||
|
// 保存 tenantId(后续所有请求会自动在 X-Tenant-Id header 中携带)
|
||||||
|
if (loginData.tenantId) {
|
||||||
|
uni.setStorageSync('backend-tenant-id', loginData.tenantId)
|
||||||
|
console.log('[Login] tenantId 已保存:', loginData.tenantId)
|
||||||
|
} else {
|
||||||
|
console.warn('[Login] 登录响应中未包含 tenantId,后续请求可能失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存 roleName 和 scenario,后续所有请求会自动在 header 中携带
|
||||||
|
if (loginData.roleName) {
|
||||||
|
uni.setStorageSync('backend-role-name', loginData.roleName)
|
||||||
|
console.log('[Login] roleName 已保存:', loginData.roleName)
|
||||||
|
}
|
||||||
|
if (loginData.scenario) {
|
||||||
|
uni.setStorageSync('backend-scenario', loginData.scenario)
|
||||||
|
console.log('[Login] scenario 已保存:', loginData.scenario)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('缓存登录信息失败:', e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步更新前端 store,保证"我的"页等能识别为已登录状态
|
||||||
|
try {
|
||||||
|
mutations.setUserInfo({
|
||||||
|
username: loginData.userName,
|
||||||
|
mobile: loginData.phone,
|
||||||
|
email: loginData.email,
|
||||||
|
avatar_file: loginData.avatar ? { url: loginData.avatar } : undefined
|
||||||
|
}, { cover: true })
|
||||||
|
} catch (e) {
|
||||||
|
console.error('更新本地用户信息失败:', e)
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.showToast({
|
||||||
|
title: body.message || '登录成功',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 800
|
||||||
|
})
|
||||||
|
|
||||||
|
// 登录成功后跳转到 tabBar 首页(接待页)
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/reception/reception'
|
||||||
|
})
|
||||||
|
}, 300)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('调用登录接口失败:', err)
|
||||||
|
uni.showToast({
|
||||||
|
title: '网络异常,登录失败',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
uni.hideLoading()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/* 前往注册 */
|
/* 前往注册 */
|
||||||
toRegister() {
|
toRegister() {
|
||||||
|
|||||||
Reference in New Issue
Block a user