Initial commit: 风影 OA 全栈源码(API/Web/Flutter/IM)
含 Phase 1.1 IM seq 排序、断线重连、多端已读同步与微信式语音转文字 UI。 排除 node_modules、构建产物、安装包与 .env 密钥。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { ensureWonLedger } from '../src/contract/won-ledger';
|
||||
import { BIZ_TYPE } from '../src/bidding/bid-workflow';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
const owner = await prisma.user.findFirst({
|
||||
where: { tenantId: '1', status: 'ACTIVE', roles: { some: { role: { code: { in: ['owner', 'admin'] } } } } },
|
||||
select: { id: true },
|
||||
});
|
||||
const won = await prisma.bidCase.findMany({
|
||||
where: { tenantId: '1', status: 'WON' },
|
||||
include: { party: true, legalEntity: true, expenses: { select: { amount: true } } },
|
||||
});
|
||||
let newContracts = 0;
|
||||
let newProjects = 0;
|
||||
let todos = 0;
|
||||
for (const bid of won) {
|
||||
const actorId = bid.createdById || owner?.id;
|
||||
if (!actorId) throw new Error('没有可用的合同创建人');
|
||||
const beforeC = await prisma.contract.count({
|
||||
where: { bidCaseId: bid.id, status: { in: ['DRAFT', 'PENDING', 'APPROVED'] } },
|
||||
});
|
||||
const beforeP = await prisma.project.count({
|
||||
where: { contract: { bidCaseId: bid.id } },
|
||||
});
|
||||
const result = await prisma.$transaction((tx) => ensureWonLedger(tx, bid, actorId));
|
||||
if (
|
||||
(await prisma.contract.count({
|
||||
where: { bidCaseId: bid.id, status: { in: ['DRAFT', 'PENDING', 'APPROVED'] } },
|
||||
})) > beforeC
|
||||
) {
|
||||
newContracts += 1;
|
||||
}
|
||||
if ((await prisma.project.count({ where: { contract: { bidCaseId: bid.id } } })) > beforeP) {
|
||||
newProjects += 1;
|
||||
}
|
||||
|
||||
await prisma.todoTask.updateMany({
|
||||
where: {
|
||||
status: 'OPEN',
|
||||
bizType: BIZ_TYPE.CONVERT_CONTRACT,
|
||||
bizId: bid.id,
|
||||
},
|
||||
data: { bizId: result.contract.id, title: `完善合同草稿:${bid.name}` },
|
||||
});
|
||||
const openTodo = await prisma.todoTask.findFirst({
|
||||
where: {
|
||||
status: 'OPEN',
|
||||
bizType: BIZ_TYPE.CONVERT_CONTRACT,
|
||||
bizId: result.contract.id,
|
||||
},
|
||||
});
|
||||
if (!openTodo && result.contract.status === 'DRAFT') {
|
||||
const assignees = await prisma.user.findMany({
|
||||
where: {
|
||||
tenantId: '1',
|
||||
status: 'ACTIVE',
|
||||
roles: { some: { role: { code: { in: ['biz_director', 'biz_staff', 'owner'] } } } },
|
||||
},
|
||||
});
|
||||
if (assignees.length) {
|
||||
await prisma.todoTask.createMany({
|
||||
data: assignees.map((u) => ({
|
||||
tenantId: '1',
|
||||
title: `完善合同草稿:${bid.name}`,
|
||||
bizType: BIZ_TYPE.CONVERT_CONTRACT,
|
||||
bizId: result.contract.id,
|
||||
assigneeId: u.id,
|
||||
})),
|
||||
});
|
||||
todos += assignees.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
`won bids ${won.length}; new contracts ${newContracts}; new projects ${newProjects}; todos ${todos}`,
|
||||
);
|
||||
}
|
||||
|
||||
main()
|
||||
.then(async () => prisma.$disconnect())
|
||||
.catch(async (e) => {
|
||||
console.error(e);
|
||||
await prisma.$disconnect();
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user