Compare commits

...

2 Commits

@ -1,14 +1,40 @@
import CryptoJS from 'crypto-js'
// 加密
const keyStr = '-mall4j-password' // 解密用的key
export function encrypt (word) {
const time = Date.now()
const key = CryptoJS.enc.Utf8.parse(keyStr)
const srcs = CryptoJS.enc.Utf8.parse(time + word) // 加密方式: 时间戳 + 密文
// 引入 CryptoJS 库
// CryptoJS 是一个流行的 JavaScript 加密库,提供多种加密算法,
// 包括 AES高级加密标准。它允许开发者在客户端对数据进行加密和解密。
import CryptoJS from 'crypto-js';
// 定义用于加密和解密的密钥
// keyStr 是一个固定的字符串,作为加密和解密时使用的密钥。
// 注意:在实际应用中,应确保密钥的安全性,避免硬编码或泄露。
const keyStr = '-mall4j-password'; // 解密用的key
/**
* 加密函数
* @param {string} word - 需要加密的明文字符串
* @returns {string} - 返回经过 AES 加密后的密文字符串
*/
export function encrypt(word) {
// 获取当前时间戳,用于生成唯一的加密内容前缀
// 这有助于防止相同的明文产生相同的密文,增加了安全性。
const time = Date.now();
// 将密钥字符串转换为字节数组 (WordArray),以便用于加密操作
// 使用 Utf8 编码来解析密钥字符串确保正确处理非ASCII字符。
const key = CryptoJS.enc.Utf8.parse(keyStr);
// 将时间戳与需要加密的文本连接起来,并将其转换为字节数组
// 同样使用 Utf8 编码来解析字符串,以确保正确处理所有字符。
const srcs = CryptoJS.enc.Utf8.parse(time + word); // 加密方式: 时间戳 + 密文
// 使用 AES 算法进行加密
// mode: ECB 表示使用电子密码本模式,这是一种简单的加密模式,但不适合加密大量数据或要求高安全性的场景。
// padding: Pkcs7 表示使用 PKCS#7 填充方案这是AES加密推荐的填充方式。
const encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.toString()
});
// 将加密后的结果转换为 Base64 字符串返回
// 这样可以方便地在网络上传输或存储加密数据。
return encrypted.toString();
}

@ -1,19 +1,44 @@
// 防抖 防止表单重复提交
/**
* 防抖函数 (Debounce Function)
* 用于限制某个函数在短时间内频繁触发时只执行一次
* 这对于防止表单重复提交搜索框输入触发等场景非常有用
* 因为它可以确保即使用户快速连续点击按钮或输入内容
* 相关操作也只会被执行一次直到经过一段设定的时间间隔后才会允许再次触发
*
* @param {Function} fn - 要防抖处理的目标函数
* @param {number} t - 可选参数指定等待的时间间隔毫秒默认为1000ms
* @returns {Function} - 返回一个新的函数该函数具有防抖行为
*/
export const Debounce = (fn, t) => {
const delay = t || 1000
let timer
// 设置默认延迟时间为1000毫秒1秒
const delay = t || 1000;
// 定义一个变量来保存定时器ID用于清除之前的定时器
let timer;
// 返回一个新函数,这个函数会替代原始函数被调用
return function () {
const args = arguments
// 保存当前函数调用的所有参数和上下文
const args = arguments;
const context = this;
// 如果之前有未完成的定时器,则清除它
if (timer) {
clearTimeout(timer)
clearTimeout(timer);
}
const callNow = !timer
// 检查是否是首次调用或上一次调用已经超过了设定的时间间隔
const callNow = !timer;
// 设置一个新的定时器在指定的延迟时间后将timer置为空
// 置空是为了下一次调用时能够正确判断是否立即执行目标函数
timer = setTimeout(() => {
timer = null
}, delay)
timer = null;
}, delay);
if (callNow) fn.apply(this, args)
}
}
// 如果是首次调用或者上一次调用已经超过了设定的时间间隔,则立即执行目标函数
if (callNow) {
fn.apply(context, args);
}
};
};

