支持设置默认企业
This commit is contained in:
@@ -202,10 +202,15 @@ class Analyze extends BaseController
|
||||
'amountYuan' => $standardAmountFen > 0 ? round($standardAmountFen / 100, 2) : 0,
|
||||
];
|
||||
|
||||
// 若该类型需付费才显示完整报告:返回给前端的也做脱敏,与详情/历史一致(只显示部分,付费后从详情接口拿完整)
|
||||
if ($requiresPayment) {
|
||||
$responsePayload['faceAnalysis'] = null;
|
||||
$responsePayload['boneAnalysis'] = null;
|
||||
// 未付费 / 资料未完善:与 /api/test/detail 一致做预览脱敏,防止直接抓包拿到完整报告
|
||||
$gateResponse = false;
|
||||
if ($requiresPayment > 0) {
|
||||
$gateResponse = true;
|
||||
} elseif ($earlyUserId > 0 && !TestController::isWechatProfileComplete($earlyUserId)) {
|
||||
$gateResponse = true;
|
||||
}
|
||||
if (is_array($responsePayload) && $gateResponse) {
|
||||
$responsePayload = TestController::filterFaceResultToPreview($responsePayload);
|
||||
}
|
||||
|
||||
// 把本次测试记录ID一起返回,便于解锁后通过 /api/test/detail 拉取完整数据
|
||||
|
||||
@@ -50,6 +50,30 @@ class AppConfig extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
// 系统配置:审核模式、默认企业(无带参入口时小程序回落)
|
||||
$maintenanceMode = false;
|
||||
$defaultEnterpriseId = null;
|
||||
$systemRow = Db::name('system_config')->where('key', 'system')->find();
|
||||
if ($systemRow && !empty($systemRow['value'])) {
|
||||
$sysValEarly = is_string($systemRow['value']) ? json_decode($systemRow['value'], true) : $systemRow['value'];
|
||||
if (is_array($sysValEarly)) {
|
||||
if (!empty($sysValEarly['maintenanceMode'])) {
|
||||
$maintenanceMode = true;
|
||||
}
|
||||
if (!empty($sysValEarly['defaultEnterpriseId'])) {
|
||||
$de = (int) $sysValEarly['defaultEnterpriseId'];
|
||||
if ($de > 0) {
|
||||
$defaultEnterpriseId = $de;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// scope=enterprise 且用户未绑定企业时,用超管默认企业拉企业定价与文案
|
||||
if ($scope !== 'personal' && $enterpriseId === null && $defaultEnterpriseId !== null) {
|
||||
$enterpriseId = $defaultEnterpriseId;
|
||||
$pricingType = 'enterprise';
|
||||
}
|
||||
|
||||
$config = PricingConfigModel::getByTypeAndEnterprise($pricingType, $enterpriseId);
|
||||
if ($config && !empty($config->config)) {
|
||||
// PricingConfig 模型已对 config 做 JSON 转换,这里直接当数组/对象用即可
|
||||
@@ -103,16 +127,6 @@ class AppConfig extends BaseController
|
||||
}
|
||||
$siteTitle = $miniprogramName !== '' ? $miniprogramName : ($siteName !== '' ? $siteName : '神仙团队AI性格测试');
|
||||
|
||||
// 审核模式(原 maintenanceMode):开启后首页展示「开始性格测试」并跳转 test-select
|
||||
$maintenanceMode = false;
|
||||
$systemRow = Db::name('system_config')->where('key', 'system')->find();
|
||||
if ($systemRow && !empty($systemRow['value'])) {
|
||||
$sysVal = is_string($systemRow['value']) ? json_decode($systemRow['value'], true) : $systemRow['value'];
|
||||
if (is_array($sysVal) && !empty($sysVal['maintenanceMode'])) {
|
||||
$maintenanceMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 小程序文案配置(分析中提示、按钮、报告标题等)
|
||||
$textConfig = [
|
||||
'analyzingTitle' => '正在分析中',
|
||||
@@ -155,6 +169,7 @@ class AppConfig extends BaseController
|
||||
'siteTitle' => $siteTitle,
|
||||
'textConfig' => $textConfig,
|
||||
'maintenanceMode' => $maintenanceMode,
|
||||
'defaultEnterpriseId' => $defaultEnterpriseId,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,11 @@ class Payment extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
// 测试结果未带 enterpriseId 时,使用小程序请求中的企业上下文(scene/绑定/超管默认企业)
|
||||
if (empty($enterpriseId) && $enterpriseIdParam > 0) {
|
||||
$enterpriseId = $enterpriseIdParam;
|
||||
}
|
||||
|
||||
// 充值场景:优先使用显式传入的企业ID,否则回退到当前用户已绑定企业
|
||||
if ($productType === 'recharge') {
|
||||
if ($enterpriseIdParam > 0) {
|
||||
|
||||
@@ -80,6 +80,9 @@ class Test extends BaseController
|
||||
$requiresPayment = (int) ($row['requiresPayment'] ?? 0);
|
||||
$isPaid = (int) ($row['isPaid'] ?? 0);
|
||||
$orderId = isset($row['orderId']) ? (int) $row['orderId'] : null;
|
||||
$paidAmountRow = isset($row['paidAmount']) ? (int) $row['paidAmount'] : 0;
|
||||
$needPayUnlock = $requiresPayment && !$isPaid && $paidAmountRow > 0;
|
||||
$profileIncomplete = !self::isWechatProfileComplete($userId);
|
||||
|
||||
$raw = $row['resultData'] ?? ($row['result'] ?? null);
|
||||
$data = null;
|
||||
@@ -87,8 +90,14 @@ class Test extends BaseController
|
||||
$decoded = json_decode($raw, true);
|
||||
$data = is_array($decoded) ? $decoded : $raw;
|
||||
}
|
||||
if ($requiresPayment && !$isPaid && $data !== null) {
|
||||
$data = $this->filterResultToPartial($testType, $data);
|
||||
if ($data !== null && is_array($data)) {
|
||||
if (in_array($testType, ['face', 'ai'], true)) {
|
||||
if ($needPayUnlock || $profileIncomplete) {
|
||||
$data = self::filterFaceResultToPreview($data);
|
||||
}
|
||||
} elseif ($requiresPayment && !$isPaid) {
|
||||
$data = $this->filterResultToPartial($testType, $data);
|
||||
}
|
||||
}
|
||||
|
||||
$paymentFields = [
|
||||
@@ -358,8 +367,15 @@ class Test extends BaseController
|
||||
$testType = $row['testType'] ?? '';
|
||||
// 仅当需要付款且未付款且金额>0 时才脱敏;系统设置需付款但金额为0 则直接可查看
|
||||
$needPaymentToUnlock = $requiresPayment && !$isPaid && $paidAmount > 0;
|
||||
if ($needPaymentToUnlock && $data !== null) {
|
||||
$data = $this->filterResultToPartial($testType, $data);
|
||||
$profileIncomplete = !self::isWechatProfileComplete($userId);
|
||||
if ($data !== null && is_array($data)) {
|
||||
if (in_array($testType, ['face', 'ai'], true)) {
|
||||
if ($needPaymentToUnlock || $profileIncomplete) {
|
||||
$data = self::filterFaceResultToPreview($data);
|
||||
}
|
||||
} elseif ($needPaymentToUnlock) {
|
||||
$data = $this->filterResultToPartial($testType, $data);
|
||||
}
|
||||
}
|
||||
|
||||
return success([
|
||||
@@ -550,12 +566,6 @@ class Test extends BaseController
|
||||
if (!is_array($data)) {
|
||||
return $data;
|
||||
}
|
||||
if ($testType === 'face' || $testType === 'ai') {
|
||||
$out = $data;
|
||||
$out['faceAnalysis'] = null;
|
||||
$out['boneAnalysis'] = null;
|
||||
return $out;
|
||||
}
|
||||
if ($testType === 'mbti') {
|
||||
return [
|
||||
'mbtiType' => $data['mbtiType'] ?? $data['mbti'] ?? '',
|
||||
@@ -577,6 +587,82 @@ class Test extends BaseController
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信用户资料是否与小程序 isProfileComplete 一致:头像、昵称、手机号必填
|
||||
*/
|
||||
public static function isWechatProfileComplete(int $userId): bool
|
||||
{
|
||||
if ($userId <= 0) {
|
||||
return false;
|
||||
}
|
||||
$row = Db::name('wechat_users')->where('id', $userId)->field('nickname,avatar,phone')->find();
|
||||
if (!$row) {
|
||||
return false;
|
||||
}
|
||||
$nick = trim((string) ($row['nickname'] ?? ''));
|
||||
$avatar = trim((string) ($row['avatar'] ?? ''));
|
||||
$phone = trim((string) ($row['phone'] ?? ''));
|
||||
|
||||
return $nick !== '' && $avatar !== '' && $phone !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸/AI 分析报告:未付费或资料未完善时仅返回预览级字段(防止抓包看全文)
|
||||
*/
|
||||
public static function filterFaceResultToPreview(array $data): array
|
||||
{
|
||||
$out = $data;
|
||||
$out['faceAnalysis'] = null;
|
||||
$out['boneAnalysis'] = null;
|
||||
unset($out['faceAnalysisText'], $out['boneAnalysisText']);
|
||||
$out['relationship'] = '';
|
||||
$out['portrait'] = null;
|
||||
$out['hrView'] = null;
|
||||
$out['bossView'] = null;
|
||||
$out['resumeHighlights'] = '';
|
||||
if (isset($out['careers'])) {
|
||||
$out['careers'] = [];
|
||||
}
|
||||
|
||||
$sum = (string) ($out['personalitySummary'] ?? '');
|
||||
$ov = (string) ($out['overview'] ?? '');
|
||||
$out['personalitySummary'] = self::truncatePreviewText($sum, 72);
|
||||
$out['overview'] = self::truncatePreviewText($ov, 72);
|
||||
$out['gallupTop3'] = [];
|
||||
|
||||
$adv = $out['advantages'] ?? [];
|
||||
if (is_array($adv) && $adv !== []) {
|
||||
$slice = array_slice($adv, 0, 2);
|
||||
$out['advantages'] = array_map(function ($x) {
|
||||
return self::truncatePreviewText((string) $x, 28);
|
||||
}, $slice);
|
||||
} else {
|
||||
$out['advantages'] = [];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private static function truncatePreviewText(string $s, int $maxChars): string
|
||||
{
|
||||
$s = trim($s);
|
||||
if ($s === '') {
|
||||
return '';
|
||||
}
|
||||
if (function_exists('mb_strlen') && function_exists('mb_substr')) {
|
||||
if (mb_strlen($s, 'UTF-8') > $maxChars) {
|
||||
return mb_substr($s, 0, $maxChars, 'UTF-8') . '…';
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
if (strlen($s) > $maxChars) {
|
||||
return substr($s, 0, $maxChars) . '…';
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户最近的 MBTI / DISC / PDP 测试记录(暂不使用人脸/AI 结果),供简历综合分析使用
|
||||
* @param int $userId 微信用户 ID
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace app\controller\superadmin;
|
||||
use app\BaseController;
|
||||
use app\model\SystemConfig as SystemConfigModel;
|
||||
use app\model\User as UserModel;
|
||||
use app\model\Enterprise as EnterpriseModel;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
|
||||
@@ -55,7 +56,8 @@ class Settings extends BaseController
|
||||
'miniprogramName' => '神仙团队AI性格测试',
|
||||
'maintenanceMode' => false,
|
||||
'maxTestsPerDay' => 100,
|
||||
'trialTestCount' => 10
|
||||
'trialTestCount' => 10,
|
||||
'defaultEnterpriseId' => null,
|
||||
],
|
||||
'notification' => $notificationConfig ? $notificationConfig->value : [
|
||||
'emailNotification' => true,
|
||||
@@ -100,12 +102,30 @@ class Settings extends BaseController
|
||||
$input = [];
|
||||
}
|
||||
|
||||
$allowedKeys = ['siteName', 'siteDescription', 'miniprogramName', 'maintenanceMode', 'maxTestsPerDay', 'trialTestCount'];
|
||||
$allowedKeys = ['siteName', 'siteDescription', 'miniprogramName', 'maintenanceMode', 'maxTestsPerDay', 'trialTestCount', 'defaultEnterpriseId'];
|
||||
$data = array_intersect_key($input, array_flip($allowedKeys));
|
||||
// 兼容 fallback:JSON 解析失败时尝试 Request::only
|
||||
if (empty($data)) {
|
||||
$data = Request::only($allowedKeys);
|
||||
}
|
||||
// 默认企业:0 或空视为不启用
|
||||
if (array_key_exists('defaultEnterpriseId', $data)) {
|
||||
$de = $data['defaultEnterpriseId'];
|
||||
if ($de === '' || $de === null) {
|
||||
$data['defaultEnterpriseId'] = null;
|
||||
} else {
|
||||
$deInt = (int) $de;
|
||||
if ($deInt <= 0) {
|
||||
$data['defaultEnterpriseId'] = null;
|
||||
} else {
|
||||
$exists = EnterpriseModel::where('id', $deInt)->find();
|
||||
if (!$exists) {
|
||||
return error('所选默认企业不存在', 400);
|
||||
}
|
||||
$data['defaultEnterpriseId'] = $deInt;
|
||||
}
|
||||
}
|
||||
}
|
||||
$textConfig = $input['textConfig'] ?? (Request::param('textConfig') ?: []);
|
||||
|
||||
try {
|
||||
@@ -117,7 +137,13 @@ class Settings extends BaseController
|
||||
$config->enterprise_id = 0;
|
||||
$config->description = '系统基础配置';
|
||||
}
|
||||
$config->value = $data;
|
||||
// 合并保存,避免仅提交部分字段时丢失其它键(如 defaultEnterpriseId)
|
||||
$oldVal = $config->value;
|
||||
$oldArr = is_array($oldVal) ? $oldVal : (is_string($oldVal) ? (json_decode($oldVal, true) ?: []) : []);
|
||||
if (!is_array($oldArr)) {
|
||||
$oldArr = [];
|
||||
}
|
||||
$config->value = array_merge($oldArr, $data);
|
||||
$config->save();
|
||||
|
||||
// 更新站点信息
|
||||
|
||||
Reference in New Issue
Block a user