feat(assets): 完成故障维修运维 BI 与 Excel 报表导出
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import type { RowDataPacket } from 'mysql2';
|
||||
import pool from '../../db.js';
|
||||
import { mapFault, type RawFault } from './model.js';
|
||||
|
||||
// OneOS fault ledger: latest delivery first; do not reuse the active-asset WHERE clause.
|
||||
export const FAULT_SQL = `SELECT
|
||||
CAST(f.id AS CHAR) id, f.fault_code, f.plate_number, f.fault_desc, f.handling_status,
|
||||
DATE_FORMAT(f.fault_report_time, '%Y-%m-%d %H:%i:%s') reported_at,
|
||||
DATE_FORMAT(f.archived_at, '%Y-%m-%d %H:%i:%s') archived_at,
|
||||
DATE_FORMAT(f.deadline_at, '%Y-%m-%d %H:%i:%s') deadline_at,
|
||||
DATE_FORMAT(receipt.received_at, '%Y-%m-%d %H:%i:%s') received_at,
|
||||
CAST(vi.id AS CHAR) matched_vehicle_id, vi.operation_city,
|
||||
COALESCE(city.NAME, district.NAME) city_name, vi.registered_ownership subject,
|
||||
COALESCE(province.NAME, vi.province_name) province_name,
|
||||
vm.brand, vm.model model_name, vm.vehicle_type model_type, vi.body_color, vi.vehicle_source, vi.actual_ownership, vi.rental_company,
|
||||
vs.operation_status, vs.vehicle_status, lease.customer_name, lease.business_dept,
|
||||
lease.business_manager,
|
||||
CAST(COALESCE(contract.business_manager_id, vi.business_id) AS CHAR) manager_id,
|
||||
CAST(f.inspection_operator_id AS CHAR) handler_id, f.inspection_operator_name handler_name,
|
||||
f.inspection_operator_ids_json handler_ids, f.inspection_operator_names_json handler_names,
|
||||
CAST(wo.current_executor_user_id AS CHAR) work_id, wo.current_executor_name work_name,
|
||||
CAST(wo.current_executor_user_ids_json AS CHAR) work_ids,
|
||||
CAST(wo.current_executor_names_json AS CHAR) work_names
|
||||
FROM vehicle_fault_manage f
|
||||
LEFT JOIN (
|
||||
SELECT fault_id, MIN(create_time) received_at
|
||||
FROM vehicle_fault_operation_log
|
||||
WHERE del_flag='0' AND action_code='SAVE_PROGRESS'
|
||||
AND COALESCE(TRIM(before_status), '') IN ('', '待处理', '待处置', '未处理')
|
||||
AND TRIM(after_status) IN ('处理中', '处置中', '处理')
|
||||
GROUP BY fault_id
|
||||
) receipt ON receipt.fault_id=f.id
|
||||
LEFT JOIN vehicle_info vi ON vi.id=f.vehicle_id AND vi.del_flag='0'
|
||||
LEFT JOIN vehicle_model vm ON vm.id=vi.vehicle_model_id AND vm.del_flag='0'
|
||||
LEFT JOIN common_district province ON province.CODE=CONCAT(LEFT(vi.operation_city,2),'0000') COLLATE utf8mb4_unicode_ci AND province.STATUS='VALID'
|
||||
LEFT JOIN vehicle_status vs ON vs.id=(
|
||||
SELECT s.id FROM vehicle_status s WHERE s.vehicle_id=vi.id AND s.del_flag=0
|
||||
ORDER BY s.update_time DESC, s.id DESC LIMIT 1
|
||||
)
|
||||
LEFT JOIN vehicle_lease_order_record lease ON lease.id=(
|
||||
SELECT r.id FROM vehicle_lease_order_record r WHERE r.vehicle_id=vi.id AND r.del_flag='0'
|
||||
ORDER BY r.last_delivery_time DESC, r.id DESC LIMIT 1
|
||||
)
|
||||
LEFT JOIN vehicle_lease_contract_info contract ON contract.id=lease.contract_id AND contract.del_flag='0'
|
||||
LEFT JOIN common_district district ON district.CODE=vi.operation_city COLLATE utf8mb4_unicode_ci AND district.STATUS='VALID'
|
||||
LEFT JOIN common_district city ON city.CODE=(CASE
|
||||
WHEN LEFT(vi.operation_city,2) IN ('11','12','31','50') THEN CONCAT(LEFT(vi.operation_city,2),'0000')
|
||||
ELSE CONCAT(LEFT(vi.operation_city,4),'00') END) COLLATE utf8mb4_unicode_ci AND city.STATUS='VALID'
|
||||
LEFT JOIN task_work_order wo ON wo.id=f.source_work_order_id AND wo.del_flag='0'
|
||||
WHERE f.del_flag='0' AND f.is_submit IN (0,1)`;
|
||||
|
||||
export async function loadFaults() {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
await connection.query('START TRANSACTION WITH CONSISTENT SNAPSHOT, READ ONLY');
|
||||
const [raw] = await connection.query<RowDataPacket[]>({ sql: FAULT_SQL, timeout: 20000 });
|
||||
const [users] = await connection.query<RowDataPacket[]>({ sql: `SELECT CAST(user_id AS CHAR) id, nick_name name
|
||||
FROM \`ry-cloud\`.sys_user WHERE del_flag='0' AND status='0'
|
||||
AND (user_type IS NULL OR user_type='sys_user')`, timeout: 10000 });
|
||||
const directory = new Map<string, string>(users.map(row => [String(row.id), String(row.name || '').trim()]));
|
||||
// Defensive ID de-duplication keeps imperfect lookup tables from multiplying tickets.
|
||||
const rows = [...new Map(raw.map(row => [String(row.id), mapFault(row as RawFault, directory)])).values()];
|
||||
return { rows, updatedAt: new Date().toISOString() };
|
||||
} finally {
|
||||
try { await connection.rollback(); } finally { connection.release(); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user