@ -1,190 +1,202 @@
import axios from 'axios'
import qs from 'qs'
import cookie from 'vue-cookies'
import router from '@/router'
import merge from 'lodash/merge'
import { clearLoginInfo } from '@/utils'
import { ElMessage } from 'element-plus'
// 引入必要的库和模块
import axios from 'axios'; // 用于发起HTTP请求
import qs from 'qs'; // 用于序列化查询参数
import cookie from 'vue-cookies'; // 用于管理cookie
import router from '@/router'; // 项目路由实例
import merge from 'lodash/merge'; // 用于合并对象
import { clearLoginInfo } from '@/utils'; // 清除登录信息的工具函数
import { ElMessage } from 'element-plus'; // Element Plus的消息提示组件
// 创建一个自定义的axios实例
const http = axios.create({
timeout: 1000 * 30,
withCredentials: true,
timeout: 1000 * 30, // 设置请求超时时间为30秒
withCredentials: true, // 允许跨域请求时携带凭证如Cookie
headers: {
'Content-Type': 'application/json; charset=utf-8'
'Content-Type': 'application/json; charset=utf-8' // 默认设置请求头为JSON格式
}
})
});
/**
* 请求拦截
* 请求拦截器
* 在每个请求发送之前执行可以在此处添加通用的请求头或处理请求参数等
*/
http.interceptors.request.use(
config => {
config.headers.Authorization = cookie.get('Authorization') // 请求头带上token
// 只针对get方式进行序列化
if (config.method === 'get' || config.method === 'GET') {
config.paramsSerializer = function (params) {
return qs.stringify(params, { arrayFormat: 'repeat' })
}
// 如果存在Authorization token则添加到请求头中
config.headers.Authorization = cookie.get('Authorization');
// 对GET请求进行参数序列化支持数组格式重复参数
if (config.method.toLowerCase() === 'get') {
config.paramsSerializer = params => qs.stringify(params, { arrayFormat: 'repeat' });
}
return config
return config;
},
error => {
return Promise.reject(error)
}
)
error => Promise.reject(error) // 捕获请求错误并返回拒绝的Promise
);
/**
* 响应拦截
* 响应拦截器
* 在接收到响应数据后执行可以根据响应状态码或自定义业务逻辑来处理响应
*/
http.interceptors.response.use(
response => {
// blob 格式处理
// 直接返回blob类型的响应数据
if (response.request.responseType === 'blob') {
return response
}
const res = response.data
// 00000 请求成功
if (res.code === '00000' || res.code === 'A00002') {
return res
}
// A00001 用于直接显示提示用户的错误,内容由输入决定
if (res.code === 'A00001') {
ElMessage({
message: res.msg || res.data || 'Error',
type: 'error',
duration: 1.5 * 1000
})
return Promise.reject(res)
}
// A00004 未授权
if (res.code === 'A00004') {
clearLoginInfo()
router.push({ name: 'login' })
return response;
}
// A00005 服务器异常
if (res.code === 'A00005') {
// eslint-disable-next-line no-console
console.error('============== 请求异常 ==============', '\n', `接口地址: ${response.config.url.replace(import.meta.env.VITE_APP_BASE_API, '')}`, '\n', `异常信息: ${res}`, '\n', '============== 请求异常 end ==========')
ElMessage({
message: '服务器出了点小差,请稍后再试',
type: 'error',
duration: 1.5 * 1000,
customClass: 'element-error-message-zindex'
})
return Promise.reject(res)
const res = response.data;
// 根据不同的响应码执行相应的操作
switch (res.code) {
case '00000': // 成功响应
case 'A00002': // 特定成功的响应码
return res;
case 'A00001': // 用户级错误消息
ElMessage({
message: res.msg || res.data || 'Error',
type: 'error',
duration: 1500
});
return Promise.reject(res);
case 'A00004': // 未授权
clearLoginInfo();
router.push({ name: 'login' });
break;
case 'A00005': // 服务器异常
console.error(`接口地址: ${response.config.url.replace(import.meta.env.VITE_APP_BASE_API, '')}`, '\n', `异常信息: ${res}`);
ElMessage({
message: '服务器出了点小差,请稍后再试',
type: 'error',
duration: 1500,
customClass: 'element-error-message-zindex'
});
return Promise.reject(res);
default:
return res;
}
},
error => {
// eslint-disable-next-line no-console
console.log('========请求失败========', '\n', error.response, '\n', '========请求失败 end========')
switch (error.response.status) {
case 400:
// 处理不同HTTP状态码的错误响应
console.log('请求失败:', error.response);
const status = error.response?.status;
switch (status) {
case 400: // 客户端错误
ElMessage({
message: error.response.data,
type: 'error',
duration: 1500,
customClass: 'element-error-message-zindex'
})
break
case 401:
clearLoginInfo()
router.push({ name: 'login' })
break
case 405:
});
break;
case 401: // 未授权
clearLoginInfo();
router.push({ name: 'login' });
break;
case 405: // 方法不允许
ElMessage({
message: 'http请求方式有误',
type: 'error',
duration: 1500,
customClass: 'element-error-message-zindex'
})
break
case 500:
});
break;
case 500: // 服务器内部错误
ElMessage({
message: '服务器出了点小差,请稍后再试',
type: 'error',
duration: 1500,
customClass: 'element-error-message-zindex'
})
break
case 501:
});
break;
case 501: // 服务器不支持当前请求功能
ElMessage({
message: '服务器不支持当前请求所需要的某个功能',
type: 'error',
duration: 1500,
customClass: 'element-error-message-zindex'
})
break
});
break;
}
return Promise.reject(error)
return Promise.reject(error);
}
)
);
/**
* 请求地址处理
* @param {*} actionName action方法名称
* @param {string} actionName - API方法名称
* @returns {string} - 完整的API请求URL
*/
http.adornUrl = actionName => {
return import.meta.env.VITE_APP_BASE_API + actionName
}
http.adornUrl = actionName => import.meta.env.VITE_APP_BASE_API + actionName;
/**
* im请求地址处理
* @param {*} actionName action方法名称
* IM请求地址处理
* @param {string} actionName - IM API方法名称
* @returns {string} - 完整的IM API请求URL
*/
http.adornImUrl = actionName => {
return import.meta.env.VITE_APP_IM_API + actionName
}
http.adornImUrl = actionName => import.meta.env.VITE_APP_IM_API + actionName;
/**
* im ws 请求地址处理
* @param {*} actionName action方法名称
* IM WebSocket请求地址处理
* @param {string} actionName - WebSocket IM API方法名称
* @returns {string} - 完整的WebSocket IM API请求URL
*/
http.adornWsImUrl = actionName => {
return import.meta.env.VITE_APP_WS_IM_API + actionName
}
http.adornWsImUrl = actionName => import.meta.env.VITE_APP_WS_IM_API + actionName;
/**
* get请求参数处理
* @param {*} params 参数对象
* @param {*} openDefultParams 是否开启默认参数?
* GET请求参数处理
* @param {Object} [params={}] - 参数对象
* @param {boolean} [openDefultParams=true] - 是否开启默认参数
* @returns {Object} - 处理后的参数对象
*/
http.adornParams = (params = {}, openDefultParams = true) => {
const defaults = {
t: Date.now()
}
return openDefultParams ? merge(defaults, params) : params
}
const defaults = { t: Date.now() }; // 添加时间戳以防止缓存
return openDefultParams ? merge(defaults, params) : params;
};
/**
* post请求数据处理
* @param {*} data 数据对象
* @param {*} openDefultdata 是否开启默认数据?
* @param {*} contentType 数据格式
* json: 'application/json; charset=utf-8'
* form: 'application/x-www-form-urlencoded; charset=utf-8'
* POST请求数据处理
* @param {Object} [data={}] - 数据对象
* @param {boolean} [openDefultdata=true] - 是否开启默认数据
* @param {string} [contentType='json'] - 数据格式'json' 'form'
* @returns {string|FormData} - 处理后的数据
*/
http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => {
const defaults = {
t: Date.now()
}
data = openDefultdata ? merge(defaults, data) : data
return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
}
const defaults = { t: Date.now() };
data = openDefultdata ? merge(defaults, data) : data;
// 根据contentType决定如何序列化数据
return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data);
};
/**
* 文件上传函数
* @param {string} url - 上传文件的目标URL
* @param {File} file - 要上传的文件
* @returns {Promise} - 返回上传结果的Promise
*/
const uploadFile = function (url, file) {
const config = {
// 添加请求头
headers: {
'Content-Type': 'multipart/form-data',
Authorization: cookie.get('Authorization') // 请求头带上token
Authorization: cookie.get('Authorization') // 添加token到请求头
}
}
const param = new FormData()
// 通过append向form对象添加数据
param.append('file', file)
return axios.post(url, param, config)
}
export default http
export { uploadFile }
};
const param = new FormData();
param.append('file', file); // 向FormData对象添加文件
return axios.post(url, param, config);
};
export default http;
export { uploadFile };

