需要修复商城顶部筛选左右滑动问题

This commit is contained in:
cbb
2025-12-24 17:53:13 +08:00
parent 6f418fae8a
commit b67f9611c7
48 changed files with 1067 additions and 221 deletions

View File

@@ -1,75 +1,81 @@
import { getToken, removeToken } from './storage';
import { getToken, removeToken } from './storage'
const BASE_URL = 'xxxxx'
const BASE_URL = 'http://c36bd4b4.natappfree.cc'
/**
* 网络请求封装
* @param {Object} options 请求参数
* @returns {Promise}
*/
const request = (options) => {
// 默认配置
const defaultOptions = {
url: '',
method: 'GET',
data: {},
header: {
'Content-Type': 'application/json' // 默认请求内容类型
}
}
const request = options => {
// 默认配置
const defaultOptions = {
url: '',
method: 'GET',
data: {},
header: {
'Content-Type': 'application/json' // 默认请求内容类型
}
}
// 合并配置
const config = { ...defaultOptions, ...options }
// 合并配置
const config = { ...defaultOptions, ...options }
// 请求拦截添加token等通用header
if (getToken()) {
config.header['Authorization'] = 'Bearer ' + getToken()
}
// 请求拦截添加token等通用header
if (getToken()) {
config.header['Authorization'] = 'Bearer ' + getToken()
}
// 显示加载状态(可选)
if (options.loading !== false) {
uni.showLoading({
title: '加载中...',
mask: true
})
};
// 显示加载状态(可选)
if (options.loading !== false) {
uni.showLoading({
title: '加载中...',
mask: true
})
}
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + config.url,
method: config.method,
data: config.data,
timeout: 10000, // 请求超时时间
header: config.header,
success: (response) => {
// 响应拦截:根据状态码处理
if (response.statusCode === 200) {
// 这里可以根据后端数据格式调整
// 例如if (response.data.code === 0) {...}
resolve(response.data)
} else {
// 状态码错误处理
handleError(response.statusCode, response.data)
reject(response)
}
},
fail: (error) => {
// 网络错误处理
uni.showToast({
title: '网络异常,请检查网络连接',
icon: 'none',
duration: 2000
})
reject(error)
},
complete: () => {
// 隐藏加载状态
if (options.loading !== false) {
uni.hideLoading()
}
}
})
})
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + config.url,
method: config.method,
data: config.data,
timeout: 10000, // 请求超时时间
header: config.header,
success: response => {
console.log(response)
// 响应拦截:根据状态码处理
if (response.statusCode === 200) {
// 这里可以根据后端数据格式调整
// 例如if (response.data.code === 0) {...}
if (response.data.code === 200) {
resolve(response.data)
} else {
handleError(response.data.code, response.data)
}
} else {
// 状态码错误处理
handleError(response.statusCode, response.data)
reject(response)
}
},
fail: error => {
// 网络错误处理
uni.showToast({
title: '网络异常,请检查网络连接',
icon: 'none',
duration: 2000,
mask: true
})
reject(error)
},
complete: () => {
// 隐藏加载状态
if (options.loading !== false) {
uni.hideLoading()
}
}
})
})
}
/**
@@ -78,49 +84,53 @@ const request = (options) => {
* @param {Object} data 响应数据
*/
const handleError = (statusCode, data) => {
switch (statusCode) {
case 401:
uni.showModal({
title: '提示',
content: '登录已过期,请重新登录',
showCancel: false,
success: () => {
// 清除本地存储的token并跳转到登录页
removeToken()
uni.navigateTo({
url: '/pages/login/index'
})
}
})
break
case 403:
uni.showToast({
title: '没有权限访问',
icon: 'none',
duration: 2000
})
break
case 404:
uni.showToast({
title: '请求资源不存在',
icon: 'none',
duration: 2000
})
break
case 500:
uni.showToast({
title: '服务器内部错误',
icon: 'none',
duration: 2000
})
break
default:
uni.showToast({
title: data.message || '请求失败,请重试',
icon: 'none',
duration: 2000
})
}
switch (statusCode) {
case 401:
uni.showModal({
title: '提示',
content: '登录已过期,请重新登录',
showCancel: false,
success: () => {
// 清除本地存储的token并跳转到登录页
removeToken()
uni.navigateTo({
url: '/pages/login/index'
})
}
})
break
case 403:
uni.showToast({
title: '没有权限访问',
icon: 'none',
duration: 2000,
mask: true
})
break
case 404:
uni.showToast({
title: '请求资源不存在',
icon: 'none',
duration: 2000,
mask: true
})
break
case 500:
uni.showToast({
title: data.msg || '服务器内部错误',
icon: 'none',
duration: 2000,
mask: true
})
break
default:
uni.showToast({
title: data.msg || '请求失败,请重试',
icon: 'none',
duration: 2000,
mask: true
})
}
}
export default request
export default request

