forked from wangziqi/gongxue-base
- 拆分 SSE reducer 到 sseReducer.ts,provider.ts 降至 220 行 - artifact 合并工具抽到 uiArtifacts.ts,去除双重类型断言 - 业务上下文注册表改用 field/relation/entity 构建器收敛重复 - aislop 分数 71 → 81(Healthy),AI Slop 0 告警
319 lines
12 KiB
TypeScript
319 lines
12 KiB
TypeScript
import type {
|
|
BusinessEntity,
|
|
BusinessEntityField,
|
|
BusinessEntityRelation,
|
|
BusinessWorkflow,
|
|
} from './business-context.types';
|
|
|
|
function field(
|
|
key: string,
|
|
label: string,
|
|
type: BusinessEntityField['type'],
|
|
extra: Partial<Omit<BusinessEntityField, 'key' | 'label' | 'type'>> = {},
|
|
): BusinessEntityField {
|
|
return { key, label, type, ...extra };
|
|
}
|
|
|
|
function relation(
|
|
entityKey: string,
|
|
via: string,
|
|
requiredFor: readonly string[],
|
|
): BusinessEntityRelation {
|
|
return { entityKey, via, requiredFor };
|
|
}
|
|
|
|
function entity(
|
|
key: string,
|
|
name: string,
|
|
description: string,
|
|
options: {
|
|
searchTool?: string;
|
|
requiredPermissions: readonly string[];
|
|
fields: readonly BusinessEntityField[];
|
|
relations?: readonly BusinessEntityRelation[];
|
|
},
|
|
): BusinessEntity {
|
|
return {
|
|
key,
|
|
name,
|
|
description,
|
|
...(options.searchTool ? { searchTool: options.searchTool } : {}),
|
|
requiredPermissions: options.requiredPermissions,
|
|
fields: options.fields,
|
|
relations: options.relations ?? [],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 恭学系统业务上下文(代码内维护)。
|
|
*
|
|
* v1 覆盖三大闭环:学生教学、住宿计费、教室租赁。实体字段字典用于
|
|
* render_form 生成正确表单,工作流阶段/前置依赖/下一步建议用于引导
|
|
* Agent 感知业务流程。
|
|
*/
|
|
export const BUSINESS_ENTITIES: readonly BusinessEntity[] = [
|
|
entity('student', '学生档案', '学生基础档案(姓名、学号、手机号、性别等),是分班、入住、账单的前置数据。', {
|
|
searchTool: 'search_students',
|
|
requiredPermissions: ['student:view'],
|
|
fields: [
|
|
field('name', '姓名', 'string', { required: true }),
|
|
field('studentNo', '学号', 'string'),
|
|
field('phone', '手机号', 'string'),
|
|
field('gender', '性别', 'enum', { enumFrom: 'student.gender' }),
|
|
field('idNumber', '身份证号', 'string'),
|
|
],
|
|
relations: [
|
|
relation('class', 'class_student', ['class']),
|
|
relation('occupancy', 'occupancy', ['checkin']),
|
|
relation('bill', 'bill', ['bill']),
|
|
relation('exam', 'exam_score', ['exam']),
|
|
],
|
|
}),
|
|
entity('class', '班级', '班级档案与在读分班关系,排课、考勤、考试依赖班级。', {
|
|
searchTool: 'search_classes',
|
|
requiredPermissions: ['class:view'],
|
|
fields: [
|
|
field('name', '班级名称', 'string', { required: true }),
|
|
field('grade', '年级', 'string'),
|
|
field('headTeacher', '班主任', 'string'),
|
|
],
|
|
relations: [
|
|
relation('student', 'class_student', ['class']),
|
|
relation('schedule', 'class_schedule', ['schedule']),
|
|
],
|
|
}),
|
|
entity('schedule', '排课/日程', '班级与教室的课程安排,考勤和教室日程依赖排课。', {
|
|
searchTool: 'search_schedules',
|
|
requiredPermissions: ['schedule:view'],
|
|
fields: [
|
|
field('classId', '班级', 'number'),
|
|
field('classroomId', '教室', 'number'),
|
|
field('weekDay', '星期', 'number'),
|
|
field('startTime', '开始时间', 'string'),
|
|
field('endTime', '结束时间', 'string'),
|
|
],
|
|
relations: [
|
|
relation('class', 'class_schedule', ['schedule']),
|
|
relation('classroom', 'class_schedule', ['schedule']),
|
|
],
|
|
}),
|
|
entity('attendance', '考勤', '按班级与日期的考勤记录(出勤/迟到/缺勤/请假)。', {
|
|
searchTool: 'get_attendance_summary',
|
|
requiredPermissions: ['attendance:view'],
|
|
fields: [
|
|
field('studentId', '学生', 'number', { required: true }),
|
|
field('date', '日期', 'date', { required: true }),
|
|
field('status', '状态', 'enum', { enumFrom: 'attendance.status' }),
|
|
],
|
|
relations: [
|
|
relation('class', 'class_schedule', ['attendance']),
|
|
relation('schedule', 'class_schedule', ['attendance']),
|
|
],
|
|
}),
|
|
entity('exam', '考试/成绩', '考试安排与成绩记录,依赖班级与学生档案。', {
|
|
searchTool: 'search_exams',
|
|
requiredPermissions: ['exam:view'],
|
|
fields: [
|
|
field('name', '考试名称', 'string', { required: true }),
|
|
field('date', '考试日期', 'date'),
|
|
field('subject', '科目', 'string'),
|
|
],
|
|
relations: [
|
|
relation('class', 'exam_score', ['exam']),
|
|
relation('student', 'exam_score', ['exam']),
|
|
],
|
|
}),
|
|
entity('room', '宿舍档案', '宿舍/床位基础档案,入住登记的前置数据。', {
|
|
searchTool: 'search_rooms',
|
|
requiredPermissions: ['room:view'],
|
|
fields: [
|
|
field('roomNumber', '宿舍号', 'string', { required: true }),
|
|
field('building', '楼栋', 'string'),
|
|
field('floor', '楼层', 'number'),
|
|
field('capacity', '容量', 'number', { required: true }),
|
|
field('roomType', '房型', 'string'),
|
|
field('monthlyRate', '月租金', 'number'),
|
|
],
|
|
relations: [relation('occupancy', 'occupancy', ['checkin'])],
|
|
}),
|
|
entity('occupancy', '入住记录', '学生入住/换宿/退宿记录,费用与账单依赖入住状态。', {
|
|
searchTool: 'get_room_occupancy_summary',
|
|
requiredPermissions: ['occupancy:view'],
|
|
fields: [
|
|
field('studentId', '学生', 'number', { required: true }),
|
|
field('roomId', '宿舍', 'number', { required: true }),
|
|
field('checkInDate', '入住日期', 'date', { required: true }),
|
|
field('billingStartDate', '计费开始日期', 'date', { required: true }),
|
|
field('stayType', '住宿类型', 'enum', { enumFrom: 'occupancy.stayType' }),
|
|
],
|
|
relations: [
|
|
relation('student', 'occupancy', ['checkin']),
|
|
relation('room', 'occupancy', ['checkin']),
|
|
relation('bill', 'bill', ['bill']),
|
|
],
|
|
}),
|
|
entity('expense', '费用', '公共费用与个人费用,是生成账单的基础。', {
|
|
searchTool: 'search_expenses',
|
|
requiredPermissions: ['expense:view'],
|
|
fields: [
|
|
field('type', '费用类型', 'string', { required: true }),
|
|
field('amount', '金额', 'number', { required: true }),
|
|
field('periodStart', '费用开始日期', 'date'),
|
|
field('periodEnd', '费用结束日期', 'date'),
|
|
],
|
|
relations: [
|
|
relation('occupancy', 'expense', ['expense']),
|
|
relation('bill', 'bill_item', ['bill']),
|
|
],
|
|
}),
|
|
entity('bill', '账单', '按学生与账期生成的账单(公共+个人费用分摊),支持确认与付款。', {
|
|
searchTool: 'search_bills',
|
|
requiredPermissions: ['bill:view'],
|
|
fields: [
|
|
field('studentId', '学生', 'number', { required: true }),
|
|
field('periodStart', '账期开始', 'date', { required: true }),
|
|
field('periodEnd', '账期结束', 'date', { required: true }),
|
|
field('totalAmount', '总金额', 'number', { required: true }),
|
|
field('status', '状态', 'enum', { enumFrom: 'bill.status' }),
|
|
],
|
|
relations: [
|
|
relation('student', 'bill', ['bill']),
|
|
relation('occupancy', 'bill', ['bill']),
|
|
relation('deposit', 'deposit', ['deposit']),
|
|
],
|
|
}),
|
|
entity('deposit', '押金', '押金收取与退还记录,通常在账单确认后处理。', {
|
|
searchTool: 'search_deposits',
|
|
requiredPermissions: ['deposit:view'],
|
|
fields: [
|
|
field('studentId', '学生', 'number', { required: true }),
|
|
field('amount', '金额', 'number', { required: true }),
|
|
field('status', '状态', 'enum', { enumFrom: 'deposit.status' }),
|
|
],
|
|
relations: [
|
|
relation('student', 'deposit', ['deposit']),
|
|
relation('bill', 'deposit', ['deposit']),
|
|
],
|
|
}),
|
|
entity('classroom', '教室档案', '教室基础档案,租赁与教室日程的前置数据。', {
|
|
searchTool: 'search_classrooms',
|
|
requiredPermissions: ['classroom:view'],
|
|
fields: [
|
|
field('name', '教室名称', 'string', { required: true }),
|
|
field('building', '楼栋', 'string'),
|
|
field('capacity', '容量', 'number'),
|
|
],
|
|
relations: [
|
|
relation('rental', 'classroom_rental', ['rental']),
|
|
relation('schedule', 'class_schedule', ['schedule']),
|
|
],
|
|
}),
|
|
entity('organization', '组织/校区', '校区与组织归属,租赁双方与档案归属依赖组织。', {
|
|
requiredPermissions: ['organization:view'],
|
|
fields: [
|
|
field('name', '名称', 'string', { required: true }),
|
|
field('code', '编码', 'string'),
|
|
field('isHost', '是否本部', 'boolean'),
|
|
],
|
|
relations: [
|
|
relation('student', 'organization', ['profile']),
|
|
relation('rental', 'classroom_rental', ['rental']),
|
|
],
|
|
}),
|
|
entity('rental', '教室租赁', '教室租赁订单与合同(合同字段在租赁记录上),依赖教室与组织。', {
|
|
searchTool: 'search_classroom_rentals',
|
|
requiredPermissions: ['rental:view'],
|
|
fields: [
|
|
field('classroomId', '教室', 'number', { required: true }),
|
|
field('lesseeOrganizationId', '承租方', 'number'),
|
|
field('startDate', '开始日期', 'date', { required: true }),
|
|
field('endDate', '结束日期', 'date', { required: true }),
|
|
field('dailyRate', '日租金', 'number'),
|
|
field('contractPath', '合同文件', 'string'),
|
|
],
|
|
relations: [
|
|
relation('classroom', 'classroom_rental', ['rental']),
|
|
relation('organization', 'classroom_rental', ['rental']),
|
|
relation('schedule', 'class_schedule', ['schedule']),
|
|
],
|
|
}),
|
|
];
|
|
|
|
export const BUSINESS_WORKFLOWS: readonly BusinessWorkflow[] = [
|
|
{
|
|
key: 'student_teaching',
|
|
name: '学生教学闭环',
|
|
description: '学生档案 → 分班 → 排课 → 考勤 → 考试/成绩。',
|
|
requiredPermissions: ['student:view'],
|
|
stages: [
|
|
{ key: 'profile', label: '学生档案', entities: ['student'] },
|
|
{ key: 'class', label: '分班', entities: ['class', 'student'] },
|
|
{ key: 'schedule', label: '排课', entities: ['schedule', 'class'] },
|
|
{ key: 'attendance', label: '考勤', entities: ['attendance', 'schedule', 'class'] },
|
|
{ key: 'exam', label: '考试/成绩', entities: ['exam', 'class', 'student'] },
|
|
],
|
|
prerequisites: {
|
|
class: ['profile'],
|
|
schedule: ['class'],
|
|
attendance: ['schedule'],
|
|
exam: ['class'],
|
|
},
|
|
nextSteps: [
|
|
{ key: 'after_profile', label: '学生档案完成 → 建议分班', after: ['profile'] },
|
|
{ key: 'after_class', label: '分班完成 → 建议排课', after: ['class'] },
|
|
{ key: 'after_attendance', label: '考勤稳定 → 建议记录考试成绩', after: ['attendance'] },
|
|
],
|
|
},
|
|
{
|
|
key: 'dormitory_billing',
|
|
name: '住宿计费闭环',
|
|
description: '学生/宿舍档案 → 入住 → 费用录入 → 生成账单 → 押金。',
|
|
requiredPermissions: ['occupancy:view'],
|
|
stages: [
|
|
{ key: 'profile', label: '学生档案', entities: ['student'] },
|
|
{ key: 'room', label: '宿舍档案', entities: ['room'] },
|
|
{ key: 'checkin', label: '入住/换宿/退宿', entities: ['occupancy', 'student', 'room'] },
|
|
{ key: 'expense', label: '费用录入', entities: ['expense', 'occupancy'] },
|
|
{ key: 'bill', label: '生成账单', entities: ['bill', 'occupancy', 'expense'] },
|
|
{ key: 'deposit', label: '押金', entities: ['deposit', 'bill', 'student'] },
|
|
],
|
|
prerequisites: {
|
|
checkin: ['profile', 'room'],
|
|
expense: ['checkin'],
|
|
bill: ['checkin', 'expense'],
|
|
deposit: ['bill'],
|
|
},
|
|
nextSteps: [
|
|
{ key: 'after_checkin', label: '入住完成 → 建议录入本月公共/个人费用', after: ['checkin'] },
|
|
{ key: 'after_expense', label: '费用录入完成 → 建议生成并确认账单', after: ['expense'] },
|
|
{ key: 'after_bill', label: '账单确认 → 建议标记已付并处理押金', after: ['bill'] },
|
|
],
|
|
},
|
|
{
|
|
key: 'classroom_rental',
|
|
name: '教室租赁闭环',
|
|
description: '教室/组织档案 → 租赁订单 → 合同 → 教室日程。',
|
|
requiredPermissions: ['rental:view'],
|
|
stages: [
|
|
{ key: 'classroom', label: '教室档案', entities: ['classroom'] },
|
|
{ key: 'organization', label: '组织/校区', entities: ['organization'] },
|
|
{ key: 'rental', label: '租赁订单', entities: ['rental', 'classroom', 'organization'] },
|
|
{ key: 'contract', label: '合同', entities: ['rental'] },
|
|
{ key: 'schedule', label: '教室日程', entities: ['schedule', 'classroom', 'rental'] },
|
|
],
|
|
prerequisites: {
|
|
rental: ['classroom', 'organization'],
|
|
contract: ['rental'],
|
|
schedule: ['rental'],
|
|
},
|
|
nextSteps: [
|
|
{ key: 'after_rental', label: '租赁订单生成 → 建议补充合同', after: ['rental'] },
|
|
{ key: 'after_contract', label: '合同归档 → 建议排定教室日程', after: ['contract'] },
|
|
],
|
|
},
|
|
];
|
|
|
|
export const BUSINESS_WORKFLOW_KEYS: readonly string[] = BUSINESS_WORKFLOWS.map(
|
|
(workflow) => workflow.key,
|
|
);
|