refactor: 企业管理端设置页精简与 CRM 报告接口调整

1、修复了管理端系统设置交互与表单项冗余问题。

2、优化了 admin Settings 控制器与新 Settings 页面对齐。

3、调整 CrmReport 接口逻辑与数据结构。

Made-with: Cursor
This commit is contained in:
Ghost
2026-04-02 09:40:56 +08:00
parent ef19f6860e
commit 48c4d551d2
3 changed files with 191 additions and 161 deletions

View File

@@ -175,22 +175,18 @@ class Settings extends BaseController
}
/**
* 存客宝 Key 默认结构(人脸/MBTI/PDP/DISC × 企业版与个人版
* 存客宝默认结构(测评线索共用一个 Key + 上报时机
*/
private static function defaultCunkebaoKeysStructure(): array
{
$blank = ['enterprise' => '', 'personal' => '', 'reportTiming' => 'after_paid'];
return [
'face' => $blank,
'pdp' => $blank,
'disc' => $blank,
'mbti' => $blank,
'apiKey' => '',
'reportTiming' => 'after_paid',
];
}
/**
* @param mixed $raw 已解码的配置或 null
* @param mixed $raw 已解码的配置或 null(单 Key兼容旧版 enterprise/personal 及按题型分栏)
*/
private static function normalizeCunkebaoKeysPayload($raw): array
{
@@ -198,16 +194,54 @@ class Settings extends BaseController
if (!is_array($raw)) {
return $out;
}
foreach (array_keys($out) as $type) {
$rtIn = static function ($v) use (&$out): void {
$rt = (string) ($v ?? '');
if (in_array($rt, ['after_paid', 'after_test'], true)) {
$out['reportTiming'] = $rt;
}
};
// 新版apiKey + reportTiming
if (array_key_exists('apiKey', $raw)) {
$out['apiKey'] = isset($raw['apiKey']) ? trim((string) $raw['apiKey']) : '';
$rtIn($raw['reportTiming'] ?? '');
return $out;
}
// 上一版enterprise / personal 合二为一(优先企业栏)
if (array_key_exists('enterprise', $raw) || array_key_exists('personal', $raw)) {
$e = isset($raw['enterprise']) ? trim((string) $raw['enterprise']) : '';
$p = isset($raw['personal']) ? trim((string) $raw['personal']) : '';
$out['apiKey'] = $e !== '' ? $e : $p;
$rtIn($raw['reportTiming'] ?? '');
return $out;
}
// 旧版:按题型分栏
$types = ['face', 'pdp', 'disc', 'mbti'];
foreach ($types as $type) {
if (!isset($raw[$type]) || !is_array($raw[$type])) {
continue;
}
$row = $raw[$type];
$out[$type]['enterprise'] = isset($row['enterprise']) ? trim((string) $row['enterprise']) : '';
$out[$type]['personal'] = isset($row['personal']) ? trim((string) $row['personal']) : '';
$out[$type]['reportTiming'] = in_array($row['reportTiming'] ?? '', ['after_paid', 'after_test'], true)
? $row['reportTiming']
: 'after_paid';
if ($out['apiKey'] === '' && isset($row['enterprise'])) {
$x = trim((string) $row['enterprise']);
if ($x !== '') {
$out['apiKey'] = $x;
}
}
if ($out['apiKey'] === '' && isset($row['personal'])) {
$x = trim((string) $row['personal']);
if ($x !== '') {
$out['apiKey'] = $x;
}
}
if ((string) ($row['reportTiming'] ?? '') === 'after_test') {
$out['reportTiming'] = 'after_test';
}
}
return $out;
@@ -275,7 +309,7 @@ class Settings extends BaseController
$sanitized = self::normalizeCunkebaoKeysPayload($payload);
try {
self::saveConfig('cunkebao_keys', $sanitized, $eid, '存客宝 Key本企业 · 人脸/MBTI/PDP/DISC');
self::saveConfig('cunkebao_keys', $sanitized, $eid, '存客宝 Key本企业 · 测评类共用');
return success($sanitized, '存客宝 Key 已保存');
} catch (\Exception $e) {

View File

@@ -139,17 +139,15 @@ class CrmReport extends BaseController
return null;
}
$testScope = '';
$trEnterpriseId = 0;
if ($testResultId > 0) {
$tr = Db::name('test_results')
->where('id', $testResultId)
->where('userId', $userId)
->field('enterpriseId,testScope')
->field('enterpriseId')
->find();
if ($tr) {
$testScope = (string) ($tr['testScope'] ?? 'personal');
$trEnterpriseId = (int) ($tr['enterpriseId'] ?? 0);
}
}
@@ -159,32 +157,15 @@ class CrmReport extends BaseController
$configEid = (int) (Db::name('wechat_users')->where('id', $userId)->value('enterpriseId') ?? 0);
}
$useEnterpriseColumn = ($testScope === 'enterprise')
|| ($testScope === '' && $contextEnterpriseId > 0);
$col = $useEnterpriseColumn ? 'enterprise' : 'personal';
$key = self::readCunkebaoCellWithFallback($configEid, $testType, $col);
$key = self::readSingleCunkebaoApiKeyWithFallback($configEid);
return $key !== '' ? $key : null;
}
/**
* 读取企业 cunkebao_keys 中一格;为空时再读 enterprise_id=0 全局行
* 读取企业 cunkebao_keys:单 apiKey兼容旧版 enterprise/personal 及按题型分栏
*/
private static function readCunkebaoCellWithFallback(int $enterpriseId, string $testType, string $col): string
{
$v = self::readCunkebaoCell($enterpriseId, $testType, $col);
if ($v !== '') {
return $v;
}
if ($enterpriseId > 0) {
$v = self::readCunkebaoCell(0, $testType, $col);
}
return $v;
}
private static function readCunkebaoCell(int $enterpriseId, string $testType, string $col): string
private static function readSingleCunkebaoApiKey(int $enterpriseId): string
{
$row = Db::name('system_config')
->where('key', 'cunkebao_keys')
@@ -194,11 +175,45 @@ class CrmReport extends BaseController
return '';
}
$decoded = is_string($row['value']) ? json_decode($row['value'], true) : $row['value'];
if (!is_array($decoded) || !isset($decoded[$testType][$col])) {
if (!is_array($decoded)) {
return '';
}
if (array_key_exists('apiKey', $decoded)) {
return trim((string) ($decoded['apiKey'] ?? ''));
}
if (array_key_exists('enterprise', $decoded) || array_key_exists('personal', $decoded)) {
$e = trim((string) ($decoded['enterprise'] ?? ''));
$p = trim((string) ($decoded['personal'] ?? ''));
return trim((string) $decoded[$testType][$col]);
return $e !== '' ? $e : $p;
}
foreach (['face', 'mbti', 'pdp', 'disc'] as $t) {
if (!isset($decoded[$t]) || !is_array($decoded[$t])) {
continue;
}
$rowT = $decoded[$t];
foreach (['enterprise', 'personal'] as $col) {
$v = trim((string) ($rowT[$col] ?? ''));
if ($v !== '') {
return $v;
}
}
}
return '';
}
private static function readSingleCunkebaoApiKeyWithFallback(int $enterpriseId): string
{
$v = self::readSingleCunkebaoApiKey($enterpriseId);
if ($v !== '') {
return $v;
}
if ($enterpriseId > 0) {
$v = self::readSingleCunkebaoApiKey(0);
}
return $v;
}
private static function testTypeSiteTag(string $testType): string
@@ -352,13 +367,12 @@ class CrmReport extends BaseController
// 未配置付费(免费):测试完成即上报(与「没付款可直接调用」一致)
// 若需付费:仅当后台为「测试完即上报」时在提交后上报;「付款后才上报」则等支付成功后再走前端/接口
$timing = self::readReportTiming($enterpriseId, $testType);
$timing = self::readReportTiming($enterpriseId);
if ($requiresPayment === 1 && $timing !== 'after_test') {
return;
}
$col = ($testScope === 'enterprise') ? 'enterprise' : 'personal';
$apiKey = self::readCunkebaoCellWithFallback($enterpriseId, $testType, $col);
$apiKey = self::readSingleCunkebaoApiKeyWithFallback($enterpriseId);
if ($apiKey === '') {
return;
}
@@ -382,22 +396,22 @@ class CrmReport extends BaseController
}
/**
* 读取企业某测评类型的 reportTimingafter_paid / after_test
* 读取企业 reportTimingafter_paid / after_test,测评类共用
*/
private static function readReportTiming(int $enterpriseId, string $testType): string
private static function readReportTiming(int $enterpriseId): string
{
$val = self::readReportTimingFromRow($enterpriseId, $testType);
$val = self::readReportTimingFromRow($enterpriseId);
if ($val !== '') {
return $val;
}
if ($enterpriseId > 0) {
$val = self::readReportTimingFromRow(0, $testType);
$val = self::readReportTimingFromRow(0);
}
return $val !== '' ? $val : 'after_paid';
}
private static function readReportTimingFromRow(int $enterpriseId, string $testType): string
private static function readReportTimingFromRow(int $enterpriseId): string
{
$row = Db::name('system_config')
->where('key', 'cunkebao_keys')
@@ -407,12 +421,34 @@ class CrmReport extends BaseController
return '';
}
$decoded = is_string($row['value']) ? json_decode($row['value'], true) : $row['value'];
if (!is_array($decoded) || !isset($decoded[$testType]['reportTiming'])) {
if (!is_array($decoded)) {
return '';
}
$t = (string) $decoded[$testType]['reportTiming'];
if (isset($decoded['reportTiming'])) {
$t = (string) $decoded['reportTiming'];
return in_array($t, ['after_paid', 'after_test'], true) ? $t : '';
return in_array($t, ['after_paid', 'after_test'], true) ? $t : '';
}
foreach (['face', 'mbti', 'pdp', 'disc'] as $tKey) {
if (!isset($decoded[$tKey]['reportTiming'])) {
continue;
}
$t = (string) $decoded[$tKey]['reportTiming'];
if ($t === 'after_test') {
return 'after_test';
}
}
foreach (['face', 'mbti', 'pdp', 'disc'] as $tKey) {
if (!isset($decoded[$tKey]['reportTiming'])) {
continue;
}
$t = (string) $decoded[$tKey]['reportTiming'];
if (in_array($t, ['after_paid', 'after_test'], true)) {
return $t;
}
}
return '';
}
/**