v1.0.31: 股票代码与是否上市联动 - 表单非上市(否/空)禁用股票代码输入并提交清空(前后端双保险)+完整度引擎条件字段(stock_code仅在is_listed=1时参与统计,非上市不要求补全股票代码)+已重算回填

This commit is contained in:
nanguaboss
2026-08-09 21:55:13 +08:00
parent 13e7b2180e
commit 07dd4670f5
5 changed files with 58 additions and 15 deletions
+35 -12
View File
@@ -24,7 +24,8 @@ const COMPLETENESS_LAYERS = [
'important' => ['address', 'country'],
'optional' => ['registration_number', 'legal_form', 'legal_representative', 'business_scope',
'established_date', 'registered_capital', 'industry_subdivision',
'latest_employee_count', 'latest_annual_revenue', 'is_listed', 'stock_code', 'website'],
'latest_employee_count', 'latest_annual_revenue', 'is_listed', 'website'],
'conditional' => ['stock_code' => ['layer' => 'optional', 'when' => ['is_listed' => '1']]], // 股票代码仅在“是否上市=是”时参与完整度
'virtual' => [],
],
'social_accounts' => [
@@ -93,8 +94,6 @@ function completenessCalc($table, $row)
$result = [];
$missing = ['core' => [], 'important' => [], 'optional' => []];
$totalAll = 0;
$filledAll = 0;
foreach (['core', 'important', 'optional'] as $layer) {
$total = count($layers[$layer]);
@@ -118,15 +117,39 @@ function completenessCalc($table, $row)
$filled++;
}
}
$rate = $total > 0 ? round($filled / $total * 100, 1) : 100;
$result[$layer] = [
'filled' => $filled,
'total' => $total,
'rate' => $rate,
'passed' => $rate >= COMPLETENESS_THRESHOLDS[$layer],
];
$totalAll += $total;
$filledAll += $filled;
$result[$layer] = ['filled' => $filled, 'total' => $total, 'rate' => 0, 'passed' => false];
}
// 条件字段:满足条件才计入完整度(如 stock_code 仅在 is_listed=1 时统计)
foreach (($layers['conditional'] ?? []) as $cf => $cond) {
$layer = $cond['layer'] ?? 'optional';
$match = true;
foreach (($cond['when'] ?? []) as $wf => $wv) {
if ((string)($row[$wf] ?? '') !== (string)$wv) {
$match = false;
break;
}
}
if (!$match) {
continue;
}
$result[$layer]['total']++;
if (completenessIsMissing($row[$cf] ?? null)) {
$missing[$layer][] = $cf;
} else {
$result[$layer]['filled']++;
}
}
// 条件字段处理完后重算各层 rate/passed 与整体
$totalAll = 0;
$filledAll = 0;
foreach (['core', 'important', 'optional'] as $layer) {
$rate = $result[$layer]['total'] > 0 ? round($result[$layer]['filled'] / $result[$layer]['total'] * 100, 1) : 100;
$result[$layer]['rate'] = $rate;
$result[$layer]['passed'] = $rate >= COMPLETENESS_THRESHOLDS[$layer];
$totalAll += $result[$layer]['total'];
$filledAll += $result[$layer]['filled'];
}
$overall = $totalAll > 0 ? round($filledAll / $totalAll * 100, 1) : 100;
+5
View File
@@ -22,6 +22,11 @@ if (empty($data['display_name'])) {
Response::error('企业名称(中文名称)为必填项', 400);
}
// 非上市(否或空白)不允许有股票代码
if ((int)($data['is_listed'] ?? 0) !== 1) {
$data['stock_code'] = null;
}
$pdo = DB::getInstance()->getPdo();
[$sql, $params] = buildInsert($data);
$pdo->prepare("INSERT INTO companies $sql")->execute($params);
+4
View File
@@ -20,6 +20,10 @@ if ($id <= 0) {
$data = extractFields(COMPANY_FIELDS);
unset($data['display_name']); // 显示名称不允许通过编辑接口置空/改名,如需改名请走完整字段
// 非上市(否)不允许有股票代码:提交 is_listed=0 时强制清空
if (array_key_exists('is_listed', $data) && (int)$data['is_listed'] !== 1) {
$data['stock_code'] = null;
}
$hasFinancials = array_key_exists('financials', $_POST);
$hasCertifications = array_key_exists('certifications', $_POST);
$hasAccounts = array_key_exists('accounts', $_POST);
+13 -2
View File
@@ -367,10 +367,10 @@ $(function () {
}
var finHtml =
'<div class="form-grid">' +
' <div class="form-item"><label>是否上市</label><select name="is_listed">' +
' <div class="form-item"><label>是否上市</label><select name="is_listed" id="company-is-listed">' +
' <option value="0"' + (c.is_listed ? '' : ' selected') + '>否</option>' +
' <option value="1"' + (c.is_listed ? ' selected' : '') + '>是</option></select></div>' +
' <div class="form-item"><label>股票代码</label><input type="text" name="stock_code" value="' + escHtml(c.stock_code) + '"></div>' +
' <div class="form-item"><label>股票代码</label><input type="text" name="stock_code" id="company-stock-code" value="' + escHtml(c.stock_code) + '" title="仅上市企业可填写"></div>' +
' <div class="form-item"><label>最新员工数</label><input type="number" name="latest_employee_count" value="' + escHtml(c.latest_employee_count) + '"></div>' +
' <div class="form-item"><label>最新年营收</label><input type="text" name="latest_annual_revenue" value="' + escHtml(c.latest_annual_revenue) + '"></div>' +
'</div>' +
@@ -434,6 +434,14 @@ $(function () {
Dialog.alert('工商查询API预留中,接入后可通过企业名称自动查询并填写企业名称、注册号、注册地址等信息');
});
// 是否上市 → 股票代码 联动:非上市(否/空白)时禁用股票代码
function syncStockCodeDisabled() {
var listed = $('#company-is-listed').val() === '1';
$('#company-stock-code').prop('disabled', !listed);
}
$('#company-is-listed').on('change', syncStockCodeDisabled);
syncStockCodeDisabled();
$('#company-form').on('submit', function (e) {
e.preventDefault();
var fd = new FormData(this);
@@ -444,6 +452,9 @@ $(function () {
Dialog.error('企业名称为必填项');
return;
}
if ($('#company-is-listed').val() !== '1') {
fd.set('stock_code', ''); // 非上市不允许有股票代码,提交空值由后端清空
}
// 年度财务明细(整表替换)
var financials = [];
+1 -1
View File
@@ -5,7 +5,7 @@ var BASE_URL = '/api/';
var PAGE_SIZE = 20;
/** 系统版本号(logo旁展示):修改代码后运行 tools/bump_version.php 自动递增 */
var APP_VERSION = 'v1.0.30';
var APP_VERSION = 'v1.0.31';
/** 页脚版权/备案信息(在 config.js 中修改) */
var FOOTER_TEXT = '© 2026 SuperLink 管理系统 版权所有 | 备案号:请替换为真实备案号';