add
This commit is contained in:
77
app/admin/model/Admin.php
Normal file
77
app/admin/model/Admin.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* Admin模型
|
||||
* @property int $id 管理员ID
|
||||
* @property string $username 管理员用户名
|
||||
* @property string $nickname 管理员昵称
|
||||
* @property string $email 管理员邮箱
|
||||
* @property string $mobile 管理员手机号
|
||||
* @property string $last_login_ip 上次登录IP
|
||||
* @property string $last_login_time 上次登录时间
|
||||
* @property int $login_failure 登录失败次数
|
||||
* @property string $password 密码密文
|
||||
* @property string $salt 密码盐(废弃待删)
|
||||
* @property string $status 状态:enable=启用,disable=禁用,...(string存储,可自定义其他)
|
||||
*/
|
||||
class Admin extends Model
|
||||
{
|
||||
/**
|
||||
* @var string 自动写入时间戳
|
||||
*/
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 追加属性
|
||||
*/
|
||||
protected $append = [
|
||||
'group_arr',
|
||||
'group_name_arr',
|
||||
];
|
||||
|
||||
public function getGroupArrAttr($value, $row): array
|
||||
{
|
||||
return Db::name('admin_group_access')
|
||||
->where('uid', $row['id'])
|
||||
->column('group_id');
|
||||
}
|
||||
|
||||
public function getGroupNameArrAttr($value, $row): array
|
||||
{
|
||||
$groupAccess = Db::name('admin_group_access')
|
||||
->where('uid', $row['id'])
|
||||
->column('group_id');
|
||||
return AdminGroup::whereIn('id', $groupAccess)->column('name');
|
||||
}
|
||||
|
||||
public function getAvatarAttr($value): string
|
||||
{
|
||||
return full_url($value, false, config('buildadmin.default_avatar'));
|
||||
}
|
||||
|
||||
public function setAvatarAttr($value): string
|
||||
{
|
||||
return $value == full_url('', false, config('buildadmin.default_avatar')) ? '' : $value;
|
||||
}
|
||||
|
||||
public function getLastLoginTimeAttr($value): string
|
||||
{
|
||||
return $value ? date('Y-m-d H:i:s', $value) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
* @param int|string $uid 管理员ID
|
||||
* @param string $newPassword 新密码
|
||||
* @return int|Admin
|
||||
*/
|
||||
public function resetPassword(int|string $uid, string $newPassword): int|Admin
|
||||
{
|
||||
return $this->where(['id' => $uid])->update(['password' => hash_password($newPassword), 'salt' => '']);
|
||||
}
|
||||
}
|
||||
13
app/admin/model/AdminGroup.php
Normal file
13
app/admin/model/AdminGroup.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* AdminGroup模型
|
||||
*/
|
||||
class AdminGroup extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
}
|
||||
167
app/admin/model/AdminLog.php
Normal file
167
app/admin/model/AdminLog.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\facade\Db;
|
||||
use Throwable;
|
||||
use think\Model;
|
||||
use app\admin\library\Auth;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
/**
|
||||
* AdminLog模型
|
||||
*/
|
||||
class AdminLog extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
protected $updateTime = false;
|
||||
|
||||
/**
|
||||
* 自定义日志标题
|
||||
* @var string
|
||||
*/
|
||||
protected string $title = '';
|
||||
|
||||
/**
|
||||
* 自定义日志内容
|
||||
* @var string|array
|
||||
*/
|
||||
protected string|array $data = '';
|
||||
|
||||
/**
|
||||
* 忽略的链接正则列表
|
||||
* @var array
|
||||
*/
|
||||
protected array $urlIgnoreRegex = [
|
||||
'/^(.*)\/(select|index|logout)$/i',
|
||||
];
|
||||
|
||||
protected array $desensitizationRegex = [
|
||||
'/(password|salt|token)/i'
|
||||
];
|
||||
|
||||
public static function instance()
|
||||
{
|
||||
$request = request();
|
||||
if (!isset($request->adminLog)) {
|
||||
$request->adminLog = new static();
|
||||
}
|
||||
return $request->adminLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle(string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置日志内容
|
||||
* @param string|array $data
|
||||
*/
|
||||
public function setData(string|array $data): void
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置忽略的链接正则列表
|
||||
* @param array|string $regex
|
||||
*/
|
||||
public function setUrlIgnoreRegex(array|string $regex = []): void
|
||||
{
|
||||
$regex = is_array($regex) ? $regex : [$regex];
|
||||
$this->urlIgnoreRegex = array_merge($this->urlIgnoreRegex, $regex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要进行数据脱敏的正则列表
|
||||
* @param array|string $regex
|
||||
*/
|
||||
public function setDesensitizationRegex(array|string $regex = []): void
|
||||
{
|
||||
$regex = is_array($regex) ? $regex : [$regex];
|
||||
$this->desensitizationRegex = array_merge($this->desensitizationRegex, $regex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据脱敏(只数组,根据数组 key 脱敏)
|
||||
* @param array|string $data
|
||||
* @return array|string
|
||||
*/
|
||||
protected function desensitization(array|string $data): array|string
|
||||
{
|
||||
if (!is_array($data) || !$this->desensitizationRegex) {
|
||||
return $data;
|
||||
}
|
||||
foreach ($data as $index => &$item) {
|
||||
foreach ($this->desensitizationRegex as $reg) {
|
||||
if (preg_match($reg, $index)) {
|
||||
$item = "***";
|
||||
} elseif (is_array($item)) {
|
||||
$item = $this->desensitization($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入日志
|
||||
* @param string $title
|
||||
* @param string|array|null $data
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function record(string $title = '', string|array $data = null): void
|
||||
{
|
||||
$auth = Auth::instance();
|
||||
$adminId = $auth->isLogin() ? $auth->user_id : 0;
|
||||
$username = $auth->isLogin() ? $auth->username : request()->param('username', __('Unknown'));
|
||||
|
||||
$controller = str_replace('.', '/', request()->controller(true));
|
||||
$action = request()->action(true);
|
||||
$path = $controller . '/' . $action;
|
||||
if ($this->urlIgnoreRegex) {
|
||||
foreach ($this->urlIgnoreRegex as $item) {
|
||||
if (preg_match($item, $path)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data = $data ?: $this->data;
|
||||
if (!$data) {
|
||||
$data = request()->param('', null, 'trim,strip_tags,htmlspecialchars');
|
||||
}
|
||||
$data = $this->desensitization($data);
|
||||
$title = $title ?: $this->title;
|
||||
if (!$title) {
|
||||
|
||||
$slave_db = Db::connect(config('database.search_library'));
|
||||
$admin_rule = $slave_db->name('sys_menu');
|
||||
$controllerTitle = $admin_rule->where('url', $controller)->value('name');
|
||||
$title = $admin_rule->where('url', $path)->value('name');
|
||||
$title = $title ?: __('Unknown') . '(' . $action . ')';
|
||||
$title = $controllerTitle ? ($controllerTitle . '-' . $title) : $title;
|
||||
}
|
||||
|
||||
// 主库写入
|
||||
$master_db = Db::connect(config('database.z_library'));
|
||||
$master_db->name('sys_log')->insert([
|
||||
'username' => $username,
|
||||
'method' => substr(request()->url(), 0, 1500),
|
||||
'operation' => $title,
|
||||
'params' => !is_scalar($data) ? json_encode($data) : $data,
|
||||
'ip' => request()->ip(),
|
||||
'time' => 0,
|
||||
// 'useragent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
|
||||
]);
|
||||
}
|
||||
|
||||
public function admin(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Admin::class);
|
||||
}
|
||||
}
|
||||
21
app/admin/model/AdminRule.php
Normal file
21
app/admin/model/AdminRule.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* AdminRule 模型
|
||||
* @property int $status 状态:0=禁用,1=启用
|
||||
*/
|
||||
class AdminRule extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
public function setComponentAttr($value)
|
||||
{
|
||||
if ($value) $value = str_replace('\\', '/', $value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
293
app/admin/model/Cash.php
Normal file
293
app/admin/model/Cash.php
Normal file
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\library\DatabaseRoute;
|
||||
use ba\Exception;
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
|
||||
|
||||
class Cash extends Model
|
||||
{
|
||||
public static function statisticsIncomeMoney($time, $flag, $num)
|
||||
{
|
||||
$rest = DatabaseRoute::getAllDbData('pay_details', function ($query) use ($time, $flag, $num) {
|
||||
$query->where(['state' => 1]);
|
||||
if(!empty($flag)) {
|
||||
if($flag == 1) {
|
||||
$query->whereTime('create_time', '>=', strtotime(date('Y-m-d 00:00:00', strtotime($time))));
|
||||
$query->whereTime('create_time', '<=', strtotime(date('Y-m-d 23:59:59', strtotime($time))));
|
||||
}
|
||||
if($flag == 2) {
|
||||
$query->whereTime('create_time', '>=', strtotime(date('Y-m-01 00:00:00', strtotime($time))));
|
||||
$query->whereTime('create_time', '<=', strtotime(date('Y-m-t 23:59:59', strtotime($time))));
|
||||
}
|
||||
if($flag == 3) {
|
||||
$query->whereTime('create_time', '>=', strtotime(date('Y-01-01 00:00:00', strtotime($time))));
|
||||
$query->whereTime('create_time', '<=', strtotime(date('Y-12-31 23:59:59', strtotime($time))));
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
})->sum('money');
|
||||
return $rest;
|
||||
}
|
||||
|
||||
|
||||
public static function selectPayDetails($get)
|
||||
{
|
||||
return DatabaseRoute::paginateAllDb('pay_details', function ($query)use($get){
|
||||
$query->alias('s')
|
||||
->field([
|
||||
's.id',
|
||||
's.classify',
|
||||
's.order_id as orderId',
|
||||
's.money',
|
||||
's.user_id as userId',
|
||||
's.pay_diamond as payDiamond',
|
||||
's.diamond',
|
||||
's.state',
|
||||
's.create_time as createTime',
|
||||
's.pay_time as payTime',
|
||||
'u.user_name as userName',
|
||||
'u.phone'
|
||||
])
|
||||
->leftJoin('tb_user u', 'u.user_id = s.user_id');
|
||||
// 添加动态查询条件
|
||||
if (!empty($get['startTime']) && !empty($get['endTime'])) {
|
||||
$query->whereBetween('s.create_time', [$get['startTime'], $get['endTime']]);
|
||||
}
|
||||
if (!empty($get['userName'])) {
|
||||
$query->where('u.user_name', 'like', "%{$get['userName']}%");
|
||||
}
|
||||
if (!empty($get['orderId'])) {
|
||||
$query->where('s.order_id', 'like', "%{$get['orderId']}%");
|
||||
}
|
||||
if (isset($get['userId']) && $get['userId'] !== null) {
|
||||
$query->where('u.user_id', $get['userId']);
|
||||
}
|
||||
if (isset($get['state']) && $get['state'] !== -1) {
|
||||
$query->where('s.state', $get['state']);
|
||||
} elseif (!isset($get['state']) || $get['state'] === -1) {
|
||||
$query->where('s.state', '<>', -1);
|
||||
}
|
||||
return $query;
|
||||
}, $get['page'], $get['limit'], 's.create_time');
|
||||
}
|
||||
|
||||
|
||||
public static function selectCashOutList($page, $limit, $cashOut, $isApp = false):array
|
||||
{
|
||||
$cashOutList = DatabaseRoute::paginateAllDb('cash_out', function ($query)use($page, $limit, $cashOut, $isApp){
|
||||
// 根据请求端设置不同查询条件
|
||||
if ($isApp) {
|
||||
// APP端:查询用户自身的提现记录(用户类型1)
|
||||
$query->where('user_id', $cashOut['user_id'] ?? 0)
|
||||
->where('user_type', 1);
|
||||
} else {
|
||||
// 管理后台:根据条件查询
|
||||
if (isset($cashOut['user_id'])) {
|
||||
$query->where('user_id', $cashOut['user_id']);
|
||||
} else {
|
||||
if (!isset($cashOut['sys_user_id'])) {
|
||||
return $query;
|
||||
} else {
|
||||
// 查询系统用户的提现记录(用户类型2)
|
||||
$query->where('user_id', $cashOut['sys_user_id'])
|
||||
->where('user_type', 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}, $page, $limit, 'create_at');
|
||||
|
||||
if (!$isApp) {
|
||||
// 管理后台:补充用户信息和统计数据
|
||||
$userIdList = [];
|
||||
foreach ($cashOutList['list'] as $out) {
|
||||
$userIdList[] = $out['user_id'];
|
||||
}
|
||||
|
||||
// 查询用户提现总数和总金额
|
||||
$cashoutSumMap = [];
|
||||
$cashoutVerifySumMap = [];
|
||||
$userinfoMap = [];
|
||||
|
||||
if (!empty($userIdList)) {
|
||||
// 获取已完成提现统计
|
||||
$cashoutSumList = \app\api\model\Cash::selectSumByUserIdList($userIdList, 1);
|
||||
$cashoutSumMap = array_column($cashoutSumList, null, 'user_id');
|
||||
|
||||
// 获取审核中提现统计
|
||||
$cashoutVerifyList = \app\api\model\Cash::selectSumByUserIdList($userIdList, 3);
|
||||
$cashoutVerifySumMap = array_column($cashoutVerifyList, null, 'user_id');
|
||||
|
||||
// 获取用户信息
|
||||
$userList = DatabaseRoute::getAllDbData('tb_user', function ($query) use($userIdList) {
|
||||
return $query->whereIn('user_id', $userIdList)
|
||||
->field('user_id, user_name');
|
||||
})->select();
|
||||
|
||||
|
||||
$userinfoMap = array_column($userList->toArray(), 'user_name', 'user_id');
|
||||
}
|
||||
|
||||
// 补充数据到提现记录
|
||||
foreach ($cashOutList['list'] as &$item) {
|
||||
$info = $cashoutSumMap[$item['user_id']] ?? null;
|
||||
$info2 = $cashoutVerifySumMap[$item['user_id']] ?? null;
|
||||
|
||||
$item['user_name'] = $userinfoMap[$item['user_id']] ?? '';
|
||||
$item['count'] = $info ? $info['count'] : 0;
|
||||
$item['total'] = $info ? $info['total'] : 0.00;
|
||||
$item['verify_count'] = $info2 ? $info2['count'] : 0;
|
||||
$item['verify_total'] = $info2 ? $info2['total'] : 0.00;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isApp) {
|
||||
// APP端:对敏感信息进行脱敏处理
|
||||
foreach ($cashOutList['list'] as &$item) {
|
||||
if (!empty($item['bank_name'])) {
|
||||
// 银行卡号脱敏
|
||||
$item['zhifubao'] = bankCard($item['zhifubao']);
|
||||
} elseif (filter_var($item['zhifubao'], FILTER_VALIDATE_EMAIL)) {
|
||||
// 邮箱脱敏
|
||||
$item['zhifubao'] = email($item['zhifubao']);
|
||||
} elseif (preg_match('/^1[3-9]\d{9}$/', $item['zhifubao'])) {
|
||||
// 手机号脱敏
|
||||
$item['zhifubao'] = maskPhoneNumber($item['zhifubao']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cashOutList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退回提现金额
|
||||
* @param array $entity 提现实体
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function backCashAmount($entity, $db)
|
||||
{
|
||||
// 开启事务确保数据一致性
|
||||
$db->startTrans();
|
||||
try {
|
||||
if ($entity['user_type'] == 2) {
|
||||
// 代理用户退款逻辑
|
||||
$detailsData = [
|
||||
'user_id' => $entity['user_id'],
|
||||
'operate_id' => $entity['user_id'],
|
||||
'title' => "提现失败存入余额",
|
||||
'type' => 4,
|
||||
'money_type' => 1,
|
||||
'money' => $entity['money'],
|
||||
'content' => "提现失败存入余额{$entity['money']}元",
|
||||
'status' => 1,
|
||||
'create_time' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
// 记录资金流水
|
||||
$db->name('sys_user_money_details')->insert($detailsData);
|
||||
|
||||
// 更新代理账户余额(增加余额)
|
||||
self::updateSysMoney(1, $entity['user_id'], $entity['money']);
|
||||
} else {
|
||||
// 普通用户退款逻辑
|
||||
self::updateByUserId($entity, $db);
|
||||
|
||||
$detailsData = [
|
||||
'user_id' => $entity['user_id'],
|
||||
'sys_user_id' => $entity['sys_user_id'] ?? null,
|
||||
'title' => "[提现退款]",
|
||||
'type' => 4,
|
||||
'money_type' => 1,
|
||||
'money' => $entity['money'],
|
||||
'content' => "提现失败,自动退款{$entity['money']}元",
|
||||
'status' => 1,
|
||||
'cash_out_id' => $entity['id'],
|
||||
'create_time' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
// 记录资金流水
|
||||
$db->name('user_money_details')->insert($detailsData);
|
||||
|
||||
// 归还用户余额
|
||||
self::updateAmount(1, $entity['user_id'], $entity['money'], $db);
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
$db->commit();
|
||||
} catch (Exception $e) {
|
||||
// 回滚事务
|
||||
$db->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function updateSysMoney($type, $userId, $money)
|
||||
{
|
||||
$query = Db::name('sys_user_money')
|
||||
->where('user_id', $userId);
|
||||
|
||||
// 根据类型决定是增加还是减少余额
|
||||
if ($type == 1) {
|
||||
// 增加余额
|
||||
return $query->inc('money', $money)->update();
|
||||
} elseif ($type == 2) {
|
||||
// 减少余额
|
||||
return $query->dec('money', $money)->update();
|
||||
}
|
||||
return 0; // 无效类型返回 0
|
||||
}
|
||||
|
||||
|
||||
public static function updateAmount($type, $userId, $amount, $db)
|
||||
{
|
||||
User::selectUserMoneyByUserId($userId);
|
||||
// 构建基础查询
|
||||
$query = $db->name('user_money')
|
||||
->where('user_id', $userId);
|
||||
|
||||
// 根据类型执行增减操作
|
||||
if ($type == 1) {
|
||||
// 增加金额:amount = amount + #{amount}
|
||||
return $query->inc('amount', $amount)->update();
|
||||
} elseif ($type == 2) {
|
||||
// 减少金额:amount = amount - #{amount}
|
||||
// 可选:添加余额充足校验
|
||||
return $query->where('amount', '>=', $amount) // 确保余额不小于要减少的金额
|
||||
->dec('amount', $amount)
|
||||
->update();
|
||||
}
|
||||
|
||||
return 0; // 无效类型返回0
|
||||
}
|
||||
|
||||
|
||||
public static function updateByUserId($entity, $db)
|
||||
{
|
||||
// 验证userId是否存在
|
||||
if (empty($entity['user_id'])) {
|
||||
throw new Exception("cashOut修改失败: userId必须传递");
|
||||
}
|
||||
|
||||
// 构建更新条件
|
||||
$conditions = [
|
||||
'user_id' => $entity['user_id'],
|
||||
'id' => $entity['id']
|
||||
];
|
||||
|
||||
// 过滤掉主键和条件字段,避免更新这些字段
|
||||
$updateData = $entity;
|
||||
unset($updateData['user_id'], $updateData['id']);
|
||||
|
||||
// 执行更新操作
|
||||
$db->name('cash_out')
|
||||
->where($conditions)
|
||||
->update($updateData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
133
app/admin/model/Config.php
Normal file
133
app/admin/model/Config.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use Throwable;
|
||||
use think\Model;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 系统配置模型
|
||||
* @property mixed $content
|
||||
* @property mixed $rule
|
||||
* @property mixed $extend
|
||||
* @property mixed $allow_del
|
||||
*/
|
||||
class Config extends Model
|
||||
{
|
||||
public static string $cacheTag = 'sys_config';
|
||||
|
||||
protected $append = [
|
||||
'value',
|
||||
'content',
|
||||
'extend',
|
||||
'input_extend',
|
||||
];
|
||||
|
||||
protected array $jsonDecodeType = ['checkbox', 'array', 'selects'];
|
||||
protected array $needContent = ['radio', 'checkbox', 'select', 'selects'];
|
||||
|
||||
/**
|
||||
* 入库前
|
||||
* @throws Throwable
|
||||
*/
|
||||
public static function onBeforeInsert(Config $model): void
|
||||
{
|
||||
if (!in_array($model->getData('type'), $model->needContent)) {
|
||||
$model->content = null;
|
||||
} else {
|
||||
$model->content = json_encode(str_attr_to_array($model->getData('content')));
|
||||
}
|
||||
if (is_array($model->rule)) {
|
||||
$model->rule = implode(',', $model->rule);
|
||||
}
|
||||
if ($model->getData('extend') || $model->getData('inputExtend')) {
|
||||
$extend = str_attr_to_array($model->getData('extend'));
|
||||
$inputExtend = str_attr_to_array($model->getData('inputExtend'));
|
||||
if ($inputExtend) $extend['baInputExtend'] = $inputExtend;
|
||||
if ($extend) $model->extend = json_encode($extend);
|
||||
}
|
||||
$model->allow_del = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入后
|
||||
*/
|
||||
public static function onAfterWrite(): void
|
||||
{
|
||||
// 清理配置缓存
|
||||
Cache::tag(self::$cacheTag)->clear();
|
||||
}
|
||||
|
||||
public function getValueAttr($value, $row)
|
||||
{
|
||||
if (!isset($row['type']) || $value == '0') return $value;
|
||||
if (in_array($row['type'], $this->jsonDecodeType)) {
|
||||
return empty($value) ? [] : json_decode($value, true);
|
||||
} elseif ($row['type'] == 'switch') {
|
||||
return (bool)$value;
|
||||
} elseif ($row['type'] == 'editor') {
|
||||
return !$value ? '' : htmlspecialchars_decode($value);
|
||||
} elseif (in_array($row['type'], ['city', 'remoteSelects'])) {
|
||||
if (!$value) return [];
|
||||
if (!is_array($value)) return explode(',', $value);
|
||||
return $value;
|
||||
} else {
|
||||
return $value ?: '';
|
||||
}
|
||||
}
|
||||
|
||||
public function setValueAttr(mixed $value, $row): mixed
|
||||
{
|
||||
if (in_array($row['type'], $this->jsonDecodeType)) {
|
||||
return $value ? json_encode($value) : '';
|
||||
} elseif ($row['type'] == 'switch') {
|
||||
return $value ? '1' : '0';
|
||||
} elseif ($row['type'] == 'time') {
|
||||
return $value ? date('H:i:s', strtotime($value)) : '';
|
||||
} elseif ($row['type'] == 'city') {
|
||||
if ($value && is_array($value)) {
|
||||
return implode(',', $value);
|
||||
}
|
||||
return $value ?: '';
|
||||
} elseif (is_array($value)) {
|
||||
return implode(',', $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getContentAttr($value, $row)
|
||||
{
|
||||
if (!isset($row['type'])) return '';
|
||||
if (in_array($row['type'], $this->needContent)) {
|
||||
$arr = json_decode($value, true);
|
||||
return $arr ?: [];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function getExtendAttr($value)
|
||||
{
|
||||
if ($value) {
|
||||
$arr = json_decode($value, true);
|
||||
if ($arr) {
|
||||
unset($arr['baInputExtend']);
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getInputExtendAttr($value, $row)
|
||||
{
|
||||
if ($row && $row['extend']) {
|
||||
$arr = json_decode($row['extend'], true);
|
||||
if ($arr && isset($arr['baInputExtend'])) {
|
||||
return $arr['baInputExtend'];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
24
app/admin/model/CrudLog.php
Normal file
24
app/admin/model/CrudLog.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* Log
|
||||
*/
|
||||
class CrudLog extends Model
|
||||
{
|
||||
// 表名
|
||||
protected $name = 'crud_log';
|
||||
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = true;
|
||||
protected $updateTime = false;
|
||||
|
||||
protected $type = [
|
||||
'table' => 'array',
|
||||
'fields' => 'array',
|
||||
];
|
||||
|
||||
}
|
||||
15
app/admin/model/DataRecycle.php
Normal file
15
app/admin/model/DataRecycle.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* DataRecycle 模型
|
||||
*/
|
||||
class DataRecycle extends Model
|
||||
{
|
||||
protected $name = 'security_data_recycle';
|
||||
|
||||
protected $autoWriteTimestamp = true;
|
||||
}
|
||||
27
app/admin/model/DataRecycleLog.php
Normal file
27
app/admin/model/DataRecycleLog.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
/**
|
||||
* DataRecycleLog 模型
|
||||
*/
|
||||
class DataRecycleLog extends Model
|
||||
{
|
||||
protected $name = 'security_data_recycle_log';
|
||||
|
||||
protected $autoWriteTimestamp = true;
|
||||
protected $updateTime = false;
|
||||
|
||||
public function recycle(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DataRecycle::class, 'recycle_id');
|
||||
}
|
||||
|
||||
public function admin(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Admin::class, 'admin_id');
|
||||
}
|
||||
}
|
||||
151
app/admin/model/DiscSpinning.php
Normal file
151
app/admin/model/DiscSpinning.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\library\DatabaseRoute;
|
||||
use ba\Exception;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* UserGroup 模型
|
||||
*/
|
||||
class DiscSpinning extends Model
|
||||
{
|
||||
|
||||
|
||||
public static function updateBatchById(array $entityList, int $batchSize = 50)
|
||||
{
|
||||
// 验证实体列表非空
|
||||
if (empty($entityList)) {
|
||||
throw new Exception("error: entityList must not be empty");
|
||||
}
|
||||
// 获取主键字段名(默认假设为 'id',可根据实际情况调整)
|
||||
$primaryKey = 'id';
|
||||
$modelName = 'disc_spinning';
|
||||
// 开启事务确保数据一致性
|
||||
Db::startTrans();
|
||||
try {
|
||||
$count = 0;
|
||||
foreach ($entityList as $entity) {
|
||||
// 验证实体包含主键
|
||||
if (!isset($entity[$primaryKey])) {
|
||||
throw new Exception("Entity must contain primary key '{$primaryKey}'");
|
||||
}
|
||||
|
||||
// 构建更新数据(排除主键字段)
|
||||
$updateData = array_diff_key($entity, [$primaryKey => null]);
|
||||
|
||||
// 执行更新(使用模型或Db类)
|
||||
Db::name($modelName)
|
||||
->where($primaryKey, $entity[$primaryKey])
|
||||
->update($updateData);
|
||||
|
||||
// 每batchSize条记录刷新一次(提交部分事务)
|
||||
$count++;
|
||||
if ($count % $batchSize === 0) {
|
||||
Db::commit();
|
||||
Db::startTrans(); // 重新开启事务
|
||||
}
|
||||
}
|
||||
|
||||
// 提交剩余事务
|
||||
Db::commit();
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
// 回滚事务
|
||||
Db::rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function receive1($receive)
|
||||
{
|
||||
$userId = $receive['user_id'] ?? 0;
|
||||
$drawCount = self::countDraw($userId);
|
||||
$maxDraws = Db::name('common_info')
|
||||
->where('type', 901)
|
||||
->value('value');
|
||||
// 校验是否超过限制
|
||||
if ($drawCount > $maxDraws) {
|
||||
Log::write('超过限制' . $receive['id'] . '/' . $drawCount);
|
||||
return false; // 超过次数限制,终止处理
|
||||
}
|
||||
|
||||
// 查询抽奖记录
|
||||
$recordId = $receive['id'] ?? 0;
|
||||
$db = Db::connect(DatabaseRoute::getConnection('disc_spinning_record', ['user_id' => $userId]));
|
||||
$record = $db->name('disc_spinning_record')->find($recordId);
|
||||
// 校验记录是否已处理
|
||||
if (!empty($record['target_id'])) {
|
||||
Log::write('记录已处理无需继续处理' . $record['id'] . '/' . $record['target_id']);
|
||||
return false; // 已处理,终止处理
|
||||
}
|
||||
self::receiveAsync($record);
|
||||
}
|
||||
|
||||
|
||||
public static function countDraw($userId)
|
||||
{
|
||||
return DatabaseRoute::getDb('disc_spinning_record', $userId)->where('source', 'order')->where('draw_day', date('Y-m-d'))
|
||||
->count();
|
||||
}
|
||||
|
||||
public static function receiveAsync($receive)
|
||||
{
|
||||
Log::write('正式补偿' . $receive['id']);
|
||||
// 校验奖励类型(必须为2)
|
||||
if (($receive['type'] ?? 0) != 2) {
|
||||
Log::info("非现金转盘奖励,type={$receive['type']}");
|
||||
return false;
|
||||
}
|
||||
|
||||
$db_name = DatabaseRoute::getConnection('tb_user', ['user_id' => $receive['user_id']], true);
|
||||
$db = Db::connect($db_name);
|
||||
|
||||
// 获取用户信息
|
||||
$userInfo = $db->name('tb_user')->where('user_id', $receive['user_id'])->find();
|
||||
if (!$userInfo || $userInfo['status'] == 0) {
|
||||
Log::info("用户状态无效,user_id={$receive['user_id']}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 开启事务确保数据一致性
|
||||
$db->startTrans();
|
||||
try {
|
||||
// 创建资金流水记录
|
||||
$moneyDetails = [
|
||||
'user_id' => $receive['user_id'],
|
||||
'title' => "[现金大转盘]",
|
||||
'type' => 1,
|
||||
'money_type' => 1,
|
||||
'money' => $receive['number'],
|
||||
'content' => "现金红包奖励{$receive['number']}元",
|
||||
'source_id' => $receive['id'],
|
||||
'create_time' => date('Y-m-d H:i:s', time() - 1) // 上一秒时间
|
||||
];
|
||||
|
||||
$detailId = $db->name('user_money_details')->insertGetId($moneyDetails);
|
||||
|
||||
// 更新奖励记录
|
||||
$a = $db->name('disc_spinning_record')
|
||||
->where('id', $receive['id'])
|
||||
->update([
|
||||
'target' => "2",
|
||||
'target_id' => $detailId
|
||||
]);
|
||||
Log::write('更新奖励' . $a);
|
||||
Cash::updateAmount(1, $receive['user_id'], $receive['number'], $db);
|
||||
// 提交事务
|
||||
$db->commit();
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
// 回滚事务
|
||||
$db->rollback();
|
||||
Log::error("现金转盘奖励处理失败:{$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
63
app/admin/model/MessageInfo.php
Normal file
63
app/admin/model/MessageInfo.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\library\DatabaseRoute;
|
||||
use think\facade\Db;
|
||||
use Throwable;
|
||||
use think\Model;
|
||||
use think\facade\Cache;
|
||||
|
||||
|
||||
class MessageInfo extends Model
|
||||
{
|
||||
|
||||
|
||||
public static function selectMessageList($params)
|
||||
{
|
||||
// 解析查询参数
|
||||
$userId = $params['userId'] ?? null;
|
||||
$state = $params['state'] ?? null;
|
||||
$type = $params['type'] ?? null;
|
||||
$pageNum = $params['page'] ?? 1;
|
||||
$pageSize = $params['limit'] ?? 10;
|
||||
|
||||
|
||||
$query = Db::connect(get_slave_connect_name())->name('message_info');
|
||||
|
||||
|
||||
|
||||
// 添加条件(仅当参数不为空时)
|
||||
if ($userId !== null) {
|
||||
$query = $query->where('user_id', $userId);
|
||||
}
|
||||
|
||||
if ($state !== null) {
|
||||
$query = $query->where('state', $state);
|
||||
}
|
||||
|
||||
if ($type !== null) {
|
||||
$query = $query->where('type', $type);
|
||||
}
|
||||
$total = $query->count();
|
||||
// 构建查询
|
||||
$messageList = $query->order('create_at', 'desc')->limit(page($pageNum, $pageSize), $pageSize)->select()->toArray();
|
||||
|
||||
// 关联用户信息
|
||||
foreach ($messageList as &$message) {
|
||||
if ($message['user_id'] !== null) {
|
||||
$user = DatabaseRoute::getDb('tb_user', $message['user_id'])->find();
|
||||
$message['user_entity'] = $user ?: null;
|
||||
}
|
||||
}
|
||||
return [
|
||||
'list' => $messageList,
|
||||
'totalCount' => $total,
|
||||
'totalPage' => (int)ceil($total / $pageSize),
|
||||
'currPage' => $pageNum,
|
||||
'pageSize' => $pageSize,
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
490
app/admin/model/Order.php
Normal file
490
app/admin/model/Order.php
Normal file
@@ -0,0 +1,490 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\api\model\UserMoney;
|
||||
use app\common\library\DatabaseRoute;
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
|
||||
|
||||
class Order extends Model
|
||||
{
|
||||
|
||||
public static function selectOrdersCountStatisticsByYear($flag, $time, $status)
|
||||
{
|
||||
return DatabaseRoute::getAllDbData('orders', function ($query)use($flag, $time, $status) {
|
||||
// 添加状态条件
|
||||
if (!is_null($status) && $status != 0) {
|
||||
$query->where('status', $status);
|
||||
}
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query->whereRaw("date_format(create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
})->count();
|
||||
}
|
||||
|
||||
|
||||
public static function selectFenXiaoMoney($type, $sysUserId, $flag, $time)
|
||||
{
|
||||
$result = DatabaseRoute::getAllDbData('orders', function($query)use($type, $sysUserId, $flag, $time) {
|
||||
$query->where('status', 1); // 固定条件:订单状态为1(已完成)
|
||||
// 2. 根据类型设置聚合字段(处理null值为0.00)
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$query->field('sum(ifnull(one_money, 0.00)) as total'); // 一级分销金额
|
||||
break;
|
||||
case 2:
|
||||
$query->field('sum(ifnull(two_money, 0.00)) as total'); // 二级分销金额
|
||||
break;
|
||||
case 3:
|
||||
$query->field('sum(ifnull(qd_money, 0.00)) as total'); // 渠道分销金额
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException("无效的金额类型:{$type}");
|
||||
}
|
||||
|
||||
// 3. 添加系统用户ID条件
|
||||
if (!is_null($sysUserId)) {
|
||||
$query->where('sys_user_id', $sysUserId);
|
||||
}
|
||||
|
||||
// 4. 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配
|
||||
$query->whereRaw("date_format(create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException("无效的时间标志:{$flag}");
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
})->find();
|
||||
return $result['total'] ?? 0.00;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function selectOrdersCount($status, $orderType, $flag, $time, $sysUserId)
|
||||
{
|
||||
return DatabaseRoute::getAllDbData('orders', function($query)use($status, $orderType, $flag, $time, $sysUserId) {
|
||||
$query->where('pay_way', 9);
|
||||
// 添加系统用户ID条件(排除sysUserId=1的情况)
|
||||
if (!is_null($sysUserId) && $sysUserId != 1) {
|
||||
$query->where('sys_user_id', $sysUserId);
|
||||
}
|
||||
|
||||
// 添加订单状态条件
|
||||
if (!is_null($status)) {
|
||||
$query->where('status', $status);
|
||||
}
|
||||
|
||||
// 添加订单类型条件
|
||||
if (!is_null($orderType)) {
|
||||
$query->where('orders_type', $orderType);
|
||||
}
|
||||
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query->whereRaw("date_format(create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
})->count();
|
||||
}
|
||||
public static function selectOrdersMoney($status, $orderType, $flag, $time, $courseId, $sysUserId)
|
||||
{
|
||||
$result = DatabaseRoute::getAllDbData('orders', function($query)use($status, $orderType, $flag, $time, $sysUserId, $courseId) {
|
||||
// 初始化查询
|
||||
$query->where('pay_way', 9) // 固定条件:支付方式为9
|
||||
->where('status', 1) // 固定条件:订单状态为1
|
||||
->field('sum(pay_money) as total'); // 聚合计算总支付金额
|
||||
|
||||
// 添加系统用户ID条件
|
||||
if (!is_null($sysUserId) && $sysUserId != 1) {
|
||||
$query->where('sys_user_id', $sysUserId);
|
||||
}
|
||||
|
||||
// 添加订单状态条件
|
||||
if (!is_null($status)) {
|
||||
$query->where('status', $status);
|
||||
}
|
||||
|
||||
// 添加课程ID条件
|
||||
if (!is_null($courseId)) {
|
||||
$query->where('course_id', $courseId);
|
||||
}
|
||||
|
||||
// 添加订单类型条件
|
||||
if (!is_null($orderType)) {
|
||||
$query->where('orders_type', $orderType);
|
||||
}
|
||||
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query->whereRaw("date_format(create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
})->find();
|
||||
return (float)$result['total'] ?? 0.00;
|
||||
}
|
||||
public static function selectSignInAwardMoney($flag, $time, $sysUserId)
|
||||
{
|
||||
$db = Db::connect(get_slave_connect_name());
|
||||
// 初始化查询
|
||||
$query = $db->name('v_user_money_detail_temp')
|
||||
->alias('x')
|
||||
->where('x.classify', 6) // 固定条件:分类为6
|
||||
->where('x.type', 1) // 固定条件:类型为1
|
||||
->where('x.state', 2) // 固定条件:状态为2
|
||||
->where('x.user_id', '<>', 1) // 固定条件:用户ID不为1
|
||||
->where('x.title', '签到奖励') // 固定条件:标题为"签到奖励"
|
||||
->field('ifnull(sum(x.money), 0) as total'); // 聚合计算总金额
|
||||
|
||||
// 添加系统用户ID条件
|
||||
if (!is_null($sysUserId) && $sysUserId != 1) {
|
||||
$query = $query->where('x.sys_user_id', $sysUserId);
|
||||
}
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query = $query->whereRaw("date_format(x.create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query = $query->whereRaw("date_format(x.create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query = $query->whereRaw("date_format(x.create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行查询并返回结果
|
||||
$result = $query->find();
|
||||
return (float)$result['total'];
|
||||
}
|
||||
|
||||
public static function selectShareAwardMoney($flag, $time, $sysUserId)
|
||||
{
|
||||
$db = Db::connect(get_slave_connect_name());
|
||||
// 初始化查询
|
||||
$query = $db->name('v_user_money_detail_temp')
|
||||
->alias('x')
|
||||
->where('x.classify', 6) // 固定条件:分类为6
|
||||
->where('x.type', 1) // 固定条件:类型为1
|
||||
->where('x.state', 2) // 固定条件:状态为2
|
||||
->where('x.user_id', '<>', 1) // 固定条件:用户ID不为1
|
||||
->where('x.title', '分享达标奖励') // 固定条件:标题为"分享达标奖励"
|
||||
->field('ifnull(sum(x.money), 0) as total'); // 聚合计算总金额
|
||||
|
||||
// 添加系统用户ID条件
|
||||
if (!is_null($sysUserId) && $sysUserId != 1) {
|
||||
$query->where('x.sys_user_id', $sysUserId);
|
||||
}
|
||||
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行查询并返回结果
|
||||
$result = $query->find();
|
||||
return (float)$result['total'];
|
||||
}
|
||||
|
||||
public static function selectNewUserTaskDoneAwardMoney($flag, $time, $sysUserId)
|
||||
{
|
||||
$db = Db::connect(get_slave_connect_name());
|
||||
// 初始化查询
|
||||
$query = $db->name('v_user_money_detail_temp')
|
||||
->alias('x')
|
||||
->where('x.classify', 7) // 固定条件:分类为7
|
||||
->where('x.type', 1) // 固定条件:类型为1
|
||||
->where('x.state', 2) // 固定条件:状态为2
|
||||
->where('x.user_id', '<>', 1) // 固定条件:用户ID不为1
|
||||
->where('x.money_type', 1) // 新增条件:金额类型为1
|
||||
->field('ifnull(sum(x.money), 0) as total'); // 聚合计算总金额
|
||||
|
||||
// 添加系统用户ID条件
|
||||
if (!is_null($sysUserId) && $sysUserId != 1) {
|
||||
$query->where('x.sys_user_id', $sysUserId);
|
||||
}
|
||||
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行查询并返回结果
|
||||
$result = $query->find();
|
||||
return (float)$result['total'];
|
||||
}
|
||||
|
||||
|
||||
public static function selectInviteTaskDoneAwardMoney($flag, $time, $sysUserId)
|
||||
{
|
||||
$db = Db::connect(get_slave_connect_name());
|
||||
// 初始化查询
|
||||
$query = $db->name('v_user_money_detail_temp')
|
||||
->alias('x')
|
||||
->where('x.classify', 6) // 固定条件:分类为6
|
||||
->where('x.type', 1) // 固定条件:类型为1
|
||||
->where('x.state', 2) // 固定条件:状态为2
|
||||
->where('x.user_id', '<>', 1) // 固定条件:用户ID不为1
|
||||
->where('x.title', '[分享达标额外奖励]') // 固定条件:标题为"[分享达标额外奖励]"
|
||||
->field('ifnull(sum(x.money), 0) as total'); // 聚合计算总金额
|
||||
|
||||
// 添加系统用户ID条件
|
||||
if (!is_null($sysUserId) && $sysUserId != 1) {
|
||||
$query->where('x.sys_user_id', $sysUserId);
|
||||
}
|
||||
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query->whereRaw("date_format(x.create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行查询并返回结果
|
||||
$result = $query->find();
|
||||
return (float)$result['total'];
|
||||
}
|
||||
|
||||
public static function executeExtractCallback(mixed $cashOut, ?array $baseResp)
|
||||
{
|
||||
$state = 0;
|
||||
if (!empty($baseResp['status']) && $baseResp['status'] == 2) {
|
||||
$state = 1;
|
||||
}else if (!empty($baseResp['status']) && ($baseResp['status'] == 3 || $baseResp['status'] == 99999)) {
|
||||
$state = 2;
|
||||
}
|
||||
|
||||
$reason = '';
|
||||
if (!empty($baseResp['reason']) && $baseResp['reason'] == '已驳回') {
|
||||
$reason = '提现失败,请检查收款账号与收款人姓名后重试。';
|
||||
}
|
||||
|
||||
if ($state == 1) {
|
||||
$cashOut['state'] = 1;
|
||||
$cashOut['out_at'] = getNormalDate();
|
||||
$cashOut['refund'] = null;
|
||||
DatabaseRoute::getDb('cash_out', $cashOut['user_id'], true)->where([
|
||||
'id' => $cashOut['id']
|
||||
])->update($cashOut);
|
||||
|
||||
$userMoney = UserMoney::selectUserMoneyfind($cashOut['user_id']);
|
||||
if ($userMoney) {
|
||||
DatabaseRoute::getDb('user_money', $cashOut['user_id'], true)->where([
|
||||
'id' => $userMoney['id']
|
||||
])->update([
|
||||
'cash_count' => $userMoney['cash_count'] + 1,
|
||||
'cash_amount' => $userMoney['cash_amount'] ?? 0 + $cashOut['amount'],
|
||||
]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($state == 2) {
|
||||
// 设置失败状态
|
||||
$cashOut['out_at'] = date('Y-m-d H:i:s');
|
||||
$cashOut['state'] = 2;
|
||||
$cashOut['refund'] = $reason;
|
||||
|
||||
// 企业用户
|
||||
if ($cashOut['user_type'] === 2) {
|
||||
// 判断是否已经返还过
|
||||
$count = DatabaseRoute::getDb('sys_user_money_details', $cashOut['user_id'])->where([
|
||||
'user_id' => $cashOut['user_id'],
|
||||
'classify' => 4,
|
||||
'state' => 2,
|
||||
'money_type' => 1,
|
||||
'type' => 1,
|
||||
'source_id' => $cashOut['id'],
|
||||
])->count();
|
||||
|
||||
if ($count > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 写入返还明细
|
||||
DatabaseRoute::getDb('sys_user_money_details', $cashOut['user_id'], true)->insert([
|
||||
'user_id' => $cashOut['user_id'],
|
||||
'relation_id'=> $cashOut['user_id'],
|
||||
'title' => '提现失败存入余额',
|
||||
'classify' => 4,
|
||||
'money_type' => 1,
|
||||
'state' => 2,
|
||||
'money' => $cashOut['money'],
|
||||
'content' => '提现失败存入余额' . $cashOut['money'] . '元',
|
||||
'type' => 1,
|
||||
]);
|
||||
|
||||
// 更新余额
|
||||
|
||||
$userMoney = SysUserMoney::selectSysUserMoneyByUserId($cashOut['user_id']);
|
||||
Db::name('sys_user_money')->where([
|
||||
'id' => $userMoney['id']
|
||||
])->dec('money', $cashOut['money'])->update();
|
||||
|
||||
} else {
|
||||
// 普通用户
|
||||
$count = DatabaseRoute::getDb('user_money_details', $cashOut['user_id'])->where([
|
||||
'user_id' => $cashOut['user_id'],
|
||||
'classify' => 4,
|
||||
'state' => 2,
|
||||
'money_type' => 1,
|
||||
'type' => 1,
|
||||
'source_id' => $cashOut['id'],
|
||||
])->count();
|
||||
|
||||
if ($count > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 写入返还明细
|
||||
DatabaseRoute::getDb('user_money_details', $cashOut['user_id'], true)->insert([
|
||||
'user_id' => $cashOut['user_id'],
|
||||
'title' => '提现失败存入余额',
|
||||
'classify' => 4,
|
||||
'money_type' => 1,
|
||||
'state' => 2,
|
||||
'money' => $cashOut['money'],
|
||||
'content' => '提现失败存入余额' . $cashOut['money'] . '元',
|
||||
'type' => 1,
|
||||
'create_time'=> date('Y-m-d H:i:s'),
|
||||
'source_id' => $cashOut['id'],
|
||||
]);
|
||||
|
||||
// 更新余额
|
||||
(new UserMoney())->updateAmount($cashOut['user_id'], $cashOut['money'], false);
|
||||
}
|
||||
|
||||
// 更新提现记录
|
||||
DatabaseRoute::getDb('cash_out', $cashOut['user_id'], true)->where('user_id', $cashOut->user_id)
|
||||
->where('id', $cashOut['id'])
|
||||
->update([
|
||||
'out_at' => $cashOut['out_at'],
|
||||
'state' => $cashOut['state'],
|
||||
'refund' => $cashOut['refund'],
|
||||
]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
59
app/admin/model/PayDetails.php
Normal file
59
app/admin/model/PayDetails.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\library\DatabaseRoute;
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* UserGroup 模型
|
||||
*/
|
||||
class PayDetails extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
|
||||
|
||||
public static function selectSumPayByClassify($classify, $flag, $time, $payClassify)
|
||||
{
|
||||
$result = DatabaseRoute::getAllDbData('pay_details', function ($query) use($time, $flag, $classify, $payClassify){
|
||||
$query->where('state', 1) // 固定条件:state=1
|
||||
->field('sum(money) as total'); // 聚合计算总金额
|
||||
// 添加分类条件
|
||||
if (!is_null($classify)) {
|
||||
$query->where('classify', $classify);
|
||||
}
|
||||
|
||||
// 添加时间条件
|
||||
if (!is_null($flag)) {
|
||||
switch ($flag) {
|
||||
case 1:
|
||||
// 按日匹配(精确到天)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$time]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月匹配(精确到月)
|
||||
$query->whereRaw("date_format(create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$time]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年匹配(精确到年)
|
||||
$query->whereRaw("date_format(create_time, '%Y') = date_format(?, '%Y')", [$time]);
|
||||
break;
|
||||
default:
|
||||
// 无效flag,不添加时间条件
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加支付分类条件
|
||||
if (!is_null($payClassify) && $payClassify != 0) {
|
||||
$query->where('pay_classify', $payClassify);
|
||||
}
|
||||
return $query;
|
||||
})->find();
|
||||
return $result['total'] ?? 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
19
app/admin/model/SensitiveData.php
Normal file
19
app/admin/model/SensitiveData.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* SensitiveData 模型
|
||||
*/
|
||||
class SensitiveData extends Model
|
||||
{
|
||||
protected $name = 'security_sensitive_data';
|
||||
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
protected $type = [
|
||||
'data_fields' => 'array',
|
||||
];
|
||||
}
|
||||
27
app/admin/model/SensitiveDataLog.php
Normal file
27
app/admin/model/SensitiveDataLog.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
/**
|
||||
* SensitiveDataLog 模型
|
||||
*/
|
||||
class SensitiveDataLog extends Model
|
||||
{
|
||||
protected $name = 'security_sensitive_data_log';
|
||||
|
||||
protected $autoWriteTimestamp = true;
|
||||
protected $updateTime = false;
|
||||
|
||||
public function sensitive(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(SensitiveData::class, 'sensitive_id');
|
||||
}
|
||||
|
||||
public function admin(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Admin::class, 'admin_id');
|
||||
}
|
||||
}
|
||||
21
app/admin/model/SysCaptcha.php
Normal file
21
app/admin/model/SysCaptcha.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\captcha\facade\Captcha as thinkCaptcha;
|
||||
|
||||
class SysCaptcha extends Model
|
||||
{
|
||||
public static function getCode($uuid)
|
||||
{
|
||||
$code_data = thinkCaptcha::create('czg');
|
||||
// 保存至数据库
|
||||
self::create([
|
||||
'uuid' => $uuid,
|
||||
'code' => $code_data['code'],
|
||||
'expire_time' => date('Y-m-d H:i:s', time() + config('captcha.expire_time')),
|
||||
]);
|
||||
return ['img' => $code_data['img']];
|
||||
}
|
||||
}
|
||||
103
app/admin/model/SysMenu.php
Normal file
103
app/admin/model/SysMenu.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use ba\Exception;
|
||||
use think\facade\Db;
|
||||
use think\model;
|
||||
|
||||
/**
|
||||
* 菜单模型
|
||||
*/
|
||||
class SysMenu extends model
|
||||
{
|
||||
// 菜单类型常量
|
||||
const MENU_TYPE_CATALOG = 0; // 目录
|
||||
const MENU_TYPE_MENU = 1; // 菜单
|
||||
const MENU_TYPE_BUTTON = 2; // 按钮
|
||||
|
||||
public static function getMenuList($menu):array
|
||||
{
|
||||
$one_menu = [];
|
||||
$t_menu = [];
|
||||
$p_list = [];
|
||||
foreach ($menu as $k => $v) {
|
||||
if(in_array($v['type'], [0, 1])) {
|
||||
if($v['parent_id'] == 0) {
|
||||
$one_menu[] = $v;
|
||||
}else {
|
||||
$t_menu[] = $v;
|
||||
}
|
||||
}
|
||||
// 权限处理
|
||||
if($v['perms'] ) {
|
||||
if(strpos($v['perms'], ',') !== false) {
|
||||
foreach (explode(',', $v['perms']) as $item) {
|
||||
$p_list[] = $item;
|
||||
}
|
||||
}else {
|
||||
$p_list[] = $v['perms'];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($one_menu as $k => &$one_value) {
|
||||
foreach ($t_menu as $two_k => $two_value) {
|
||||
if($two_value['parent_id'] == $one_value['menu_id']) {
|
||||
$one_value['list'][] = convertToCamelCase($two_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
$return['menuList'] = convertToCamelCase($one_menu);
|
||||
$return['permissions'] = $p_list;
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function verifyForm($menu)
|
||||
{
|
||||
// 验证菜单名称
|
||||
if (empty($menu['name'])) {
|
||||
throw new Exception("菜单名称不能为空");
|
||||
}
|
||||
|
||||
// 验证上级菜单
|
||||
if (!isset($menu['parentId'])) {
|
||||
throw new Exception("上级菜单不能为空");
|
||||
}
|
||||
|
||||
// 菜单类型为菜单时,验证 URL
|
||||
if ($menu['type'] == self::MENU_TYPE_MENU) {
|
||||
if (empty($menu['url'])) {
|
||||
throw new Exception("菜单URL不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
// 获取上级菜单类型
|
||||
$parentType = self::MENU_TYPE_CATALOG;
|
||||
if ($menu['parentId'] != 0) {
|
||||
$parentMenu = Db::name('sys_menu')->where(['menu_id' => $menu['parentId']])->find();
|
||||
if (!$parentMenu) {
|
||||
throw new Exception("上级菜单不存在");
|
||||
}
|
||||
$parentType = $parentMenu['type'];
|
||||
}
|
||||
|
||||
// 目录、菜单类型验证
|
||||
if ($menu['type'] == self::MENU_TYPE_CATALOG || $menu['type'] == self::MENU_TYPE_MENU) {
|
||||
if ($parentType != self::MENU_TYPE_CATALOG) {
|
||||
throw new Exception("上级菜单只能为目录类型");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 按钮类型验证
|
||||
if ($menu['type'] == self::MENU_TYPE_BUTTON) {
|
||||
if ($parentType != self::MENU_TYPE_MENU) {
|
||||
throw new Exception("上级菜单只能为菜单类型");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
app/admin/model/SysUser.php
Normal file
11
app/admin/model/SysUser.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
|
||||
class SysUser extends Model
|
||||
{
|
||||
|
||||
}
|
||||
33
app/admin/model/SysUserMoney.php
Normal file
33
app/admin/model/SysUserMoney.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\library\DatabaseRoute;
|
||||
use ba\Random;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
|
||||
class SysUserMoney extends Model
|
||||
{
|
||||
|
||||
public static function selectSysUserMoneyByUserId($userId):array
|
||||
{
|
||||
$db = Db::connect(get_slave_connect_name());
|
||||
// 查询用户钱包信息
|
||||
$userMoney = $db->name('sys_user_money')->where('user_id', $userId)->find();
|
||||
// 若不存在,则创建新记录
|
||||
if (is_null($userMoney)) {
|
||||
$userMoney = [
|
||||
'user_id' => $userId,
|
||||
'money' => 0.00,
|
||||
'id' => Random::generateRandomPrefixedId(19),
|
||||
];
|
||||
$id = Db::connect(get_master_connect_name())->name('sys_user_money')->insert($userMoney);
|
||||
}
|
||||
return $db->name('sys_user_money')->where('user_id', $userId)->find();
|
||||
}
|
||||
|
||||
}
|
||||
85
app/admin/model/SysUserMoneyDetails.php
Normal file
85
app/admin/model/SysUserMoneyDetails.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\library\DatabaseRoute;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
|
||||
class SysUserMoneyDetails extends Model
|
||||
{
|
||||
|
||||
public static function queryUserMoneyDetails($page, $limit, $sysUserId, $userId, $classify, $type, $moneyType, $viewType)
|
||||
{
|
||||
if ($sysUserId !== null) {
|
||||
$sysUserId = intval($sysUserId);
|
||||
$db = DatabaseRoute::getDb('sys_user_money_details', $sysUserId);
|
||||
$total = $db->name('sys_user_money_details')->where('user_id', $sysUserId)->count();
|
||||
// 系统用户模式:查询系统用户资金明细
|
||||
$list = $db->name('sys_user_money_details')->where('user_id', $sysUserId)
|
||||
->order('create_time', 'desc')
|
||||
->limit(page($page, $limit), $limit)
|
||||
->select()
|
||||
->toArray();
|
||||
return [
|
||||
'list' => $list,
|
||||
'totalCount' => $total,
|
||||
'totalPage' => (int)ceil($total / $limit),
|
||||
'currPage' => $page,
|
||||
'pageSize' => $limit,
|
||||
];
|
||||
}
|
||||
if($userId !== null) {
|
||||
$db = DatabaseRoute::getDb('user_money_details', $userId)->name('user_money_details');
|
||||
$query = $db->where('user_id', $userId);
|
||||
if ($classify !== null) {
|
||||
$query = $query->where('classify', $classify);
|
||||
}
|
||||
|
||||
if ($type !== null) {
|
||||
$query = $query->where('type', $type);
|
||||
}
|
||||
|
||||
if ($moneyType !== null) {
|
||||
$query = $query->where('money_type', $moneyType);
|
||||
}
|
||||
if ($viewType == 1) {
|
||||
// 视图类型1:特殊分类(1和6)
|
||||
$query = $query->whereIn('classify', [1, 6]);
|
||||
}
|
||||
$total = $query->count();
|
||||
$query = $query->limit(page($page, $limit), $limit)
|
||||
->order('create_time', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
return [
|
||||
'list' => $query,
|
||||
'totalCount' => $total,
|
||||
'totalPage' => (int)ceil($total / $limit),
|
||||
'currPage' => $page,
|
||||
'pageSize' => $limit,
|
||||
];
|
||||
}else {
|
||||
return DatabaseRoute::paginateAllDb('user_money_details', function ($query)use($page, $limit, $sysUserId, $userId, $classify, $type, $moneyType, $viewType) {
|
||||
if ($classify !== null) {
|
||||
$query->where('classify', $classify);
|
||||
}
|
||||
if ($type !== null) {
|
||||
$query->where('type', $type);
|
||||
}
|
||||
if ($moneyType !== null) {
|
||||
$query->where('money_type', $moneyType);
|
||||
}
|
||||
if ($viewType == 1) {
|
||||
// 视图类型1:特殊分类(1和6)
|
||||
$query->whereIn('classify', [1, 6]);
|
||||
}
|
||||
return $query;
|
||||
}, $page, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
606
app/admin/model/User.php
Normal file
606
app/admin/model/User.php
Normal file
@@ -0,0 +1,606 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\library\DatabaseRoute;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
/**
|
||||
* User 模型
|
||||
* @property int $id 用户ID
|
||||
* @property string password 密码密文
|
||||
*/
|
||||
class User extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
public function getAvatarAttr($value): string
|
||||
{
|
||||
return full_url($value, false, config('buildadmin.default_avatar'));
|
||||
}
|
||||
|
||||
public function setAvatarAttr($value): string
|
||||
{
|
||||
return $value == full_url('', false, config('buildadmin.default_avatar')) ? '' : $value;
|
||||
}
|
||||
|
||||
public function getMoneyAttr($value): string
|
||||
{
|
||||
return bcdiv($value, 100, 2);
|
||||
}
|
||||
|
||||
public function setMoneyAttr($value): string
|
||||
{
|
||||
return bcmul($value, 100, 2);
|
||||
}
|
||||
|
||||
public function userGroup(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(UserGroup::class, 'group_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
* @param int|string $uid 用户ID
|
||||
* @param string $newPassword 新密码
|
||||
* @return int|User
|
||||
*/
|
||||
public function resetPassword(int|string $uid, string $newPassword): int|User
|
||||
{
|
||||
return $this->where(['id' => $uid])->update(['password' => hash_password($newPassword), 'salt' => '']);
|
||||
}
|
||||
|
||||
public static function queryCourseOrder($page, $limit, $type, $date, $sysUserId):array
|
||||
{
|
||||
// 1. 处理时间范围
|
||||
$timestamp = strtotime($date);
|
||||
if ($type == 2) {
|
||||
// 按月统计
|
||||
$startTime = date('Y-m-01 00:00:00', $timestamp);
|
||||
$endTime = date('Y-m-t 23:59:59', $timestamp);
|
||||
} elseif ($type == 3) {
|
||||
// 按年统计
|
||||
$startTime = date('Y-01-01 00:00:00', $timestamp);
|
||||
$endTime = date('Y-12-31 23:59:59', $timestamp);
|
||||
} else {
|
||||
// 按日统计
|
||||
$startTime = date('Y-m-d 00:00:00', $timestamp);
|
||||
$endTime = date('Y-m-d 23:59:59', $timestamp);
|
||||
}
|
||||
|
||||
// 2. 查询课程订单统计数据(带分页)
|
||||
$courseList = self::selectGroupCourseId($startTime, $endTime, $page, $limit);
|
||||
|
||||
// 3. 提取课程ID集合
|
||||
$courseIds = array_column($courseList['list'], 'orders_id');
|
||||
|
||||
// 4. 批量查询课程信息并构建映射
|
||||
if (!empty($courseIds)) {
|
||||
$courseMap = [];
|
||||
$db = Db::connect(get_slave_connect_name());
|
||||
$courses = $db->name('course')
|
||||
->whereIn('course_id', $courseIds)
|
||||
->field('course_id, title')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
// 构建ID到课程的映射
|
||||
foreach ($courses as $course) {
|
||||
$courseMap[$course['course_id']] = $course;
|
||||
}
|
||||
|
||||
// 5. 关联课程名称到订单统计数据
|
||||
foreach ($courseList['list'] as &$item) {
|
||||
if (isset($courseMap[$item['orders_id']])) {
|
||||
$item['coursename'] = $courseMap[$item['orders_id']]['title'];
|
||||
}
|
||||
}
|
||||
unset($item); // 释放引用
|
||||
$courseList['list'] = convertToCamelCase($courseList['list']);
|
||||
}
|
||||
return $courseList;
|
||||
}
|
||||
|
||||
|
||||
public static function selectGroupCourseId($startTime, $endTime, $page, $limit)
|
||||
{
|
||||
return DatabaseRoute::paginateAllDb('orders', function($query) use($startTime, $endTime) {
|
||||
return $query->alias('o')
|
||||
->field([
|
||||
'sum(o.pay_money) as coursemoney',
|
||||
'count(*) as coursenum',
|
||||
'o.course_id as courseId'
|
||||
])
|
||||
->where('o.status', 1)
|
||||
->where('o.orders_type', 1)
|
||||
->whereBetween('o.create_time', [$startTime, $endTime])
|
||||
->group('o.course_id');
|
||||
}, $page, $limit, 'coursenum');
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function queryUserCount($type, $date, $platform, $qdCode)
|
||||
{
|
||||
|
||||
// 检查日期是否为空
|
||||
if (empty($date)) {
|
||||
// 格式化当前时间(注意:PHP时间格式符与Java略有不同)
|
||||
$date = date('Y-m-d H:i:s');
|
||||
}
|
||||
return DatabaseRoute::getAllDbData('tb_user', function($query) use($type, $date, $platform, $qdCode) {
|
||||
// 处理时间条件
|
||||
$dateTime = strtotime($date);
|
||||
if ($dateTime === false) {
|
||||
throw new \InvalidArgumentException("无效的日期格式:{$date}");
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 1:
|
||||
// 按日统计(精确到天)
|
||||
$startDate = date('Y-m-d 00:00:00', $dateTime);
|
||||
$endDate = date('Y-m-d 23:59:59', $dateTime);
|
||||
$query->whereBetweenTime('create_time', $startDate, $endDate);
|
||||
break;
|
||||
case 2:
|
||||
// 按月统计
|
||||
$startDate = date('Y-m-01 00:00:00', $dateTime);
|
||||
$endDate = date('Y-m-t 23:59:59', $dateTime);
|
||||
$query->whereBetweenTime('create_time', $startDate, $endDate);
|
||||
break;
|
||||
case 3:
|
||||
// 按年统计
|
||||
$startDate = date('Y-01-01 00:00:00', $dateTime);
|
||||
$endDate = date('Y-12-31 23:59:59', $dateTime);
|
||||
$query->whereBetweenTime('create_time', $startDate, $endDate);
|
||||
break;
|
||||
default:
|
||||
// 无效类型,不添加时间条件
|
||||
break;
|
||||
}
|
||||
|
||||
// 处理平台条件
|
||||
if (!is_null($platform)) {
|
||||
$query->where('platform', $platform);
|
||||
}
|
||||
|
||||
// 处理渠道码条件
|
||||
if (!is_null($qdCode)) {
|
||||
$query->where('qd_code', $qdCode);
|
||||
}
|
||||
return $query;
|
||||
})->count();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function queryPayMoney($type, $qdCode)
|
||||
{
|
||||
$date = date('Y-m-d H:i:s');
|
||||
$result = DatabaseRoute::getAllDbData('pay_details', function($query) use($type, $date, $qdCode) {
|
||||
$query->alias('p')
|
||||
->leftJoin('tb_user u', 'u.user_id = p.user_id')
|
||||
->where('p.state', 1) // 支付状态为1(成功)
|
||||
->field('sum(p.money) as total_money'); // 聚合计算总金额
|
||||
|
||||
// 根据类型添加时间条件(匹配date_format的逻辑)
|
||||
switch ($type) {
|
||||
case 1:
|
||||
// 按日:日期部分完全匹配
|
||||
$query->whereRaw("date_format(p.create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$date]);
|
||||
break;
|
||||
case 2:
|
||||
// 按月:年月部分匹配
|
||||
$query->whereRaw("date_format(p.create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$date]);
|
||||
break;
|
||||
case 3:
|
||||
// 按年:年份部分匹配
|
||||
$query->whereRaw("date_format(p.create_time, '%Y') = date_format(?, '%Y')", [$date]);
|
||||
break;
|
||||
default:
|
||||
// 默认为空,可根据业务补充默认条件
|
||||
break;
|
||||
}
|
||||
|
||||
// 可选条件:渠道码
|
||||
if (!empty($qdCode)) {
|
||||
$query->where('u.qd_code', $qdCode);
|
||||
}
|
||||
return $query;
|
||||
})->find();
|
||||
return $result['total_money'] ?? 0.0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function userMessage($date, $type, $qdCode, $vipType)
|
||||
{
|
||||
// 1. 处理时间条件
|
||||
$timestamp = strtotime($date);
|
||||
if ($timestamp === false) {
|
||||
throw new \InvalidArgumentException("无效的日期格式:{$date}");
|
||||
}
|
||||
if ($type == 1) {
|
||||
// 按日开始(00:00:00)
|
||||
$startTime = date('Y-m-d 00:00:00', $timestamp);
|
||||
} elseif ($type == 2) {
|
||||
// 按月开始(当月1日 00:00:00)
|
||||
$startTime = date('Y-m-01 00:00:00', $timestamp);
|
||||
} else {
|
||||
// 按年开始(当年1月1日 00:00:00)
|
||||
$startTime = date('Y-01-01 00:00:00', $timestamp);
|
||||
}
|
||||
|
||||
$cachestr = 'userMessageUserIdList';
|
||||
$userIds = Cache::get($cachestr);
|
||||
if(!$userIds) {
|
||||
if (!empty($qdCode)) {
|
||||
$userIds = DatabaseRoute::getAllDbData('tb_user', function($query) use($qdCode, $startTime) {
|
||||
$query->where('qd_code', $qdCode);
|
||||
// 2. 查询符合条件的用户ID集合
|
||||
$query->where('create_time', '>=', $startTime)
|
||||
->field('user_id');
|
||||
return $query;
|
||||
})->column('user_id');
|
||||
}
|
||||
// 3. 若用户ID集合为空,直接返回0
|
||||
if (empty($userIds)) {
|
||||
return 0;
|
||||
}
|
||||
Cache::set($cachestr, json_encode($userIds));
|
||||
}else {
|
||||
$userIds = json_decode($userIds, true);
|
||||
}
|
||||
$db = Db::connect(get_slave_connect_name());
|
||||
// 4. 查询符合条件的VIP用户数量
|
||||
$query = $db->name('user_vip');
|
||||
if($userIds) {
|
||||
$query = $query->whereIn('user_id', $userIds);
|
||||
}
|
||||
$query = $query->where('is_vip', 2);
|
||||
if (!is_null($vipType)) {
|
||||
$query = $query->where('vip_type', $vipType);
|
||||
}
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询今日支付和提现统计信息
|
||||
* @return array 包含支付金额、支付次数、提现金额、提现次数的关联数组
|
||||
*/
|
||||
public static function queryPayAndExtractInfo()
|
||||
{
|
||||
|
||||
// 1. 计算今日开始和结束时间
|
||||
$beginOfDay = date('Y-m-d 00:00:00'); // 今日0点
|
||||
$endOfDay = date('Y-m-d 23:59:59'); // 今日23点59分59秒
|
||||
|
||||
// 2. 查询今日支付信息
|
||||
$payInfo = self::queryPayInfo($beginOfDay, $endOfDay);
|
||||
|
||||
// 3. 查询今日提现信息
|
||||
$extractInfo = self::queryExtractInfo($beginOfDay, $endOfDay);
|
||||
|
||||
// 4. 合并结果
|
||||
return [
|
||||
'payAmount' => $payInfo['totalMoney'] ?? null,
|
||||
'payCount' => $payInfo['totalCount'] ?? null,
|
||||
'extractAmount' => $extractInfo['totalMoney'] ?? null,
|
||||
'extractCount' => $extractInfo['totalCount'] ?? null
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查询指定时间范围内的支付信息
|
||||
* @param string $begin 开始时间(格式:Y-m-d H:i:s)
|
||||
* @param string $end 结束时间(格式:Y-m-d H:i:s)
|
||||
* @return array 支付统计数据
|
||||
*/
|
||||
private static function queryPayInfo($begin, $end)
|
||||
{
|
||||
return DatabaseRoute::getAllDbData('orders', function($query) use($begin, $end) {
|
||||
return $query->where('create_time', 'between', [$begin, $end])
|
||||
->where('status', 1) // 假设1表示支付成功
|
||||
->where('pay_way', 9) // 假设1表示支付成功
|
||||
->field([
|
||||
'SUM(pay_money) as totalMoney', // 总支付金额
|
||||
'COUNT(1) as totalCount' // 支付次数
|
||||
]);
|
||||
})->find() ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定时间范围内的提现信息
|
||||
* @param string $begin 开始时间(格式:Y-m-d H:i:s)
|
||||
* @param string $end 结束时间(格式:Y-m-d H:i:s)
|
||||
* @return array 提现统计数据
|
||||
*/
|
||||
private static function queryExtractInfo($begin, $end)
|
||||
{
|
||||
return DatabaseRoute::getAllDbData('cash_out', function($query) use($begin, $end) {
|
||||
return $query->where('create_at', 'between', [$begin, $end])
|
||||
->where('state', 1)
|
||||
->field([
|
||||
'SUM(money) as totalMoney', // 总提现金额
|
||||
'COUNT(1) as totalCount' // 提现次数
|
||||
]);
|
||||
})->find() ?: [];
|
||||
}
|
||||
|
||||
|
||||
public static function selectUserPage($page, $limit, $phone, $sex, $platform, $sysPhone, $status, $member,
|
||||
$inviterCode, $userName, $invitationCode, $startTime, $endTime, $qdCode, $sysUserName, $vipType, $delegate)
|
||||
{
|
||||
|
||||
$result = DatabaseRoute::paginateAllDb('tb_user', function ($query) use($page, $limit, $phone, $sex, $platform, $sysPhone, $status, $member,
|
||||
$inviterCode, $userName, $invitationCode, $startTime, $endTime, $qdCode, $sysUserName, $vipType, $delegate) {
|
||||
|
||||
// 初始化查询
|
||||
$query->alias('u')
|
||||
// 左连接sys_user表(别名s)
|
||||
->leftJoin('sys_user s', 's.qd_code = u.qd_code')
|
||||
// 左连接user_money表(别名m)
|
||||
->leftJoin('user_money m', 'm.user_id = u.user_id')
|
||||
// 固定条件:s.sys_user_id is null
|
||||
->where('s.sys_user_id', null)
|
||||
// 字段选择(与原SQL一致)
|
||||
->field([
|
||||
'u.*',
|
||||
'1 as member',
|
||||
's.username as sysUserName',
|
||||
'm.cash_count as cashCount',
|
||||
'm.cash_amount as cashAmount',
|
||||
'm.amount as balance'
|
||||
]);
|
||||
|
||||
// 搜索条件(user_id/phone/user_name匹配)
|
||||
if (!is_null($phone) && $phone !== '') {
|
||||
$query->where(function ($query) use ($phone) {
|
||||
$query->where('u.user_id', $phone)
|
||||
->whereOr('u.phone', $phone)
|
||||
->whereOr('u.user_name', $phone);
|
||||
});
|
||||
}
|
||||
|
||||
// 系统用户名模糊查询
|
||||
if (!is_null($sysUserName) && $sysUserName !== '') {
|
||||
$query->where('s.username', 'like', "%{$sysUserName}%");
|
||||
}
|
||||
|
||||
// 用户名模糊查询
|
||||
if (!is_null($userName) && $userName !== '') {
|
||||
$query->where('u.user_name', 'like', "%{$userName}%");
|
||||
}
|
||||
|
||||
// 性别筛选(非0值)
|
||||
if (!is_null($sex) && $sex != 0) {
|
||||
$query->where('u.sex', $sex);
|
||||
}
|
||||
|
||||
// 平台筛选
|
||||
if (!is_null($platform) && $platform !== '') {
|
||||
$query->where('u.platform', $platform);
|
||||
}
|
||||
|
||||
// 系统手机号筛选
|
||||
if (!is_null($sysPhone) && $sysPhone !== '') {
|
||||
$query->where('u.sys_phone', $sysPhone);
|
||||
}
|
||||
|
||||
// 邀请人编码模糊查询
|
||||
if (!is_null($inviterCode) && $inviterCode !== '') {
|
||||
$query->where('u.inviter_code', 'like', "%{$inviterCode}%");
|
||||
}
|
||||
|
||||
// 邀请码模糊查询
|
||||
if (!is_null($invitationCode) && $invitationCode !== '') {
|
||||
$query->where('u.invitation_code', 'like', "%{$invitationCode}%");
|
||||
}
|
||||
|
||||
// 渠道码精确匹配
|
||||
if (!is_null($qdCode) && $qdCode !== '') {
|
||||
$query->where('u.qd_code', $qdCode);
|
||||
}
|
||||
|
||||
// 时间范围筛选
|
||||
if (!is_null($startTime) && $startTime !== '' && !is_null($endTime) && $endTime !== '') {
|
||||
// 开始时间和结束时间都存在
|
||||
$query->whereBetween('u.create_time', [$startTime, $endTime]);
|
||||
} elseif (!is_null($startTime) && $startTime !== '') {
|
||||
// 仅开始时间
|
||||
$query->where('u.create_time', '>=', $startTime);
|
||||
} elseif (!is_null($endTime) && $endTime !== '') {
|
||||
// 仅结束时间
|
||||
$query->where('u.create_time', '<=', $endTime);
|
||||
}
|
||||
|
||||
// 邀请人数筛选(delegate)
|
||||
if (!is_null($delegate)) {
|
||||
if ($delegate == 0) {
|
||||
// 邀请人数=0
|
||||
$query->where('u.invite_count', 0);
|
||||
} elseif ($delegate == 1) {
|
||||
// 邀请人数>0
|
||||
$query->where('u.invite_count', '>', 0);
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}, $page, $limit, 'u.create_time');
|
||||
|
||||
return $result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static function upUserBlack($user, $status, $db)
|
||||
{
|
||||
$userId = $user['user_id']; // 获取用户ID
|
||||
|
||||
if ($status == 0) {
|
||||
// 拉黑操作:设置状态为0并更新
|
||||
$db->name('tb_user')->where(['user_id' => $userId])->update(['status' => 0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 解除拉黑操作:设置状态为1,平台为h5并更新
|
||||
$db->name('tb_user')->where(['user_id' => $userId])->update(['status' => 1, 'platform' => 'h5']);
|
||||
|
||||
// 查询用户信息(身份证号)
|
||||
$userInfo = $db->name('user_info')->where('user_id', $userId)->find();
|
||||
|
||||
// 若存在身份证号,则删除黑名单记录
|
||||
if (!is_null($userInfo) && !empty($userInfo['cert_no'])) {
|
||||
Db::connect(get_master_connect_name())->name('tb_user_blacklist')
|
||||
->where('id_card_no', $userInfo['cert_no'])
|
||||
->delete();
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static function selectInviteMoneyByUserId($user_id, $db)
|
||||
{
|
||||
return $db->name('invite_money')->where(['user_id' => $user_id])->find();
|
||||
}
|
||||
|
||||
public static function instantselectSumPay($date, $userId, $db)
|
||||
{
|
||||
$startTime = date('Y-m-01 00:00:00', strtotime($date));
|
||||
$endTime = date('Y-m-t 23:59:59', strtotime($date));
|
||||
$sumMoney = $db->name('pay_details')
|
||||
->where('create_time', '>', $startTime) // 创建时间大于开始时间
|
||||
->where('create_time', '<', $endTime) // 创建时间小于结束时间
|
||||
->where('state', 1) // 支付状态为1(成功)
|
||||
->where('user_id', $userId) // 指定用户ID
|
||||
->sum('money'); // 计算金额总和
|
||||
return $sumMoney !== null ? (float)$sumMoney : 0.00;
|
||||
}
|
||||
|
||||
|
||||
public static function monthIncome($date, $userId, $db)
|
||||
{
|
||||
// 构建查询
|
||||
$sumMoney = $db->name('user_money_details')
|
||||
->where('user_id', $userId) // 固定条件:用户ID匹配
|
||||
->where('classify', 4) // 固定条件:分类为4
|
||||
->where('type', 2) // 固定条件:类型为2
|
||||
->where('state', 2) // 固定条件:状态为2
|
||||
// 时间条件:当月匹配(与原SQL的date_format逻辑一致)
|
||||
->whereRaw("date_format(create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$date])
|
||||
->sum('money'); // 计算金额总和
|
||||
|
||||
// 处理空值并保留两位小数
|
||||
return $sumMoney !== null ? number_format($sumMoney, 2) : '0.00';
|
||||
}
|
||||
|
||||
public static function queryInviterCount($inviterCode)
|
||||
{
|
||||
return DatabaseRoute::getAllDbData('tb_user', function($query) use($inviterCode) {
|
||||
return $query->where('inviter_code', $inviterCode);
|
||||
})->count();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function selectUserVipByUserId($userId)
|
||||
{
|
||||
return Db::connect(get_slave_connect_name())->name('user_vip')->where(['user_id' => $userId])->find();
|
||||
|
||||
}
|
||||
|
||||
public static function selectUserMoneyByUserId($userId)
|
||||
{
|
||||
$db_name = DatabaseRoute::getConnection('user_money', ['user_id' => $userId]);
|
||||
$db = Db::connect($db_name);
|
||||
// 查询用户钱包信息
|
||||
$userMoney = $db->name('user_money')->where('user_id', $userId)->find();
|
||||
// 若不存在,则创建新记录
|
||||
if (is_null($userMoney)) {
|
||||
$db_name = DatabaseRoute::getConnection('user_money', ['user_id' => $userId], true);
|
||||
$userMoney = [
|
||||
'user_id' => $userId,
|
||||
'money' => 0.00,
|
||||
'amount' => 0.00,
|
||||
];
|
||||
Db::connect($db_name)->name('user_money')->insert($userMoney);
|
||||
}
|
||||
return $userMoney;
|
||||
|
||||
}
|
||||
|
||||
public static function userListExcel($startTime, $endTime, $page = 1, $limit = 20, $userEntity = [])
|
||||
{
|
||||
$list = DatabaseRoute::getAllDbData('tb_user', function ($query) use ($startTime, $endTime, $page, $limit, $userEntity) {
|
||||
$query->alias('u');
|
||||
// 处理 phone 条件
|
||||
if (!empty($userEntity['phone'])) {
|
||||
$query->where('u.phone', 'like', "%{$userEntity['phone']}%");
|
||||
}
|
||||
|
||||
// 处理 userName 条件
|
||||
if (!empty($userEntity['userName'])) {
|
||||
$query->where('u.user_name', 'like', "%{$userEntity['userName']}%");
|
||||
}
|
||||
|
||||
// 处理 invitationCode 条件
|
||||
if (!empty($userEntity['invitationCode'])) {
|
||||
$query->where('u.invitation_code', 'like', "%{$userEntity['invitationCode']}%");
|
||||
}
|
||||
|
||||
// 处理 inviterCode 条件
|
||||
if (!empty($userEntity['inviterCode'])) {
|
||||
$query->where('u.inviter_code', 'like', "%{$userEntity['inviterCode']}%");
|
||||
}
|
||||
|
||||
// 处理 platform 条件
|
||||
if (!empty($userEntity['platform'])) {
|
||||
$query->where('u.platform', $userEntity['platform']);
|
||||
}
|
||||
|
||||
// 处理时间范围条件
|
||||
if (!empty($startTime) && !empty($endTime)) {
|
||||
$query->whereTime('u.create_time', 'between', [$startTime, $endTime]);
|
||||
} elseif (!empty($startTime)) {
|
||||
$query->whereTime('u.create_time', '>=', $startTime);
|
||||
} elseif (!empty($endTime)) {
|
||||
$query->whereTime('u.create_time', '<=', $endTime);
|
||||
}
|
||||
if (!empty($page) && !empty($limit)) {
|
||||
$query->limit(page($page, $limit), $limit);
|
||||
}
|
||||
return $query;
|
||||
})->select()->toArray();
|
||||
$export = new \alei\Export('用户列表');
|
||||
$export->setColumn([
|
||||
['field' => 'user_id', 'title' => '用户ID'],
|
||||
['field' => 'user_name', 'title' => '用户名'], //格式化时间,时间戳格式化为时间日期格式,默认格式: “Y-m-d H:i:s”
|
||||
['field' => 'phone', 'title' => '手机号'],
|
||||
['field' => 'sys_phone', 'title' => '手机类型 1安卓 2ios'],
|
||||
['field' => 'jifen', 'title' => '积分'],
|
||||
['field' => 'invitation_code', 'title' => '邀请码'],
|
||||
['field' => 'inviter_code', 'title' => '邀请人邀请码'],
|
||||
['field' => 'zhi_fu_bao_name', 'title' => '支付宝名称'],
|
||||
['field' => 'zhi_fu_bao', 'title' => '支付宝账号'],
|
||||
['field' => 'cert_name', 'title' => '姓名'],
|
||||
['field' => 'cert_no', 'title' => '身份证号码'],
|
||||
['field' => 'create_time', 'title' => '创建时间'],
|
||||
]);
|
||||
//设置数据
|
||||
$export->setData($list);
|
||||
//生成表格,返回url
|
||||
$url = $export->build(); //'export/文章.xlsx'
|
||||
return ['data' => config('buildadmin.run_api_url') . $url];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
13
app/admin/model/UserGroup.php
Normal file
13
app/admin/model/UserGroup.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* UserGroup 模型
|
||||
*/
|
||||
class UserGroup extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
}
|
||||
57
app/admin/model/UserIntegral.php
Normal file
57
app/admin/model/UserIntegral.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* UserGroup 模型
|
||||
*/
|
||||
class UserIntegral extends Model
|
||||
{
|
||||
|
||||
|
||||
public static function selectUserIntegralDetailsByUserId($page, $limit, $userId)
|
||||
{
|
||||
$query = Db::connect(get_slave_connect_name())->name('user_integral_details');
|
||||
// 添加用户ID条件(如果不为空)
|
||||
if ($userId !== null) {
|
||||
$query = $query->where('user_id', $userId);
|
||||
}
|
||||
$count = $query->count();
|
||||
$query = $query->order('create_time', 'desc')->limit(page($page, $limit), $limit)->select()->toArray();
|
||||
return [
|
||||
'currPage' => $page,
|
||||
'pageSize' => $limit,
|
||||
'list' => convertToCamelCase($query),
|
||||
'totalCount' => $count,
|
||||
'totalPage' => ceil($count / $limit),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function updateIntegral($type, $userId, $num, $db)
|
||||
{
|
||||
$db = $db->name('user_integral');
|
||||
$query = $db->where('user_id', $userId);
|
||||
// 根据类型决定是增加还是减少积分
|
||||
if ($type == 1) {
|
||||
// 增加积分
|
||||
$query->inc('integral_num', $num);
|
||||
} elseif ($type == 2) {
|
||||
// 减少积分
|
||||
$query->where('integral_num', '>=', $num);
|
||||
$query->dec('integral_num', $num);
|
||||
}
|
||||
|
||||
// 执行更新
|
||||
return $query->update();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
80
app/admin/model/UserMoneyLog.php
Normal file
80
app/admin/model/UserMoneyLog.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use Throwable;
|
||||
use think\model;
|
||||
use think\Exception;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
/**
|
||||
* UserMoneyLog 模型
|
||||
* 1. 创建余额日志自动完成会员余额的添加
|
||||
* 2. 创建余额日志时,请开启事务
|
||||
*/
|
||||
class UserMoneyLog extends model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
protected $updateTime = false;
|
||||
|
||||
/**
|
||||
* 入库前
|
||||
* @throws Throwable
|
||||
*/
|
||||
public static function onBeforeInsert($model): void
|
||||
{
|
||||
$user = User::where('id', $model->user_id)->lock(true)->find();
|
||||
if (!$user) {
|
||||
throw new Exception("The user can't find it");
|
||||
}
|
||||
if (!$model->memo) {
|
||||
throw new Exception("Change note cannot be blank");
|
||||
}
|
||||
$model->before = $user->money;
|
||||
|
||||
$user->money += $model->money;
|
||||
$user->save();
|
||||
|
||||
$model->after = $user->money;
|
||||
}
|
||||
|
||||
public static function onBeforeDelete(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getMoneyAttr($value): string
|
||||
{
|
||||
return bcdiv($value, 100, 2);
|
||||
}
|
||||
|
||||
public function setMoneyAttr($value): string
|
||||
{
|
||||
return bcmul($value, 100, 2);
|
||||
}
|
||||
|
||||
public function getBeforeAttr($value): string
|
||||
{
|
||||
return bcdiv($value, 100, 2);
|
||||
}
|
||||
|
||||
public function setBeforeAttr($value): string
|
||||
{
|
||||
return bcmul($value, 100, 2);
|
||||
}
|
||||
|
||||
public function getAfterAttr($value): string
|
||||
{
|
||||
return bcdiv($value, 100, 2);
|
||||
}
|
||||
|
||||
public function setAfterAttr($value): string
|
||||
{
|
||||
return bcmul($value, 100, 2);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
}
|
||||
26
app/admin/model/UserRule.php
Normal file
26
app/admin/model/UserRule.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\model;
|
||||
|
||||
/**
|
||||
* UserRule 模型
|
||||
* @property int $status 状态:0=禁用,1=启用
|
||||
*/
|
||||
class UserRule extends model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
protected static function onAfterInsert($model): void
|
||||
{
|
||||
$pk = $model->getPk();
|
||||
$model->where($pk, $model[$pk])->update(['weigh' => $model[$pk]]);
|
||||
}
|
||||
|
||||
public function setComponentAttr($value)
|
||||
{
|
||||
if ($value) $value = str_replace('\\', '/', $value);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
50
app/admin/model/UserScoreLog.php
Normal file
50
app/admin/model/UserScoreLog.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use Throwable;
|
||||
use think\model;
|
||||
use think\Exception;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
/**
|
||||
* UserScoreLog 模型
|
||||
* 1. 创建积分日志自动完成会员积分的添加
|
||||
* 2. 创建积分日志时,请开启事务
|
||||
*/
|
||||
class UserScoreLog extends model
|
||||
{
|
||||
protected $autoWriteTimestamp = true;
|
||||
protected $updateTime = false;
|
||||
|
||||
/**
|
||||
* 入库前
|
||||
* @throws Throwable
|
||||
*/
|
||||
public static function onBeforeInsert($model): void
|
||||
{
|
||||
$user = User::where('id', $model->user_id)->lock(true)->find();
|
||||
if (!$user) {
|
||||
throw new Exception("The user can't find it");
|
||||
}
|
||||
if (!$model->memo) {
|
||||
throw new Exception("Change note cannot be blank");
|
||||
}
|
||||
$model->before = $user->score;
|
||||
|
||||
$user->score += $model->score;
|
||||
$user->save();
|
||||
|
||||
$model->after = $user->score;
|
||||
}
|
||||
|
||||
public static function onBeforeDelete(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user