<?php
namespace app\common\business\lib;
use app\BaseController;
use think\facade\Db;
use think\facade\Validate;
use think\facade\Request;
use think\exception\ValidateException;
use think\exception\DbException;
/**
* 增强版基础控制器 - BaseMethod
*
* 整合原有BaseMethod所有功能,并添加增强方法
* 功能特性:
* 1. 保留所有原有数据库操作方法
* 2. 添加统一的API响应格式
* 3. 增强数据验证和参数处理
* 4. 提供丰富的工具方法
* 5. 支持操作日志记录
* 6. 完整兼容ThinkPHP8原生功能
*
* 使用示例:
* class Product extends BaseMethod
* {
* public function index()
* {
* // 使用原有方法
* $list = $this->Retrieve('product', 'status', 1);
*
* // 使用新增方法
* $pagedList = $this->newGetList('product', ['status' => 1], ['*'], 'id DESC', [], true);
*
* return $this->newSuccess($pagedList);
* }
* }
*/
class BaseMethod extends BaseController
{
/**
* 字段映射表(可被子类覆盖)
*/
protected $fieldMap = [
'username' => '用户名',
'email' => '邮箱',
'password' => '密码',
'id_card' => '身份证号码',
'mobile' => '手机号',
'age' => '年龄',
];
/**
* 每页显示数量
*/
protected $pageSize = 20;
/******************************************************************
* 原有BaseMethod方法
* 保持完全兼容,不做任何修改
******************************************************************/
/**
* 快速验证方法(支持字符串或数组规则)
*
* @param array $data 需要验证的数据
* @param array|string $rules 验证规则(字符串格式或数组)
* @param array $messages 自定义错误提示
* @return bool|\think\Response
*/
protected function validateOrFail(array $data, $rules, array $messages = [])
{
$validate = new Validate();
if (is_string($rules)) {
$rules = $this->parseStringRule($rules);
}
foreach ($rules as $field => $rule) {
if (is_array($rule)) {
$validate->rule($field, implode('|', $rule));
} else {
$validate->rule($field, $rule);
}
}
// 设置自定义消息
if (!empty($messages)) {
$validate->message($messages);
}
if (!$validate->check($data)) {
return $this->error('参数验证失败', ['errors' => $this->formatError($validate->getError())]);
}
return true;
}
/**
* 返回错误信息(自动替换字段名为中文)
*
* @param string $msg
* @param array $extra
* @return \think\Response
*/
protected function error(string $msg = '操作失败', array $extra = [])
{
$response = ['code' => 400, 'msg' => $msg];
if (isset($extra['errors']) && is_array($extra['errors'])) {
$response['errors'] = $extra['errors'];
}
return json($response)->code(400);
}
/**
* 解析字符串格式的规则为数组
*/
private function parseStringRule(string $ruleString): array
{
$rules = [];
$lines = explode(',', $ruleString);
foreach ($lines as $line) {
list($field, $rule) = explode(':', trim($line), 2);
$rules[trim($field)] = explode('|', trim($rule));
}
return $rules;
}
/**
* 格式化错误信息(将字段名替换为中文)
*/
private function formatError(array $errors): array
{
$localizedErrors = [];
foreach ($errors as $field => $error) {
$chineseField = $this->getFieldLabel($field);
if (is_array($error)) {
$localizedErrors[$chineseField] = implode(', ', $error);
} else {
$localizedErrors[$chineseField] = $error;
}
}
return $localizedErrors;
}
/**
* 获取字段的中文标签
*/
protected function getFieldLabel(string $field): string
{
return $this->fieldMap[$field] ?? $field;
}
/**
* 下拉菜单基本数据 1店名 2状态 3会员卡 4性别 5职业 6职务 7婚姻 8学历 9银行 10支付 11民族 12地区 13更多状态 14考勤 15企业类型 16单位 17SPH 18CYL 19ADD 20轴向 21逻辑运算
* @param $value
* @return bool|\PDOStatement|string|\think\Collection
* Date : 2024/3/23 22:18
*/
public function BaseInfo($value){
try {
return Db::name('info_base')->whereIn('type', $value)->where('status', 0)->order('type')->order('sort', 'asc')->select();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 员工基础数据查询
* @param $value
* @return bool|\PDOStatement|string|\think\Collection
* Date : 2024/3/23 22:18
*/
public function BaseStaff($value){
try {
return Db::name('base_staff')->whereIn('type', $value)->whereRaw('status=0 OR status=3')->order('type')->order('sort', 'asc')->select();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 供应商基础数据
* @return bool|\PDOStatement|string|\think\Collection
* Date : 2024/3/23 22:18
*/
public function BaseVendor(){
try {
return Db::name('base_vendor')->where('status', 0)->order('py', 'asc')->select();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 查分类到下拉
* @param $value
* @return bool|\PDOStatement|string|\think\Collection
* Date : 2024/4/6 0:06
*/
public function BaseType($value, $status){
try {
return Db::name('base_goods')->whereIn('type', $value)->where('status', $status)->order('type')->order('py')->select();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 供应商分类查询
* @param $value
* @param $status
* @return bool|\PDOStatement|string|\think\Collection
* Date : 2024/4/9 21:01
*/
public function BaseTypeVendor($status){
try {
return Db::name('base_vendor')->where('status', $status)->order('py')->select();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 获取最大值
* @param $tablename
* @param $type
* @param $value
* @param $field
* @return bool|\PDOStatement|string|\think\Collection
* Date : 2024/4/6 0:06
*/
public function BaseTypeMax($tablename, $type, $value, $field){
try {
return Db::name($tablename)->whereIn($type, $value)->max($field, false);
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* Goods Update
* @param $tableName
* @param $id
* @param $value
* @param $data
* @return int|string
* @throws \think\Exception
* Date : 2024/4/13 20:15
*/
public function GoodsSave($tableName, $id, $value, $data){
$data['update_time'] = date("Y-m-d H:i:s");
try {
return Db::name($tableName)->where($id, $value)->update($data);
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* Goods Exp Update
* @param $tableName
* @param $id
* @param $value
* @param $data
* @return int|string
* @throws \think\Exception
* Date : 2024/4/9 9:03
*/
public function GoodsExpUpdate($tableName, $id, $value, $data){
try {
return Db::name($tableName)->where($id, $value)->data($data)->update();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 查
* @param $tableName
* @param $key
* @param $value
* @return bool|\PDOStatement|string|\think\Collection
* Date : 2024/3/16/016 2:38
*/
public function Retrieve($tableName, $key, $value){
try {
return Db::name($tableName)->where($key, $value)->select();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 改
* @param $tableName
* @param $id
* @param $data
* @return int|string
* @throws \think\Exception
* Date : 2024/3/16/016 2:30
*/
public function Update($tableName, $id, $data){
try {
return Db::name($tableName)->where('id', $id)->data($data)->update();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 删
* @param $tableName
* @param $id
* @return int|string
* @throws \think\Exception
* Date : 2024/3/16/016 2:20
*/
public function Delete($tableName, $id){
try {
return Db::name($tableName)->where('id', $id)->delete();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 增 strict(false) 强制模式 避免错误
* @param $tableName
* @param $data
* @return int|string
* Date : 2024/3/16/016 1:56
*/
public function Create($tableName, $data){
try {
return Db::name($tableName)->strict(false)->insert($data);
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 统计数量
* @param $tableName
* @return int|string
* Date : 2024/3/16/016 1:56
*/
public function Count($tableName){
try {
return Db::name($tableName)->count();
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/**
* 遍历 CRUD=增删改查 $dataName, `$dataName`.
* @param $tableName
* @return array|mixed
* @throws \think\db\exception\BindParamException
* @throws \think\exception\PDOException
* Date : 2024/3/16/016 1:52
*/
public function throwAll($tableName){
$str = "SELECT * FROM `$tableName`";
return Db::query($str);
}
/**
* 删除多条数据
* @param $tableName
* @param $ids
* @return string|void
* @throws \think\Exception
* Date : 2024/3/16/016 2:55
*/
public function batchDelete($tableName, $ids){
try {
foreach($ids as $id){
Db::name($tableName)->where('id', $id)->delete();
}
} catch (DbException $exception) {
return $exception->getMessage();
}
}
/******************************************************************
* 新增增强方法
* 所有方法以 new 前缀命名,避免冲突
******************************************************************/
/**************************
* 新增响应方法
**************************/
/**
* 成功响应(新增)
*
* @param mixed $data 返回数据
* @param string $msg 提示信息
* @param int $code 状态码
* @return \think\Response
*
* @example
* return $this->newSuccess($data, '操作成功');
* return $this->newSuccess(null, '删除成功');
*/
protected function newSuccess($data = null, string $msg = '操作成功', int $code = 1)
{
$result = [
'code' => $code,
'msg' => $msg,
'time' => time(),
'data' => $data,
];
// 兼容分页数据格式
if (isset($data['list']) && isset($data['total'])) {
$result['count'] = $data['total'];
$result['data'] = $data['list'];
}
return json($result);
}
/**
* 错误响应(新增)
*
* @param string $msg 错误信息
* @param int $code 错误码
* @param mixed $data 附加数据
* @return \think\Response
*
* @example
* return $this->newError('参数错误');
* return $this->newError('系统错误', 500);
*/
protected function newError(string $msg = '操作失败', int $code = 0, $data = null)
{
$result = [
'code' => $code,
'msg' => $msg,
'time' => time(),
'data' => $data,
];
return json($result);
}
/**
* 分页响应(新增,兼容Layui表格)
*
* @param mixed $data 数据列表
* @param int $total 总记录数
* @param string $msg 提示信息
* @return \think\Response
*
* @example
* return $this->newPageResponse($list, $total);
*/
protected function newPageResponse($data, int $total = 0, string $msg = '')
{
$result = [
'code' => 1,
'msg' => $msg,
'count' => $total,
'data' => $data,
'time' => time(),
];
return json($result);
}
/**************************
* 新增数据库操作方法
**************************/
/**
* 获取列表数据(支持分页)- 新增增强版
*
* @param string $table 表名
* @param array $where 查询条件
* @param array $field 查询字段
* @param string $order 排序
* @param array $with 关联预载入
* @param bool $paginate 是否分页
* @return array
*
* @example
* // 不分页
* $list = $this->newGetList('user', ['status' => 1]);
*
* // 分页
* $list = $this->newGetList('user', ['status' => 1], ['id', 'name'], 'id DESC', [], true);
*/
protected function newGetList(string $table, array $where = [], array $field = ['*'], string $order = 'id DESC', array $with = [], bool $paginate = false): array
{
$query = Db::name($table)->where($where)->field($field)->order($order);
// 关联查询
if (!empty($with)) {
$query->with($with);
}
if ($paginate) {
$page = Request::param('page', 1);
$limit = Request::param('limit', $this->pageSize);
$result = $query->paginate([
'list_rows' => $limit,
'page' => $page,
]);
return [
'list' => $result->items(),
'total' => $result->total(),
];
} else {
return $query->select()->toArray();
}
}
/**
* 获取单条数据 - 新增增强版
*
* @param string $table 表名
* @param array $where 查询条件
* @param array $field 查询字段
* @param array $with 关联预载入
* @return array|null
*
* @example
* $user = $this->newGetOne('user', ['id' => 1]);
*/
protected function newGetOne(string $table, array $where = [], array $field = ['*'], array $with = []): ?array
{
$query = Db::name($table)->where($where)->field($field);
if (!empty($with)) {
$query->with($with);
}
$result = $query->find();
return $result ? $result->toArray() : null;
}
/**
* 创建数据 - 新增增强版(自动时间戳)
*
* @param string $table 表名
* @param array $data 数据
* @param bool $filter 是否过滤非表字段
* @return int|string
*
* @example
* $id = $this->newCreate('user', [
* 'name' => '张三',
* 'email' => 'zhangsan@example.com'
* ]);
*/
protected function newCreate(string $table, array $data, bool $filter = true)
{
// 自动添加时间戳
if (!isset($data['create_time'])) {
$data['create_time'] = $this->newTimestamp();
}
if (!isset($data['update_time'])) {
$data['update_time'] = $this->newTimestamp();
}
return Db::name($table)->insert($data, $filter);
}
/**
* 更新数据 - 新增增强版(自动时间戳)
*
* @param string $table 表名
* @param array $where 更新条件
* @param array $data 更新数据
* @param bool $filter 是否过滤非表字段
* @return int
*
* @example
* $result = $this->newUpdate('user', ['id' => 1], [
* 'name' => '李四',
* 'update_time' => time()
* ]);
*/
protected function newUpdate(string $table, array $where, array $data, bool $filter = true): int
{
// 自动更新更新时间
if (!isset($data['update_time'])) {
$data['update_time'] = $this->newTimestamp();
}
return Db::name($table)->where($where)->update($data, $filter);
}
/**
* 删除数据(支持软删除)- 新增
*
* @param string $table 表名
* @param array $where 删除条件
* @param bool $softDelete 是否软删除
* @return int
*
* @example
* // 硬删除
* $this->newDelete('user', ['id' => 1]);
*
* // 软删除
* $this->newDelete('user', ['id' => 1], true);
*/
protected function newDelete(string $table, array $where, bool $softDelete = false): int
{
if ($softDelete) {
// 软删除:更新status字段为0
return Db::name($table)->where($where)->update([
'status' => 0,
'update_time' => $this->newTimestamp()
]);
} else {
// 硬删除
return Db::name($table)->where($where)->delete();
}
}
/**
* 批量插入数据 - 新增
*
* @param string $table 表名
* @param array $data 数据数组
* @param bool $filter 是否过滤非表字段
* @return int
*
* @example
* $data = [
* ['name' => '张三', 'email' => 'zhangsan@example.com'],
* ['name' => '李四', 'email' => 'lisi@example.com']
* ];
* $this->newInsertAll('user', $data);
*/
protected function newInsertAll(string $table, array $data, bool $filter = true): int
{
$time = $this->newTimestamp();
foreach ($data as &$item) {
if (!isset($item['create_time'])) {
$item['create_time'] = $time;
}
if (!isset($item['update_time'])) {
$item['update_time'] = $time;
}
}
return Db::name($table)->insertAll($data, $filter);
}
/**
* 递增字段 - 新增
*
* @param string $table 表名
* @param array $where 条件
* @param string $field 字段名
* @param int $step 步进值
* @return int
*
* @example
* $this->newInc('user', ['id' => 1], 'login_count');
*/
protected function newInc(string $table, array $where, string $field, int $step = 1): int
{
return Db::name($table)->where($where)->inc($field, $step)->update([
'update_time' => $this->newTimestamp()
]);
}
/**
* 递减字段 - 新增
*
* @param string $table 表名
* @param array $where 条件
* @param string $field 字段名
* @param int $step 步进值
* @return int
*
* @example
* $this->newDec('product', ['id' => 1], 'stock');
*/
protected function newDec(string $table, array $where, string $field, int $step = 1): int
{
return Db::name($table)->where($where)->dec($field, $step)->update([
'update_time' => $this->newTimestamp()
]);
}
/**
* 统计数量 - 新增增强版
*
* @param string $table 表名
* @param array $where 条件
* @param string $field 字段名
* @return int
*
* @example
* $count = $this->newCount('user', ['status' => 1]);
*/
protected function newCount(string $table, array $where = [], string $field = '*'): int
{
return Db::name($table)->where($where)->count($field);
}
/**
* 求和 - 新增
*
* @param string $table 表名
* @param array $where 条件
* @param string $field 字段名
* @return float
*
* @example
* $total = $this->newSum('order', ['status' => 1], 'amount');
*/
protected function newSum(string $table, array $where, string $field): float
{
return Db::name($table)->where($where)->sum($field) ?: 0;
}
/**************************
* 新增验证方法
**************************/
/**
* 快速验证 - 验证字段是否为空
*
* @param mixed $value 字段值
* @param string $field 字段名
* @return bool
* @throws ValidateException
*
* @example
* $this->newCheckEmpty($name, '姓名');
*/
protected function newCheckEmpty($value, string $field = ''): bool
{
if (empty($value) && $value !== '0' && $value !== 0) {
throw new ValidateException($field ? $field . '不能为空' : '参数不能为空');
}
return true;
}
/**
* 快速验证 - 验证数字范围
*
* @param mixed $value 字段值
* @param int $min 最小值
* @param int $max 最大值
* @param string $field 字段名
* @return bool
* @throws ValidateException
*
* @example
* $this->newCheckNumberRange($age, 1, 150, '年龄');
*/
protected function newCheckNumberRange($value, int $min, int $max, string $field = ''): bool
{
if (!is_numeric($value) || $value < $min || $value > $max) {
throw new ValidateException($field ? $field . '必须在' . $min . '-' . $max . '之间' : '参数范围错误');
}
return true;
}
/**
* 快速验证 - 验证字符串长度
*
* @param string $value 字段值
* @param int $min 最小长度
* @param int $max 最大长度
* @param string $field 字段名
* @return bool
* @throws ValidateException
*
* @example
* $this->newCheckLength($name, 2, 20, '姓名');
*/
protected function newCheckLength(string $value, int $min, int $max, string $field = ''): bool
{
$length = mb_strlen($value, 'utf-8');
if ($length < $min || $length > $max) {
throw new ValidateException($field ? $field . '长度必须在' . $min . '-' . $max . '之间' : '参数长度错误');
}
return true;
}
/**
* 快速验证 - 验证手机号格式
*
* @param string $mobile 手机号
* @param string $field 字段名
* @return bool
* @throws ValidateException
*
* @example
* $this->newCheckMobile('13800138000', '手机号');
*/
protected function newCheckMobile(string $mobile, string $field = '手机号'): bool
{
if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) {
throw new ValidateException($field . '格式不正确');
}
return true;
}
/**
* 快速验证 - 验证邮箱格式
*
* @param string $email 邮箱地址
* @param string $field 字段名
* @return bool
* @throws ValidateException
*
* @example
* $this->newCheckEmail('test@example.com', '邮箱');
*/
protected function newCheckEmail(string $email, string $field = '邮箱'): bool
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new ValidateException($field . '格式不正确');
}
return true;
}
/**************************
* 新增参数处理和安全方法
**************************/
/**
* 获取请求参数(带默认值和过滤)- 新增增强版
*
* @param string $key 参数名
* @param mixed $default 默认值
* @param string $filter 过滤方法
* @return mixed
*
* @example
* $name = $this->newParam('name', '', 'trim');
* $page = $this->newParam('page', 1, 'intval');
*/
protected function newParam(string $key = '', $default = null, string $filter = '')
{
$value = Request::param($key, $default);
if ($filter && $value !== $default) {
if (function_exists($filter)) {
$value = $filter($value);
} elseif (is_callable($filter)) {
$value = call_user_func($filter, $value);
}
}
return $value;
}
/**
* 获取所有参数(带过滤)- 新增
*
* @param array $defaults 默认值数组
* @param array $filters 过滤规则
* @return array
*
* @example
* $data = $this->newParams([
* 'name' => '',
* 'age' => 0
* ], [
* 'name' => 'trim',
* 'age' => 'intval'
* ]);
*/
protected function newParams(array $defaults = [], array $filters = []): array
{
$params = [];
foreach ($defaults as $key => $default) {
$filter = $filters[$key] ?? '';
$params[$key] = $this->newParam($key, $default, $filter);
}
return $params;
}
/**
* 过滤HTML标签 - 新增
*
* @param string $str 要过滤的字符串
* @param string $allowableTags 允许的标签
* @return string
*
* @example
* $content = $this->newFilterHtml($content, '<p><br>');
*/
protected function newFilterHtml(string $str, string $allowableTags = ''): string
{
return strip_tags($str, $allowableTags);
}
/**
* SQL注入过滤 - 新增
*
* @param string $str 要过滤的字符串
* @return string
*
* @example
* $keyword = $this->newFilterSql($keyword);
*/
protected function newFilterSql(string $str): string
{
$dangerousPatterns = [
'/\b(union|select|insert|update|delete|drop|create|alter)\b/i',
'/\b(and|or)\b.*\b(1=1|1=0)\b/i',
'/\'|\"|;|\*|\#|\-\-/'
];
return preg_replace($dangerousPatterns, '', $str);
}
/**************************
* 新增工具方法
**************************/
/**
* 获取当前时间戳 - 新增
*
* @return string
*/
protected function newTimestamp(): string
{
return date('Y-m-d H:i:s');
}
/**
* 生成随机字符串 - 新增
*
* @param int $length 长度
* @param string $type 类型:number, letter, mixed
* @return string
*
* @example
* $code = $this->newRandomString(6, 'number'); // 生成6位数字
* $token = $this->newRandomString(32); // 生成32位混合字符串
*/
protected function newRandomString(int $length = 6, string $type = 'mixed'): string
{
$number = '0123456789';
$letter = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
switch ($type) {
case 'number':
$chars = $number;
break;
case 'letter':
$chars = $letter;
break;
case 'mixed':
default:
$chars = $number . $letter;
break;
}
$str = '';
$max = strlen($chars) - 1;
for ($i = 0; $i < $length; $i++) {
$str .= $chars[mt_rand(0, $max)];
}
return $str;
}
/**
* 记录操作日志 - 新增
*
* @param string $action 操作描述
* @param array $data 操作数据
* @param string $module 模块名
* @return bool
*
* @example
* $this->newLog('添加用户', ['name' => '张三'], 'user');
*/
protected function newLog(string $action, array $data = [], string $module = ''): bool
{
$logData = [
'module' => $module ?: Request::controller(),
'action' => $action,
'data' => json_encode($data, JSON_UNESCAPED_UNICODE),
'ip' => Request::ip(),
'user_agent' => Request::server('HTTP_USER_AGENT'),
'create_time' => $this->newTimestamp(),
];
// 记录到文件日志
$logContent = sprintf(
"[%s] %s %s %s %s\n",
$logData['create_time'],
$logData['module'],
$logData['action'],
$logData['data'],
$logData['ip']
);
$logFile = runtime_path() . 'log/operation.log';
file_put_contents($logFile, $logContent, FILE_APPEND | LOCK_EX);
return true;
}
/**
* 数组转树形结构 - 新增
*
* @param array $list 数据列表
* @param string $pk 主键字段名
* @param string $pid 父级字段名
* @param string $child 子级键名
* @param int $root 根节点ID
* @return array
*
* @example
* $tree = $this->newListToTree($list, 'id', 'pid', 'children');
*/
protected function newListToTree(array $list, string $pk = 'id', string $pid = 'pid', string $child = 'children', int $root = 0): array
{
$tree = [];
$refer = [];
foreach ($list as $key => $data) {
$refer[$data[$pk]] = &$list[$key];
}
foreach ($list as $key => $data) {
$parentId = $data[$pid];
if ($root == $parentId) {
$tree[] = &$list[$key];
} else {
if (isset($refer[$parentId])) {
$parent = &$refer[$parentId];
$parent[$child][] = &$list[$key];
}
}
}
return $tree;
}
/**
* 生成分页参数 - 新增
*
* @param int $total 总记录数
* @param int $page 当前页
* @param int $pageSize 每页数量
* @return array
*
* @example
* $pagination = $this->newBuildPagination(100, 1, 20);
*/
protected function newBuildPagination(int $total, int $page = 1, int $pageSize = 20): array
{
$totalPage = ceil($total / $pageSize);
return [
'total' => $total,
'page' => $page,
'page_size' => $pageSize,
'total_page' => $totalPage,
'has_prev' => $page > 1,
'has_next' => $page < $totalPage,
];
}
/**
* 生成订单号 - 新增
*
* @param string $prefix 前缀
* @return string
*
* @example
* $orderNo = $this->newGenerateOrderNo('SO');
*/
protected function newGenerateOrderNo(string $prefix = ''): string
{
return $prefix . date('YmdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}
/**
* 文件大小格式化 - 新增
*
* @param int $bytes 字节数
* @param int $decimals 小数位数
* @return string
*
* @example
* $size = $this->newFormatBytes(1024); // 1 KB
*/
protected function newFormatBytes(int $bytes, int $decimals = 2): string
{
$size = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . ' ' . @$size[$factor];
}
/**
* 检查文件扩展名是否允许 - 新增
*
* @param string $filename 文件名
* @param array $allowedExtensions 允许的扩展名
* @return bool
*
* @example
* $allowed = $this->newCheckFileExtension('image.jpg', ['jpg', 'png', 'gif']);
*/
protected function newCheckFileExtension(string $filename, array $allowedExtensions): bool
{
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
return in_array($extension, $allowedExtensions);
}
/**
* 获取客户端IP - 新增
*
* @return string
*/
protected function newGetClientIp(): string
{
return Request::ip();
}
/**
* 获取当前URL - 新增
*
* @return string
*/
protected function newGetCurrentUrl(): string
{
return Request::url(true);
}
/**
* 重定向(增强版)- 新增
*
* @param string $url 跳转地址
* @param array $params 参数
* @param int $code 状态码
* @return \think\Response
*
* @example
* return $this->newRedirect('index/index', ['id' => 1]);
*/
protected function newRedirect(string $url, array $params = [], int $code = 302)
{
if (!empty($params)) {
$url .= '?' . http_build_query($params);
}
return redirect($url, $code);
}
}
完整使用示例
<?php
namespace app\controller;
use app\common\business\lib\BaseMethod;
use think\exception\ValidateException;
class Product extends BaseMethod
{
protected $pageSize = 15;
/**
* 商品列表 - 混合使用新旧方法
*/
public function index()
{
try {
// 使用新增的参数获取方法
$page = $this->newParam('page', 1, 'intval');
$limit = $this->newParam('limit', $this->pageSize, 'intval');
$keyword = $this->newParam('keyword', '', 'trim');
// 构建查询条件
$where = ['status' => 1];
if ($keyword) {
$where[] = ['name|barcode', 'like', "%{$keyword}%"];
}
// 方法1:使用原有的查询方法
$simpleList = $this->Retrieve('product', 'status', 1);
// 方法2:使用新增的分页查询方法
$pagedResult = $this->newGetList('product', $where, ['*'], 'id DESC', [], true);
// 使用新增的日志记录
$this->newLog('查询商品列表', [
'keyword' => $keyword,
'page' => $page,
'simple_count' => count($simpleList),
'paged_count' => count($pagedResult['list'])
], 'product');
// 使用新增的分页响应
return $this->newPageResponse($pagedResult['list'], $pagedResult['total'], '获取成功');
} catch (\Exception $e) {
return $this->newError('获取商品列表失败:' . $e->getMessage());
}
}
/**
* 添加商品 - 展示多种验证方式
*/
public function add()
{
try {
// 使用新增的参数获取方法
$data = $this->newParams([
'barcode' => '',
'name' => '',
'price' => 0,
'category' => '',
'stock' => 0
], [
'barcode' => 'trim',
'name' => 'trim',
'price' => 'floatval',
'stock' => 'intval'
]);
// 方法1:使用原有的验证方法
$rules = 'barcode:required|max:50,name:required|max:100,price:required|float|gt:0,category:required|max:50,stock:number|egt:0';
if (!$this->validateOrFail($data, $rules)) {
return; // 已返回错误响应
}
// 方法2:使用新增的快速验证
$this->newCheckEmpty($data['barcode'], '商品条码');
$this->newCheckEmpty($data['name'], '商品名称');
$this->newCheckNumberRange($data['price'], 0.01, 999999, '商品价格');
$this->newCheckNumberRange($data['stock'], 0, 999999, '库存数量');
// 检查条码是否重复
$exists = $this->newGetOne('product', ['barcode' => $data['barcode']]);
if ($exists) {
return $this->newError('商品条码已存在');
}
// 方法1:使用原有的创建方法
// $id = $this->Create('product', $data);
// 方法2:使用新增的创建方法(自动时间戳)
$id = $this->newCreate('product', $data);
// 使用新增的日志记录
$this->newLog('添加商品', array_merge(['id' => $id], $data), 'product');
return $this->newSuccess(['id' => $id], '商品添加成功');
} catch (ValidateException $e) {
return $this->newError($e->getMessage());
} catch (\Exception $e) {
return $this->newError('添加商品失败:' . $e->getMessage());
}
}
/**
* 更新库存 - 展示数据库操作
*/
public function updateStock()
{
try {
$id = $this->newParam('id', 0, 'intval');
$stock = $this->newParam('stock', 0, 'intval');
$this->newCheckEmpty($id, '商品ID');
$this->newCheckNumberRange($stock, 0, 999999, '库存数量');
// 方法1:使用原有的更新方法
// $result = $this->Update('product', $id, ['stock' => $stock]);
// 方法2:使用新增的更新方法(自动时间戳)
$result = $this->newUpdate('product', ['id' => $id], ['stock' => $stock]);
// 方法3:使用新增的递减方法(适用于减少库存)
// $result = $this->newDec('product', ['id' => $id], 'stock', 1);
if ($result) {
$this->newLog('更新库存', ['id' => $id, 'stock' => $stock], 'product');
return $this->newSuccess(null, '库存更新成功');
} else {
return $this->newError('库存更新失败');
}
} catch (ValidateException $e) {
return $this->newError($e->getMessage());
} catch (\Exception $e) {
return $this->newError('更新库存失败:' . $e->getMessage());
}
}
/**
* 导出商品数据 - 展示工具方法使用
*/
public function export()
{
try {
// 使用原有的查询方法
$products = $this->throwAll('product');
// 使用新增的工具方法
$exportInfo = [
'export_time' => $this->newTimestamp(),
'total_count' => count($products),
'exported_by' => 'system',
'ip_address' => $this->newGetClientIp()
];
// 记录日志
$this->newLog('导出商品数据', $exportInfo, 'product');
return $this->newSuccess([
'products' => $products,
'export_info' => $exportInfo
], '导出成功');
} catch (\Exception $e) {
return $this->newError('导出失败:' . $e->getMessage());
}
}
}
评论区