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 [];
|
||
}
|
||
}
|
||
} |