View File

@@ -1,16 +1,31 @@
import { STORAGE_KEYS } from '@/constants/storage-keys'
/** 保存 token */
export const setToken = (v) => {
return uni.setStorageSync(STORAGE_KEYS.TOKEN, v)
export const setTokenData = v => {
return uni.setStorageSync(STORAGE_KEYS.TOKEN, v)
}
/** 获取 token */
export const getToken = () => {
return uni.getStorageSync(STORAGE_KEYS.TOKEN) || ''
return uni.getStorageSync(STORAGE_KEYS.TOKEN) || ''
}
/** 清楚 token */
export const removeToken = () => {
return uni.removeStorageSync(STORAGE_KEYS.TOKEN)
}
return uni.removeStorageSync(STORAGE_KEYS.TOKEN)
}
/** 保存用户信息 */
export const setUserInfoData = v => {
return uni.setStorageSync(STORAGE_KEYS.USER, JSON.stringify(v))
}
/** 获取用户信息 */
export const getUserInfoData = () => {
return uni.getStorageSync(STORAGE_KEYS.USER) || ''
}
/** 删除用户信息 */
export const removeUserInfoData = () => {
return uni.removeStorageSync(STORAGE_KEYS.USER)
}

View File

@@ -37,11 +37,14 @@ const showToast = (message, type = 'none', duration = 2000) => {
if (type === 'error') icon = 'error'
if (type === 'warning') icon = 'none'
uni.showToast({
title: message,
icon,
duration,
mask: true
return new Promise(resolve => {
uni.showToast({
title: message,
icon,
duration,
mask: true
})
setTimeout(() => resolve(), duration)
})
}

84
utils/validate.js Normal file
View File

@@ -0,0 +1,84 @@
// 正则
/** 手机号正则(中国大陆) */
const PHONE_REGEX = /^1[3-9]\d{9}$/
/** 邮箱正则 */
const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
/** 身份证号(简化版) */
const ID_CARD_REGEX = /(^\d{15}$)|(^\d{18}$)|(^\d{17}[\dXx]$)/
/** 密码强度至少8位包含数字和字母 */
const PASSWORD_REGEX = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/
/**
* 校验手机号
* @param {string} phone - 待校验的手机号
* @returns {{ valid: boolean, message: string }}
*/
export const validatePhone = phone => {
if (!phone) return { valid: false, message: '手机号不能为空' }
if (!PHONE_REGEX.test(phone)) {
return { valid: false, message: '手机号格式不正确' }
}
return { valid: true, message: '' }
}
/**
* 校验邮箱
* @param {string} email - 待校验的邮箱
* @returns {{ valid: boolean, message: string }}
*/
export const validateEmail = email => {
if (!email) return { valid: false, message: '邮箱不能为空' }
if (!EMAIL_REGEX.test(email)) {
return { valid: false, message: '邮箱格式不正确' }
}
return { valid: true, message: '' }
}
/**
* 校验密码强度
* @param {string} password - 待校验的密码
* @returns {{ valid: boolean, message: string }}
*/
export const validatePassword = password => {
if (!password) return { valid: false, message: '密码不能为空' }
if (password.length < 8) {
return { valid: false, message: '密码长度不能少于8位' }
}
if (!PASSWORD_REGEX.test(password)) {
return { valid: false, message: '密码需包含字母和数字' }
}
return { valid: true, message: '' }
}
/**
* 校验确认密码是否与原密码一致
* @param {string} password - 原始密码
* @param {string} confirmPassword - 确认密码
* @returns {{ valid: boolean, message: string }}
*/
export function validateConfirmPassword(password, confirmPassword) {
if (!confirmPassword) {
return { valid: false, message: '请再次输入密码' }
}
if (password !== confirmPassword) {
return { valid: false, message: '两次输入的密码不一致' }
}
return { valid: true, message: '' }
}
/**
* 校验身份证号(仅格式校验,不验证真实性)
* @param {string} idCard - 待校验的身份证号
* @returns {{ valid: boolean, message: string }}
*/
export const validateIdCard = idCard => {
if (!idCard) return { valid: false, message: '身份证号不能为空' }
if (!ID_CARD_REGEX.test(idCard)) {
return { valid: false, message: '身份证号格式不正确' }
}
return { valid: true, message: '' }
}