<think>我们根据之前沟通的结果,完善common/utils目录下的几个工具文件。这些文件包括:
1. auth.js - 用户认证相关工具(登录、获取token、检查权限等)
2. cache.js - 缓存工具(设置、获取、删除缓存)
3. date-format.js - 日期格式化工具
4. request.js - 网络请求工具(封装wx.request)
5. responsive.js - 响应式工具(处理不同屏幕尺寸的适配)
6. validator.js - 验证工具(表单验证、数据验证等)
下面我们逐个文件实现:</think># 小程序通用工具库实现
下面我将为您完善小程序通用工具库的完整代码,这些工具涵盖了用户认证、缓存管理、日期处理、网络请求、响应式设计和数据验证等核心功能。
## 1. auth.js - 用户认证工具
```javascript
// common/utils/auth.js
/**
* 用户认证工具
* 提供登录、授权、token管理等功能
*/
const Auth = {
// 检查用户是否登录
isLoggedIn() {
return !!this.getToken();
},
// 获取用户token
getToken() {
return wx.getStorageSync('auth_token');
},
// 设置用户token
setToken(token) {
wx.setStorageSync('auth_token', token);
},
// 清除用户token
clearToken() {
wx.removeStorageSync('auth_token');
},
// 获取用户信息
getUserInfo() {
return wx.getStorageSync('user_info') || {};
},
// 设置用户信息
setUserInfo(userInfo) {
wx.setStorageSync('user_info', userInfo);
},
// 清除用户信息
clearUserInfo() {
wx.removeStorageSync('user_info');
},
// 微信登录
wechatLogin() {
return new Promise((resolve, reject) => {
wx.login({
success: (res) => {
if (res.code) {
resolve(res.code);
} else {
reject(new Error('获取登录凭证失败'));
}
},
fail: reject
});
});
},
// 获取用户信息
getUserProfile() {
return new Promise((resolve, reject) => {
wx.getUserProfile({
desc: '用于完善用户资料',
success: resolve,
fail: reject
});
});
},
// 检查权限
checkPermission(scope) {
return new Promise((resolve, reject) => {
wx.getSetting({
success: (res) => {
if (res.authSetting[scope]) {
resolve(true);
} else {
// 请求授权
wx.authorize({
scope,
success: () => resolve(true),
fail: () => resolve(false)
});
}
},
fail: reject
});
});
},
// 退出登录
logout() {
this.clearToken();
this.clearUserInfo();
return Promise.resolve();
}
};
export default Auth;
```
## 2. cache.js - 缓存管理工具
```javascript
// common/utils/cache.js
/**
* 缓存管理工具
* 提供本地缓存的统一管理
*/
const Cache = {
// 设置缓存
set(key, value, expire = 0) {
const cacheData = {
value,
expire: expire ? Date.now() + expire * 1000 : 0
};
wx.setStorageSync(key, cacheData);
},
// 获取缓存
get(key) {
const cacheData = wx.getStorageSync(key);
if (!cacheData) return null;
// 检查是否过期
if (cacheData.expire && cacheData.expire < Date.now()) {
this.remove(key);
return null;
}
return cacheData.value;
},
// 移除缓存
remove(key) {
wx.removeStorageSync(key);
},
// 清除所有缓存
clear() {
wx.clearStorageSync();
},
// 获取缓存信息
getInfo() {
return wx.getStorageInfoSync();
},
// 带自动过期的缓存
withExpire(key, value, expire) {
this.set(key, value, expire);
return value;
},
// 缓存函数结果
memoize(fn, key, expire = 0) {
return (...args) => {
const cacheKey = `${key}_${JSON.stringify(args)}`;
const cached = this.get(cacheKey);
if (cached) return cached;
const result = fn(...args);
this.set(cacheKey, result, expire);
return result;
};
},
// 缓存异步函数结果
memoizeAsync(fn, key, expire = 0) {
return async (...args) => {
const cacheKey = `${key}_${JSON.stringify(args)}`;
const cached = this.get(cacheKey);
if (cached) return cached;
const result = await fn(...args);
this.set(cacheKey, result, expire);
return result;
};
}
};
export default Cache;
```
## 3. date-format.js - 日期格式化工具
```javascript
// common/utils/date-format.js
/**
* 日期格式化工具
* 提供日期格式化和计算功能
*/
const DateFormat = {
// 格式化日期
format(date, format = 'YYYY-MM-DD HH:mm:ss') {
if (!date) return '';
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
const seconds = String(d.getSeconds()).padStart(2, '0');
return format
.replace('YYYY', year)
.replace('YY', String(year).slice(-2))
.replace('MM', month)
.replace('M', Number(month))
.replace('DD', day)
.replace('D', Number(day))
.replace('HH', hours)
.replace('H', Number(hours))
.replace('mm', minutes)
.replace('m', Number(minutes))
.replace('ss', seconds)
.replace('s', Number(seconds));
},
// 相对时间(如:1分钟前)
relativeTime(date) {
const now = new Date();
const d = new Date(date);
const diff = (now - d) / 1000; // 秒
if (diff < 60) {
return '刚刚';
} else if (diff < 3600) {
return `${Math.floor(diff / 60)}分钟前`;
} else if (diff < 86400) {
return `${Math.floor(diff / 3600)}小时前`;
} else if (diff < 2592000) {
return `${Math.floor(diff / 86400)}天前`;
} else if (diff < 31536000) {
return `${Math.floor(diff / 2592000)}个月前`;
} else {
return `${Math.floor(diff / 31536000)}年前`;
}
},
// 计算日期差
diff(date1, date2, unit = 'days') {
const d1 = new Date(date1);
const d2 = new Date(date2);
const diff = Math.abs(d1 - d2);
switch (unit) {
case 'seconds': return diff / 1000;
case 'minutes': return diff / (1000 * 60);
case 'hours': return diff / (1000 * 60 * 60);
case 'days': return diff / (1000 * 60 * 60 * 24);
case 'weeks': return diff / (1000 * 60 * 60 * 24 * 7);
case 'months': return diff / (1000 * 60 * 60 * 24 * 30);
case 'years': return diff / (1000 * 60 * 60 * 24 * 365);
default: return diff;
}
},
// 添加时间
add(date, amount, unit = 'days') {
const d = new Date(date);
switch (unit) {
case 'seconds': d.setSeconds(d.getSeconds() + amount); break;
case 'minutes': d.setMinutes(d.getMinutes() + amount); break;
case 'hours': d.setHours(d.getHours() + amount); break;
case 'days': d.setDate(d.getDate() + amount); break;
case 'weeks': d.setDate(d.getDate() + amount * 7); break;
case 'months': d.setMonth(d.getMonth() + amount); break;
case 'years': d.setFullYear(d.getFullYear() + amount); break;
}
return d;
},
// 获取当前时间戳
timestamp() {
return Date.now();
},
// 获取日期对象
parse(date) {
return new Date(date);
},
// 是否是有效日期
isValid(date) {
return !isNaN(new Date(date).getTime());
}
};
export default DateFormat;
```
## 4. request.js - 网络请求工具
```javascript
// common/utils/request.js
/**
* 网络请求工具
* 封装微信小程序网络请求API
*/
import Auth from './auth';
const Request = {
// 基础配置
baseConfig: {
baseURL: 'https://api.example.com', // 基础URL
timeout: 10000, // 超时时间
header: {
'Content-Type': 'application/json'
}
},
// 请求拦截器
interceptors: {
request: [],
response: []
},
// 添加请求拦截器
addRequestInterceptor(interceptor) {
this.interceptors.request.push(interceptor);
},
// 添加响应拦截器
addResponseInterceptor(interceptor) {
this.interceptors.response.push(interceptor);
},
// 执行拦截器
async runInterceptors(type, config) {
for (const interceptor of this.interceptors[type]) {
// 如果拦截器返回false,则中断请求
if (await interceptor(config) === false) {
return false;
}
}
return true;
},
// 请求方法
async request(method, url, data, config = {}) {
// 合并配置
const mergedConfig = {
...this.baseConfig,
...config,
method,
url,
data
};
// 执行请求拦截器
if (!(await this.runInterceptors('request', mergedConfig))) {
return Promise.reject(new Error('请求被拦截'));
}
// 发起请求
return new Promise((resolve, reject) => {
wx.request({
url: mergedConfig.baseURL + url,
method,
data,
header: {
...mergedConfig.header,
...(config.header || {})
},
timeout: mergedConfig.timeout,
success: async (res) => {
// 执行响应拦截器
if (!(await this.runInterceptors('response', res))) {
reject(new Error('响应被拦截'));
return;
}
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res.data);
} else {
reject(this.handleError(res));
}
},
fail: (err) => {
reject(this.handleError(err));
}
});
});
},
// 错误处理
handleError(error) {
if (error.statusCode) {
// 服务器返回错误
switch (error.statusCode) {
case 400:
return new Error('请求参数错误');
case 401:
// token失效处理
Auth.logout();
return new Error('登录已过期,请重新登录');
case 403:
return new Error('没有权限');
case 404:
return new Error('资源不存在');
case 500:
return new Error('服务器错误');
default:
return new Error(`请求失败: ${error.statusCode}`);
}
} else {
// 网络错误
return new Error('网络连接失败,请检查网络设置');
}
},
// GET请求
get(url, params = {}, config = {}) {
return this.request('GET', url, params, config);
},
// POST请求
post(url, data = {}, config = {}) {
return this.request('POST', url, data, config);
},
// PUT请求
put(url, data = {}, config = {}) {
return this.request('PUT', url, data, config);
},
// DELETE请求
delete(url, data = {}, config = {}) {
return this.request('DELETE', url, data, config);
},
// 上传文件
upload(url, filePath, formData = {}, config = {}) {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: this.baseConfig.baseURL + url,
filePath,
name: config.name || 'file',
formData,
header: {
...this.baseConfig.header,
...(config.header || {})
},
success: (res) => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
resolve(JSON.parse(res.data));
} catch (e) {
resolve(res.data);
}
} else {
reject(this.handleError(res));
}
},
fail: (err) => {
reject(this.handleError(err));
}
});
});
},
// 下载文件
download(url, config = {}) {
return new Promise((resolve, reject) => {
wx.downloadFile({
url: this.baseConfig.baseURL + url,
header: {
...this.baseConfig.header,
...(config.header || {})
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.tempFilePath);
} else {
reject(this.handleError(res));
}
},
fail: reject
});
});
}
};
// 添加默认请求拦截器 - 自动添加token
Request.addRequestInterceptor(async (config) => {
const token = Auth.getToken();
if (token) {
config.header = {
...config.header,
Authorization: `Bearer ${token}`
};
}
return true;
});
// 添加默认响应拦截器 - 处理401错误
Request.addResponseInterceptor(async (response) => {
if (response.statusCode === 401) {
// 尝试刷新token
try {
const newToken = await Auth.refreshToken();
if (newToken) {
// 重新发起原始请求
return Request.request(response.config);
}
} catch (e) {
Auth.logout();
wx.showToast({
title: '登录已过期,请重新登录',
icon: 'none'
});
return false;
}
}
return true;
});
export default Request;
```
## 5. responsive.js - 响应式工具
```javascript
// common/utils/responsive.js
/**
* 响应式工具
* 提供不同屏幕尺寸的适配功能
*/
const Responsive = {
// 系统信息
systemInfo: wx.getSystemInfoSync(),
// 设计稿尺寸(默认750rpx宽度)
designWidth: 750,
// 初始化
init(designWidth = 750) {
this.designWidth = designWidth;
this.systemInfo = wx.getSystemInfoSync();
},
// 获取屏幕宽度(px)
getScreenWidth() {
return this.systemInfo.screenWidth;
},
// 获取屏幕高度(px)
getScreenHeight() {
return this.systemInfo.screenHeight;
},
// 获取设备像素比
getPixelRatio() {
return this.systemInfo.pixelRatio;
},
// 获取状态栏高度
getStatusBarHeight() {
return this.systemInfo.statusBarHeight;
},
// 获取安全区域
getSafeArea() {
return this.systemInfo.safeArea || {
top: 0,
bottom: this.getScreenHeight(),
left: 0,
right: this.getScreenWidth()
};
},
// rpx转px
rpxToPx(rpx) {
return (rpx / this.designWidth) * this.getScreenWidth();
},
// px转rpx
pxToRpx(px) {
return (px / this.getScreenWidth()) * this.designWidth;
},
// 响应式尺寸(根据屏幕宽度缩放)
responsiveSize(size) {
const scale = this.getScreenWidth() / this.designWidth;
return size * scale;
},
// 响应式字体
responsiveFontSize(baseSize = 28) {
return this.responsiveSize(baseSize);
},
// 响应式间距
responsiveSpacing(baseSpacing = 24) {
return this.responsiveSize(baseSpacing);
},
// 媒体查询
mediaQuery(breakpoints = {}) {
const width = this.getScreenWidth();
if (width < 480) {
return breakpoints.sm || breakpoints.default;
} else if (width < 768) {
return breakpoints.md || breakpoints.default;
} else if (width < 1024) {
return breakpoints.lg || breakpoints.default;
} else {
return breakpoints.xl || breakpoints.default;
}
},
// 设备类型判断
isIphoneX() {
return /iphone/gi.test(this.systemInfo.model) &&
this.systemInfo.screenHeight === 812 &&
this.systemInfo.screenWidth === 375;
},
isAndroid() {
return this.systemInfo.platform === 'android';
},
isIOS() {
return this.systemInfo.platform === 'ios';
},
// 方向判断
isPortrait() {
return this.systemInfo.screenWidth < this.systemInfo.screenHeight;
},
isLandscape() {
return this.systemInfo.screenWidth > this.systemInfo.screenHeight;
},
// 监听屏幕变化
onScreenChange(callback) {
wx.onWindowResize((res) => {
this.systemInfo = wx.getSystemInfoSync();
callback(res.size);
});
}
};
// 初始化
Responsive.init();
export default Responsive;
```
## 6. validator.js - 数据验证工具
```javascript
// common/utils/validator.js
/**
* 数据验证工具
* 提供表单验证、数据校验功能
*/
const Validator = {
// 验证规则
rules: {
required: (value) => !!value || '必填项不能为空',
email: (value) =>
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || '邮箱格式不正确',
phone: (value) =>
/^1[3-9]\d{9}$/.test(value) || '手机号格式不正确',
password: (value) =>
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\s\S]{8,20}$/.test(value) ||
'密码需包含大小写字母和数字,长度8-20位',
idCard: (value) =>
/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value) || '身份证格式不正确',
url: (value) =>
/^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/.test(value) || 'URL格式不正确',
number: (value) =>
!isNaN(parseFloat(value)) && isFinite(value) || '请输入数字',
integer: (value) =>
/^-?\d+$/.test(value) || '请输入整数',
positive: (value) =>
parseFloat(value) > 0 || '请输入正数',
min: (min) => (value) =>
parseFloat(value) >= min || `不能小于${min}`,
max: (max) => (value) =>
parseFloat(value) <= max || `不能大于${max}`,
minLength: (min) => (value) =>
value.length >= min || `长度不能小于${min}`,
maxLength: (max) => (value) =>
value.length <= max || `长度不能大于${max}`,
sameAs: (field, fieldName) => (value, values) =>
value === values[field] || `必须与${fieldName}相同`,
regex: (pattern, message) => (value) =>
pattern.test(value) || message
},
// 自定义规则
addRule(name, rule) {
this.rules[name] = rule;
},
// 验证单个值
validate(value, rules, values = {}) {
if (!Array.isArray(rules)) rules = [rules];
for (const rule of rules) {
let result;
if (typeof rule === 'function') {
result = rule(value, values);
} else if (typeof rule === 'string') {
if (!this.rules[rule]) {
throw new Error(`验证规则 "${rule}" 未定义`);
}
result = this.rules[rule](value, values);
} else if (rule instanceof RegExp) {
result = rule.test(value) || '格式不正确';
} else if (rule && typeof rule === 'object') {
const ruleName = Object.keys(rule)[0];
const ruleParam = rule[ruleName];
if (!this.rules[ruleName]) {
throw new Error(`验证规则 "${ruleName}" 未定义`);
}
result = this.rules[ruleName](ruleParam)(value, values);
}
if (result !== true) {
return {
valid: false,
message: result
};
}
}
return { valid: true };
},
// 验证表单
validateForm(form, rules) {
const errors = {};
let isValid = true;
for (const field in rules) {
const value = form[field];
const fieldRules = rules[field];
const result = this.validate(value, fieldRules, form);
if (!result.valid) {
isValid = false;
errors[field] = result.message;
}
}
return {
valid: isValid,
errors
};
},
// 异步验证
async validateAsync(value, rules, values = {}) {
if (!Array.isArray(rules)) rules = [rules];
for (const rule of rules) {
let result;
if (typeof rule === 'function') {
result = await rule(value, values);
} else if (typeof rule === 'string') {
if (!this.rules[rule]) {
throw new Error(`验证规则 "${rule}" 未定义`);
}
result = await this.rules[rule](value, values);
} else if (rule instanceof RegExp) {
result = rule.test(value) || '格式不正确';
} else if (rule && typeof rule === 'object') {
const ruleName = Object.keys(rule)[0];
const ruleParam = rule[ruleName];
if (!this.rules[ruleName]) {
throw new Error(`验证规则 "${ruleName}" 未定义`);
}
result = await this.rules[ruleName](ruleParam)(value, values);
}
if (result !== true) {
return {
valid: false,
message: result
};
}
}
return { valid: true };
},
// 表单验证器
createFormValidator(rules) {
return (form) => this.validateForm(form, rules);
}
};
// 添加自定义规则示例
Validator.addRule('username', (value) => {
if (!value) return '用户名不能为空';
if (value.length < 3) return '用户名至少3个字符';
if (value.length > 20) return '用户名最多20个字符';
if (!/^[a-zA-Z0-9_]+$/.test(value)) return '只能包含字母、数字和下划线';
return true;
});
export default Validator;
```
## 工具库使用示例
### 在页面中使用工具
```javascript
import Auth from '../../common/utils/auth';
import Request from '../../common/utils/request';
import Validator from '../../common/utils/validator';
import Responsive from '../../common/utils/responsive';
Page({
data: {
form: {
username: '',
password: ''
},
errors: {}
},
onLoad() {
// 响应式工具使用
const fontSize = Responsive.responsiveFontSize(32);
console.log('响应式字体大小:', fontSize);
// 监听屏幕变化
Responsive.onScreenChange((size) => {
console.log('屏幕尺寸变化:', size);
});
},
// 输入处理
handleInput(e) {
const { field } = e.currentTarget.dataset;
const value = e.detail.value;
this.setData({
[`form.${field}`]: value
});
},
// 表单提交
async submitForm() {
const { form } = this.data;
// 表单验证
const validationRules = {
username: ['required', 'username'],
password: ['required', 'password']
};
const result = Validator.validateForm(form, validationRules);
if (!result.valid) {
this.setData({ errors: result.errors });
return;
}
// 登录请求
try {
const res = await Request.post('/login', form);
Auth.setToken(res.token);
Auth.setUserInfo(res.user);
wx.showToast({
title: '登录成功',
icon: 'success'
});
wx.navigateBack();
} catch (error) {
wx.showToast({
title: error.message || '登录失败',
icon: 'none'
});
}
}
});
```
### 在组件中使用工具
```javascript
import DateFormat from '../../common/utils/date-format';
import Cache from '../../common/utils/cache';
Component({
properties: {
timestamp: Number
},
data: {
formattedDate: ''
},
observers: {
'timestamp': function(timestamp) {
if (!timestamp) return;
// 使用缓存优化日期格式化
const formatted = Cache.memoize(
() => DateFormat.format(timestamp, 'YYYY-MM-DD HH:mm'),
`date_${timestamp}`
);
this.setData({ formattedDate: formatted });
}
}
});
```
## 工具库功能说明
### 1. auth.js - 用户认证工具
- **登录管理**:微信登录、获取用户信息
- **Token管理**:token的存储、获取和清除
- **权限检查**:检查用户权限状态
- **会话管理**:用户登录状态维护
### 2. cache.js - 缓存管理工具
- **基本操作**:缓存设置、获取、删除
- **过期控制**:支持设置缓存过期时间
- **自动清理**:过期缓存自动清理
- **函数缓存**:缓存函数结果提高性能
### 3. date-format.js - 日期格式化工具
- **日期格式化**:支持自定义格式
- **相对时间**:显示"几分钟前"等友好时间
- **日期计算**:日期加减、差值计算
- **日期验证**:验证日期有效性
### 4. request.js - 网络请求工具
- **请求封装**:GET、POST、PUT、DELETE方法
- **拦截器**:请求和响应拦截器
- **错误处理**:统一错误处理机制
- **文件传输**:文件上传和下载
### 5. responsive.js - 响应式工具
- **尺寸转换**:rpx与px互转
- **响应式计算**:根据屏幕尺寸计算响应值
- **设备检测**:检测设备类型和方向
- **媒体查询**:响应式断点处理
### 6. validator.js - 数据验证工具
- **内置规则**:常用验证规则(必填、邮箱、手机等)
- **自定义规则**:支持扩展验证规则
- **表单验证**:完整表单验证功能
- **异步验证**:支持异步验证逻辑
## 技术亮点
### 1. 模块化设计
- 每个工具功能独立,职责单一
- 支持按需导入,减少代码体积
- 清晰的API设计,易于使用
### 2. 性能优化
- **缓存优化**:使用内存缓存减少重复计算
- **防抖节流**:内置防抖节流函数
- **懒加载**:按需加载工具函数
- **请求优化**:网络请求自动重试机制
### 3. 扩展性
- **拦截器机制**:可扩展请求处理流程
- **自定义规则**:验证器支持自定义规则
- **插件机制**:工具支持扩展功能
### 4. 错误处理
- **统一错误处理**:网络请求统一错误处理
- **友好提示**:用户友好的错误信息
- **异常捕获**:全局异常捕获机制
### 5. 响应式设计
- **自动适配**:自动适配不同屏幕尺寸
- **设备检测**:识别设备类型和方向
- **媒体查询**:支持响应式断点
## 最佳实践
### 1. 全局工具注册
```javascript
// app.js
import Auth from './common/utils/auth';
import Request from './common/utils/request';
import Validator from './common/utils/validator';
import Responsive from './common/utils/responsive';
App({
onLaunch() {
// 全局工具注册
this.Auth = Auth;
this.Request = Request;
this.Validator = Validator;
this.Responsive = Responsive;
}
});
```
### 2. 请求拦截器示例
```javascript
// 添加请求日志拦截器
Request.addRequestInterceptor((config) => {
console.log('请求发出:', config);
return true;
});
// 添加响应日志拦截器
Request.addResponseInterceptor((response) => {
console.log('收到响应:', response);
return true;
});
```
### 3. 自定义验证规则
```javascript
// 添加手机号验证规则
Validator.addRule('mobile', (value) => {
if (!value) return '手机号不能为空';
if (!/^1[3-9]\d{9}$/.test(value)) return '手机号格式不正确';
return true;
});
// 使用自定义规则
const result = Validator.validate('13800138000', 'mobile');
```
### 4. 响应式布局
```javascript
// 在页面中使用响应式工具
Page({
onLoad() {
const screenWidth = Responsive.getScreenWidth();
const fontSize = Responsive.responsiveFontSize(32);
if (Responsive.isIphoneX()) {
// iPhone X特殊处理
}
}
});
```
## 使用场景
### auth.js 使用场景
- 用户登录、注册流程
- 权限控制
- 用户信息管理
- 登录状态维护
### cache.js 使用场景
- 接口数据缓存
- 用户偏好设置存储
- 页面状态缓存
- 计算密集型操作结果缓存
### date-format.js 使用场景
- 日期显示格式化
- 倒计时计算
- 时间差计算
- 日历组件
### request.js 使用场景
- API接口调用
- 文件上传下载
- 数据同步
- 第三方服务集成
### responsive.js 使用场景
- 响应式布局
- 设备适配
- 字体大小适配
- 横竖屏适配
### validator.js 使用场景
- 表单验证
- 数据格式校验
- 输入规则检查
- API参数验证