92 lines
3.5 KiB
PHP
92 lines
3.5 KiB
PHP
<?php
|
||
/**
|
||
* 软碎片列表接口 GET /api/fragment/soft_list.php
|
||
* 参数:page / limit / table(persons|companies|social_accounts|media)/ level(core|important|optional)/ keyword
|
||
* 返回:{ list, total, page, limit }
|
||
* 每行:{ table, table_label, id, name, overall 整体完整度, level 缺失层级,
|
||
* layer_rates {core,important,optional}, missing_fields 缺失字段(按核心→重要→非必要优先级), created_at }
|
||
*/
|
||
require_once __DIR__ . '/../common/db.php';
|
||
require_once __DIR__ . '/../common/response.php';
|
||
require_once __DIR__ . '/../common/auth.php';
|
||
require_once __DIR__ . '/../common/completeness.php';
|
||
|
||
checkPermission('preliminary');
|
||
|
||
[$page, $limit] = pageParams();
|
||
$table = trim($_REQUEST['table'] ?? '');
|
||
$level = trim($_REQUEST['level'] ?? '');
|
||
$keyword = trim($_REQUEST['keyword'] ?? '');
|
||
|
||
$tableMap = [
|
||
'persons' => ['label' => '人员', 'name' => 'full_name'],
|
||
'companies' => ['label' => '企业', 'name' => 'display_name'],
|
||
'social_accounts' => ['label' => '联系方式', 'name' => 'account_id'],
|
||
'media' => ['label' => '媒体', 'name' => null], // media 需 JOIN social_accounts 取名
|
||
];
|
||
|
||
$pdo = DB::getInstance()->getPdo();
|
||
$all = [];
|
||
|
||
foreach ($tableMap as $t => $cfg) {
|
||
if ($table !== '' && $table !== $t) {
|
||
continue;
|
||
}
|
||
if ($t === 'media') {
|
||
$rows = $pdo->query(
|
||
"SELECT m.social_account_id AS id, sa.account_id AS name, sa.created_at AS created_at
|
||
FROM media_commercial_attributes m
|
||
LEFT JOIN social_accounts sa ON sa.id = m.social_account_id
|
||
WHERE m.is_incomplete = 1"
|
||
)->fetchAll();
|
||
} else {
|
||
$rows = $pdo->query("SELECT id, {$cfg['name']} AS name, created_at FROM `$t` WHERE is_incomplete = 1")->fetchAll();
|
||
}
|
||
foreach ($rows as $r) {
|
||
$info = completenessInfo($pdo, $t, (int)$r['id']);
|
||
if (!$info) {
|
||
continue;
|
||
}
|
||
if ($level !== '' && $info['level'] !== $level) {
|
||
continue;
|
||
}
|
||
// 缺失字段按优先级:核心 → 重要 → 非必要
|
||
$missingFields = array_merge($info['missing']['core'], $info['missing']['important'], $info['missing']['optional']);
|
||
$all[] = [
|
||
'table' => $t,
|
||
'table_label' => $cfg['label'],
|
||
'id' => (int)$r['id'],
|
||
'name' => $r['name'] ?: ('#' . $r['id']),
|
||
'overall' => $info['overall'],
|
||
'level' => $info['level'],
|
||
'layer_rates' => [
|
||
'core' => $info['layers']['core']['rate'],
|
||
'important' => $info['layers']['important']['rate'],
|
||
'optional' => $info['layers']['optional']['rate'],
|
||
],
|
||
'missing_fields' => array_map(function ($f) { return COMPLETENESS_LABELS[$f] ?? $f; }, $missingFields),
|
||
'created_at' => $r['created_at'] ?? null,
|
||
];
|
||
}
|
||
}
|
||
|
||
// 排序:整体完整度升序(最残缺在前),同分按时间倒序
|
||
usort($all, function ($a, $b) {
|
||
if ($a['overall'] !== $b['overall']) {
|
||
return $a['overall'] <=> $b['overall'];
|
||
}
|
||
return strcmp($b['created_at'] ?? '', $a['created_at'] ?? '');
|
||
});
|
||
|
||
if ($keyword !== '') {
|
||
$all = array_values(array_filter($all, function ($r) use ($keyword) {
|
||
return mb_strpos($r['name'], $keyword) !== false;
|
||
}));
|
||
}
|
||
|
||
$total = count($all);
|
||
$offset = ($page - 1) * $limit;
|
||
$list = array_slice($all, $offset, $limit);
|
||
|
||
Response::success(['list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit]);
|