@ -1,109 +1,150 @@
import cookie from 'vue-cookies'
import router from '@/router'
import cookie from 'vue-cookies'; // 用于管理浏览器中的cookie
import router from '@/router'; // 引入Vue Router实例
/**
* 获取uuid
* 获取UUID通用唯一识别码
* @returns {string} - 返回一个随机生成的UUID字符串
*/
export function getUUID () {
export function getUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16)
})
// 使用位运算生成随机数,并根据'x'或'y'的不同生成不同的值
return (c === 'x' ? (Math.random() * 16) | 0 : ('r&0x3' | '0x8')).toString(16);
});
}
/**
* 是否有权限
* @param {*} key
* 检查用户是否有特定权限
* @param {string} key - 权限标识符
* @returns {boolean} - 如果用户有此权限则返回true否则返回false
*/
export function isAuth (key) {
const authorities = JSON.parse(sessionStorage.getItem('Authorities') || '[]')
export function isAuth(key) {
const authorities = JSON.parse(sessionStorage.getItem('Authorities') || '[]'); // 尝试从sessionStorage中获取用户权限列表
if (authorities.length) {
for (const i in authorities) {
const element = authorities[i]
const element = authorities[i];
if (element === key) {
return true
return true; // 如果找到匹配的权限则返回true
}
}
}
return false
return false; // 如果没有找到匹配的权限则返回false
}
/**
* 清除登录信息
*/
export function clearLoginInfo () {
cookie.remove('Authorization')
router.options.isAddDynamicMenuRoutes = false
export function clearLoginInfo() {
cookie.remove('Authorization'); // 移除存储在cookie中的授权token
router.options.isAddDynamicMenuRoutes = false; // 禁用动态路由添加功能
}
/**
* 树形数据转换
* @param {*} data
* @param {*} id
* @param {*} pid
* 将扁平的数据结构转换为树形结构
* @param {Array} data - 扁平化的数据数组
* @param {string} [id='id'] - 数据项ID字段名默认为'id'
* @param {string} [pid='parentId'] - 数据项父级ID字段名默认为'parentId'
* @returns {Array} - 转换后的树形数据结构
*/
export function treeDataTranslate (data, id = 'id', pid = 'parentId') {
const res = []
const temp = {}
export function treeDataTranslate(data, id = 'id', pid = 'parentId') {
const res = []; // 存储根节点
const temp = {}; // 临时对象,用于快速查找子节点
// 首先将所有元素存入temp对象中以它们的ID作为键
for (let i = 0; i < data.length; i++) {
temp[data[i][id]] = data[i]
temp[data[i][id]] = data[i];
}
// 再次遍历data数组构建树结构
for (let k = 0; k < data.length; k++) {
// 如果当前元素有父级元素且不是自身,则将其作为子元素加入到父元素下
if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
if (!temp[data[k][pid]].children) {
temp[data[k][pid]].children = []
temp[data[k][pid]].children = [];
}
if (!temp[data[k][pid]]._level) {
temp[data[k][pid]]._level = 1
temp[data[k][pid]]._level = 1;
}
data[k]._level = temp[data[k][pid]]._level + 1
temp[data[k][pid]].children.push(data[k])
data[k]._level = temp[data[k][pid]]._level + 1;
temp[data[k][pid]].children.push(data[k]);
} else {
res.push(data[k])
// 如果没有父级元素,则认为是根节点,直接加入到结果数组中
res.push(data[k]);
}
}
return res
return res;
}
function idListFromTree (data, val, res = [], id = 'id', children = 'children') {
/**
* 递归函数从树结构中提取指定ID路径
* @param {Array} data - 树形数据结构
* @param {any} val - 查找的目标ID
* @param {Array} [res=[]] - 存储找到的ID路径
* @param {string} [id='id'] - 数据项ID字段名默认为'id'
* @param {string} [children='children'] - 数据项子元素字段名默认为'children'
* @returns {boolean} - 是否找到了目标ID
*/
function idListFromTree(data, val, res = [], id = 'id', children = 'children') {
for (let i = 0; i < data.length; i++) {
const element = data[i]
if (element[children]) {
if (idListFromTree(element[children], val, res, id, children)) {
res.push(element[id])
return true
}
const element = data[i];
// 递归处理子元素
if (element[children] && idListFromTree(element[children], val, res, id, children)) {
res.push(element[id]); // 当找到目标时将当前节点ID加入路径
return true;
}
// 如果当前节点就是目标节点,直接加入路径并返回
if (element[id] === val) {
res.push(element[id])
return true
res.push(element[id]);
return true;
}
}
return false;
}
/**
* 将数组中的parentId列表取出倒序排列
* @param {Array} data - 树形数据结构
* @param {any} val - 查找的目标ID
* @param {string} [id='id'] - 数据项ID字段名默认为'id'
* @param {string} [children='children'] - 数据项子元素字段名默认为'children'
* @returns {Array} - 倒序排列的ID路径
*/
// eslint-disable-next-line no-unused-vars
export function idList (data, val, id = 'id', children = 'children') {
const res = []
idListFromTree(data, val, res, id)
return res
export function idList(data, val, id = 'id', children = 'children') {
const res = [];
idListFromTree(data, val, res, id, children); // 调用递归函数查找ID路径
return res.reverse(); // 返回倒序排列的结果
}
/**
* 文件地址校验
* @param fileUrl 获取到的文件路径
* 文件地址校验与处理
* @param {string|Array} fileUrl - 获取到的文件路径或文件路径数组
* @returns {string|Array} - 处理后的文件路径或路径数组
*/
export function checkFileUrl (fileUrl) {
if (fileUrl === '') return ''
const baseUrl = import.meta.env.VITE_APP_RESOURCES_URL
// 适配el-image 图片组件预览功能
if (fileUrl && typeof fileUrl === 'object') {
// eslint-disable-next-line no-return-assign
return fileUrl.map(el => el = checkFileUrl(el))
} else {
if (fileUrl && fileUrl.indexOf('http') === -1) {
return baseUrl + fileUrl
} else {
return fileUrl
}
export function checkFileUrl(fileUrl) {
if (fileUrl === '') return ''; // 如果输入为空字符串,直接返回空字符串
const baseUrl = import.meta.env.VITE_APP_RESOURCES_URL; // 获取资源基础URL
// 如果fileUrl是一个对象如el-image组件传递的对象则递归处理每个元素
if (fileUrl && typeof fileUrl === 'object' && !Array.isArray(fileUrl)) {
return Object.keys(fileUrl).reduce((acc, key) => {
acc[key] = checkFileUrl(fileUrl[key]);
return acc;
}, {});
}
// 如果fileUrl是数组则映射处理每个元素
if (Array.isArray(fileUrl)) {
return fileUrl.map(el => checkFileUrl(el));
}
// 对于单个文件路径如果它不是绝对路径则拼接基础URL
if (fileUrl && typeof fileUrl === 'string' && fileUrl.indexOf('http') === -1) {
return baseUrl + fileUrl;
}
return fileUrl; // 如果已经是绝对路径或无效路径,则直接返回原值
}

@ -1,102 +1,35 @@
/**
* 单位选项列表
* 此数组包含了多个对象每个对象代表一个可能的商品单位
* 用于在用户界面中提供选择比如商品库存管理订单录入等场景
* 每个对象都有两个属性
* - label: 显示给用户的文本标签
* - value: 实际存储或传递的数据值
*/
export const unitOption = [
{
lable: '件',
value: '件'
},
{
lable: '盒',
value: '盒'
},
{
lable: '箱',
value: '箱'
},
{
lable: '包',
value: '包'
},
{
lable: '瓶',
value: '瓶'
},
{
lable: '只',
value: '只'
},
{
lable: '千克',
value: '千克'
},
{
lable: '克',
value: '克'
},
{
lable: '斤',
value: '斤'
},
{
lable: '两',
value: '两'
},
{
lable: '双',
value: '双'
},
{
lable: '套',
value: '套'
},
{
lable: '对',
value: '对'
},
{
lable: '块',
value: '块'
},
{
lable: '台',
value: '台'
},
{
lable: '本',
value: '本'
},
{
lable: '把',
value: '把'
},
{
lable: '码',
value: '码'
},
{
lable: '捆',
value: '捆'
},
{
lable: '提',
value: '提'
},
{
lable: '杯',
value: '杯'
},
{
lable: '听',
value: '听'
},
{
lable: '条',
value: '条'
},
{
lable: '副',
value: '副'
},
{
lable: '顶',
value: '顶'
}
]
{ label: '件', value: '件' }, // 通用计数单位
{ label: '盒', value: '盒' }, // 适用于装在盒子中的物品
{ label: '箱', value: '箱' }, // 大量物品的包装单位
{ label: '包', value: '包' }, // 适用于包裹或小袋装的物品
{ label: '瓶', value: '瓶' }, // 适用于液体或粉末状物品
{ label: '只', value: '只' }, // 适用于单个独立物品,如手套、袜子等
{ label: '千克', value: '千克' }, // 重量单位1000克
{ label: '克', value: '克' }, // 较小的重量单位
{ label: '斤', value: '斤' }, // 传统中国重量单位等于500克
{ label: '两', value: '两' }, // 传统中国重量单位等于50克
{ label: '双', value: '双' }, // 适用于成对物品,如鞋子、筷子等
{ label: '套', value: '套' }, // 适用于一组或多件相关联的物品
{ label: '对', value: '对' }, // 适用于成对物品,类似“双”
{ label: '块', value: '块' }, // 适用于固体物品,如巧克力、石头等
{ label: '台', value: '台' }, // 适用于大型设备或机器
{ label: '本', value: '本' }, // 适用于书籍或其他装订成册的物品
{ label: '把', value: '把' }, // 适用于手持工具或武器
{ label: '码', value: '码' }, // 长度单位约等于0.9144米
{ label: '捆', value: '捆' }, // 适用于捆绑在一起的物品
{ label: '提', value: '提' }, // 适用于手提袋或携带方便的物品
{ label: '杯', value: '杯' }, // 适用于饮品或小容量容器
{ label: '听', value: '听' }, // 适用于罐装食品或饮料
{ label: '条', value: '条' }, // 适用于细长形物品,如鱼、香烟等
{ label: '副', value: '副' }, // 适用于眼镜、耳环等成对使用的物品
{ label: '顶', value: '顶' } // 适用于帽子、帐篷等覆盖物
];

@ -1,49 +1,69 @@
/**
* 邮箱
* @param {*} s
* 验证邮箱格式是否正确
* @param {string} s - 要验证的字符串
* @returns {boolean} - 如果符合标准邮箱格式则返回true否则返回false
*/
export function isEmail (s) {
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
export function isEmail(s) {
// 正则表达式用于匹配标准的电子邮件地址格式:
// - 用户名部分只能包含字母、数字、下划线或连字符
// - 域名部分同样只允许字母、数字、下划线或连字符
// - 域名后缀长度为2到3个字符并且可以有一个或两个层级例如.com, .co.uk
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s);
}
/**
* 手机号码
* @param {*} s
* 验证手机号码格式是否正确
* @param {string} s - 要验证的字符串
* @returns {boolean} - 如果符合中国大陆手机号码格式则返回true否则返回false
*/
export function isMobile (s) {
return /^1[0-9]{10}$/.test(s)
export function isMobile(s) {
// 正则表达式用于匹配中国大陆的手机号码:
// - 以1开头后面跟随10位数字
return /^1[0-9]{10}$/.test(s);
}
/**
* 电话号码
* @param {*} s
* 验证电话号码格式是否正确
* @param {string} s - 要验证的字符串
* @returns {boolean} - 如果符合固定电话号码格式则返回true否则返回false
*/
export function isPhone (s) {
return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
export function isPhone(s) {
// 正则表达式用于匹配中国大陆的固定电话号码:
// - 可选区号3到4位数字用短横线分隔
// - 主号码由7到8位数字组成
return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s);
}
/**
* URL地址
* @param {*} s
* 验证URL地址格式是否正确
* @param {string} s - 要验证的字符串
* @returns {boolean} - 如果符合标准URL格式则返回true否则返回false
*/
export function isURL (s) {
return /^http[s]?:\/\/.*/.test(s)
export function isURL(s) {
// 正则表达式用于匹配标准的URL地址
// - 开头必须是http:// 或 https://
// - 后面跟任意数量的字符
return /^http[s]?:\/\/.*/.test(s);
}
/**
* qq
* @param {*} s
* 验证QQ号码格式是否正确
* @param {string} s - 要验证的字符串
* @returns {boolean} - 如果符合QQ号码格式则返回true否则返回false
*/
export function isQq (s) {
return /[1-9][0-9]{4,14}/.test(s)
export function isQq(s) {
// 正则表达式用于匹配有效的QQ号码
// - QQ号码至少5位最多15位数字
// - 不能以0开头
return /^[1-9][0-9]{4,14}$/.test(s);
}
/**
* 判断是否全为空格 只要有一个其他字符返回false
* @param {String} str
* @returns {Boolean}
* 判断字符串是否全为空格只要有一个非空格字符即返回false
* @param {string} str - 要验证的字符串
* @returns {boolean} - 如果字符串全部为空格则返回true否则返回false
*/
export function validNoEmptySpace (str) {
const reg = /^\s+$/g
return reg.test(str)
export function validNoEmptySpace(str) {
const reg = /^\s+$/g; // 匹配整个字符串全是空白字符(包括空格、制表符等)的正则表达式
return reg.test(str); // 如果字符串完全匹配上述规则则返回true否则返回false
}

Loading…
Cancel
Save