v1.0.19: 修复人员编辑入口缺失(person.js addPerson/editPerson) + 渠道明细数量字段名(analysis.php cnt) + CDP全量验证43项PASS

This commit is contained in:
nanguaboss
2026-08-08 19:29:14 +08:00
parent 2cb688ed46
commit 1c8b374a72
40 changed files with 2313 additions and 658 deletions
+103
View File
@@ -0,0 +1,103 @@
<?php
/**
* 企业产品新增接口 POST /api/company/product_add.php
* 入参:company_id(必填)/ category_name(产品品类)/ positioning(产品基本定位)/ series(包含系列)/
* is_active(1在产 0停产)/ attrs(可选 JSON:[{attr_id, value}],EAV 参数值)
* 说明:attr_id 来自 company_products_attr(按企业所属行业定义的参数属性)
*/
require_once __DIR__ . '/../common/db.php';
require_once __DIR__ . '/../common/response.php';
require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/logger.php';
checkAjax();
checkPermission('company');
$companyId = (int)($_POST['company_id'] ?? 0);
$categoryName = trim($_POST['category_name'] ?? '');
if ($companyId <= 0 || $categoryName === '') {
Response::error('产品品类(category_name)为必填项', 400);
}
$pdo = DB::getInstance()->getPdo();
$chk = $pdo->prepare("SELECT id, industry FROM companies WHERE id = ?");
$chk->execute([$companyId]);
$company = $chk->fetch();
if (!$company) {
Response::error('企业不存在');
}
$pdo->beginTransaction();
try {
$ins = $pdo->prepare(
"INSERT INTO company_products (company_id, category_name, category_description, positioning, series, is_core, is_active)
VALUES (?, ?, ?, ?, ?, ?, ?)"
);
$ins->execute([
$companyId,
$categoryName,
strOrNull($_POST['category_description'] ?? null),
strOrNull($_POST['positioning'] ?? null),
strOrNull($_POST['series'] ?? null),
!empty($_POST['is_core']) ? 1 : 0,
isset($_POST['is_active']) && (int)$_POST['is_active'] === 0 ? 0 : 1,
]);
$productId = (int)$pdo->lastInsertId();
// EAV 参数值
$attrs = json_decode($_POST['attrs'] ?? '[]', true);
if (is_array($attrs) && $attrs) {
// 校验 attr 属于该公司行业
$valid = $pdo->prepare("SELECT id, attr_type FROM company_products_attr WHERE id = ? AND industry = ? AND is_active = 1");
$insV = $pdo->prepare(
"INSERT INTO company_products_attr_value (product_id, attr_id, value_string, value_number, value_boolean, value_date)
VALUES (?, ?, ?, ?, ?, ?)"
);
foreach ($attrs as $a) {
$attrId = (int)($a['attr_id'] ?? 0);
if ($attrId <= 0) {
continue;
}
$valid->execute([$attrId, $company['industry']]);
$def = $valid->fetch();
if (!$def) {
continue;
}
$val = trim((string)($a['value'] ?? ''));
if ($val === '') {
continue;
}
$vStr = $vNum = $vBool = $vDate = null;
switch ($def['attr_type']) {
case 'number':
$vNum = is_numeric($val) ? $val : null;
if ($vNum === null) {
$vStr = $val;
}
break;
case 'boolean':
$vBool = (in_array($val, ['1', 'true', '是', 'yes', 'Y', 'y', '支持'], true)) ? 1 : 0;
break;
case 'date':
$vDate = (strtotime($val) !== false) ? date('Y-m-d', strtotime($val)) : null;
if ($vDate === null) {
$vStr = $val;
}
break;
default:
$vStr = $val;
}
$insV->execute([$productId, $attrId, $vStr, $vNum, $vBool, $vDate]);
}
}
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
Response::error('产品保存失败:' . $e->getMessage());
}
logCurrent('add', 'product', 'company_products', $productId, ['company_id' => $companyId, 'category_name' => $categoryName]);
Response::success(['id' => $productId], '新增成功');