完成批次 L-R:限流移除/白名单驱动/打印增强/全屏/表格对齐/主题变量/滚动闪烁修复
- 移除登录失败限流;fix-config.php 修正 e2e 串味的 127.0.0.1 连接 - 白名单驱动缺/待考名单(DataService + SurveyKingClient::getWhitelist,复用已取 survey) - 打印成绩明细增强(范围/合格列默认关/去页脚);看板全屏占满;表格 vertical-align:middle;隐藏登陆账号;导入默认追加 - 主题变量收口(:root 新增 brand/primary-2/ok-2 等,替换硬编码渐变);删死规则 - 表头/数据列对齐修复(index 未匹配表、dashboard 成员榜、draw 结果/历史/排除表);看板占位卡片配色一致 - 修复滚动闪烁:row-drop-in 动画经 _dropAnim 门控,仅强制重绘时播放 - 测试:新增 test-whitelist.js;run-all.sh 全绿 132
This commit is contained in:
@@ -483,6 +483,100 @@ class SurveyKingClient
|
||||
return is_array($r['data']) ? $r['data'] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 取问卷设置的「答题白名单」成员列表(待考名单来源)
|
||||
*
|
||||
* 卷王不同版本字段形状不一,这里尽量兼容:
|
||||
* - survey.surveySetting.whiteLists:{ 题ID: [值,...] }(社区版常见)
|
||||
* - survey.surveySetting.whiteList:{ 题ID: [值,...] }
|
||||
* - 也可能直接是字符串或嵌套数组
|
||||
* 返回去重后的纯值数组(顺序保持首次出现),值本身通常是学号 / 姓名 / 登陆账号。
|
||||
* 未设置白名单返回空数组(上层据此「按现在的方案显示」)。
|
||||
*
|
||||
* @param string $projectId 问卷 ID
|
||||
* @param array|null $survey 可传入已解析的 survey 对象,避免重复请求 API(DataService::build 已取过 project)
|
||||
* @return array<int,string>
|
||||
*/
|
||||
public function getWhitelist(string $projectId, ?array $survey = null): array
|
||||
{
|
||||
if ($survey === null) {
|
||||
$proj = $this->getProject($projectId);
|
||||
if (!is_array($proj)) {
|
||||
return [];
|
||||
}
|
||||
$survey = $proj['survey'] ?? null;
|
||||
if (is_string($survey) && $survey !== '') {
|
||||
$decoded = json_decode($survey, true);
|
||||
if (is_array($decoded)) {
|
||||
$survey = $decoded;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 兼容 { surveySetting: ... } 与 { survey: { surveySetting: ... } } 两种结构,
|
||||
// 也允许白名单直接挂在 survey 顶层(whiteLists / whiteList / whitelist)。
|
||||
$setting = null;
|
||||
if (is_array($survey)) {
|
||||
if (isset($survey['surveySetting']) && is_array($survey['surveySetting'])) {
|
||||
$setting = $survey['surveySetting'];
|
||||
} elseif (isset($survey['survey']) && is_array($survey['survey']) && isset($survey['survey']['surveySetting'])) {
|
||||
$setting = $survey['survey']['surveySetting'];
|
||||
} else {
|
||||
// 顶层直接是白名单结构
|
||||
foreach (['whiteLists', 'whiteList', 'whitelist'] as $wk) {
|
||||
if (isset($survey[$wk]) && (is_array($survey[$wk]) || is_string($survey[$wk]))) {
|
||||
$setting = $survey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_array($setting)) {
|
||||
return [];
|
||||
}
|
||||
return self::parseWhitelist($setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 surveySetting 中解析白名单成员(去重、保留首次出现顺序)。
|
||||
* @return array<int,string>
|
||||
*/
|
||||
public static function parseWhitelist(array $setting): array
|
||||
{
|
||||
$raw = $setting['whiteLists'] ?? $setting['whiteList'] ?? $setting['whitelist'] ?? null;
|
||||
if ($raw === null || $raw === [] || $raw === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$out = [];
|
||||
$walk = static function ($node) use (&$out, &$walk): void {
|
||||
if (is_array($node)) {
|
||||
// 列表或对象都逐值递归(兼容 { 题ID: [值] })
|
||||
foreach ($node as $v) {
|
||||
$walk($v);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (is_string($node) && trim($node) !== '') {
|
||||
$out[] = trim($node);
|
||||
} elseif (is_scalar($node) && $node !== '' && $node !== null) {
|
||||
$out[] = (string)$node;
|
||||
}
|
||||
};
|
||||
$walk($raw);
|
||||
|
||||
// 去重(大小写不敏感),保留首次出现顺序
|
||||
$seen = [];
|
||||
$res = [];
|
||||
foreach ($out as $item) {
|
||||
$key = strtolower($item);
|
||||
if (!isset($seen[$key])) {
|
||||
$seen[$key] = true;
|
||||
$res[] = $item;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/** 答卷列表(自动翻页取全量) */
|
||||
public function listAnswers(string $projectId): array
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user