v1.0.51: 批次1架构筑基 - 1)版本迁移(common/migrate.php+schema_versions+natsort迁移文件);2)登录安全(bcrypt平滑迁移login/user_add/user_update旧sha1命中自动重写+system_login_attempts限流+session加固httponly/samesite/secure);3)CSRF Token(服务端checkCsrf+auth/csrf.php登录页取token+前端common.js/login.js统一携带X-CSRF-Token);4)统一基座common/Api.php并存量强制迁移全部70个endpoint(Api::boot按public/super/module/permissions分流,写接口强制checkAjax+checkCsrf,全局异常处理);5)前端收敛(common.js新增esc转义别名);6)REV-4硬数据来源渠道可编辑(hard_update+补全弹窗下拉);7)prepared卫生(soft_update.php修复+analysis.php表名白名单REV-9)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -6,15 +6,9 @@
|
||||
* target_product_category / description / source_channel
|
||||
* 写入 preliminary_data,recorded_by=当前登录用户(v1.0.50 起无 status 字段)
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
require_once __DIR__ . '/../common/validate.php';
|
||||
require_once __DIR__ . '/../common/duplicate_check.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
checkAjax();
|
||||
checkPermission('preliminary');
|
||||
|
||||
$sourceType = trim($_POST['source_type'] ?? '');
|
||||
if (!in_array($sourceType, ['company', 'person', 'product', 'need', 'mixed'], true)) {
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
* description, industry, need_category, application_scenario, contact_person
|
||||
* 逻辑:按目标类型写入主表(product/need 缺公司时自动建公司)→ 标记碎片已转换(converted_type/id, processed_at)
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
require_once __DIR__ . '/../common/completeness.php';
|
||||
require_once __DIR__ . '/../common/duplicate_check.php';
|
||||
require_once __DIR__ . '/../common/validate.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
checkAjax();
|
||||
checkPermission('preliminary');
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$targetType = trim($_POST['target_type'] ?? '');
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
/**
|
||||
* 硬碎片详情接口 GET /api/fragment/hard_detail.php?id=1
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
require_once __DIR__ . '/hard_common.php';
|
||||
|
||||
checkPermission('preliminary');
|
||||
|
||||
$id = (int)($_REQUEST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
* 入参:id
|
||||
* v1.0.50:废弃改为从 preliminary_data 彻底硬删除(不再保留记录)
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
checkAjax();
|
||||
checkPermission('preliminary');
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
* 返回:{ list, total, page, limit },每行含完整度 score、缺失层级、内容摘要
|
||||
* 说明:v1.0.50 起移除 status 字段(查看弹窗/数据表均不再展示状态),列表仅返回未转换(converted_id IS NULL)记录
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
require_once __DIR__ . '/hard_common.php';
|
||||
|
||||
checkPermission('preliminary');
|
||||
|
||||
[$page, $limit] = pageParams();
|
||||
$keyword = trim($_REQUEST['keyword'] ?? '');
|
||||
|
||||
@@ -4,22 +4,14 @@
|
||||
* 仅更新硬碎片字段(企业名/联系人/手机/邮箱/身份证/社媒账号/主页链接),不执行转换。
|
||||
* 转换请走 hard_convert.php(前端「转软碎片」按钮)。
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
require_once __DIR__ . '/../common/validate.php';
|
||||
require_once __DIR__ . '/../common/duplicate_check.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('preliminary');
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
Response::error('参数错误', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$stmt = $pdo->prepare("SELECT * FROM preliminary_data WHERE id = ? AND is_active = 1");
|
||||
$stmt->execute([$id]);
|
||||
$frag = $stmt->fetch();
|
||||
@@ -45,6 +37,7 @@ $idNumber = trim($_POST['id_number'] ?? '');
|
||||
$platform = trim($_POST['platform'] ?? '');
|
||||
$accountId = trim($_POST['account_id'] ?? '');
|
||||
$profileUrl = trim($_POST['profile_url'] ?? '');
|
||||
$sourceChannel = trim($_POST['source_channel'] ?? ($frag['source_channel'] ?? '')); // REV-4 来源渠道可编辑
|
||||
if (!in_array($sourceType, ['company', 'person', 'product', 'need', 'mixed'], true)) {
|
||||
Response::error('碎片类型不合法', 400);
|
||||
}
|
||||
@@ -89,7 +82,8 @@ if (!empty($dups)) Response::duplicates($dups);
|
||||
$pdo->prepare(
|
||||
"UPDATE preliminary_data
|
||||
SET source_type = ?, company_name = ?, industry = ?, registration_number = ?, business_role = ?, country = ?, address = ?,
|
||||
person_name = ?, contact_phone = ?, contact_email = ?, work_location = ?, id_number = ?, platform = ?, account_id = ?, profile_url = ?
|
||||
person_name = ?, contact_phone = ?, contact_email = ?, work_location = ?, id_number = ?, platform = ?, account_id = ?, profile_url = ?,
|
||||
source_channel = ?
|
||||
WHERE id = ?"
|
||||
)->execute([
|
||||
$sourceType,
|
||||
@@ -107,6 +101,7 @@ $pdo->prepare(
|
||||
$platform !== '' ? $platform : null,
|
||||
$accountId !== '' ? $accountId : null,
|
||||
$profileUrl !== '' ? $profileUrl : null,
|
||||
$sourceChannel !== '' ? $sourceChannel : null,
|
||||
$id,
|
||||
]);
|
||||
|
||||
@@ -117,6 +112,7 @@ logCurrent('update', 'fragment', 'preliminary_data', $id, [
|
||||
'phone' => $phone,
|
||||
'email' => $email,
|
||||
'id_number' => $idNumber,
|
||||
'source_channel' => $sourceChannel,
|
||||
]);
|
||||
|
||||
Response::success(null, '已保存,点击「转软碎片」完成转换');
|
||||
|
||||
@@ -4,12 +4,9 @@
|
||||
* 返回:{ table, table_label, id, name, overall, level, layers, missing_core, missing_important,
|
||||
* missing_optional, missing_labels, row }
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/completeness.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
checkPermission('preliminary');
|
||||
|
||||
$table = trim($_REQUEST['table'] ?? '');
|
||||
$id = (int)($_REQUEST['id'] ?? 0);
|
||||
|
||||
@@ -6,12 +6,9 @@
|
||||
* 每行:{ 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';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
checkPermission('preliminary');
|
||||
|
||||
[$page, $limit] = pageParams();
|
||||
$table = trim($_REQUEST['table'] ?? '');
|
||||
|
||||
@@ -5,17 +5,9 @@
|
||||
* 逻辑:更新主表字段 → 重新计算完整度 → 达标则 is_incomplete=0
|
||||
* 特殊:persons 的 phone/email 写 social_accounts(platform=phone/email)
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
require_once __DIR__ . '/../common/helpers.php';
|
||||
require_once __DIR__ . '/../common/completeness.php';
|
||||
require_once __DIR__ . '/../common/duplicate_check.php';
|
||||
require_once __DIR__ . '/../common/validate.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('preliminary');
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
$table = trim($_POST['table'] ?? '');
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
@@ -23,8 +15,6 @@ if (!in_array($table, ['persons', 'companies', 'social_accounts', 'media'], true
|
||||
Response::error('参数错误', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
|
||||
/** 按白名单收集 POST 字段 */
|
||||
$fields = [];
|
||||
$collect = function ($whitelist) use (&$fields) {
|
||||
@@ -74,7 +64,9 @@ switch ($table) {
|
||||
$dup = findDuplicate($pdo, 'id_number', $fields['id_number'], [$id]);
|
||||
if ($dup) $dups[] = $dup;
|
||||
}
|
||||
$ownAccountIds = $pdo->query("SELECT id FROM social_accounts WHERE owner_type = 'person' AND owner_id = $id")->fetchAll(PDO::FETCH_COLUMN);
|
||||
$ownStmt = $pdo->prepare("SELECT id FROM social_accounts WHERE owner_type = 'person' AND owner_id = ?");
|
||||
$ownStmt->execute([$id]);
|
||||
$ownAccountIds = $ownStmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
if (isset($_POST['phone'])) {
|
||||
$dups = array_merge($dups, checkSingleAccountDuplicate($pdo, $_POST['phone'] !== '' ? 'phone' : '', $_POST['phone'], '', $ownAccountIds));
|
||||
}
|
||||
|
||||
@@ -10,11 +10,9 @@
|
||||
* - pending 待处理碎片(硬待处理 + 软待处理)
|
||||
* 说明:v1.0.50 起 preliminary_data 无 status 字段,已转换以 converted_id 非空标识
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/Api.php';
|
||||
$pdo = Api::boot(['module' => 'preliminary']);
|
||||
|
||||
checkPermission('preliminary');
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$monthStart = "DATE_FORMAT(CURDATE(), '%Y-%m-01')";
|
||||
|
||||
Reference in New Issue
Block a user