refactor: 企业管理端设置页精简与 CRM 报告接口调整
1、修复了管理端系统设置交互与表单项冗余问题。 2、优化了 admin Settings 控制器与新 Settings 页面对齐。 3、调整 CrmReport 接口逻辑与数据结构。 Made-with: Cursor
This commit is contained in:
@@ -44,61 +44,42 @@
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="activeTab === 'cunkebao'" class="tab-content" v-loading="cunkebaoLoading">
|
||||
<div class="content-header">
|
||||
<h3>存客宝 Key</h3>
|
||||
<p class="content-description">
|
||||
按测评类型配置企业版与个人版 Key(人脸、MBTI、DISC、PDP 各自独立),数据仅保存在当前企业维度;留空表示未配置。下方「上报时机」对上述四类均生效:免费测评完成后即上报;若该类型标价需付费,可选付款后才上报或测试完即上报。
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<div
|
||||
v-for="row in cunkebaoRows"
|
||||
:key="row.key"
|
||||
class="cunkebao-type-block"
|
||||
>
|
||||
<div class="cunkebao-section-title">{{ row.label }}</div>
|
||||
<div class="cunkebao-two-col">
|
||||
<div class="form-item">
|
||||
<label>企业版 Key</label>
|
||||
<template v-if="canConfigureCunkebaoKeys()">
|
||||
<div class="cunkebao-embed-section" v-loading="cunkebaoLoading">
|
||||
<div class="cunkebao-embed-header">
|
||||
<h4 class="cunkebao-embed-title">存客宝线索(测评)</h4>
|
||||
<p class="hint-muted cunkebao-embed-desc">
|
||||
人脸、MBTI、DISC、PDP 共用一把 Key,仅本企业有效;留空表示不启用。上报时机对全部测评生效。
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-item cunkebao-key-row">
|
||||
<label>存客宝 Key</label>
|
||||
<el-input
|
||||
v-model="cunkebaoKeys[row.key].enterprise"
|
||||
v-model="cunkebaoUnified.apiKey"
|
||||
clearable
|
||||
:placeholder="`请输入 ${row.label} 企业版 Key`"
|
||||
placeholder="请输入存客宝场景 Key"
|
||||
class="w-full"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>个人版 Key</label>
|
||||
<el-input
|
||||
v-model="cunkebaoKeys[row.key].personal"
|
||||
clearable
|
||||
:placeholder="`请输入 ${row.label} 个人版 Key`"
|
||||
class="w-full"
|
||||
<div class="cunkebao-timing-row">
|
||||
<label>上报时机</label>
|
||||
<el-switch
|
||||
v-model="cunkebaoUnified.reportTiming"
|
||||
active-value="after_test"
|
||||
inactive-value="after_paid"
|
||||
active-text="测试完即上报"
|
||||
inactive-text="付款后才上报"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #7c3aed; --el-switch-off-color: #909399"
|
||||
/>
|
||||
</div>
|
||||
<div class="save-actions">
|
||||
<el-button type="primary" color="#7c3aed" class="save-btn" :loading="cunkebaoSaving" @click="saveCunkebaoKeys">
|
||||
保存存客宝设置
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cunkebao-timing-row">
|
||||
<label>上报时机</label>
|
||||
<el-switch
|
||||
v-model="cunkebaoKeys[row.key].reportTiming"
|
||||
active-value="after_test"
|
||||
inactive-value="after_paid"
|
||||
active-text="测试完即上报"
|
||||
inactive-text="付款后才上报"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #7c3aed; --el-switch-off-color: #909399"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="save-actions">
|
||||
<el-button type="primary" color="#7c3aed" class="save-btn" :loading="cunkebaoSaving" @click="saveCunkebaoKeys">
|
||||
保存存客宝 Key
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -170,7 +151,7 @@ import { request } from '@/utils/request'
|
||||
import { getAdminRole } from '@/utils/authStorage'
|
||||
import Finance from './Finance.vue'
|
||||
|
||||
const TAB_IDS = ['account', 'features', 'cunkebao', 'finance'] as const
|
||||
const TAB_IDS = ['account', 'features', 'finance'] as const
|
||||
type TabId = (typeof TAB_IDS)[number]
|
||||
|
||||
function isTabId(s: string): s is TabId {
|
||||
@@ -192,22 +173,21 @@ const canConfigureCunkebaoKeys = () => {
|
||||
|
||||
const tabs = computed(() => {
|
||||
const rows: { label: string; value: TabId }[] = [{ label: '账号设置', value: 'account' }]
|
||||
if (isEnterpriseAdmin()) {
|
||||
if (isEnterpriseAdmin() || canConfigureCunkebaoKeys()) {
|
||||
rows.push({ label: '功能开关', value: 'features' })
|
||||
}
|
||||
if (canConfigureCunkebaoKeys()) {
|
||||
rows.push({ label: '存客宝key', value: 'cunkebao' })
|
||||
}
|
||||
rows.push({ label: '企业余额', value: 'finance' })
|
||||
return rows
|
||||
})
|
||||
|
||||
const applyRouteTab = () => {
|
||||
const t = route.query.tab
|
||||
if (typeof t === 'string' && t === 'cunkebao') {
|
||||
activeTab.value = 'features'
|
||||
return
|
||||
}
|
||||
if (typeof t === 'string' && isTabId(t)) {
|
||||
if (t === 'features' && !isEnterpriseAdmin()) {
|
||||
activeTab.value = 'account'
|
||||
} else if (t === 'cunkebao' && !canConfigureCunkebaoKeys()) {
|
||||
if (t === 'features' && !isEnterpriseAdmin() && !canConfigureCunkebaoKeys()) {
|
||||
activeTab.value = 'account'
|
||||
} else {
|
||||
activeTab.value = t
|
||||
@@ -254,20 +234,11 @@ const permSaving = ref(false)
|
||||
const adminPermsCeiling = ref<Record<string, boolean>>(defaultAdminPermissions())
|
||||
const adminPerms = reactive<Record<string, boolean>>(defaultAdminPermissions())
|
||||
|
||||
type CunkebaoKeyScope = 'face' | 'pdp' | 'disc' | 'mbti'
|
||||
|
||||
const cunkebaoRows: { key: CunkebaoKeyScope; label: string }[] = [
|
||||
{ key: 'face', label: '人脸测试' },
|
||||
{ key: 'pdp', label: 'PDP' },
|
||||
{ key: 'disc', label: 'DISC' },
|
||||
{ key: 'mbti', label: 'MBTI' }
|
||||
]
|
||||
|
||||
const cunkebaoKeys = reactive<Record<CunkebaoKeyScope, { enterprise: string; personal: string; reportTiming: string }>>({
|
||||
face: { enterprise: '', personal: '', reportTiming: 'after_paid' },
|
||||
pdp: { enterprise: '', personal: '', reportTiming: 'after_paid' },
|
||||
disc: { enterprise: '', personal: '', reportTiming: 'after_paid' },
|
||||
mbti: { enterprise: '', personal: '', reportTiming: 'after_paid' }
|
||||
/** 测评类存客宝:共用一对 Key + 统一上报时机 */
|
||||
const cunkebaoUnified = reactive({
|
||||
enterprise: '',
|
||||
personal: '',
|
||||
reportTiming: 'after_paid' as 'after_paid' | 'after_test'
|
||||
})
|
||||
|
||||
const cunkebaoLoading = ref(false)
|
||||
@@ -280,14 +251,8 @@ const loadCunkebaoKeys = async () => {
|
||||
const res: any = await request.get('/admin/settings/cunkebao-keys')
|
||||
if (res.code === 200 && res.data?.cunkebaoKeys && typeof res.data.cunkebaoKeys === 'object') {
|
||||
const ck = res.data.cunkebaoKeys
|
||||
cunkebaoRows.forEach(({ key }) => {
|
||||
const row = ck[key]
|
||||
if (row && typeof row === 'object') {
|
||||
cunkebaoKeys[key].enterprise = String(row.enterprise ?? '')
|
||||
cunkebaoKeys[key].personal = String(row.personal ?? '')
|
||||
cunkebaoKeys[key].reportTiming = row.reportTiming === 'after_test' ? 'after_test' : 'after_paid'
|
||||
}
|
||||
})
|
||||
cunkebaoUnified.apiKey = String(ck.apiKey ?? '')
|
||||
cunkebaoUnified.reportTiming = ck.reportTiming === 'after_test' ? 'after_test' : 'after_paid'
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error(e)
|
||||
@@ -302,7 +267,7 @@ const saveCunkebaoKeys = async () => {
|
||||
cunkebaoSaving.value = true
|
||||
try {
|
||||
const res: any = await request.put('/admin/settings/cunkebao-keys', {
|
||||
cunkebaoKeys: { ...cunkebaoKeys }
|
||||
cunkebaoKeys: { ...cunkebaoUnified }
|
||||
})
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('存客宝 Key 已保存')
|
||||
@@ -412,11 +377,13 @@ watch(
|
||||
watch(
|
||||
() => activeTab.value,
|
||||
(tab) => {
|
||||
if (tab === 'features' && isEnterpriseAdmin()) {
|
||||
loadAdminPermissions()
|
||||
}
|
||||
if (tab === 'cunkebao' && canConfigureCunkebaoKeys()) {
|
||||
loadCunkebaoKeys()
|
||||
if (tab === 'features') {
|
||||
if (isEnterpriseAdmin()) {
|
||||
loadAdminPermissions()
|
||||
}
|
||||
if (canConfigureCunkebaoKeys()) {
|
||||
loadCunkebaoKeys()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -424,11 +391,13 @@ watch(
|
||||
onMounted(() => {
|
||||
applyRouteTab()
|
||||
loadSettings()
|
||||
if (activeTab.value === 'features' && isEnterpriseAdmin()) {
|
||||
loadAdminPermissions()
|
||||
}
|
||||
if (activeTab.value === 'cunkebao' && canConfigureCunkebaoKeys()) {
|
||||
loadCunkebaoKeys()
|
||||
if (activeTab.value === 'features') {
|
||||
if (isEnterpriseAdmin()) {
|
||||
loadAdminPermissions()
|
||||
}
|
||||
if (canConfigureCunkebaoKeys()) {
|
||||
loadCunkebaoKeys()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -464,28 +433,25 @@ onMounted(() => {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cunkebao-type-block {
|
||||
margin-bottom: 28px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #f3f4f6;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: none;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.cunkebao-embed-section {
|
||||
margin-top: 28px;
|
||||
padding-top: 24px;
|
||||
border-top: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.cunkebao-section-title {
|
||||
font-size: 15px;
|
||||
.cunkebao-embed-title {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.cunkebao-two-col {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
.cunkebao-embed-desc {
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
|
||||
.cunkebao-key-row {
|
||||
max-width: 560px;
|
||||
}
|
||||
|
||||
.cunkebao-timing-row {
|
||||
@@ -501,12 +467,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.cunkebao-two-col {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.perm-admin-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取某企业某测评类型的 reportTiming(after_paid / after_test)
|
||||
* 读取企业 reportTiming(after_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 '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user