完善生产查询与登录权限配置
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
import config from '@/config/index.js'
|
||||
|
||||
function buildUrl(url, baseURL = config.baseURL) {
|
||||
const normalizedBaseURL = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL
|
||||
const path = url.startsWith('/') ? url : `/${url}`
|
||||
return `${normalizedBaseURL}${path}`
|
||||
}
|
||||
|
||||
function getNetworkErrorMessage(error) {
|
||||
const errorMessage = String(error?.errMsg || '')
|
||||
if (errorMessage.toLowerCase().includes('timeout')) {
|
||||
return '请求超时,请稍后重试'
|
||||
}
|
||||
return '无法连接服务器,请检查网络后重试'
|
||||
}
|
||||
|
||||
function getHeaders(headers = {}, includeJsonContentType = true) {
|
||||
const token = uni.getStorageSync(config.tokenKey)
|
||||
const result = {
|
||||
...(includeJsonContentType ? { 'Content-Type': 'application/json' } : {}),
|
||||
[config.channelHeaderKey]: config.channel,
|
||||
...headers
|
||||
}
|
||||
|
||||
if (token) {
|
||||
result[config.tokenHeaderKey] = String(token).startsWith('Bearer ') ? token : `Bearer ${token}`
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
async function refreshAccessToken() {
|
||||
const refreshToken = uni.getStorageSync('scanapp_refresh_token')
|
||||
if (!refreshToken) return ''
|
||||
const response = await uniRequest('/auth/refresh', 'POST', { refresh_token: refreshToken }, {
|
||||
baseURL: config.apiBaseURL,
|
||||
showError: false
|
||||
})
|
||||
const accessToken = response?.access_token
|
||||
if (!accessToken) return ''
|
||||
uni.setStorageSync(config.tokenKey, accessToken)
|
||||
if (response.refresh_token) uni.setStorageSync('scanapp_refresh_token', response.refresh_token)
|
||||
return accessToken
|
||||
}
|
||||
|
||||
function uniRequest(url, method, data = {}, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const requestUrl = buildUrl(url, options.baseURL || config.baseURL)
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
method,
|
||||
data,
|
||||
header: getHeaders(options.headers),
|
||||
timeout: options.timeout || 15000,
|
||||
success: (res) => {
|
||||
let body = res.data || {}
|
||||
if (typeof body === 'string') {
|
||||
try { body = JSON.parse(body) } catch { body = { msg: body } }
|
||||
}
|
||||
if (Number(body.code) === 0) {
|
||||
resolve(body.data)
|
||||
return
|
||||
}
|
||||
reject(new Error(body.msg || '请求失败'))
|
||||
},
|
||||
fail: () => reject(new Error('网络请求失败'))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function request(url, method, data = {}, options = {}) {
|
||||
const baseURL = options.baseURL || config.baseURL
|
||||
return new Promise((resolve, reject) => {
|
||||
const requestUrl = buildUrl(url, baseURL)
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
method,
|
||||
data,
|
||||
header: getHeaders(options.headers),
|
||||
timeout: options.timeout || 15000,
|
||||
success: async (res) => {
|
||||
let body = res.data || {}
|
||||
if (typeof body === 'string') {
|
||||
try {
|
||||
body = JSON.parse(body)
|
||||
} catch (error) {
|
||||
body = { msg: body }
|
||||
}
|
||||
}
|
||||
|
||||
if (Number(body.code) === 401 && !options._retry) {
|
||||
try {
|
||||
const token = await refreshAccessToken()
|
||||
if (token) {
|
||||
resolve(request(url, method, data, { ...options, _retry: true }))
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[scanapp] 刷新登录令牌失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
if (Number(body.code) === 0) {
|
||||
resolve(options.returnFullResponse ? body : body.data)
|
||||
return
|
||||
}
|
||||
|
||||
const message = body.msg || `请求失败(HTTP ${res.statusCode || 0},code ${body.code ?? 'unknown'})`
|
||||
console.error('[scanapp] 请求失败', {
|
||||
url: requestUrl,
|
||||
statusCode: res.statusCode,
|
||||
code: body.code,
|
||||
message,
|
||||
body
|
||||
})
|
||||
if (options.showError !== false) {
|
||||
uni.showToast({ title: message, icon: 'none' })
|
||||
}
|
||||
reject(new Error(message))
|
||||
},
|
||||
fail: (error) => {
|
||||
const message = getNetworkErrorMessage(error)
|
||||
console.error('[scanapp] 网络请求失败', {
|
||||
url: requestUrl,
|
||||
rawMessage: error?.errMsg,
|
||||
message,
|
||||
error
|
||||
})
|
||||
if (options.showError !== false) {
|
||||
uni.showToast({ title: message, icon: 'none' })
|
||||
}
|
||||
reject(new Error(message))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function uploadFile(url, filePath, formData = {}, options = {}) {
|
||||
const baseURL = options.baseURL || config.baseURL
|
||||
return new Promise((resolve, reject) => {
|
||||
const requestUrl = buildUrl(url, baseURL)
|
||||
const token = uni.getStorageSync(config.tokenKey)
|
||||
const header = getHeaders(options.headers, false)
|
||||
if (token) {
|
||||
header[config.tokenHeaderKey] = String(token).startsWith('Bearer ') ? token : `Bearer ${token}`
|
||||
}
|
||||
|
||||
uni.uploadFile({
|
||||
url: requestUrl,
|
||||
filePath,
|
||||
name: options.name || 'file',
|
||||
formData,
|
||||
header,
|
||||
timeout: options.timeout || 30000,
|
||||
success: (res) => {
|
||||
let body = res.data || {}
|
||||
if (typeof body === 'string') {
|
||||
try {
|
||||
body = JSON.parse(body)
|
||||
} catch (error) {
|
||||
body = { msg: body }
|
||||
}
|
||||
}
|
||||
|
||||
if (Number(body.code) === 0) {
|
||||
resolve(options.returnFullResponse ? body : body.data)
|
||||
return
|
||||
}
|
||||
|
||||
const message = body.msg || `上传失败(HTTP ${res.statusCode || 0},code ${body.code ?? 'unknown'})`
|
||||
if (options.showError !== false) {
|
||||
uni.showToast({ title: message, icon: 'none' })
|
||||
}
|
||||
reject(new Error(message))
|
||||
},
|
||||
fail: (error) => {
|
||||
const message = getNetworkErrorMessage(error)
|
||||
if (options.showError !== false) {
|
||||
uni.showToast({ title: message, icon: 'none' })
|
||||
}
|
||||
reject(new Error(message))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
get(url, data = {}, options = {}) {
|
||||
return request(url, 'GET', data, options)
|
||||
},
|
||||
post(url, data = {}, options = {}) {
|
||||
return request(url, 'POST', data, options)
|
||||
},
|
||||
put(url, data = {}, options = {}) {
|
||||
return request(url, 'PUT', data, options)
|
||||
},
|
||||
delete(url, data = {}, options = {}) {
|
||||
return request(url, 'DELETE', data, options)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
const DEFAULT_SCAN_REGION = {
|
||||
width: 0.96,
|
||||
height: 0.24,
|
||||
centerX: 0.5,
|
||||
centerY: 0.5
|
||||
}
|
||||
|
||||
const clamp = (value, min, max, fallback) => {
|
||||
const number = Number(value)
|
||||
return Number.isFinite(number) ? Math.max(min, Math.min(max, number)) : fallback
|
||||
}
|
||||
|
||||
export function getScanappUserCodes() {
|
||||
const user = uni.getStorageSync('scanapp_user') || {}
|
||||
const codes = [user.username, user.nickname, user.id, user.userId, user.uid, 'U001']
|
||||
return codes.filter((code, index) => code !== undefined && code !== null && code !== '' && codes.indexOf(code) === index).map(String)
|
||||
}
|
||||
|
||||
export function getScanappUserCode() {
|
||||
return getScanappUserCodes()[0]
|
||||
}
|
||||
|
||||
export function getScanappSettingsStorageKey() {
|
||||
return `scanapp_settings_${getScanappUserCode()}`
|
||||
}
|
||||
|
||||
export function getScanappSettings() {
|
||||
for (const userCode of getScanappUserCodes()) {
|
||||
const userSettings = uni.getStorageSync(`scanapp_settings_${userCode}`)
|
||||
if (userSettings && typeof userSettings === 'object') return userSettings
|
||||
}
|
||||
const legacySettings = uni.getStorageSync('scanapp_settings')
|
||||
return legacySettings && typeof legacySettings === 'object' ? legacySettings : {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取当前用户的有效识别区域设置,供所有业务扫码入口统一使用。
|
||||
*/
|
||||
export function getScanRegionSetting() {
|
||||
const settings = getScanappSettings()
|
||||
if (!settings.scanRegionPreset && !settings.scanRegion) return {}
|
||||
if (settings.scanRegionPreset === 'fullscreen' || (!settings.scanRegionPreset && settings.scanRegion?.fullScreen === true)) {
|
||||
return { fullScreen: true }
|
||||
}
|
||||
|
||||
const region = settings.scanRegion || {}
|
||||
const width = clamp(region.width, 0.1, 1, DEFAULT_SCAN_REGION.width)
|
||||
const height = clamp(region.height, 0.1, 1, DEFAULT_SCAN_REGION.height)
|
||||
const centerX = clamp(region.centerX, 0, 1, DEFAULT_SCAN_REGION.centerX)
|
||||
const minCenterY = Math.min(0.5, height / 2)
|
||||
const centerY = clamp(region.centerY, minCenterY, 1 - minCenterY, DEFAULT_SCAN_REGION.centerY)
|
||||
return { width, height, centerX, centerY }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
const THEME_MODE_STORAGE_KEY = 'scanapp_theme_mode'
|
||||
|
||||
export function getAppThemeMode() {
|
||||
return uni.getStorageSync(THEME_MODE_STORAGE_KEY) === 'dark' ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
export function applyAppTheme(mode) {
|
||||
const themeMode = mode === 'dark' ? 'dark' : 'light'
|
||||
uni.setStorageSync(THEME_MODE_STORAGE_KEY, themeMode)
|
||||
uni.setNavigationBarColor({
|
||||
frontColor: themeMode === 'dark' ? '#ffffff' : '#000000',
|
||||
backgroundColor: themeMode === 'dark' ? '#151923' : '#ffffff'
|
||||
})
|
||||
uni.$emit('scanapp-theme-change', themeMode)
|
||||
return themeMode
|
||||
}
|
||||
Reference in New Issue
Block a user