Files
dingding-oa-server/src/pages/api/business_details/util.ts
2026-05-27 14:12:10 +08:00

134 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { prismaClient } from '@/lib/prisma';
import dayjs from 'dayjs'
/**
* 根据开票日期获取对应的项目号
* @param kai_piao_ri_qi 开票日期,格式为 YYYY-MM-DD
* @returns 匹配的项目号数组
*/
/**
* 根据开票日期或日期范围获取对应的项目号
* 支持:
* - 单个日期字符串:'YYYY-MM-DD'
* - JSON数组字符串'["2025-09-01","2025-09-30",""]'
* - 直接数组:['2025-09-01','2025-09-30']
*/
export async function getProjectIdsByInvoiceDate(kai_piao_ri_qi: unknown): Promise<string[]> {
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
const normalizeDate = (input: unknown): string | undefined => {
if (input === null || input === undefined) return undefined;
if (typeof input === 'number' && Number.isFinite(input)) {
const parsed = dayjs(input);
return parsed.isValid() ? parsed.format('YYYY-MM-DD') : undefined;
}
const s = String(input).trim();
if (!s) return undefined;
if (dateRegex.test(s)) return s;
const parsed = dayjs(s);
if (parsed.isValid()) return parsed.format('YYYY-MM-DD');
return undefined;
};
let start: string | undefined;
let end: string | undefined;
if (Array.isArray(kai_piao_ri_qi)) {
start = normalizeDate(kai_piao_ri_qi[0]);
end = normalizeDate(kai_piao_ri_qi[1]);
} else if (kai_piao_ri_qi && typeof kai_piao_ri_qi === 'object') {
const obj = kai_piao_ri_qi as any;
start = normalizeDate(obj?.start ?? obj?.startTime ?? obj?.begin ?? obj?.beginTime ?? obj?.[0]);
end = normalizeDate(obj?.end ?? obj?.endTime ?? obj?.finish ?? obj?.finishTime ?? obj?.[1]);
} else if (typeof kai_piao_ri_qi === 'string') {
const raw = kai_piao_ri_qi.trim();
if (dateRegex.test(raw)) {
start = normalizeDate(raw);
} else if (raw.startsWith('[')) {
// 尝试解析 JSON 数组字符串,例如 '["2025-09-03","2025-09-05",""]'
try {
const arr = JSON.parse(raw);
if (Array.isArray(arr)) {
start = normalizeDate(arr[0]);
end = normalizeDate(arr[1]);
}
} catch {
// 非法 JSON后续会走错误提示
}
} else {
const parts = raw.split(/[,,、\s]+/).map(s => s.trim()).filter(Boolean);
if (parts.length >= 2) {
start = normalizeDate(parts[0]);
end = normalizeDate(parts[1]);
}
}
}
// 组装 where 条件:区间或单点
// 由于数据库中日期可能以 YYYY-MM-DD 或 YYYY/MM/DD 存储,需要同时支持两种格式
let whereClause: any;
if (start && end) {
const startDash = start.replace(/\//g, '-');
const endExclusiveDash = dayjs(end).add(1, 'day').format('YYYY-MM-DD');
const startSlash = start.replace(/-/g, '/');
const endExclusiveSlash = dayjs(end).add(1, 'day').format('YYYY/MM/DD');
whereClause = {
OR: [
{ kai_piao_ri_qi: { gte: startDash, lt: endExclusiveDash } },
{ kai_piao_ri_qi: { gte: startSlash, lt: endExclusiveSlash } }
]
};
} else if (start) {
const startDash = start.replace(/\//g, '-');
const startSlash = start.replace(/-/g, '/');
whereClause = {
OR: [
{ kai_piao_ri_qi: { startsWith: startDash } },
{ kai_piao_ri_qi: { startsWith: startSlash } }
]
};
} else {
throw new Error('开票日期格式不正确,应为 YYYY-MM-DD 或 ["YYYY-MM-DD","YYYY-MM-DD",""]');
}
const voidRecords = await prismaClient.dingding_oa_invoice_application.findMany({
where: {
remark: {
in: ['发票作废', '作废']
}
},
select: { dataId: true }
});
const voidIds = voidRecords.map(r => r.dataId).filter(Boolean);
const invoiceRows = await prismaClient.invoice_data.findMany({
where: {
...whereClause
},
select: {
dataid: true
}
});
const dataIdsRaw = Array.from(new Set(invoiceRows.map(r => String(r.dataid ?? '').trim()).filter(Boolean)));
const voidIdSet = new Set(voidIds.map(id => String(id).trim()).filter(Boolean));
const dataIds = voidIdSet.size > 0 ? dataIdsRaw.filter(id => !voidIdSet.has(id)) : dataIdsRaw;
if (dataIds.length === 0) return [];
const apps = await prismaClient.dingding_oa_invoice_application.findMany({
where: {
dataId: { in: dataIds }
},
select: {
projectNumber: true
}
});
const projectIds = Array.from(new Set(
apps.flatMap(item => ((item.projectNumber || '') as string)
.split(/[,,、\s]+/)
.filter(Boolean))
));
return projectIds;
}