140 lines
4.4 KiB
PHP
140 lines
4.4 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
namespace app\dice\helper;
|
||
|
||
use plugin\saiadmin\exception\ApiException;
|
||
|
||
/**
|
||
* 配置类数据按渠道隔离的更新(防止 find(id) 误更新其他渠道同业务主键行)
|
||
*/
|
||
class ConfigScopeEditHelper
|
||
{
|
||
/**
|
||
* 在查询上附加渠道条件
|
||
*/
|
||
public static function applyDeptIdWhere($query, int $deptId, string $column = 'dept_id'): void
|
||
{
|
||
if (AdminScopeHelper::isTemplateDeptId($deptId)) {
|
||
$query->where(function ($q) use ($deptId, $column) {
|
||
$q->where($column, $deptId);
|
||
if (method_exists($q, 'orWhereNull')) {
|
||
$q->orWhereNull($column);
|
||
} else {
|
||
$q->whereOr($column, null);
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
$query->where($column, $deptId);
|
||
}
|
||
|
||
/**
|
||
* 按主键 + 渠道更新配置行
|
||
*
|
||
* @param Model $model 模型实例(用于取表名、主键)
|
||
* @param mixed $primaryKeyValue 列表/表单中的主键值
|
||
* @param int $deptId 渠道 ID(0=默认模板)
|
||
* @param array $data 更新字段
|
||
* @param array $forbidden 禁止写入的字段名
|
||
*/
|
||
/**
|
||
* 按主键更新(主键全局唯一表如 dice_lottery_pool_config)
|
||
* 以库中记录的 dept_id 为准,避免请求未带 dept_id 时误按默认模板 0 查找失败
|
||
*/
|
||
public static function updateByPkAndDept(
|
||
object $model,
|
||
$primaryKeyValue,
|
||
int $requestDeptId,
|
||
array $data,
|
||
array $forbidden = ['id', 'dept_id', 'create_time', 'update_time', 'delete_time', 'row_id'],
|
||
?array $adminInfo = null,
|
||
$rawRequestDeptId = null
|
||
): bool {
|
||
foreach ($forbidden as $field) {
|
||
unset($data[$field]);
|
||
}
|
||
if ($data === []) {
|
||
return true;
|
||
}
|
||
|
||
$pk = self::resolvePk($model);
|
||
$record = $model->where($pk, $primaryKeyValue)->find();
|
||
if ($record === null) {
|
||
throw new ApiException('data not found');
|
||
}
|
||
|
||
$recordDeptId = AdminScopeHelper::normalizeRecordDeptId(
|
||
is_array($record) ? ($record['dept_id'] ?? null) : ($record->dept_id ?? null)
|
||
);
|
||
|
||
if ($adminInfo !== null && ! AdminScopeHelper::canAccessDept($adminInfo, $recordDeptId, $rawRequestDeptId)) {
|
||
throw new ApiException('no permission to update this record');
|
||
}
|
||
|
||
if ($rawRequestDeptId !== null && $rawRequestDeptId !== '') {
|
||
$targetDeptId = AdminScopeHelper::resolveConfigDeptId($adminInfo, $rawRequestDeptId);
|
||
if ($targetDeptId !== $recordDeptId) {
|
||
throw new ApiException('record does not belong to selected channel');
|
||
}
|
||
}
|
||
|
||
$query = $model->where($pk, $primaryKeyValue);
|
||
self::applyDeptIdWhere($query, $recordDeptId);
|
||
|
||
$affected = $query->update($data);
|
||
return $affected !== false;
|
||
}
|
||
|
||
/**
|
||
* dice_reward_config / dice_config:业务 id(0~25 等)+ 渠道更新
|
||
*/
|
||
public static function updateByBusinessIdAndDept(
|
||
object $model,
|
||
int $businessId,
|
||
int $deptId,
|
||
array $data,
|
||
array $forbidden = ['id', 'dept_id', 'create_time', 'update_time', 'delete_time', 'row_id']
|
||
): bool {
|
||
foreach ($forbidden as $field) {
|
||
unset($data[$field]);
|
||
}
|
||
if ($data === []) {
|
||
return true;
|
||
}
|
||
|
||
$query = $model->where('id', $businessId);
|
||
self::applyDeptIdWhere($query, $deptId);
|
||
|
||
$record = (clone $query)->find();
|
||
if ($record === null) {
|
||
throw new ApiException('config id=' . $businessId . ' not found for current channel');
|
||
}
|
||
|
||
$affected = $query->update($data);
|
||
return $affected !== false;
|
||
}
|
||
|
||
/**
|
||
* 列表/读取:按主键 + 渠道取单条(避免 find(pk) 命中其他渠道)
|
||
*/
|
||
private static function resolvePk(object $model): string
|
||
{
|
||
if (method_exists($model, 'getPk')) {
|
||
return (string) $model->getPk();
|
||
}
|
||
if (method_exists($model, 'getKeyName')) {
|
||
return (string) $model->getKeyName();
|
||
}
|
||
return 'id';
|
||
}
|
||
|
||
public static function findByPkAndDept(object $model, $primaryKeyValue, int $deptId)
|
||
{
|
||
$pk = self::resolvePk($model);
|
||
$query = $model->where($pk, $primaryKeyValue);
|
||
self::applyDeptIdWhere($query, $deptId);
|
||
return $query->find();
|
||
}
|
||
}
|