v1.0.31: 股票代码与是否上市联动 - 表单非上市(否/空)禁用股票代码输入并提交清空(前后端双保险)+完整度引擎条件字段(stock_code仅在is_listed=1时参与统计,非上市不要求补全股票代码)+已重算回填
This commit is contained in:
+35
-12
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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 管理系统 版权所有 | 备案号:请替换为真实备案号';
|
||||
|
||||
Reference in New Issue
Block a user