wking-jie 2 months ago
commit fea70dcbe3

@ -1,14 +1,40 @@
import CryptoJS from 'crypto-js' // 引入 CryptoJS 库
// 加密 // CryptoJS 是一个流行的 JavaScript 加密库,提供多种加密算法,
const keyStr = '-mall4j-password' // 解密用的key // 包括 AES高级加密标准。它允许开发者在客户端对数据进行加密和解密。
export function encrypt (word) { import CryptoJS from 'crypto-js';
const time = Date.now()
// 定义用于加密和解密的密钥
const key = CryptoJS.enc.Utf8.parse(keyStr) // keyStr 是一个固定的字符串,作为加密和解密时使用的密钥。
const srcs = CryptoJS.enc.Utf8.parse(time + word) // 加密方式: 时间戳 + 密文 // 注意:在实际应用中,应确保密钥的安全性,避免硬编码或泄露。
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, { const encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode: CryptoJS.mode.ECB, mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7 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) => { export const Debounce = (fn, t) => {
const delay = t || 1000 // 设置默认延迟时间为1000毫秒1秒
let timer const delay = t || 1000;
// 定义一个变量来保存定时器ID用于清除之前的定时器
let timer;
// 返回一个新函数,这个函数会替代原始函数被调用
return function () { return function () {
const args = arguments // 保存当前函数调用的所有参数和上下文
const args = arguments;
const context = this;
// 如果之前有未完成的定时器,则清除它
if (timer) { if (timer) {
clearTimeout(timer) clearTimeout(timer);
} }
const callNow = !timer // 检查是否是首次调用或上一次调用已经超过了设定的时间间隔
const callNow = !timer;
// 设置一个新的定时器在指定的延迟时间后将timer置为空
// 置空是为了下一次调用时能够正确判断是否立即执行目标函数
timer = setTimeout(() => { timer = setTimeout(() => {
timer = null timer = null;
}, delay) }, 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 axios from 'axios'; // 用于发起HTTP请求
import cookie from 'vue-cookies' import qs from 'qs'; // 用于序列化查询参数
import router from '@/router' import cookie from 'vue-cookies'; // 用于管理cookie
import merge from 'lodash/merge' import router from '@/router'; // 项目路由实例
import { clearLoginInfo } from '@/utils' import merge from 'lodash/merge'; // 用于合并对象
import { ElMessage } from 'element-plus' import { clearLoginInfo } from '@/utils'; // 清除登录信息的工具函数
import { ElMessage } from 'element-plus'; // Element Plus的消息提示组件
// 创建一个自定义的axios实例
const http = axios.create({ const http = axios.create({
timeout: 1000 * 30, timeout: 1000 * 30, // 设置请求超时时间为30秒
withCredentials: true, withCredentials: true, // 允许跨域请求时携带凭证如Cookie
headers: { headers: {
'Content-Type': 'application/json; charset=utf-8' 'Content-Type': 'application/json; charset=utf-8' // 默认设置请求头为JSON格式
} }
}) });
/** /**
* 请求拦截 * 请求拦截器
* 在每个请求发送之前执行可以在此处添加通用的请求头或处理请求参数等
*/ */
http.interceptors.request.use( http.interceptors.request.use(
config => { config => {
config.headers.Authorization = cookie.get('Authorization') // 请求头带上token // 如果存在Authorization token则添加到请求头中
// 只针对get方式进行序列化 config.headers.Authorization = cookie.get('Authorization');
if (config.method === 'get' || config.method === 'GET') {
config.paramsSerializer = function (params) { // 对GET请求进行参数序列化支持数组格式重复参数
return qs.stringify(params, { arrayFormat: 'repeat' }) if (config.method.toLowerCase() === 'get') {
} config.paramsSerializer = params => qs.stringify(params, { arrayFormat: 'repeat' });
} }
return config
return config;
}, },
error => { error => Promise.reject(error) // 捕获请求错误并返回拒绝的Promise
return Promise.reject(error) );
}
)
/** /**
* 响应拦截 * 响应拦截器
* 在接收到响应数据后执行可以根据响应状态码或自定义业务逻辑来处理响应
*/ */
http.interceptors.response.use( http.interceptors.response.use(
response => { response => {
// blob 格式处理 // 直接返回blob类型的响应数据
if (response.request.responseType === 'blob') { if (response.request.responseType === 'blob') {
return response return response;
}
const res = response.data
// 00000 请求成功
if (res.code === '00000' || res.code === 'A00002') {
return res
} }
// A00001 用于直接显示提示用户的错误,内容由输入决定
if (res.code === 'A00001') { const res = response.data;
// 根据不同的响应码执行相应的操作
switch (res.code) {
case '00000': // 成功响应
case 'A00002': // 特定成功的响应码
return res;
case 'A00001': // 用户级错误消息
ElMessage({ ElMessage({
message: res.msg || res.data || 'Error', message: res.msg || res.data || 'Error',
type: 'error', type: 'error',
duration: 1.5 * 1000 duration: 1500
}) });
return Promise.reject(res) return Promise.reject(res);
}
// A00004 未授权
if (res.code === 'A00004') {
clearLoginInfo()
router.push({ name: 'login' })
}
// A00005 服务器异常 case 'A00004': // 未授权
if (res.code === 'A00005') { clearLoginInfo();
// eslint-disable-next-line no-console router.push({ name: 'login' });
console.error('============== 请求异常 ==============', '\n', `接口地址: ${response.config.url.replace(import.meta.env.VITE_APP_BASE_API, '')}`, '\n', `异常信息: ${res}`, '\n', '============== 请求异常 end ==========') break;
case 'A00005': // 服务器异常
console.error(`接口地址: ${response.config.url.replace(import.meta.env.VITE_APP_BASE_API, '')}`, '\n', `异常信息: ${res}`);
ElMessage({ ElMessage({
message: '服务器出了点小差,请稍后再试', message: '服务器出了点小差,请稍后再试',
type: 'error', type: 'error',
duration: 1.5 * 1000, duration: 1500,
customClass: 'element-error-message-zindex' customClass: 'element-error-message-zindex'
}) });
return Promise.reject(res) return Promise.reject(res);
default:
return res;
} }
}, },
error => { error => {
// eslint-disable-next-line no-console // 处理不同HTTP状态码的错误响应
console.log('========请求失败========', '\n', error.response, '\n', '========请求失败 end========') console.log('请求失败:', error.response);
switch (error.response.status) { const status = error.response?.status;
case 400:
switch (status) {
case 400: // 客户端错误
ElMessage({ ElMessage({
message: error.response.data, message: error.response.data,
type: 'error', type: 'error',
duration: 1500, duration: 1500,
customClass: 'element-error-message-zindex' customClass: 'element-error-message-zindex'
}) });
break break;
case 401:
clearLoginInfo() case 401: // 未授权
router.push({ name: 'login' }) clearLoginInfo();
break router.push({ name: 'login' });
case 405: break;
case 405: // 方法不允许
ElMessage({ ElMessage({
message: 'http请求方式有误', message: 'http请求方式有误',
type: 'error', type: 'error',
duration: 1500, duration: 1500,
customClass: 'element-error-message-zindex' customClass: 'element-error-message-zindex'
}) });
break break;
case 500:
case 500: // 服务器内部错误
ElMessage({ ElMessage({
message: '服务器出了点小差,请稍后再试', message: '服务器出了点小差,请稍后再试',
type: 'error', type: 'error',
duration: 1500, duration: 1500,
customClass: 'element-error-message-zindex' customClass: 'element-error-message-zindex'
}) });
break break;
case 501:
case 501: // 服务器不支持当前请求功能
ElMessage({ ElMessage({
message: '服务器不支持当前请求所需要的某个功能', message: '服务器不支持当前请求所需要的某个功能',
type: 'error', type: 'error',
duration: 1500, duration: 1500,
customClass: 'element-error-message-zindex' 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 => { http.adornUrl = actionName => import.meta.env.VITE_APP_BASE_API + actionName;
return import.meta.env.VITE_APP_BASE_API + actionName
}
/** /**
* im请求地址处理 * IM请求地址处理
* @param {*} actionName action方法名称 * @param {string} actionName - IM API方法名称
* @returns {string} - 完整的IM API请求URL
*/ */
http.adornImUrl = actionName => { http.adornImUrl = actionName => import.meta.env.VITE_APP_IM_API + actionName;
return import.meta.env.VITE_APP_IM_API + actionName
}
/** /**
* im ws 请求地址处理 * IM WebSocket请求地址处理
* @param {*} actionName action方法名称 * @param {string} actionName - WebSocket IM API方法名称
* @returns {string} - 完整的WebSocket IM API请求URL
*/ */
http.adornWsImUrl = actionName => { http.adornWsImUrl = actionName => import.meta.env.VITE_APP_WS_IM_API + actionName;
return import.meta.env.VITE_APP_WS_IM_API + actionName
}
/** /**
* get请求参数处理 * GET请求参数处理
* @param {*} params 参数对象 * @param {Object} [params={}] - 参数对象
* @param {*} openDefultParams 是否开启默认参数? * @param {boolean} [openDefultParams=true] - 是否开启默认参数
* @returns {Object} - 处理后的参数对象
*/ */
http.adornParams = (params = {}, openDefultParams = true) => { http.adornParams = (params = {}, openDefultParams = true) => {
const defaults = { const defaults = { t: Date.now() }; // 添加时间戳以防止缓存
t: Date.now() return openDefultParams ? merge(defaults, params) : params;
} };
return openDefultParams ? merge(defaults, params) : params
}
/** /**
* post请求数据处理 * POST请求数据处理
* @param {*} data 数据对象 * @param {Object} [data={}] - 数据对象
* @param {*} openDefultdata 是否开启默认数据? * @param {boolean} [openDefultdata=true] - 是否开启默认数据
* @param {*} contentType 数据格式 * @param {string} [contentType='json'] - 数据格式'json' 'form'
* json: 'application/json; charset=utf-8' * @returns {string|FormData} - 处理后的数据
* form: 'application/x-www-form-urlencoded; charset=utf-8'
*/ */
http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => { http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => {
const defaults = { const defaults = { t: Date.now() };
t: Date.now() data = openDefultdata ? merge(defaults, data) : data;
}
data = openDefultdata ? merge(defaults, data) : data // 根据contentType决定如何序列化数据
return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data) 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 uploadFile = function (url, file) {
const config = { const config = {
// 添加请求头
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
Authorization: cookie.get('Authorization') // 请求头带上token Authorization: cookie.get('Authorization') // 添加token到请求头
}
} }
const param = new FormData() };
// 通过append向form对象添加数据 const param = new FormData();
param.append('file', file) param.append('file', file); // 向FormData对象添加文件
return axios.post(url, param, config) return axios.post(url, param, config);
} };
export default http export default http;
export { uploadFile } export { uploadFile };

@ -1,109 +1,150 @@
import cookie from 'vue-cookies' import cookie from 'vue-cookies'; // 用于管理浏览器中的cookie
import router from '@/router' 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 '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) { export function isAuth(key) {
const authorities = JSON.parse(sessionStorage.getItem('Authorities') || '[]') const authorities = JSON.parse(sessionStorage.getItem('Authorities') || '[]'); // 尝试从sessionStorage中获取用户权限列表
if (authorities.length) { if (authorities.length) {
for (const i in authorities) { for (const i in authorities) {
const element = authorities[i] const element = authorities[i];
if (element === key) { if (element === key) {
return true return true; // 如果找到匹配的权限则返回true
} }
} }
} }
return false return false; // 如果没有找到匹配的权限则返回false
} }
/** /**
* 清除登录信息 * 清除登录信息
*/ */
export function clearLoginInfo () { export function clearLoginInfo() {
cookie.remove('Authorization') cookie.remove('Authorization'); // 移除存储在cookie中的授权token
router.options.isAddDynamicMenuRoutes = false router.options.isAddDynamicMenuRoutes = false; // 禁用动态路由添加功能
} }
/** /**
* 树形数据转换 * 树形数据转换
* @param {*} data * 将扁平的数据结构转换为树形结构
* @param {*} id * @param {Array} data - 扁平化的数据数组
* @param {*} pid * @param {string} [id='id'] - 数据项ID字段名默认为'id'
* @param {string} [pid='parentId'] - 数据项父级ID字段名默认为'parentId'
* @returns {Array} - 转换后的树形数据结构
*/ */
export function treeDataTranslate (data, id = 'id', pid = 'parentId') { export function treeDataTranslate(data, id = 'id', pid = 'parentId') {
const res = [] const res = []; // 存储根节点
const temp = {} const temp = {}; // 临时对象,用于快速查找子节点
// 首先将所有元素存入temp对象中以它们的ID作为键
for (let i = 0; i < data.length; i++) { 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++) { for (let k = 0; k < data.length; k++) {
// 如果当前元素有父级元素且不是自身,则将其作为子元素加入到父元素下
if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) { if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
if (!temp[data[k][pid]].children) { if (!temp[data[k][pid]].children) {
temp[data[k][pid]].children = [] temp[data[k][pid]].children = [];
} }
if (!temp[data[k][pid]]._level) { 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 data[k]._level = temp[data[k][pid]]._level + 1;
temp[data[k][pid]].children.push(data[k]) temp[data[k][pid]].children.push(data[k]);
} else { } 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++) { for (let i = 0; i < data.length; i++) {
const element = data[i] const element = data[i];
if (element[children]) {
if (idListFromTree(element[children], val, res, id, children)) { // 递归处理子元素
res.push(element[id]) if (element[children] && idListFromTree(element[children], val, res, id, children)) {
return true res.push(element[id]); // 当找到目标时将当前节点ID加入路径
} return true;
} }
// 如果当前节点就是目标节点,直接加入路径并返回
if (element[id] === val) { if (element[id] === val) {
res.push(element[id]) res.push(element[id]);
return true return true;
} }
} }
return false;
} }
/** /**
* 将数组中的parentId列表取出倒序排列 * 将数组中的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') {
export function idList (data, val, id = 'id', children = 'children') { const res = [];
const res = [] idListFromTree(data, val, res, id, children); // 调用递归函数查找ID路径
idListFromTree(data, val, res, id) return res.reverse(); // 返回倒序排列的结果
return res
} }
/** /**
* 文件地址校验 * 文件地址校验与处理
* @param fileUrl 获取到的文件路径 * @param {string|Array} fileUrl - 获取到的文件路径或文件路径数组
* @returns {string|Array} - 处理后的文件路径或路径数组
*/ */
export function checkFileUrl (fileUrl) { export function checkFileUrl(fileUrl) {
if (fileUrl === '') return '' if (fileUrl === '') return ''; // 如果输入为空字符串,直接返回空字符串
const baseUrl = import.meta.env.VITE_APP_RESOURCES_URL
// 适配el-image 图片组件预览功能 const baseUrl = import.meta.env.VITE_APP_RESOURCES_URL; // 获取资源基础URL
if (fileUrl && typeof fileUrl === 'object') {
// eslint-disable-next-line no-return-assign // 如果fileUrl是一个对象如el-image组件传递的对象则递归处理每个元素
return fileUrl.map(el => el = checkFileUrl(el)) if (fileUrl && typeof fileUrl === 'object' && !Array.isArray(fileUrl)) {
} else { return Object.keys(fileUrl).reduce((acc, key) => {
if (fileUrl && fileUrl.indexOf('http') === -1) { acc[key] = checkFileUrl(fileUrl[key]);
return baseUrl + fileUrl return acc;
} else { }, {});
return fileUrl
} }
// 如果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 = [ export const unitOption = [
{ { label: '件', value: '件' }, // 通用计数单位
lable: '件', { label: '盒', value: '盒' }, // 适用于装在盒子中的物品
value: '件' { label: '箱', value: '箱' }, // 大量物品的包装单位
}, { label: '包', value: '包' }, // 适用于包裹或小袋装的物品
{ { label: '瓶', value: '瓶' }, // 适用于液体或粉末状物品
lable: '盒', { label: '只', value: '只' }, // 适用于单个独立物品,如手套、袜子等
value: '盒' { label: '千克', value: '千克' }, // 重量单位1000克
}, { label: '克', value: '克' }, // 较小的重量单位
{ { label: '斤', value: '斤' }, // 传统中国重量单位等于500克
lable: '箱', { label: '两', value: '两' }, // 传统中国重量单位等于50克
value: '箱' { label: '双', value: '双' }, // 适用于成对物品,如鞋子、筷子等
}, { label: '套', value: '套' }, // 适用于一组或多件相关联的物品
{ { label: '对', value: '对' }, // 适用于成对物品,类似“双”
lable: '包', { label: '块', value: '块' }, // 适用于固体物品,如巧克力、石头等
value: '包' { label: '台', value: '台' }, // 适用于大型设备或机器
}, { label: '本', value: '本' }, // 适用于书籍或其他装订成册的物品
{ { label: '把', value: '把' }, // 适用于手持工具或武器
lable: '瓶', { label: '码', value: '码' }, // 长度单位约等于0.9144米
value: '瓶' { label: '捆', value: '捆' }, // 适用于捆绑在一起的物品
}, { label: '提', value: '提' }, // 适用于手提袋或携带方便的物品
{ { label: '杯', value: '杯' }, // 适用于饮品或小容量容器
lable: '只', { label: '听', value: '听' }, // 适用于罐装食品或饮料
value: '只' { label: '条', value: '条' }, // 适用于细长形物品,如鱼、香烟等
}, { label: '副', value: '副' }, // 适用于眼镜、耳环等成对使用的物品
{ { label: '顶', 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: '顶'
}
]

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

Loading…
Cancel
Save