253 lines
10 KiB
SQL
253 lines
10 KiB
SQL
-- OneOS 客户账号与当前车辆范围只读审计
|
|
-- 仅允许在只读连接执行;不包含任何 INSERT/UPDATE/DELETE/DDL。
|
|
|
|
SET SESSION TRANSACTION READ ONLY;
|
|
SET SESSION MAX_EXECUTION_TIME = 10000;
|
|
|
|
-- 0. 核验实际授权。只读账号不应出现 ALL PRIVILEGES、PROCESS、REPLICATION 或 DDL/DML 权限。
|
|
SHOW GRANTS FOR CURRENT_USER;
|
|
|
|
-- 1. 核对关键表字段,识别代码、文档与生产结构漂移。
|
|
SELECT table_schema, table_name, column_name, data_type, is_nullable, column_key
|
|
FROM information_schema.columns
|
|
WHERE table_schema IN ('ln_asset_management', 'ry-cloud')
|
|
AND table_name IN (
|
|
'vehicle_info', 'vehicle_lease_order_record', 'vehicle_lease_order_record_log',
|
|
'vehicle_lease_contract_info', 'vehicle_lease_order_detail', 'delivery_vehicle',
|
|
'return_vehicle_task', 'customer_info', 'sys_user', 'sys_user_role'
|
|
)
|
|
AND column_name IN (
|
|
'id', 'user_id', 'vehicle_id', 'plate_number', 'vin', 'customer_id',
|
|
'other_customer_id', 'contract_id', 'contract_code', 'last_delivery_time',
|
|
'last_return_time', 'delivery_time', 'arrival_time', 'user_type', 'status', 'del_flag'
|
|
)
|
|
ORDER BY table_schema, table_name, ordinal_position;
|
|
|
|
-- 2. 车辆基础数据质量。
|
|
SELECT
|
|
COUNT(*) AS active_vehicles,
|
|
SUM(vin IS NULL OR TRIM(vin) = '') AS missing_vin,
|
|
COUNT(DISTINCT NULLIF(TRIM(vin), '')) AS distinct_vin,
|
|
COUNT(DISTINCT NULLIF(TRIM(plate_number), '')) AS distinct_plate
|
|
FROM ln_asset_management.vehicle_info
|
|
WHERE del_flag = '0';
|
|
|
|
-- 3. 客户档案与客户账号覆盖率,不输出手机号、密码等敏感字段。
|
|
SELECT
|
|
COUNT(*) AS active_customers,
|
|
SUM(u.user_id IS NOT NULL) AS customers_with_account,
|
|
SUM(u.status = '0' AND u.del_flag = '0') AS customers_with_enabled_account,
|
|
SUM(u.user_id IS NULL) AS customers_without_account
|
|
FROM ln_asset_management.customer_info c
|
|
LEFT JOIN `ry-cloud`.sys_user u
|
|
ON u.user_id = c.id
|
|
AND u.user_type = 'customer'
|
|
WHERE c.del_flag = '0';
|
|
|
|
-- 4. 客户账号角色覆盖率。
|
|
SELECT
|
|
COUNT(DISTINCT u.user_id) AS customer_accounts,
|
|
COUNT(DISTINCT ur.user_id) AS customer_accounts_with_role
|
|
FROM `ry-cloud`.sys_user u
|
|
LEFT JOIN `ry-cloud`.sys_user_role ur ON ur.user_id = u.user_id
|
|
WHERE u.user_type = 'customer'
|
|
AND u.del_flag = '0';
|
|
|
|
-- 5. 旧聚合时间口径,仅用于与事务事实口径对比,不能作为授权真值。
|
|
SELECT
|
|
COUNT(*) AS scope_rows,
|
|
COUNT(DISTINCT r.vehicle_id) AS scope_vehicles,
|
|
COUNT(DISTINCT r.customer_id) AS scope_customers,
|
|
SUM(r.customer_id IS NULL) AS missing_customer,
|
|
SUM(v.vin IS NULL OR TRIM(v.vin) = '') AS missing_vin,
|
|
SUM(c.id IS NULL AND r.customer_id IS NOT NULL) AS missing_customer_profile
|
|
FROM ln_asset_management.vehicle_lease_order_record r
|
|
LEFT JOIN ln_asset_management.vehicle_info v
|
|
ON v.id = r.vehicle_id AND v.del_flag = '0'
|
|
LEFT JOIN ln_asset_management.customer_info c
|
|
ON c.id = r.customer_id AND c.del_flag = '0'
|
|
WHERE r.del_flag = '0'
|
|
AND r.last_delivery_time IS NOT NULL
|
|
AND (r.last_return_time IS NULL OR r.last_return_time < r.last_delivery_time);
|
|
|
|
-- 5A. 当前交车/还车事务事实候选及归属质量。
|
|
SELECT
|
|
COUNT(*) AS candidate_rows,
|
|
COUNT(DISTINCT d.vehicle_id) AS candidate_vehicles,
|
|
SUM(v.id IS NULL OR v.vin IS NULL OR TRIM(v.vin) = '') AS invalid_vehicle,
|
|
SUM(r.id IS NULL OR r.customer_id IS NULL) AS missing_aggregate_customer,
|
|
SUM(ci.id IS NULL AND r.customer_id IS NOT NULL) AS invalid_customer_profile,
|
|
SUM(co.id IS NULL) AS invalid_contract,
|
|
SUM(co.id IS NOT NULL AND COALESCE(co.other_customer_id, co.customer_id) IS NULL) AS missing_contract_customer,
|
|
SUM(
|
|
r.customer_id IS NOT NULL
|
|
AND COALESCE(co.other_customer_id, co.customer_id) IS NOT NULL
|
|
AND r.customer_id <> COALESCE(co.other_customer_id, co.customer_id)
|
|
) AS customer_mismatch
|
|
FROM ln_asset_management.delivery_vehicle d
|
|
LEFT JOIN ln_asset_management.vehicle_info v
|
|
ON v.id = d.vehicle_id AND v.del_flag = '0'
|
|
LEFT JOIN ln_asset_management.vehicle_lease_order_record r
|
|
ON r.vehicle_id = d.vehicle_id AND r.del_flag = '0'
|
|
LEFT JOIN ln_asset_management.customer_info ci
|
|
ON ci.id = r.customer_id AND ci.del_flag = '0'
|
|
LEFT JOIN ln_asset_management.vehicle_lease_contract_info co
|
|
ON co.id = d.contract_id AND co.del_flag = '0'
|
|
WHERE d.del_flag = '0'
|
|
AND d.delivery_status IN (2, 3)
|
|
AND d.vehicle_id IS NOT NULL
|
|
AND d.delivery_time IS NOT NULL
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM ln_asset_management.delivery_vehicle newer
|
|
WHERE newer.del_flag = '0'
|
|
AND newer.vehicle_id = d.vehicle_id
|
|
AND (
|
|
COALESCE(newer.delivery_time, '1000-01-01') > COALESCE(d.delivery_time, '1000-01-01')
|
|
OR (
|
|
COALESCE(newer.delivery_time, '1000-01-01') = COALESCE(d.delivery_time, '1000-01-01')
|
|
AND newer.id > d.id
|
|
)
|
|
)
|
|
)
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM ln_asset_management.return_vehicle_task rt
|
|
WHERE rt.delivery_vehicle_id = d.id
|
|
AND rt.del_flag = '0'
|
|
AND rt.status IN (2, 3, 5)
|
|
);
|
|
|
|
-- 6. 检查同一车辆是否出现多个当前客户范围记录。
|
|
SELECT r.vehicle_id, COUNT(*) AS active_scope_rows, COUNT(DISTINCT r.customer_id) AS customer_count
|
|
FROM ln_asset_management.vehicle_lease_order_record r
|
|
WHERE r.del_flag = '0'
|
|
AND r.last_delivery_time IS NOT NULL
|
|
AND (r.last_return_time IS NULL OR r.last_return_time < r.last_delivery_time)
|
|
GROUP BY r.vehicle_id
|
|
HAVING COUNT(*) > 1 OR COUNT(DISTINCT r.customer_id) > 1
|
|
ORDER BY active_scope_rows DESC
|
|
LIMIT 100;
|
|
|
|
-- 7. 检查客户 ID 与客户档案不一致的记录。
|
|
SELECT COUNT(*) AS unmatched_customer_records
|
|
FROM ln_asset_management.vehicle_lease_order_record r
|
|
LEFT JOIN ln_asset_management.customer_info c
|
|
ON c.id = r.customer_id AND c.del_flag = '0'
|
|
WHERE r.del_flag = '0'
|
|
AND r.customer_id IS NOT NULL
|
|
AND c.id IS NULL;
|
|
|
|
-- 8. 聚合表客户与合同有效客户是否一致。
|
|
SELECT
|
|
COUNT(*) AS records_with_contract,
|
|
SUM(c.id IS NULL) AS missing_contract,
|
|
SUM(c.id IS NOT NULL AND r.customer_id IS NULL) AS missing_record_customer,
|
|
SUM(
|
|
c.id IS NOT NULL
|
|
AND r.customer_id IS NOT NULL
|
|
AND r.customer_id <> COALESCE(c.other_customer_id, c.customer_id)
|
|
) AS effective_customer_mismatch
|
|
FROM ln_asset_management.vehicle_lease_order_record r
|
|
LEFT JOIN ln_asset_management.vehicle_lease_contract_info c
|
|
ON c.id = r.contract_id AND c.del_flag = '0'
|
|
WHERE r.del_flag = '0'
|
|
AND r.contract_id IS NOT NULL;
|
|
|
|
-- 9. 已交车但聚合表被清空或缺少客户/合同的可疑记录。
|
|
-- delivery_vehicle 的正式完成状态字段需先通过第 1 项结构核对,再按生产枚举追加状态条件。
|
|
SELECT
|
|
COUNT(*) AS delivered_rows,
|
|
SUM(r.id IS NULL) AS missing_aggregate_record,
|
|
SUM(r.id IS NOT NULL AND r.customer_id IS NULL) AS aggregate_missing_customer,
|
|
SUM(r.id IS NOT NULL AND r.contract_id IS NULL) AS aggregate_missing_contract,
|
|
SUM(r.id IS NOT NULL AND r.last_delivery_time IS NULL) AS aggregate_missing_delivery_time
|
|
FROM ln_asset_management.delivery_vehicle d
|
|
LEFT JOIN ln_asset_management.vehicle_lease_order_record r
|
|
ON r.vehicle_id = d.vehicle_id AND r.del_flag = '0'
|
|
WHERE d.del_flag = '0'
|
|
AND d.delivery_time IS NOT NULL;
|
|
|
|
-- 10. 当前聚合表与最新历史记录的关键字段差异。
|
|
SELECT COUNT(*) AS aggregate_log_mismatch
|
|
FROM ln_asset_management.vehicle_lease_order_record r
|
|
JOIN ln_asset_management.vehicle_lease_order_record_log l
|
|
ON l.vehicle_id = r.vehicle_id
|
|
AND l.del_flag = '0'
|
|
AND l.id = (
|
|
SELECT MAX(l2.id)
|
|
FROM ln_asset_management.vehicle_lease_order_record_log l2
|
|
WHERE l2.vehicle_id = r.vehicle_id AND l2.del_flag = '0'
|
|
)
|
|
WHERE r.del_flag = '0'
|
|
AND NOT (
|
|
r.customer_id <=> l.customer_id
|
|
AND r.contract_id <=> l.contract_id
|
|
AND r.last_delivery_time <=> l.last_delivery_time
|
|
AND r.last_return_time <=> l.last_return_time
|
|
);
|
|
|
|
-- 11. 检查支撑客户车辆范围查询的索引。这里只读索引元数据,不执行 DDL。
|
|
SELECT table_name, index_name, non_unique,
|
|
GROUP_CONCAT(column_name ORDER BY seq_in_index) AS indexed_columns
|
|
FROM information_schema.statistics
|
|
WHERE table_schema = 'ln_asset_management'
|
|
AND table_name IN (
|
|
'vehicle_info', 'vehicle_lease_order_record', 'vehicle_lease_order_record_log',
|
|
'vehicle_lease_contract_info', 'delivery_vehicle', 'return_vehicle_task'
|
|
)
|
|
GROUP BY table_name, index_name, non_unique
|
|
ORDER BY table_name, index_name;
|
|
|
|
-- 12. 客户编码与系统用户名的冲突、错类型和错租户情况。
|
|
-- tenant_id 的目标值应由生产配置确认,这里先按客户 ID 关联并报告实际分布。
|
|
SELECT
|
|
COUNT(*) AS customer_profiles,
|
|
SUM(u.user_id IS NULL) AS no_same_id_account,
|
|
SUM(u.user_id IS NOT NULL AND u.user_type <> 'customer') AS same_id_wrong_type,
|
|
SUM(
|
|
u.user_id IS NOT NULL
|
|
AND (CONVERT(u.user_name USING utf8mb4) COLLATE utf8mb4_unicode_ci)
|
|
<> (CONVERT(c.customer_code USING utf8mb4) COLLATE utf8mb4_unicode_ci)
|
|
) AS username_code_mismatch,
|
|
COUNT(DISTINCT CASE WHEN u.user_id IS NOT NULL THEN u.tenant_id END) AS account_tenant_count
|
|
FROM ln_asset_management.customer_info c
|
|
LEFT JOIN `ry-cloud`.sys_user u ON u.user_id = c.id AND u.del_flag = '0'
|
|
WHERE c.del_flag = '0';
|
|
|
|
-- 13. 同一租户、用户名是否存在多账号或跨 user_type 冲突。
|
|
SELECT tenant_id, user_name,
|
|
COUNT(*) AS account_count,
|
|
COUNT(DISTINCT user_type) AS user_type_count
|
|
FROM `ry-cloud`.sys_user
|
|
WHERE del_flag = '0'
|
|
AND user_name IS NOT NULL
|
|
AND TRIM(user_name) <> ''
|
|
GROUP BY tenant_id, user_name
|
|
HAVING COUNT(*) > 1 OR COUNT(DISTINCT user_type) > 1
|
|
ORDER BY account_count DESC
|
|
LIMIT 100;
|
|
|
|
-- 14. 业务库整体体积与最大表。table_rows 为 InnoDB 估算值,不用于财务或业务计数。
|
|
SELECT
|
|
COUNT(*) AS base_tables,
|
|
SUM(data_length) AS data_bytes,
|
|
SUM(index_length) AS index_bytes
|
|
FROM information_schema.tables
|
|
WHERE table_schema = 'ln_asset_management'
|
|
AND table_type = 'BASE TABLE';
|
|
|
|
SELECT table_name, table_rows, data_length, index_length
|
|
FROM information_schema.tables
|
|
WHERE table_schema = 'ln_asset_management'
|
|
AND table_type = 'BASE TABLE'
|
|
ORDER BY data_length + index_length DESC
|
|
LIMIT 20;
|
|
|
|
-- 15. API 月日志体积,用于核对保留策略;不读取任何日志内容。
|
|
SELECT table_name, table_rows, data_length, index_length
|
|
FROM information_schema.tables
|
|
WHERE table_schema = 'ln_asset_management'
|
|
AND table_name LIKE 'api_request_log\\_%'
|
|
ORDER BY table_name;
|