390 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			390 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
| <?php
 | ||
| 
 | ||
| namespace app\model;
 | ||
| 
 | ||
| use Exception;
 | ||
| use think\Collection;
 | ||
| use think\db\exception\DataNotFoundException;
 | ||
| use think\db\exception\DbException;
 | ||
| use think\db\exception\ModelNotFoundException;
 | ||
| use think\Model;
 | ||
| use think\Paginator;
 | ||
| 
 | ||
| class Base extends Model
 | ||
| {
 | ||
|     protected $autoWriteTimestamp = false;
 | ||
| 
 | ||
|     // 布尔值数字关系
 | ||
|     public const BOOL_FALSE = 0;
 | ||
|     public const BOOL_TRUE  = 1;
 | ||
| 
 | ||
|     public const COMMON_ON  = 1;
 | ||
|     public const COMMON_OFF = 0;
 | ||
| 
 | ||
|     //根据Id列表获取列表
 | ||
|     public static function getListByIds($ids)
 | ||
|     {
 | ||
|         if (count($ids) == 0 || empty($ids)) {
 | ||
|             return [];
 | ||
|         }
 | ||
|         return self::where('id', 'in', $ids)->select()->toArray();
 | ||
|     }
 | ||
| 
 | ||
|     //根据ID获取单条数据
 | ||
|     public static function getById($id)
 | ||
|     {
 | ||
|         if ($id <= 0) {
 | ||
|             return [];
 | ||
|         }
 | ||
|         return self::where('id', $id)->findOrEmpty()->toArray();
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 通过ID查找记录
 | ||
|      *
 | ||
|      * @param  int  $id
 | ||
|      * @param  array  $fields
 | ||
|      * @param  callable|null  $call
 | ||
|      * @return array|Model|null
 | ||
|      * @throws DataNotFoundException
 | ||
|      * @throws DbException
 | ||
|      * @throws ModelNotFoundException
 | ||
|      */
 | ||
|     public static function findById(int $id, array $fields = [], callable $call = null)
 | ||
|     {
 | ||
|         $q = self::when(!empty($fields), function ($q) use ($fields) {
 | ||
|             $q->field($fields);
 | ||
|         });
 | ||
|         if ($call !== null) {
 | ||
|             $q = $call($q);
 | ||
|         }
 | ||
|         return $q->find($id);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 查找单个记录
 | ||
|      *
 | ||
|      * @param  array  $where
 | ||
|      * @param  array  $fields
 | ||
|      * @param  callable|null  $call
 | ||
|      * @return array|Model|null
 | ||
|      * @throws DataNotFoundException
 | ||
|      * @throws DbException
 | ||
|      * @throws ModelNotFoundException
 | ||
|      */
 | ||
|     public static function findOne(array $where = [], array $fields = [], callable $call = null)
 | ||
|     {
 | ||
|         $q = self::when(!empty($fields), function ($q) use ($fields) {
 | ||
|             $q->field($fields);
 | ||
|         })->where($where);
 | ||
| 
 | ||
|         if ($call !== null) {
 | ||
|             $q = $call($q);
 | ||
|         }
 | ||
|         return $q->find();
 | ||
|     }
 | ||
| 
 | ||
|     //根据ID更新数据
 | ||
|     public static function updateById($id, $data)
 | ||
|     {
 | ||
|         return self::where('id', $id)->update($data);
 | ||
|     }
 | ||
| 
 | ||
|     //根据where条件和排序获取记录
 | ||
|     public static function getListByWhereAndOrder($where, $order, $limit = 1)
 | ||
|     {
 | ||
|         return self::where($where)
 | ||
|             ->order($order)
 | ||
|             ->limit($limit)
 | ||
|             ->select()
 | ||
|             ->toArray();
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 根据ID删除数据
 | ||
|      *
 | ||
|      * @param  int  $id
 | ||
|      * @return bool
 | ||
|      */
 | ||
|     public static function deleteById(int $id): bool
 | ||
|     {
 | ||
|         return self::where('id', $id)->delete();
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 根据ID列表删除数据
 | ||
|      *
 | ||
|      * @param  array  $ids
 | ||
|      * @return bool
 | ||
|      */
 | ||
|     public static function deleteByIds(array $ids): bool
 | ||
|     {
 | ||
|         return self::whereIn('id', $ids)->delete();
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 排序
 | ||
|      *
 | ||
|      * @param  int  $id  调整ID
 | ||
|      * @param  string  $type  本次操作类型 向上、向下
 | ||
|      * @param  int  $num  移动位数
 | ||
|      * @param  string  $listType  列表的排序方式 默认为降序
 | ||
|      * @param  array  $where  额外条件 如限制在指定分类下 where[] = ['category_id', '=', 6]
 | ||
|      * @return array
 | ||
|      * @throws Exception
 | ||
|      */
 | ||
|     public static function sort(int $id, string $type, int $num = 1, string $listType = 'desc', array $where = []): array
 | ||
|     {
 | ||
|         $res  = ['code' => 0, 'msg' => 'success'];
 | ||
|         $item = self::getById($id);
 | ||
| 
 | ||
|         if (!$item) {
 | ||
|             $res['code'] = 1;
 | ||
|             $res['msg']  = '记录不存在';
 | ||
|             return $res;
 | ||
|         }
 | ||
| 
 | ||
|         if ($listType == 'desc') {
 | ||
|             if ($type == 'down') {
 | ||
|                 $where[] = ['sort', '<', $item['sort']];
 | ||
|                 $order   = "sort desc";
 | ||
|             } else {
 | ||
|                 $where[] = ['sort', '>', $item['sort']];
 | ||
|                 $order   = "sort asc";
 | ||
|             }
 | ||
|         } else {
 | ||
|             if ($type == 'up') {
 | ||
|                 $where[] = ['sort', '<', $item['sort']];
 | ||
|                 $order   = "sort desc";
 | ||
|             } else {
 | ||
|                 $where[] = ['sort', '>', $item['sort']];
 | ||
|                 $order   = "sort asc";
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         $forSortItems = self::getListByWhereAndOrder($where, $order, $num);
 | ||
|         if (!empty($forSortItems)) {
 | ||
|             $updateData   = [];
 | ||
|             $forSortCount = count($forSortItems);
 | ||
|             for ($i = 0; $i < $forSortCount; $i++) {
 | ||
|                 if ($i == 0) {
 | ||
|                     $updateData[] = [
 | ||
|                         'id'   => $forSortItems[$i]['id'],
 | ||
|                         'sort' => $item['sort']
 | ||
|                     ];
 | ||
|                 } else {
 | ||
|                     $updateData[] = [
 | ||
|                         'id'   => $forSortItems[$i]['id'],
 | ||
|                         'sort' => $forSortItems[$i - 1]['sort']
 | ||
|                     ];
 | ||
|                 }
 | ||
|             }
 | ||
|             $updateData[] = [
 | ||
|                 'id'   => $item['id'],
 | ||
|                 'sort' => $forSortItems[$i - 1]['sort']
 | ||
|             ];
 | ||
| 
 | ||
|             if (!empty($updateData)) {
 | ||
|                 $obj = new static();
 | ||
|                 $obj->saveAll($updateData);
 | ||
|                 return $res;
 | ||
|             }
 | ||
|         }
 | ||
|         $res['code'] = 1;
 | ||
|         $res['msg']  = '无需调整';
 | ||
|         return $res;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 查询列表 [带分页 适用于后台]
 | ||
|      *
 | ||
|      * @param  array  $data  查询数据 格式如下
 | ||
|      * [
 | ||
|      *   'fields' => ['id','title','desc'],//查询字段
 | ||
|      *   'where'  => [
 | ||
|      *                  ['name', 'like', '%thinkphp%'],
 | ||
|      *                  ['title', 'like', '%thinkphp%'],
 | ||
|      *                  ['id', '>', 0],
 | ||
|      *                  ['status', '=', 1],
 | ||
|      *               ],//查询条件
 | ||
|      *   'order'  => ['order'=>'desc','id'=>'desc'],//排序
 | ||
|      *   'size' => 50,//每页数量
 | ||
|      * ]
 | ||
|      * @param  array  $pageParams  分页参数 具体参考:https://www.kancloud.cn/manual/thinkphp6_0/1037638
 | ||
|      * @param  callable|null  $callback  复杂查询条件 使用闭包查询 此时建议data留空
 | ||
|      * @return Paginator
 | ||
|      * @throws DbException
 | ||
|      */
 | ||
|     public static function findListWithPaginate(array $data = [], array $pageParams = [], callable $callback = null): Paginator
 | ||
|     {
 | ||
|         $q      = new static();
 | ||
|         $fields = isset($data['fields']) && !empty($data['fields']) ? $data['fields'] : [];
 | ||
|         $where  = isset($data['where']) && !empty($data['where']) ? $data['where'] : [];
 | ||
|         $order  = isset($data['order']) && !empty($data['order']) ? $data['order'] : [];
 | ||
|         $limit  = $data['size'] ?? 20;
 | ||
| 
 | ||
|         if (count($where)) {
 | ||
|             $q = $q->where($where);
 | ||
|         }
 | ||
| 
 | ||
|         if (count($fields)) {
 | ||
|             $q = $q->field($fields);
 | ||
|         }
 | ||
| 
 | ||
|         if ($callback) {
 | ||
|             $q = $callback($q);
 | ||
|         }
 | ||
| 
 | ||
|         if (count($order)) {
 | ||
|             $q = $q->order($order);
 | ||
|         }
 | ||
| 
 | ||
|         $pageParams['list_rows'] = $limit;
 | ||
| 
 | ||
|         return $q->paginate($pageParams);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 查询列表
 | ||
|      *
 | ||
|      * @param  array  $simpleWhere  简易查询条件
 | ||
|      * @param  array  $fields  查询字段 []表示全部
 | ||
|      * @param  int  $page  默认第一页 0不限制
 | ||
|      * @param  int  $limit  限制条数 0不限制
 | ||
|      * @param  callable|null  $callback  复杂的条件 使用闭包查询
 | ||
|      * @param  array  $orders 键值对,排序
 | ||
|      * @return array
 | ||
|      * @throws Exception
 | ||
|      */
 | ||
|     public static function findList(array $simpleWhere = [], array $fields = [], int $page = 1, int $limit = 0, callable $callback = null, array $orders = []): array
 | ||
|     {
 | ||
|         $q    = new static();
 | ||
|         $data = [
 | ||
|             'total'   => 0,
 | ||
|             'current' => $page,
 | ||
|             'size'    => $limit,
 | ||
|             'list'    => new Collection(),
 | ||
|         ];
 | ||
| 
 | ||
|         if (count($fields)) {
 | ||
|             $q = $q->field($fields);
 | ||
|         }
 | ||
| 
 | ||
|         if (count($simpleWhere)) {
 | ||
|             $q = $q->where($simpleWhere);
 | ||
|         }
 | ||
| 
 | ||
|         if ($callback) {
 | ||
|             $q = $callback($q);
 | ||
|         }
 | ||
| 
 | ||
|         $data['total'] = $q->count();
 | ||
| 
 | ||
|         if ($data['total']) {
 | ||
|             if (count($orders)) {
 | ||
|                 $q = $q->order($orders);
 | ||
|             }
 | ||
|             if ($page) {
 | ||
|                 $q = $q->page($page);
 | ||
|             }
 | ||
|             if ($limit == 0) {
 | ||
|                 $q = $q->limit(1000);
 | ||
|             } else {
 | ||
|                 $q = $q->limit($limit);
 | ||
|             }
 | ||
| 
 | ||
|             $data['list'] = $q->select();
 | ||
|         }
 | ||
| 
 | ||
|         return $data;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取路径
 | ||
|      *
 | ||
|      * @param  int  $pid
 | ||
|      * @return string
 | ||
|      * @throws DataNotFoundException
 | ||
|      * @throws DbException
 | ||
|      * @throws ModelNotFoundException
 | ||
|      */
 | ||
|     public static function getPath(int $pid): string
 | ||
|     {
 | ||
|         if ($pid == 0) {
 | ||
|             $path = ',0,';
 | ||
|         } else {
 | ||
|             $parent = self::findById($pid);
 | ||
|             if (empty($parent)) {
 | ||
|                 $path = ',0,';
 | ||
|             } else {
 | ||
|                 $path = $parent['path'].$parent['id'].',';
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return $path;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 刷新路径
 | ||
|      *
 | ||
|      * @param  int  $pid
 | ||
|      * @param  array  $data  默认全部 若data不为空 至少包含[id,path, $pidField]
 | ||
|      * @param  string  $pidField  父级ID字段名 默认 pid
 | ||
|      * @throws Exception
 | ||
|      */
 | ||
|     public static function refreshPath(int $pid = 0, array $data = [], string $pidField = 'pid')
 | ||
|     {
 | ||
|         $data           = !empty($data) ? $data : self::column('id,path,'.$pidField);
 | ||
|         $updateAllPaths = [];
 | ||
|         self::recursionPath($pid, $data, $updateAllPaths);
 | ||
| 
 | ||
|         (new static())->saveAll($updateAllPaths);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取递归最新路径
 | ||
|      *
 | ||
|      * @param  int  $pid
 | ||
|      * @param  array  $data  全部数据 尽量传全部数据
 | ||
|      * @param  array  $paths
 | ||
|      */
 | ||
|     public static function recursionPath(int $pid, array $data, array &$paths = [])
 | ||
|     {
 | ||
|         foreach ($data as $k => $v) {
 | ||
|             if ($pid == $v['pid']) {
 | ||
|                 $arr       = [];
 | ||
|                 $arr['id'] = $v['id'];
 | ||
|                 if ($pid == 0) {
 | ||
|                     $arr['path'] = ',0,';
 | ||
|                 } else {
 | ||
|                     $arr['path'] = $paths[$v['pid']]['path'].$v['pid'].',';
 | ||
|                 }
 | ||
|                 $paths[$v['id']] = $arr;
 | ||
| 
 | ||
|                 unset($data[$k]);
 | ||
| 
 | ||
|                 self::recursionPath($v['id'], $data, $paths);
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取所有后代ID[包含孙级]  仅对拥有path字段的表生效
 | ||
|      *
 | ||
|      * @param  int  $id
 | ||
|      * @return array
 | ||
|      * @throws DataNotFoundException
 | ||
|      * @throws DbException
 | ||
|      * @throws ModelNotFoundException
 | ||
|      */
 | ||
|     public static function getAllChildrenIds(int $id): array
 | ||
|     {
 | ||
|         $item = self::find($id);
 | ||
|         if ($item && isset($item['path'])) {
 | ||
|             $path = $item['path'].$id.',';
 | ||
|             return self::where('path', 'like', $path.'%')->column('id');
 | ||
|         } else {
 | ||
|             return [];
 | ||
|         }
 | ||
|     }
 | ||
| } |