forked from wangziqi/gongxue-base
feat: add student crm push
This commit is contained in:
@@ -145,6 +145,64 @@ function compactLeadPayload(task: CrmQueueRow, configRow: CrmConfigRow | null) {
|
||||
};
|
||||
}
|
||||
|
||||
function arrayValue(value: unknown) {
|
||||
return Array.isArray(value) ? value : [];
|
||||
}
|
||||
|
||||
function compactStudentCrmPushPayload(task: CrmQueueRow, configRow: CrmConfigRow | null) {
|
||||
const payload = objectValue(task.payload);
|
||||
const student = objectValue(payload.student);
|
||||
const assignee = objectValue(payload.assignee);
|
||||
const classInfo = objectValue(payload.class);
|
||||
const followup = objectValue(payload.followup);
|
||||
const classes = arrayValue(student.classes).slice(0, 5).map(item => {
|
||||
const classItem = objectValue(item);
|
||||
return {
|
||||
classId: stringValue(classItem.classId),
|
||||
className: stringValue(classItem.className),
|
||||
classCode: stringValue(classItem.classCode),
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
formName: stringValue(payload.formName, configRow?.formName || '刷题题库'),
|
||||
examType: stringValue(payload.examType, configRow?.examType || '成人本科'),
|
||||
source: stringValue(payload.source, task.source || 'manual_batch'),
|
||||
title: stringValue(payload.title, '学生跟进提醒'),
|
||||
message: stringValue(payload.message),
|
||||
student: {
|
||||
id: stringValue(student.userId) || stringValue(student.id, task.recordId || ''),
|
||||
username: stringValue(student.username),
|
||||
name: stringValue(student.name) || stringValue(student.username) || '未填写',
|
||||
phone: stringValue(student.phone),
|
||||
email: stringValue(student.email),
|
||||
avatarPreset: stringValue(student.avatarPreset, 'male'),
|
||||
regionName: stringValue(student.regionName),
|
||||
selectedSchoolName: stringValue(student.selectedSchoolName),
|
||||
selectedMajorName: stringValue(student.selectedMajorName),
|
||||
classes,
|
||||
},
|
||||
assignee: stringValue(assignee.userId) || stringValue(assignee.id) ? {
|
||||
id: stringValue(assignee.userId) || stringValue(assignee.id),
|
||||
name: stringValue(assignee.name) || stringValue(assignee.username),
|
||||
role: stringValue(assignee.role),
|
||||
} : null,
|
||||
class: stringValue(classInfo.classId) ? {
|
||||
classId: stringValue(classInfo.classId),
|
||||
className: stringValue(classInfo.className),
|
||||
classCode: stringValue(classInfo.classCode),
|
||||
} : null,
|
||||
followup: {
|
||||
id: stringValue(followup.id),
|
||||
title: stringValue(followup.title) || stringValue(payload.title),
|
||||
followupType: stringValue(followup.followupType),
|
||||
priority: stringValue(followup.priority),
|
||||
dueAt: stringValue(followup.dueAt),
|
||||
},
|
||||
metadata: objectValue(payload.metadata),
|
||||
};
|
||||
}
|
||||
|
||||
function leadMarkdown(task: CrmQueueRow, configRow: CrmConfigRow | null) {
|
||||
const payload = compactLeadPayload(task, configRow);
|
||||
const student = payload.student;
|
||||
@@ -162,6 +220,36 @@ function leadMarkdown(task: CrmQueueRow, configRow: CrmConfigRow | null) {
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function studentCrmPushMarkdown(task: CrmQueueRow, configRow: CrmConfigRow | null) {
|
||||
const payload = compactStudentCrmPushPayload(task, configRow);
|
||||
const student = payload.student;
|
||||
const target = [student.regionName, student.selectedSchoolName, student.selectedMajorName].filter(Boolean).join(' / ');
|
||||
const classes = student.classes
|
||||
.map(item => item.className || item.classCode)
|
||||
.filter(Boolean)
|
||||
.join('、');
|
||||
const lines = [
|
||||
`### ${payload.formName}学生跟进`,
|
||||
`- 考试类型:${payload.examType}`,
|
||||
`- 来源:${payload.source}`,
|
||||
`- 任务:${payload.title}`,
|
||||
`- 学生:${student.name}`,
|
||||
`- 手机:${student.phone || '未填写'}`,
|
||||
`- 意向:${target || '未填写'}`,
|
||||
`- 班级:${payload.class?.className || classes || '无'}`,
|
||||
`- 指派:${payload.assignee?.name || payload.assignee?.id || '未指派'}`,
|
||||
`- 优先级:${payload.followup.priority || 'normal'}`,
|
||||
`- 到期时间:${payload.followup.dueAt || '无'}`,
|
||||
`- 跟进ID:${payload.followup.id || '无'}`,
|
||||
];
|
||||
if (payload.message) lines.splice(4, 0, `- 说明:${payload.message}`);
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function taskEventType(task: CrmQueueRow) {
|
||||
return stringValue(objectValue(task.payload).eventType, 'lead.created');
|
||||
}
|
||||
|
||||
function dingtalkSign(secret: string): Record<string, string> {
|
||||
if (!secret) return {};
|
||||
const timestamp = String(Date.now());
|
||||
@@ -193,7 +281,10 @@ function prepareRequest(task: CrmQueueRow, configRow: CrmConfigRow | null, secre
|
||||
const target = validateWebhookUrl(task.targetUrl || configRow?.url || '');
|
||||
const provider = providerFrom(configRow, task);
|
||||
const secretValue = secretText(secret, ['secret', 'signSecret', 'webhookSecret']);
|
||||
const markdown = leadMarkdown(task, configRow);
|
||||
const eventType = taskEventType(task);
|
||||
const isStudentPush = eventType === 'student.crm_push';
|
||||
const markdown = isStudentPush ? studentCrmPushMarkdown(task, configRow) : leadMarkdown(task, configRow);
|
||||
const title = isStudentPush ? '学生跟进提醒' : '新客资提醒';
|
||||
const headers = { 'content-type': 'application/json' };
|
||||
|
||||
if (provider === 'dingtalk') {
|
||||
@@ -204,7 +295,7 @@ function prepareRequest(task: CrmQueueRow, configRow: CrmConfigRow | null, secre
|
||||
body: {
|
||||
msgtype: 'markdown',
|
||||
markdown: {
|
||||
title: '新客资提醒',
|
||||
title,
|
||||
text: markdown,
|
||||
},
|
||||
},
|
||||
@@ -221,7 +312,7 @@ function prepareRequest(task: CrmQueueRow, configRow: CrmConfigRow | null, secre
|
||||
...feishuSign(secretValue),
|
||||
card: {
|
||||
config: { wide_screen_mode: true },
|
||||
header: { title: { tag: 'plain_text', content: '新客资提醒' }, template: 'blue' },
|
||||
header: { title: { tag: 'plain_text', content: title }, template: isStudentPush ? 'wathet' : 'blue' },
|
||||
elements: [{ tag: 'markdown', content: markdown }],
|
||||
},
|
||||
},
|
||||
@@ -244,7 +335,10 @@ function prepareRequest(task: CrmQueueRow, configRow: CrmConfigRow | null, secre
|
||||
provider,
|
||||
url: target.toString(),
|
||||
headers,
|
||||
body: {
|
||||
body: isStudentPush ? {
|
||||
event: 'student.crm_push',
|
||||
data: compactStudentCrmPushPayload(task, configRow),
|
||||
} : {
|
||||
event: 'lead.created',
|
||||
data: compactLeadPayload(task, configRow),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user