好的, 我们来添加短信和邮件通知功能, 以及生成笔试和面试日程表的功能。这些功能将进一步完善招聘流程。我们将使用第三方服务来发送短信和邮件, 并添加一个新的表来管理面试日程。
首先, 让我们更新数据库结构和安装必要的依赖:
- 更新数据库结构:
-- 添加电话号码字段到users表
ALTER TABLE users ADD COLUMN phone TEXT;
-- 创建interviews表
CREATE TABLE interviews (
id INTEGER PRIMARY KEY AUTOINCREMENT,
job_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
type TEXT NOT NULL, -- 'written' or 'oral'
status TEXT NOT NULL, -- 'scheduled', 'completed', 'cancelled'
datetime DATETIME NOT NULL,
location TEXT,
notes TEXT,
FOREIGN KEY (job_id) REFERENCES jobs(id),
FOREIGN KEY (user_id) REFERENCES users(id)
);- 安装新的依赖:
bun add nodemailer twilio ical-generator现在, 让我们更新 src/index.ts 文件, 添加新的功能:
import { Elysia, t } from 'elysia'
import { html } from '@elysiajs/html'
import { staticPlugin } from '@elysiajs/static'
import { cookie } from '@elysiajs/cookie'
import { jwt } from '@elysiajs/jwt'
import { multipart } from '@elysiajs/multipart'
import { Client } from '@libsql/client'
import * as oauth from 'oauth4webapi'
import { writeFile, mkdir } from 'fs/promises'
import { join } from 'path'
import nodemailer from 'nodemailer'
import twilio from 'twilio'
import ical from 'ical-generator'
const db = new Client({
url: 'YOUR_TURSO_DATABASE_URL',
authToken: 'YOUR_TURSO_AUTH_TOKEN'
})
// 配置邮件发送器
const emailTransporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 587,
secure: false,
auth: {
user: 'your-email@example.com',
pass: 'your-email-password'
}
})
// 配置Twilio客户端
const twilioClient = twilio('YOUR_TWILIO_ACCOUNT_SID', 'YOUR_TWILIO_AUTH_TOKEN')
const app = new Elysia()
// ... (保留之前的配置)
// 更新个人资料
.post('/profile', async ({ body, jwt, cookie: { auth } }) => {
if (!auth) return 'Please login to update your profile'
const { sub: userId } = await jwt.verify(auth)
const { name, bio, skills, phone, resume, education_cert } = body
// ... (保留之前的文件上传逻辑)
await db.execute({
sql: `UPDATE users SET name = ?, bio = ?, skills = ?, phone = ?,
resume_url = COALESCE(?, resume_url),
education_cert_url = COALESCE(?, education_cert_url)
WHERE id = ?`,
args: [name, bio, skills, phone, resumeUrl, educationCertUrl, userId]
})
return 'Profile updated successfully!'
})
// 应聘者申请职位
.post('/apply/:id', async ({ params, jwt, cookie: { auth } }) => {
if (!auth) return 'Please login to apply'
const { sub: userId } = await jwt.verify(auth)
const jobId = params.id
// 检查是否已经申请过
const existingApplication = await db.execute({
sql: 'SELECT * FROM applications WHERE job_id = ? AND user_id = ?',
args: [jobId, userId]
})
if (existingApplication.rows.length > 0) {
return 'You have already applied for this job'
}
await db.execute({
sql: 'INSERT INTO applications (job_id, user_id) VALUES (?, ?)',
args: [jobId, userId]
})
// 获取用户和工作信息
const user = await db.execute({
sql: 'SELECT * FROM users WHERE id = ?',
args: [userId]
})
const job = await db.execute({
sql: 'SELECT * FROM jobs WHERE id = ?',
Args: [jobId]
})
// 发送邮件通知
Await emailTransporter.SendMail ({
from: 'noreply@jobboard.com',
to: user.rows[0].email,
subject: `Application Received for ${job.rows[0].title}`,
text: `Dear ${user.rows[0].name},\n\nYour application for ${job.rows[0].title} at ${job.rows[0].company} has been received. We will contact you soon with further details.\n\nBest regards,\nJob Board Team`
})
// 发送短信通知
if (user.rows[0].phone) {
await twilioClient.messages.create({
body: `Your application for ${job.rows[0].title} at ${job.rows[0].company} has been received. Check your email for more details.`,
from: 'YOUR_TWILIO_PHONE_NUMBER',
to: user.rows[0].phone
})
}
return 'Application submitted successfully! Check your email for confirmation.'
})
// 雇主安排面试
.post('/schedule-interview', async ({ body }) => {
const { jobId, userId, type, datetime, location, notes } = body
await db.execute({
sql: `INSERT INTO interviews (job_id, user_id, type, status, datetime, location, notes)
VALUES (?, ?, ?, 'scheduled', ?, ?, ?)`,
args: [jobId, userId, type, datetime, location, notes]
})
// 获取用户和工作信息
const user = await db.execute({
sql: 'SELECT * FROM users WHERE id = ?',
args: [userId]
})
const job = await db.execute({
sql: 'SELECT * FROM jobs WHERE id = ?',
args: [jobId]
})
// 创建iCal事件
const cal = ical({ name: 'Interview Schedule' })
cal.createEvent({
start: new Date(datetime),
end: new Date(new Date(datetime).getTime() + 60*60*1000), // 假设面试持续1小时
summary: `Interview for ${job.rows[0].title}`,
description: notes,
location: location
})
// 发送邮件通知
await emailTransporter.sendMail({
from: 'noreply@jobboard.com',
to: user.rows[0].email,
subject: `Interview Scheduled for ${job.rows[0].title}`,
text: `Dear ${user.rows[0].name},\n\nYour interview for ${job.rows[0].title} at ${job.rows[0].company} has been scheduled for ${datetime} at ${location}.\n\nNotes: ${notes}\n\nBest regards,\nJob Board Team`,
icalEvent: {
filename: 'interview.ics',
method: 'REQUEST',
content: cal.toString()
}
})
// 发送短信通知
if (user.rows[0].phone) {
await twilioClient.messages.create({
body: `Your interview for ${job.rows[0].title} has been scheduled for ${datetime}. Check your email for more details.`,
from: 'YOUR_TWILIO_PHONE_NUMBER',
to: user.rows[0].phone
})
}
return 'Interview scheduled successfully!'
})
// 获取面试日程表
.get('/interview-schedule', async ({ jwt, cookie: { auth } }) => {
if (!auth) return 'Please login to view your interview schedule'
const { sub: userId } = await jwt.verify(auth)
const interviews = await db.execute({
sql: `SELECT i.*, j.title, j.company
FROM interviews i
JOIN jobs j ON i.job_id = j.id
WHERE i.user_id = ?
ORDER BY i.datetime`,
args: [userId]
})
Return interviews.Rows.Map (interview => `
<div>
<h3>${interview. Title} at ${interview. Company}</h3>
<p>Type: ${interview.type}</p>
<p>Date & Time: ${interview.datetime}</p>
<p>Location: ${interview.location}</p>
<p>Notes: ${interview.notes}</p>
<p>Status: ${interview.status}</p>
</div>
`).join('')
})
// ... (保留之前的路由和其他功能)
.listen(3000)
console.log(`Elysia is running at http://localhost:3000`)这个更新版本添加了以下新功能:
- 短信和邮件通知: 当应聘者申请工作或面试被安排时, 系统会发送邮件和短信通知。
- 面试安排: 雇主可以为应聘者安排笔试或面试。
- ICal 日程生成: 系统会生成包含面试详情的 iCal 文件, 并通过邮件发送给应聘者。
- 面试日程表: 应聘者可以查看自己的面试日程表。
要使这个版本正常工作, 你需要:
- 更新 Turso 数据库结构。
- 配置 SMTP 服务器以发送邮件。
- 注册 Twilio 账户并配置短信发送服务。
- 确保你的服务器有足够的资源来处理这些额外的功能。
这个版本提供了一个更加完整的招聘网站框架, 包括通知系统和面试管理功能。你可以根据需要进一步优化 UI/UX, 添加更多的错误处理, 实现更复杂的面试安排算法, 或者添加其他功能, 如在线笔试系统、视频面试集成等。