src/vendor 语义是'第三方/参考',却装着线上氢能看板并反向 import
src/modules,依赖方向倒挂。本次把生产代码归位并建立氢能分层:
src/modules/energy/hydrogen/
index.tsx 导航入口(原 HydrogenModule.tsx)
api.ts types.ts HTTP 与 DTO
dev-mock-api.ts 仅 dev 的 vite 插件(仍由 vite.config.ts 引用)
model/ 纯逻辑(format / bearing-labels / daily-detail-format)
board/ 经营看板 UI(原 vendor energy-h2-bi-board)
station-daily/ 单站日报 UI(原 vendor energy-h2-station-daily)
drill/ 下钻弹层 UI(原 hydrogen-bi-v2 的 UI 部分)
common/ 工具与共享组件(原 vendor common + prototype-download)
fonts/ JetBrains Mono(原 vendor resources/design-system)
- UI 与 CSS 逐字节保留,仅移动位置与改写相对 import。
- 删除自挂载原型入口后遗留的 2 个 annotation-source.json。
- vite.config.ts 与 tsconfig 的路径/exclude 同步清理。
- independent-entry.test.ts 不再硬编码路径,改为断言'两个入口解析到同一文件'。
导入改写用一次性 codemod 完成(按旧位置解析、按新位置重写),
lint / test(131) / build 全绿,可达性分析仍为 0 未引用文件。
38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
/**
|
|
* 客户月度接口固定返回“截至查询结束日的近 12 个月”。
|
|
* 键保留完整 YYYY-MM,避免跨年时把不同年份的同月合并。
|
|
*/
|
|
export function customerMonthRange(asOfYmd: string, count = 12): string[] {
|
|
const matched = /^(\d{4})-(\d{2})-\d{2}$/.exec(asOfYmd);
|
|
if (!matched || count < 1) return [];
|
|
|
|
const endYear = Number(matched[1]);
|
|
const endMonth = Number(matched[2]);
|
|
if (endMonth < 1 || endMonth > 12) return [];
|
|
|
|
const months: string[] = [];
|
|
for (let offset = count - 1; offset >= 0; offset -= 1) {
|
|
const date = new Date(Date.UTC(endYear, endMonth - 1 - offset, 1));
|
|
months.push(`${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`);
|
|
}
|
|
return months;
|
|
}
|
|
|
|
export function customerMonthLabel(monthKey: string): string {
|
|
const matched = /^(\d{4})-(\d{2})$/.exec(monthKey);
|
|
return matched ? `${matched[1]}年${Number(matched[2])}月` : monthKey;
|
|
}
|
|
|
|
/** 闭区间日数;用于让卡片副标题与实际查询口径保持一致。 */
|
|
export function inclusiveDayCount(start: string, end: string): number {
|
|
const startTime = Date.parse(`${start}T00:00:00Z`);
|
|
const endTime = Date.parse(`${end}T00:00:00Z`);
|
|
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || endTime < startTime) return 0;
|
|
return Math.floor((endTime - startTime) / 86_400_000) + 1;
|
|
}
|
|
|
|
export function dateRangeLabel(start: string, end: string): string {
|
|
const days = inclusiveDayCount(start, end);
|
|
return days > 0 ? `${start} 至 ${end}(共 ${days} 天)` : `${start} 至 ${end}`;
|
|
}
|