Files
MBTI_wang/api/app/model/Enterprise.php
Ghost 6fec2965aa feat: SBTI 测评接入与管理端题目/财务/用户联动
1、修复了用户详情、定价与题目管理、财务与分销等管理端展示与接口问题。

2、新增 SBTI 小程序测评/结果页、sbtiData 引擎、题库 SQL 与脚本;admin sbtiDisplay。

3、优化 AppConfig/CrmReport/Test、历史与个人中心、test-select 与支付相关逻辑。

Made-with: Cursor
2026-04-11 16:16:32 +08:00

168 lines
5.2 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
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
/**
* 企业模型
*/
class Enterprise extends Model
{
use SoftDelete;
// 设置表名(不带前缀,前缀在数据库配置中设置)
protected $name = 'enterprises';
// 软删除字段(驼峰命名,时间戳格式)
protected $deleteTime = 'deletedAt';
// 设置字段信息(匹配数据库字段命名:驼峰命名)
protected $schema = [
'id' => 'int',
'name' => 'string',
'code' => 'string',
'contactName' => 'string',
'contactPhone' => 'string',
'contactEmail' => 'string',
'balance' => 'float',
'status' => 'string',
'permissions' => 'json',
'permissionsCeiling' => 'json',
'trialExpireAt' => 'int',
'deletedAt' => 'int',
'createdAt' => 'int',
'updatedAt' => 'int',
];
// 自动时间戳(使用驼峰命名,时间戳格式)
protected $autoWriteTimestamp = 'int';
// 时间戳字段名(驼峰命名,匹配数据库)
protected $createTime = 'createdAt';
protected $updateTime = 'updatedAt';
// 时间字段类型(时间戳格式)
protected $type = [
'permissions' => 'json',
'permissionsCeiling' => 'json',
'trialExpireAt' => 'integer',
'deletedAt' => 'integer',
'createdAt' => 'integer',
'updatedAt' => 'integer',
];
/** 权限键默认值(库中为 null / 空 / 缺列 / 解析失败时一律回落至此) */
public static function permissionDefaults(): array
{
return [
'face' => true,
'mbti' => true,
'sbti' => true,
'pdp' => true,
'disc' => true,
'distribution' => true,
];
}
/**
* 将库中任意形态的 permissions 规范化为固定键数组(兼容 null、''、{}、[]、非法 JSON、双重 JSON 字符串)
* @param mixed $value 原始列值
*/
public static function normalizePermissionsValue($value): array
{
$defaults = self::permissionDefaults();
if ($value === null) {
return $defaults;
}
if (is_string($value)) {
$trim = trim($value);
if ($trim === '' || strcasecmp($trim, 'null') === 0) {
return $defaults;
}
$decoded = json_decode($trim, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return $defaults;
}
$value = $decoded;
}
// 双重编码:第一次 decode 后仍是 JSON 字符串
if (is_string($value)) {
$trim = trim($value);
$decoded = $trim === '' ? [] : json_decode($trim, true);
$value = (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) ? $decoded : [];
}
if (is_object($value)) {
$value = json_decode(json_encode($value, JSON_UNESCAPED_UNICODE), true);
}
if (!is_array($value)) {
return $defaults;
}
return array_merge($defaults, array_intersect_key($value, $defaults));
}
/**
* 获取规范化权限(未设置的键默认 true
*/
public function getNormalizedPermissions(): array
{
return self::normalizePermissionsValue($this->permissions);
}
/**
* 超管授权上限(未单独配置时回落为当前 permissions兼容未跑迁移库
*
* @param self|array<string,mixed>|null $enterprise 模型或 toArray 行
*/
public static function normalizedPermissionsCeiling($enterprise): array
{
if ($enterprise instanceof self) {
$raw = $enterprise->getAttr('permissionsCeiling');
if ($raw === null || $raw === '') {
$raw = $enterprise->getAttr('permissions');
}
return self::normalizePermissionsValue($raw);
}
if (is_array($enterprise)) {
$raw = $enterprise['permissionsCeiling'] ?? null;
if ($raw === null || $raw === '') {
$raw = $enterprise['permissions'] ?? null;
}
return self::normalizePermissionsValue($raw);
}
return self::permissionDefaults();
}
/**
* 在超管上限内合并企业管理员提交的开关
*/
public static function clampPermissionsToCeiling(array $ceiling, array $requested): array
{
$req = self::normalizePermissionsValue($requested);
$out = [];
foreach (array_keys(self::permissionDefaults()) as $k) {
$out[$k] = !empty($ceiling[$k]) && !empty($req[$k]);
}
return $out;
}
/**
* 超管收紧上限后,同步收缩已生效 permissions关掉的项强制 false
*/
public static function clampEffectiveToNewCeiling(array $newCeiling, array $oldEffective): array
{
$old = self::normalizePermissionsValue($oldEffective);
$out = [];
foreach (array_keys(self::permissionDefaults()) as $k) {
$out[$k] = !empty($newCeiling[$k]) && !empty($old[$k]);
}
return $out;
}
}