CRMEB/crmeb/app/dao/BaseDao.php
2026-03-23 14:57:47 +08:00

639 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
/**
* @author: liaofei<136327134@qq.com>
* @day: 2020/7/6
*/
namespace app\dao;
use crmeb\basic\BaseModel;
use think\helper\Str;
use think\Model;
/**
* Class BaseDao
* @package app\dao
*/
abstract class BaseDao
{
/**
* 当前表名别名
* @var string
*/
protected $alias;
/**
* join表别名
* @var string
*/
protected $joinAlis;
/**
* 获取当前模型
* @return string
*/
abstract protected function setModel(): string;
/**
* 设置join链表模型
* @return string
*/
protected function setJoinModel(): string
{
}
/**
* 读取数据条数
* @param array $where
* @param bool $search
* @return int
* @throws \ReflectionException
*/
public function count(array $where = [], bool $search = true)
{
return $this->search($where, $search)->count();
}
/**
* 获取某些条件数据
* @param array $where
* @param string $field
* @param int $page
* @param int $limit
* @param string $order
* @param bool $search
* @return \think\Collection
* @throws \ReflectionException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false)
{
return $this->selectModel($where, $field, $page, $limit, $order, $with, $search)->select();
}
/**
* @param array $where
* @param string $field
* @param int $page
* @param int $limit
* @param string $order
* @param array $with
* @param bool $search
* @return BaseModel
* @throws \ReflectionException
* @author 等风来
* @email 136327134@qq.com
* @date 2023/4/14
*/
public function selectModel(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false)
{
if ($search) {
$model = $this->search($where);
} else {
$model = $this->getModel()->where($where);
}
return $model->field($field)->when($page && $limit, function ($query) use ($page, $limit) {
$query->page($page, $limit);
})->when($order !== '', function ($query) use ($order) {
$query->order($order);
})->when($with, function ($query) use ($with) {
$query->with($with);
});
}
/**
* 获取某些条件总数
* @param array $where
* @return int
*/
public function getCount(array $where)
{
return $this->getModel()->where($where)->count();
}
/**
* 获取某些条件去重总数
* @param array $where
* @param $field
* @param bool $search
* @return int|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getDistinctCount(array $where, $field, bool $search = true)
{
if ($search) {
return $this->search($where)->field('COUNT(distinct(' . $field . ')) as count')->select()->toArray()[0]['count'] ?? 0;
} else {
return $this->getModel()->where($where)->field('COUNT(distinct(' . $field . ')) as count')->select()->toArray()[0]['count'] ?? 0;
}
}
/**
* 获取模型
* @return BaseModel
*/
protected function getModel()
{
return app()->make($this->setModel());
}
/**
* 获取主键
* @return array|string
*/
protected function getPk()
{
return $this->getModel()->getPk();
}
/**
* @return string
* @author 等风来
* @email 136327134@qq.com
* @date 2023/2/8
*/
public function getTableName()
{
return $this->getModel()->getName();
}
/**
* 获取一条数据
* @param $id
* @param array|null $field
* @param array|null $with
* @return array|Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function get($id, ?array $field = [], ?array $with = [])
{
if (is_array($id)) {
$where = $id;
} else {
$where = [$this->getPk() => $id];
}
return $this->getModel()->where($where)->when(count($with), function ($query) use ($with) {
$query->with($with);
})->field($field ?? ['*'])->find();
}
/**
* 查询一条数据是否存在
* @param $map
* @param string $field
* @return bool 是否存在
*/
public function be($map, string $field = '')
{
if (!is_array($map) && empty($field)) $field = $this->getPk();
$map = !is_array($map) ? [$field => $map] : $map;
return 0 < $this->getModel()->where($map)->count();
}
/**
* 根据条件获取一条数据
* @param array $where
* @param string|null $field
* @param array $with
* @return array|Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getOne(array $where, ?string $field = '*', array $with = [])
{
$field = explode(',', $field);
return $this->get($where, $field, $with);
}
/**
* 获取单个字段值
* @param $where
* @param string|null $field
* @return mixed
*/
public function value($where, ?string $field = '')
{
$pk = $this->getPk();
return $this->search($this->setWhere($where))->value($field ?: $pk);
}
/**
* 获取某个字段数组
* @param array $where
* @param string $field
* @param string $key
* @return array
*/
public function getColumn(array $where, string $field, string $key = '')
{
return $this->getModel()->where($where)->column($field, $key);
}
/**
* 删除
* @param int|string|array $id
* @return mixed
*/
public function delete($id, ?string $key = null)
{
if (is_array($id)) {
$where = $id;
} else {
$where = [is_null($key) ? $this->getPk() : $key => $id];
}
return $this->getModel()->where($where)->delete();
}
/**
* 删除记录
* @param int $id
* @param bool $force
* @return bool
* @author 等风来
* @email 136327134@qq.com
* @date 2023/4/15
*/
public function destroy(int $id, bool $force = false)
{
return $this->getModel()->destroy($id, $force);
}
/**
* 更新数据
* @param int|string|array $id
* @param array $data
* @param string|null $key
* @return BaseModel
*/
public function update($id, array $data, ?string $key = null)
{
if (is_array($id)) {
$where = $id;
} else {
$where = [is_null($key) ? $this->getPk() : $key => $id];
}
return $this->getModel()::update($data, $where);
}
/**
* @param $where
* @return array|mixed
* @author 等风来
* @email 136327134@qq.com
* @date 2023/4/6
*/
protected function setWhere($where, ?string $key = null)
{
if (!is_array($where)) {
$where = [is_null($key) ? $this->getPk() : $key => $where];
}
return $where;
}
/**
* 批量更新数据
* @param array $ids
* @param array $data
* @param string|null $key
* @return BaseModel
*/
public function batchUpdate(array $ids, array $data, ?string $key = null)
{
return $this->getModel()->whereIn(is_null($key) ? $this->getPk() : $key, $ids)->update($data);
}
/**
* 插入数据
* @param array $data
* @return mixed
*/
public function save(array $data)
{
return $this->getModel()::create($data);
}
/**
* 插入数据
* @param array $data
* @return \think\Collection
* @throws \Exception
*/
public function saveAll(array $data)
{
return $this->getModel()->saveAll($data);
}
/**
* 获取某个字段内的值
* @param $value
* @param string $filed
* @param string|null $valueKey
* @param array|string[] $where
* @return mixed
*/
public function getFieldValue($value, string $filed, ?string $valueKey = '', ?array $where = [])
{
return $this->getModel()->getFieldValue($value, $filed, $valueKey, $where);
}
/**
* 获取搜索器和搜索条件key,以及不在搜索器的条件数组
* @param array $where
* @return array[]
* @throws \ReflectionException
* @author 吴汐
* @email 442384644@qq.com
* @date 2023/03/18
*/
private function getSearchData(array $where)
{
$with = [];
$otherWhere = [];
$responses = new \ReflectionClass($this->setModel());
foreach ($where as $key => $value) {
$method = 'search' . Str::studly($key) . 'Attr';
if ($responses->hasMethod($method)) {
$with[] = $key;
} else {
if (!in_array($key, ['timeKey', 'store_stock', 'integral_time'], true)) {
if (!is_array($value)) {
$otherWhere[] = [$key, '=', $value];
} else if (count($value) === 3) {
$otherWhere[] = $value;
}
}
}
}
return [$with, $otherWhere];
}
/**
* 根据搜索器获取搜索内容
* @param $where
* @param $search
* @return BaseModel
* @throws \ReflectionException
* @author 吴汐
* @email 442384644@qq.com
* @date 2023/03/18
*/
protected function withSearchSelect($where, $search)
{
[$with, $otherWhere] = $this->getSearchData($where);
return $this->getModel()->withSearch($with, $where)->when($search, function ($query) use ($otherWhere) {
$query->where($this->filterWhere($otherWhere));
});
}
/**
* 过滤数据表中不存在的where条件字段
* @param array $where
* @return array
* @author 吴汐
* @email 442384644@qq.com
* @date 2023/04/11
*/
protected function filterWhere(array $where = [])
{
$fields = $this->getModel()->getTableFields();
foreach ($where as $key => $item) {
if (!in_array($item[0], $fields)) {
unset($where[$key]);
}
}
return $where;
}
/**
* 搜索
* @param array $where
* @param bool $search
* @return BaseModel
* @throws \ReflectionException
* @author 吴汐
* @email 442384644@qq.com
* @date 2023/03/18
*/
public function search(array $where = [], bool $search = true)
{
if ($where) {
return $this->withSearchSelect($where, $search);
} else {
return $this->getModel();
}
}
/**
* 求和
* @param array $where
* @param string $field
* @param bool $search
* @return float
* @throws \ReflectionException
*/
public function sum(array $where, string $field, bool $search = false)
{
if ($search) {
return $this->search($where)->sum($field);
} else {
return $this->getModel()->where($where)->sum($field);
}
}
/**
* 高精度加法
* @param $key
* @param string $incField
* @param string $inc
* @param string|null $keyField
* @param int $acc
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function bcInc($key, string $incField, string $inc, string $keyField = null, int $acc = 2)
{
return $this->bc($key, $incField, $inc, $keyField, 1);
}
/**
* 高精度 减法
* @param $key
* @param string $decField
* @param string $dec
* @param string|null $keyField
* @param int $acc
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function bcDec($key, string $decField, string $dec, string $keyField = null, int $acc = 2)
{
return $this->bc($key, $decField, $dec, $keyField, 2);
}
/**
* 高精度计算并保存
* @param $key
* @param string $incField
* @param string $inc
* @param string|null $keyField
* @param int $type
* @param int $acc
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function bc($key, string $incField, string $inc, string $keyField = null, int $type = 1, int $acc = 2)
{
if ($keyField === null) {
$result = $this->get($key);
} else {
$result = $this->getOne([$keyField => $key]);
}
if (!$result) return false;
$new = 0;
if ($type === 1) {
$new = bcadd($result[$incField], $inc, $acc);
} else if ($type === 2) {
if ($result[$incField] < $inc) return false;
$new = bcsub($result[$incField], $inc, $acc);
}
$result->{$incField} = $new;
return false !== $result->save();
}
/**
* 减库存加销量
* @param array $where
* @param int $num
* @param string $stock
* @param string $sales
* @return false
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function decStockIncSales(array $where, int $num, string $stock = 'stock', string $sales = 'sales')
{
$isQuota = false;
if (isset($where['type']) && $where['type']) {
$isQuota = true;
if (count($where) == 2) {
unset($where['type']);
}
}
$field = $isQuota ? 'stock,quota' : 'stock';
$product = $this->getModel()->where($where)->field($field)->find();
if ($product) {
return $this->getModel()->where($where)->when($isQuota, function ($query) use ($num) {
$query->dec('quota', $num);
})->dec($stock, $num)->inc($sales, $num)->update();
}
return false;
}
/**
* 加库存减销量
* @param array $where
* @param int $num
* @param string $stock
* @param string $sales
* @return mixed
*/
public function incStockDecSales(array $where, int $num, string $stock = 'stock', string $sales = 'sales')
{
$isQuota = false;
if (isset($where['type']) && $where['type']) {
$isQuota = true;
if (count($where) == 2) {
unset($where['type']);
}
}
$salesOne = $this->getModel()->where($where)->value($sales);
if ($salesOne) {
$salesNum = $num;
if ($num > $salesOne) {
$salesNum = $salesOne;
}
return $this->getModel()->where($where)->when($isQuota, function ($query) use ($num) {
$query->inc('quota', $num);
})->inc($stock, $num)->dec($sales, $salesNum)->update();
}
return true;
}
/**
* 获取条件数据中的某个值的最大值
* @param array $where
* @param string $field
* @return mixed
*/
public function getMax(array $where = [], string $field = '')
{
return $this->getModel()->where($where)->max($field);
}
/**
* 获取条件数据中的某个值的最小值
* @param array $where
* @param string $field
* @return mixed
*/
public function getMin(array $where = [], string $field = '')
{
return $this->getModel()->where($where)->min($field);
}
/**
* 获取(条件)按照(排序)的第一条
* @param array $where
* @param string $order
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/9/12
*/
public function getOrderOne(array $where = [], string $order = 'id desc')
{
return $this->getModel()->where($where)->order($order)->find();
}
/**
* 插入数据并返回自增ID
* @param array $data
* @return int|string
* @author wuhaotian
* @email 442384644@qq.com
* @date 2025/12/11
*/
public function insertGetId(array $data)
{
return $this->getModel()->insertGetId($data);
}
}