TP6服务基类
发表于:2025-02-09 14:56:04浏览:148次
前言
在使用ThinkPHP6框架的时候,我们通过继承服务基类,可以更方便和规范编写我们的代码
示例
namespace app\services;
use app\model\User as Model;
use app\enum\User as Enum;
use app\common\basic\BaseServices;
/**
* 授权
* Class Auth
* @package app\services
*/
class Auth extends BaseServices
{
/**
* 初始化
*/
public function __construct()
{
$this->initialize(new Model(),new Enum());
}
}
类
<?php
namespace app\common\basic;
use think\facade\Cache;
use think\facade\Config;
use think\exception\ValidateException;
use think\Validate;
/**
* 基类
* Class BaseServices
* @package app\common\basic
*/
abstract class BaseServices
{
// 模型
private $model;
// 枚举
protected $enum;
// 错误信息
protected $error;
// 不参与查询
protected $where_except = ['time_field','date','order','pages','search_field'];
// 不允许更新的字段
protected $not_update_field = ['id','mer_id','create_time','update_time','delete_time'];
// 不记录日志的表
protected $not_log_table = ['hc_system_request','hc_system_log'];
// 临时数据
protected $temp;
/**
* 初始化
* @param $model
* @param $enum
*/
protected function initialize($model,$enum)
{
$this->model = $model;
$this->enum = $enum;
}
/**
* 数据保存
* @param $input
* @param $where
* @return bool|mixed
*/
public function save($input,$where = [])
{
!$where && $where = $input['id'] ?? 0;
$detail = $where ? $this->getOne($where) : null;
$allowField = array_keys($this->getTableFields());
$handle_text = '新增';
$is_create = true;
$action = \app\dazijie\enum\system\Log::ACTION_CREATE;
$old = [];
//unset($input['create_time']);
//unset($input['update_time']);
unset($input['delete_time']);
if ($detail) {
$handle_text = '修改';
$is_false = false;
$action = \app\dazijie\enum\system\Log::ACTION_UPDATE;
$allowField = array_diff($allowField,$this->not_update_field);
$old = $detail->getData();
}
else {
if (empty($input['id']))
unset($input['id']);
$detail = $this->getModel();
}
if (!$detail->allowField($allowField)->save($input))
return $this->setError("保存失败");
$comment = $this->getTableComment();
$this->log("{$handle_text}[ {$comment} ]",[
'mer_id'=>$detail->mer_id?:0,
'action'=>$action,
'table_id'=>$detail->id,
'old_value'=>$old,
'new_value'=>$detail->getData()
]);
$detail = $this->getOne($detail->id);
$detail && $detail->is_create = $is_create;
return $detail;
}
/**
* 数据删除
* @param $where
* @param $is_true
* @return mixed
*/
public function delete($where,$is_true = false)
{
$comment = $this->getTableComment();
$detail = $this->getOne($where);
$mer_id = !empty($detail->mer_id) ? $detail->mer_id : 0;
$ids = $this->getColumn($where,'id');
if (!$ids)
return $this->setError("删除表[ {$comment} ]记录失败,记录不存在");
$id_str = implode(',',$ids);
if (!$this->getModel()::destroy($ids,$is_true)) {
return $this->setError("删除表[ {$comment} ]记录(ID集={$id_str})失败");
}
$this->log("删除表[ {$comment} ]记录(ID集={$id_str})成功",[
'mer_id'=>$mer_id,
'action'=>\app\dazijie\enum\system\Log::ACTION_DELETE,
'table_id'=>0,
'old_value'=>$ids,
'new_value'=>''
]);
return true;
}
/**
* 增加字段值
* @param $where
* @param $field
* @param int $value
* @return mixed
*/
public function setInc($where,$field,$value = 1)
{
return $this->searchBase($where)->inc($field,$value)->update();
}
/**
* 减去字段值
* @param $where
* @param $field
* @param int $value
* @return mixed
*/
public function setDec($where,$field,$value = 1)
{
return $this->searchBase($where)->dec($field,$value)->update();
}
/**
* 求和
* @param $where
* @param $field
* @return mixed
*/
public function getSum($where,$field)
{
return $this->searchBase($where)->sum($field);
}
/**
* 查询条数
* @param array $where
* @return mixed
*/
public function getCount($where = [])
{
return $this->searchBase($where)->count();
}
/**
* 查询重复数据
* @param $where
* @param $group_fields
* @param $having_field
* @param $having_count
* @param array $field
* @param array $with
* @return mixed
*/
public function getListSameField($where,$group_fields,$having_field,$having_count,array $field,$with = [])
{
$field[] = "count({$having_field}) as data_count";
return $this->searchBase($where)
->fieldRaw(implode(',',$field))
->with($with)
->group($group_fields)
->having("data_count>{$having_count}")
->select();
}
/**
* 分组查询
* @param $where
* @param $group_field
* @param $field
* @param $with
* @return mixed
*/
public function getAllByGroup($where,$group_field,$field,$with = [])
{
return $this->searchBase($where)
->with($with)
->field($field)
->group($group_field)
->select();
}
/**
* 查询所有列表
* @param array $where
* @param array $with
* @param string[] $field
* @param array $append
* @return mixed
*/
public function getListAll($where = [],$with = [],$field = ['*'],$append = [])
{
$withCount = [];
if (!empty($with['withCount'])) {
$withCount = $with['withCount'];
unset($with['withCount']);
}
return $this->searchBase($where)
->field($field)
->with($with)
->withCount($withCount)
->append($append)
->select();
}
/**
* 查询分页列表
* @param array $where
* @param array $with
* @param string[] $field
* @param array $append
* @param array $withCount
* @return mixed
*/
public function getList($where = [],$with = [],$field = ['*'],$append = [])
{
if (!empty($where['pages']) && !empty($where['pages']['page']) && !empty($where['pages']['limit'])) {
$pages = [
'page'=>$where['pages']['page'],
'limit'=>$where['pages']['limit']
];
}
else {
$pages = $this->getPages();
}
$model = $this->searchBase($where);
$append && $model->append($append);
$withCount = [];
if (!empty($with['withCount'])) {
$withCount = $with['withCount'];
unset($with['withCount']);
}
return $model
->field($field)
->with($with)
->withCount($withCount)
->page($pages['page'],$pages['limit'])
->append($append)
->select();
}
/**
* 获取单条数据
* @param array $where
* @param array $with
* @param string[] $field
* @param array $append
* @return mixed
*/
public function getOne($where = [],$with = [],$field = ['*'],$append = [])
{
return $this->searchBase($where)
->field($field)
->with($with)
->append($append)
->find();
}
/**
* 查询列
* @param $where
* @param $field
* @param string $key 作为索引
* @return array
*/
public function getColumn($where,$field,$key = '')
{
return $this->searchBase($where)->column($field,$key);
}
/**
* 查询值
* @param $where
* @param $field
* @return array
*/
public function getValue($where,$field = 'id')
{
return $this->searchBase($where)->value($field);
}
/**
* 获取最大值
* @param $where
* @param $field
*/
public function getMax($where,$field)
{
return $this->searchBase($where)->max($field);
}
/**
* 验证是否存在
* @param $where
* @param int $check_id
* @return bool
*/
public function isExist($where,$check_id = 0)
{
if (
$check = $this->getOne($where)
) {
if (($check_id && $check && $check->id != $check_id) || (!$check_id && $check)) {
return true;
}
}
return false;
}
/**
* 获取枚举
* @return mixed
*/
public function getEnum()
{
return $this->enum;
}
/**
* 数据更新(DB直接更新)
* @param $where
* @param $data
*/
public function update($where,$data)
{
return $this->searchBase($where)->update($data);
}
/**
* 设置错误信息
* @param $val
* @return bool
*/
public function setError($val)
{
$this->error = $val;
return false;
}
/**
* 获取错误信息
* @return mixed
*/
public function getError()
{
return $this->error;
}
/**
* 获取分页值
* @return array
*/
public function getPages()
{
$page = request()->param('page');
$page = $page?:1;
$limit = request()->param('limit');
$limit = $limit?:10;
return compact('page','limit');
}
/**
* 获取新model
* @return mixed
*/
public function getModel()
{
$class = "\\".get_class($this->model);
return new $class;
}
/**
* 事务操作
* @param $callback
* @param $by_bool
* @return bool|mixed|null
*/
public function transaction($callback,$by_bool = false)
{
// 回调方法返回值不为false才会提交
if ($by_bool) {
$model = $this->getModel();
$model->startTrans();
try {
$result = null;
if (is_callable($callback))
$result = call_user_func_array($callback, [$model]);
if ($result)
$model->commit();
else
$model->rollback();
return $result;
} catch (\Exception $e) {
$model->rollback();
// 记录日志
$this->log($e);
return $this->setError($e->getMessage());
}
}
// 回调方法无异常才会提交
else {
return \think\facade\Db::transaction($callback);
}
}
/**
* 查询时间
* @param $model
* @param $date
* @param string $field
* @return mixed
*/
private function searchTime($model,$date,$field = 'create_time')
{
$time = time();
return $model
->when($date,function ($query) use ($date,$field,$time) {
switch($date){
case 'today':
$query->whereDay($field);
break;
case 'yesterday':
$query->whereDay($field ,'yesterday');
break;
case 'lately7':
$start = strtotime(date('Y-m-d', strtotime('-7 days')));
$query->whereBetweenTime($field, $start, $time);
break;
case 'lately30':
$start = strtotime(date('Y-m-d', strtotime('-30 days')));
$query->whereBetweenTime($field, $start, $time);
break;
case 'month':
$query->whereMonth($field);
break;
case 'year':
$query->whereYear($field);
break;
default:
$date = is_array($date) ? $date : explode("~",$date);
if (count($date) == 2) {
$date0 = trim($date[0]);
$date1 = trim($date[1]);
if (in_array($date0,['<','<=','>','>='])) {
$end = is_numeric($date1) ? $date1 : strtotime($date1. " 23:59:59");
$query->whereTime($field,$date0,$end);
}
else if ($date0 == 'day') {
$query->whereDay($field,$date1);
}
else if ($date0 == 'week') {
$query->whereWeek($field,$date1);
}
else if ($date0 == 'month') {
$query->whereMonth($field,$date1);
}
else {
$date0_c = count(explode("-",$date0));
$date1_c = count(explode("-",$date1));
if ($date0_c == 1) {
$date0 = $date0.'-01-01';
}
else if ($date0_c == 2) {
$date0 = $date0.'-01';
}
if ($date1_c == 1) {
$date1 = $date1.'-01-01';
}
else if ($date1_c == 2) {
$date1 = date("Y-m-t", strtotime($date1.'-01'));
}
$start = is_numeric($date0) ? $date0 : strtotime($date0. " 00:00:00");
$end = is_numeric($date1) ? $date1 : strtotime($date1. " 23:59:59");
$query->whereBetweenTime($field, $start, $end);
}
}
break;
}
});
}
/**
* 查询条件初始化处理
* @param $where
* @return array|mixed
*/
protected function handleWhere($where)
{
$where = array_merge([
'id'=>NULL,
'mer_id'=>NULL,
'search_field'=>NULL,
'search_word'=>NULL,
'time_field'=>'create_time',
'date'=>NULL,
'order'=>[
'create_time'=>'desc',
'id'=>'desc',
]
],$this->getTableFields(),$where);
$except = ['time_field','date','order','pages','search_field'];
foreach ($where as $field=>$item) {
if (!in_array($field,$except)) {
if (is_array($item)) {
$fh = $item[0];
$value = $item[1];
}
else {
if ($field == 'search_word') {
$fh = 'LIKE';
}
else {
$fh = '=';
}
$value = $item;
}
$where[$field] = [$fh,$value];
}
}
return $where;
}
/**
* 基础查询
* 若是需要 find in set 查询,则以数组方式传入
* @param $where
* @return mixed
*/
public function searchBase($where)
{
$where = is_array($where) ? $where : ['id'=>$where];
$table_fields = $this->getTableFields();
$where = $this->handleWhere($where);
$model = $this->getModel();
// 常规查询
foreach ($where as $field=>$item) {
if (!in_array($field,$this->where_except)) {
$is_search = 1;
// 有些字段是如: nickname|username 这种,要验证数据库是否存在该字段,不存在则不执行查询
$field_arr = explode('|',$field);
foreach ($field_arr as $field_item) {
// 不能用isset,当值为null时候,isset也是返回false
array_key_exists($field_item,$table_fields)===FALSE && $is_search = 0;
}
if ($is_search) {
$model = $model->when($item[1]!==NULL,function ($que) use ($item,$field){
$que->where($field,$item[0],$item[1]);
});
}
}
}
// 日期
!empty($where['date']) && $model = $this->searchTime($model,$where['date'],!empty($where['time_field']) ? $where['time_field'] : 'create_time');
// 模糊查询
$model = $model
->when($where['search_word'][1]!==NULL && $where['search_field']!==NULL,function ($que) use ($where) {
$que->where($where['search_field'],$where['search_word'][0], '%' . $where['search_word'][1] . '%');
});
// 排序
$model = $model
->order($where['order']);
return $model;
}
/**
* 操作日志
* @param $content
* @param array $ext
* @return bool
*/
public function log($content,$ext = [])
{
// TODO
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
list($validate, $scene) = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : app()->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
/**
* 设置临时数据
* @param $value
* @param $type
* @return true
*/
public function setTempData($value,$type = 'reset')
{
if ($type == 'push') {
if (!$this->temp)
$this->temp = [];
array_push($this->temp,$value);
}
else
$this->temp = $value;
return true;
}
/**
* 获取临时数据
* @return mixed
*/
public function getTempData()
{
return $this->temp;
}
/**
* 清除临时数据
* @return true
*/
public function clearTempData()
{
$this->temp = [];
return true;
}
/**
* 获取表注释
* @param string $table
* @return mixed
*/
protected function getTableComment($table = '')
{
!$table && $table = $this->getModel()->getTable();
$cache_key = 'table_comment_'.$table;
$data = \think\facade\Cache::get($cache_key);
if (env('site.dev') || !$data) {
$database = \think\facade\Db::query("SELECT DATABASE()")[0]['DATABASE()'];
$info = \think\facade\Db::query("SELECT TABLE_NAME,TABLE_COMMENT FROM information_schema.`TABLES` WHERE TABLE_NAME = '{$table}' AND TABLE_SCHEMA = '{$database}'");
$data = $info[0]['TABLE_COMMENT'];
}
return $data;
}
/**
* 获取表字段
* @param string $table
* @return array|mixed
*/
protected function getTableFields($table = '')
{
!$table && $table = $this->getModel()->getTable();
$cache_key = 'table_fields_'.$table;
$data = \think\facade\Cache::get($cache_key);
if (env('site.dev') || !$data) {
$res = \think\facade\Db::query("show full columns from {$table}");
$data = [];
foreach ($res as $item) {
$data[$item['Field']] = NULL;
}
\think\facade\Cache::set($cache_key,$data,3600);
}
return $data;
}
/**
* 获取用户当前终端
* @return string
*/
public function getTerminal()
{
if ($this->isApi()) {
$terminal = \app\dazijie\enum\Cache::TERMINAL_API;
}
else if ($this->isRoutine()) {
$terminal = \app\dazijie\enum\Cache::TERMINAL_ROUTINE;
}
else if ($this->isApp()) {
$terminal = \app\dazijie\enum\Cache::TERMINAL_APP;
}
else if ($this->isMobile()) {
$terminal = \app\dazijie\enum\Cache::TERMINAL_MOBILE;
}
else {
$terminal = \app\dazijie\enum\Cache::TERMINAL_PC;
}
return $terminal;
}
/**
* 是否是API端
* @return bool
*/
public function isApi()
{
$terminal = \request()->header('Terminal');
return $terminal == "api";
}
/**
* 是否是手机端
* @return bool
*/
public function isMobile()
{
return \request()->isMobile();
}
/**
* 是否是微信端
* @return bool
*/
public function isWechat()
{
return strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false;
}
/**
* 是否是小程序端
* @return bool
*/
public function isRoutine()
{
$terminal = \request()->header('Terminal');
return $terminal == "routine";
}
/**
* 是否是app端
* @return bool
*/
public function isApp()
{
$terminal = \request()->header('Terminal');
return $terminal == "app";
}
/**
* 是否是pc端
* @return bool
*/
public function isPc()
{
return $this->isMobile() === false;
}
}
栏目分类全部>