기능구현중
This commit is contained in:
100
backend/api/report/weekly/[id]/share.post.ts
Normal file
100
backend/api/report/weekly/[id]/share.post.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { query, queryOne, insertReturning } from '../../../../utils/db'
|
||||
import { requireAuth } from '../../../../utils/session'
|
||||
import { getValidGoogleToken } from '../../../../utils/google-token'
|
||||
|
||||
/**
|
||||
* 주간보고 그룹 공유 (Gmail 발송)
|
||||
* POST /api/report/weekly/[id]/share
|
||||
*/
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireAuth(event)
|
||||
const reportId = parseInt(getRouterParam(event, 'id') || '0')
|
||||
const body = await readBody(event)
|
||||
|
||||
if (!reportId) {
|
||||
throw createError({ statusCode: 400, message: '보고서 ID가 필요합니다.' })
|
||||
}
|
||||
|
||||
const groupIds = body.groupIds as number[]
|
||||
if (!groupIds?.length) {
|
||||
throw createError({ statusCode: 400, message: '공유할 그룹을 선택해주세요.' })
|
||||
}
|
||||
|
||||
// 보고서 조회
|
||||
const report = await queryOne<any>(`
|
||||
SELECT r.*, e.employee_name, e.employee_email,
|
||||
p.project_name, p.project_code
|
||||
FROM wr_weekly_report r
|
||||
JOIN wr_employee_info e ON r.employee_id = e.employee_id
|
||||
LEFT JOIN wr_project_info p ON r.project_id = p.project_id
|
||||
WHERE r.report_id = $1
|
||||
`, [reportId])
|
||||
|
||||
if (!report) {
|
||||
throw createError({ statusCode: 404, message: '보고서를 찾을 수 없습니다.' })
|
||||
}
|
||||
|
||||
// Google 토큰 확인
|
||||
const accessToken = await getValidGoogleToken(user.employeeId)
|
||||
if (!accessToken) {
|
||||
throw createError({ statusCode: 401, message: 'Google 계정 연결이 필요합니다.' })
|
||||
}
|
||||
|
||||
// 선택된 그룹 조회
|
||||
const groups = await query<any>(`
|
||||
SELECT group_id, group_email, group_name
|
||||
FROM wr_google_group WHERE group_id = ANY($1) AND is_active = true
|
||||
`, [groupIds])
|
||||
|
||||
if (!groups.length) {
|
||||
throw createError({ statusCode: 400, message: '유효한 그룹이 없습니다.' })
|
||||
}
|
||||
|
||||
// 이메일 제목 및 본문 생성
|
||||
const weekInfo = `${report.report_year}년 ${report.report_week}주차`
|
||||
const subject = `[주간보고] ${report.project_name || '개인'} - ${weekInfo} (${report.employee_name})`
|
||||
const emailBody = buildEmailBody(report)
|
||||
|
||||
// 각 그룹에 발송
|
||||
const results: any[] = []
|
||||
|
||||
for (const group of groups) {
|
||||
try {
|
||||
const rawEmail = createRawEmail({
|
||||
to: group.group_email, subject, body: emailBody, from: user.employeeEmail
|
||||
})
|
||||
|
||||
const sendRes = await fetch('https://gmail.googleapis.com/gmail/v1/users/me/messages/send', {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ raw: rawEmail })
|
||||
})
|
||||
|
||||
if (sendRes.ok) {
|
||||
results.push({ groupId: group.group_id, groupName: group.group_name, success: true })
|
||||
} else {
|
||||
const err = await sendRes.json()
|
||||
results.push({ groupId: group.group_id, groupName: group.group_name, success: false, error: err.error?.message })
|
||||
}
|
||||
} catch (e: any) {
|
||||
results.push({ groupId: group.group_id, groupName: group.group_name, success: false, error: e.message })
|
||||
}
|
||||
}
|
||||
|
||||
return { success: results.some(r => r.success), message: `${results.filter(r => r.success).length}/${groups.length}개 그룹에 공유됨`, results }
|
||||
})
|
||||
|
||||
function buildEmailBody(report: any): string {
|
||||
return `<html><body style="font-family:sans-serif;line-height:1.6">
|
||||
<h2>📋 주간보고 - ${report.report_year}년 ${report.report_week}주차</h2>
|
||||
<p><b>작성자:</b> ${report.employee_name} | <b>프로젝트:</b> ${report.project_name || '개인'}</p>
|
||||
<hr><h3>📌 금주 실적</h3><div style="background:#f5f5f5;padding:15px;border-radius:5px">${(report.this_week_work || '').replace(/\n/g, '<br>')}</div>
|
||||
<h3>📅 차주 계획</h3><div style="background:#f5f5f5;padding:15px;border-radius:5px">${(report.next_week_plan || '').replace(/\n/g, '<br>')}</div>
|
||||
${report.issues ? `<h3>⚠️ 이슈</h3><div style="background:#fff3cd;padding:15px;border-radius:5px">${report.issues.replace(/\n/g, '<br>')}</div>` : ''}
|
||||
<hr><p style="color:#666;font-size:12px">주간업무보고 시스템에서 발송</p></body></html>`
|
||||
}
|
||||
|
||||
function createRawEmail(opts: { to: string; subject: string; body: string; from: string }): string {
|
||||
const email = [`From: ${opts.from}`, `To: ${opts.to}`, `Subject: =?UTF-8?B?${Buffer.from(opts.subject).toString('base64')}?=`, 'MIME-Version: 1.0', 'Content-Type: text/html; charset=UTF-8', '', opts.body].join('\r\n')
|
||||
return Buffer.from(email).toString('base64url')
|
||||
}
|
||||
Reference in New Issue
Block a user