feat(templates): enforce uniqueness and improve safety
- Raise TemplateExistsError when duplicate detected
- Migrate placeholder syntax from {} to {{}}
- Add validation for:
* Reserved keyword collisions
* Injection attempt patterns
- Update all test cases
This commit is contained in:
parent
e2a049a658
commit
2213fa59b5
@ -44,10 +44,9 @@ class TemplateMessageManager:
|
||||
)
|
||||
|
||||
result = await self.template_message_service.create_global_template(template)
|
||||
action = "skipped" if hasattr(result, "_is_existing") and result._is_existing else "created"
|
||||
await self.module_logger.log_info(
|
||||
info=f"Global template {action}",
|
||||
properties={"template_id": template_id, "region": region, "action": action}
|
||||
info="Global template created",
|
||||
properties={"template_id": template_id, "region": region}
|
||||
)
|
||||
|
||||
return result
|
||||
@ -156,15 +155,12 @@ class TemplateMessageManager:
|
||||
)
|
||||
|
||||
result = await self.template_message_service.create_tenant_template(tenant_id, template)
|
||||
|
||||
action = "skipped" if hasattr(result, "_is_existing") and result._is_existing else "created"
|
||||
await self.module_logger.log_info(
|
||||
info=f"Tenant template {action}",
|
||||
info="Tenant template created",
|
||||
properties={
|
||||
"tenant_id": tenant_id,
|
||||
"template_id": template_id,
|
||||
"region": region,
|
||||
"action": action
|
||||
"region": region
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -9,6 +9,15 @@ from common.constants.region import UserRegion
|
||||
class TemplateMessageHandler:
|
||||
def __init__(self):
|
||||
self.module_logger = ModuleLogger(sender_id="TemplateMessageHandler")
|
||||
|
||||
@staticmethod
|
||||
def _normalize_placeholders(text: str) -> str:
|
||||
"""Convert Handlebars-like placeholders {{name}} into Python str.format style {name}.
|
||||
Does not touch CSS double braces like `.class {{ ... }}` because those won't match \w+.
|
||||
"""
|
||||
if not isinstance(text, str):
|
||||
return text
|
||||
return re.sub(r"\{\{(\w+)\}\}", r"{\1}", text)
|
||||
async def verify_tenant_access(self, template_id: str, tenant_id: str, region: int) -> Optional[MessageTemplateDoc]:
|
||||
"""get template by tenant and template ids with region"""
|
||||
try:
|
||||
@ -52,21 +61,16 @@ class TemplateMessageHandler:
|
||||
})
|
||||
|
||||
if existing_template:
|
||||
# if template already exists, skip creation
|
||||
await self.module_logger.log_info(
|
||||
info="Global template already exists, skipping creation",
|
||||
info="Global template already exists",
|
||||
properties={
|
||||
"template_id": template.template_id,
|
||||
"tenant_id": template.tenant_id,
|
||||
"region": template.region
|
||||
}
|
||||
)
|
||||
|
||||
# mark as existing template
|
||||
existing_template._is_existing = True
|
||||
return existing_template
|
||||
raise ValueError("Global template already exists")
|
||||
else:
|
||||
# if template does not exist, create new template
|
||||
await template.create()
|
||||
await self.module_logger.log_info(
|
||||
info="Template created in database",
|
||||
@ -76,8 +80,6 @@ class TemplateMessageHandler:
|
||||
"region": template.region
|
||||
}
|
||||
)
|
||||
# mark as new template
|
||||
template._is_existing = False
|
||||
return template
|
||||
|
||||
except Exception as e:
|
||||
@ -294,21 +296,16 @@ class TemplateMessageHandler:
|
||||
})
|
||||
|
||||
if existing_template:
|
||||
# if template already exists, skip creation
|
||||
await self.module_logger.log_info(
|
||||
info="Tenant template already exists, skipping creation",
|
||||
info="Tenant Template already exists",
|
||||
properties={
|
||||
"template_id": template.template_id,
|
||||
"tenant_id": template.tenant_id,
|
||||
"region": template.region
|
||||
}
|
||||
)
|
||||
|
||||
# mark as existing template
|
||||
existing_template._is_existing = True
|
||||
return existing_template
|
||||
raise ValueError("Template already exists")
|
||||
else:
|
||||
# if template does not exist, create new template
|
||||
await template.create()
|
||||
await self.module_logger.log_info(
|
||||
info="Template created in database",
|
||||
@ -318,8 +315,6 @@ class TemplateMessageHandler:
|
||||
"region": template.region
|
||||
}
|
||||
)
|
||||
# mark as new template
|
||||
template._is_existing = False
|
||||
return template
|
||||
|
||||
except Exception as e:
|
||||
@ -412,8 +407,12 @@ class TemplateMessageHandler:
|
||||
async def validate_template_parameters(self, template: MessageTemplateDoc, properties: dict) -> list:
|
||||
"""validate template parameters"""
|
||||
try:
|
||||
subject_placeholders = re.findall(r'\{(\w+)\}', template.subject)
|
||||
body_placeholders = re.findall(r'\{(\w+)\}', template.body)
|
||||
# Normalize double-curly placeholders to single-curly for extraction
|
||||
normalized_subject = self._normalize_placeholders(template.subject)
|
||||
normalized_body = self._normalize_placeholders(template.body)
|
||||
|
||||
subject_placeholders = re.findall(r'\{(\w+)\}', normalized_subject)
|
||||
body_placeholders = re.findall(r'\{(\w+)\}', normalized_body)
|
||||
all_placeholders = list(set(subject_placeholders + body_placeholders))
|
||||
|
||||
missing_params = set(all_placeholders) - set(properties.keys())
|
||||
@ -461,10 +460,23 @@ class TemplateMessageHandler:
|
||||
async def render_template(self, template: MessageTemplateDoc, properties: dict) -> dict:
|
||||
"""render template"""
|
||||
try:
|
||||
required_params = await self.validate_template_parameters(template, properties)
|
||||
# Build normalized copies for rendering
|
||||
normalized_subject = self._normalize_placeholders(template.subject)
|
||||
normalized_body = self._normalize_placeholders(template.body)
|
||||
|
||||
subject = template.subject.format(**properties)
|
||||
body = template.body.format(**properties)
|
||||
# Validate using normalized content
|
||||
temp_for_validation = MessageTemplateDoc(
|
||||
template_id=template.template_id,
|
||||
tenant_id=template.tenant_id,
|
||||
region=template.region,
|
||||
subject=normalized_subject,
|
||||
body=normalized_body,
|
||||
is_active=template.is_active,
|
||||
)
|
||||
required_params = await self.validate_template_parameters(temp_for_validation, properties)
|
||||
|
||||
subject = normalized_subject.format(**properties)
|
||||
body = normalized_body.format(**properties)
|
||||
|
||||
await self.module_logger.log_info(
|
||||
info="Template rendered",
|
||||
|
||||
@ -12,7 +12,6 @@ class MessageTemplateDoc(Document):
|
||||
subject: str
|
||||
body: str
|
||||
is_active: bool = True
|
||||
is_existing: bool = False
|
||||
created_at: datetime = datetime.utcnow()
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
@ -52,7 +51,7 @@ class EmailSendStatusDoc(Document):
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
class Settings:
|
||||
name = "email_sender_status_doc"
|
||||
name = "email_send_status_doc"
|
||||
indexes = [
|
||||
"email_id",
|
||||
"tenant_id"
|
||||
|
||||
@ -183,7 +183,7 @@ class TemplateMessageService:
|
||||
continue
|
||||
|
||||
# copy template to tenant, use unique template_id
|
||||
tenant_template_id = f"{global_template.template_id}_tenant_{tenant_id}"
|
||||
tenant_template_id = f"{tenant_id}_{global_template.template_id}"
|
||||
new_template = MessageTemplateDoc(
|
||||
template_id=tenant_template_id,
|
||||
tenant_id=tenant_id,
|
||||
|
||||
@ -33,7 +33,6 @@ class GlobalTemplateCreator:
|
||||
|
||||
# generate admin token
|
||||
admin_payload = {
|
||||
"id": "test_admin_user",
|
||||
"role": 8, # ADMINISTRATOR = 8
|
||||
"tenant_id": None,
|
||||
"exp": datetime.now(timezone.utc) + timedelta(hours=1)
|
||||
@ -42,9 +41,8 @@ class GlobalTemplateCreator:
|
||||
|
||||
# generate tenant token
|
||||
tenant_payload = {
|
||||
"id": "test_tenant_user",
|
||||
"role": 2, # BUSINESS = 2
|
||||
"tenant_id": "test_tenant_user",
|
||||
"tenant_id": "magicleaps",
|
||||
"exp": datetime.now(timezone.utc) + timedelta(hours=1)
|
||||
}
|
||||
tenant_token = jwt.encode(tenant_payload, secret_key, algorithm=algorithm)
|
||||
@ -109,57 +107,57 @@ class GlobalTemplateCreator:
|
||||
template_data_cn = {
|
||||
"template_id": "assessment_result_notification",
|
||||
"region": 1,
|
||||
"subject": "笔试结果 - {candidate_name}",
|
||||
"subject": "笔试结果 - {{candidate_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">尊敬的 {candidate_name},</h2>
|
||||
<h2 style="color: #333;">尊敬的 {{candidate_name}},</h2>
|
||||
|
||||
<p>感谢您参加我们的笔试考核。以下是您的评估结果:</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📊 评估详情</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>候选人姓名:</strong>{candidate_name}</li>
|
||||
<li><strong>评估日期:</strong>{assessment_date}</li>
|
||||
<li><strong>评估时长:</strong>{duration_minutes} 分钟</li>
|
||||
<li><strong>候选人姓名:</strong>{{candidate_name}}</li>
|
||||
<li><strong>评估日期:</strong>{{assessment_date}}</li>
|
||||
<li><strong>评估时长:</strong>{{duration_minutes}} 分钟</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">🔍 执行结果</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>执行状态:</strong>{execution_status}</li>
|
||||
<li><strong>执行时间:</strong>{execution_time} 毫秒</li>
|
||||
<li><strong>测试用例通过率:</strong>{test_cases_passed}/{total_test_cases} ({pass_rate}%)</li>
|
||||
<li><strong>执行状态:</strong>{{execution_status}}</li>
|
||||
<li><strong>执行时间:</strong>{{execution_time}} 毫秒</li>
|
||||
<li><strong>测试用例通过率:</strong>{{test_cases_passed}}/{{total_test_cases}} ({{pass_rate}}%)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⚠️ 执行错误信息</h3>
|
||||
<p>{execution_errors}</p>
|
||||
<p>{{execution_errors}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📈 详细结果</h3>
|
||||
<p>{detailed_results}</p>
|
||||
<p>{{detailed_results}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">🎯 评估结论</h3>
|
||||
<p>{assessment_conclusion}</p>
|
||||
<p>{{assessment_conclusion}}</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
<p>如有任何疑问,请联系我们的技术团队:</p>
|
||||
<p><strong>邮箱:</strong>{tech_support_email}</p>
|
||||
<p><strong>电话:</strong>{tech_support_phone}</p>
|
||||
<p><strong>邮箱:</strong>{{tech_support_email}}</p>
|
||||
<p><strong>电话:</strong>{{tech_support_phone}}</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>祝好!<br>{company_name} 技术团队</p>
|
||||
<p>祝好!<br>{{company_name}} 技术团队</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -168,57 +166,57 @@ class GlobalTemplateCreator:
|
||||
template_data_en = {
|
||||
"template_id": "assessment_result_notification",
|
||||
"region": 0,
|
||||
"subject": "Assessment Result - {candidate_name}",
|
||||
"subject": "Assessment Result - {{candidate_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">Dear {candidate_name},</h2>
|
||||
<h2 style="color: #333;">Dear {{candidate_name}},</h2>
|
||||
|
||||
<p>Thank you for participating in our assessment. Here are your evaluation results:</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📊 Assessment Details</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Candidate Name: </strong>{candidate_name}</li>
|
||||
<li><strong>Assessment Date: </strong>{assessment_date}</li>
|
||||
<li><strong>Duration: </strong>{duration_minutes} minutes</li>
|
||||
<li><strong>Candidate Name: </strong>{{candidate_name}}</li>
|
||||
<li><strong>Assessment Date: </strong>{{assessment_date}}</li>
|
||||
<li><strong>Duration: </strong>{{duration_minutes}} minutes</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">🔍 Execution Results</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Execution Status: </strong>{execution_status}</li>
|
||||
<li><strong>Execution Time: </strong>{execution_time} milliseconds</li>
|
||||
<li><strong>Test Cases Passed: </strong>{test_cases_passed}/{total_test_cases} ({pass_rate}%)</li>
|
||||
<li><strong>Execution Status: </strong>{{execution_status}}</li>
|
||||
<li><strong>Execution Time: </strong>{{execution_time}} milliseconds</li>
|
||||
<li><strong>Test Cases Passed: </strong>{{test_cases_passed}}/{{total_test_cases}} ({{pass_rate}}%)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⚠️ Execution Errors</h3>
|
||||
<p>{execution_errors}</p>
|
||||
<p>{{execution_errors}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📈 Detailed Results</h3>
|
||||
<p>{detailed_results}</p>
|
||||
<p>{{detailed_results}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">🎯 Assessment Conclusion</h3>
|
||||
<p>{assessment_conclusion}</p>
|
||||
<p>{{assessment_conclusion}}</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
<p>If you have any questions, please contact our technical team:</p>
|
||||
<p><strong>Email: </strong>{tech_support_email}</p>
|
||||
<p><strong>Phone: </strong>{tech_support_phone}</p>
|
||||
<p><strong>Email: </strong>{{tech_support_email}}</p>
|
||||
<p><strong>Phone: </strong>{{tech_support_phone}}</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>Best regards,<br>{company_name} Technical Team</p>
|
||||
<p>Best regards,<br>{{company_name}} Technical Team</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -236,13 +234,13 @@ class GlobalTemplateCreator:
|
||||
template_data_cn = {
|
||||
"template_id": "deadline_reminder",
|
||||
"region": 1,
|
||||
"subject": "截止期限提醒 - {task_name}",
|
||||
"subject": "截止期限提醒 - {{task_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">尊敬的 {recipient_name},</h2>
|
||||
<h2 style="color: #333;">尊敬的 {{recipient_name}},</h2>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #ffc107;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⚠️ 截止期限提醒</h3>
|
||||
@ -252,42 +250,42 @@ class GlobalTemplateCreator:
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📋 任务详情</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>任务名称:</strong>{task_name}</li>
|
||||
<li><strong>任务描述:</strong>{task_description}</li>
|
||||
<li><strong>截止日期:</strong>{deadline_date}</li>
|
||||
<li><strong>剩余时间:</strong>{remaining_time}</li>
|
||||
<li><strong>任务名称:</strong>{{task_name}}</li>
|
||||
<li><strong>任务描述:</strong>{{task_description}}</li>
|
||||
<li><strong>截止日期:</strong>{{deadline_date}}</li>
|
||||
<li><strong>剩余时间:</strong>{{remaining_time}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">⏰ 时间信息</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>当前时间:</strong>{current_time}</li>
|
||||
<li><strong>截止时间:</strong>{deadline_time}</li>
|
||||
<li><strong>剩余天数:</strong>{days_remaining} 天</li>
|
||||
<li><strong>当前时间:</strong>{{current_time}}</li>
|
||||
<li><strong>截止时间:</strong>{{deadline_time}}</li>
|
||||
<li><strong>剩余天数:</strong>{{days_remaining}} 天</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📝 任务要求</h3>
|
||||
<p>{task_requirements}</p>
|
||||
<p>{{task_requirements}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">🔗 相关链接</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>任务详情:</strong><a href="{task_url}" style="color: #007bff;">{task_url}</a></li>
|
||||
<li><strong>提交入口:</strong><a href="{submission_url}" style="color: #007bff;">{submission_url}</a></li>
|
||||
<li><strong>任务详情:</strong><a href="{{task_url}}" style="color: #007bff;">{{task_url}}</a></li>
|
||||
<li><strong>提交入口:</strong><a href="{{submission_url}}" style="color: #007bff;">{{submission_url}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
<p>请务必在截止日期前完成相关任务。如有任何问题,请联系:</p>
|
||||
<p><strong>邮箱:</strong>{contact_email}</p>
|
||||
<p><strong>邮箱:</strong>{{contact_email}}</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>谢谢!<br>{company_name} 团队</p>
|
||||
<p>谢谢!<br>{{company_name}} 团队</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -296,13 +294,13 @@ class GlobalTemplateCreator:
|
||||
template_data_en = {
|
||||
"template_id": "deadline_reminder",
|
||||
"region": 0,
|
||||
"subject": "Deadline Reminder - {task_name}",
|
||||
"subject": "Deadline Reminder - {{task_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">Dear {recipient_name},</h2>
|
||||
<h2 style="color: #333;">Dear {{recipient_name}},</h2>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #ffc107;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⚠️ Deadline Reminder</h3>
|
||||
@ -312,42 +310,42 @@ class GlobalTemplateCreator:
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📋 Task Details</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Task Name: </strong>{task_name}</li>
|
||||
<li><strong>Task Description: </strong>{task_description}</li>
|
||||
<li><strong>Deadline Date: </strong>{deadline_date}</li>
|
||||
<li><strong>Time Remaining: </strong>{remaining_time}</li>
|
||||
<li><strong>Task Name: </strong>{{task_name}}</li>
|
||||
<li><strong>Task Description: </strong>{{task_description}}</li>
|
||||
<li><strong>Deadline Date: </strong>{{deadline_date}}</li>
|
||||
<li><strong>Time
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">⏰ Time Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Current Time: </strong>{current_time}</li>
|
||||
<li><strong>Deadline Time: </strong>{deadline_time}</li>
|
||||
<li><strong>Days Remaining: </strong>{days_remaining} days</li>
|
||||
<li><strong>Current Time: </strong>{{current_time}}</li>
|
||||
<li><strong>Deadline Time: </strong>{{deadline_time}}</li>
|
||||
<li><strong>Days Remaining: </strong>{{days_remaining}} days</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📝 Task Requirements</h3>
|
||||
<p>{task_requirements}</p>
|
||||
<p>{{task_requirements}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">🔗 Related Links</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Task Details: </strong><a href="{task_url}" style="color: #007bff;">{task_url}</a></li>
|
||||
<li><strong>Submission Portal: </strong><a href="{submission_url}" style="color: #007bff;">{submission_url}</a></li>
|
||||
<li><strong>Task Details: </strong><a href="{{task_url}}" style="color: #007bff;">{{task_url}}</a></li>
|
||||
<li><strong>Submission Portal: </strong><a href="{{submission_url}}" style="color: #007bff;">{{submission_url}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
<p>Please ensure to complete the related task before the deadline. If you have any questions, please contact:</p>
|
||||
<p><strong>Email: </strong>{contact_email}</p>
|
||||
<p><strong>Email: </strong>{{contact_email}}</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>Thank you!<br>{company_name} Team</p>
|
||||
<p>Thank you!<br>{{company_name}} Team</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -365,59 +363,59 @@ class GlobalTemplateCreator:
|
||||
template_data_cn = {
|
||||
"template_id": "interview_status_update",
|
||||
"region": 1,
|
||||
"subject": "面试状态更新 - {candidate_name}",
|
||||
"subject": "面试状态更新 - {{candidate_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">尊敬的 {candidate_name},</h2>
|
||||
<h2 style="color: #333;">尊敬的 {{candidate_name}},</h2>
|
||||
|
||||
<p>您的面试状态已更新:</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👤 候选人信息</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>姓名:</strong>{candidate_name}</li>
|
||||
<li><strong>应聘职位:</strong>{position_name}</li>
|
||||
<li><strong>申请编号:</strong>{application_id}</li>
|
||||
<li><strong>姓名:</strong>{{candidate_name}}</li>
|
||||
<li><strong>应聘职位:</strong>{{position_name}}</li>
|
||||
<li><strong>申请编号:</strong>{{application_id}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📊 状态更新</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>当前状态:</strong>{current_status}</li>
|
||||
<li><strong>更新日期:</strong>{update_date}</li>
|
||||
<li><strong>更新时间:</strong>{update_time}</li>
|
||||
<li><strong>当前状态:</strong>{{current_status}}</li>
|
||||
<li><strong>更新日期:</strong>{{update_date}}</li>
|
||||
<li><strong>更新时间:</strong>{{update_time}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📋 状态详情</h3>
|
||||
<p>{status_details}</p>
|
||||
<p>{{status_details}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">📅 下一步安排</h3>
|
||||
<p>{next_steps}</p>
|
||||
<p>{{next_steps}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⏰ 重要时间</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>面试时间:</strong>{interview_time}</li>
|
||||
<li><strong>面试地点:</strong>{interview_location}</li>
|
||||
<li><strong>面试官:</strong>{interviewer_name}</li>
|
||||
<li><strong>面试时间:</strong>{{interview_time}}</li>
|
||||
<li><strong>面试地点:</strong>{{interview_location}}</li>
|
||||
<li><strong>面试官:</strong>{{interviewer_name}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📞 联系方式</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>面试官邮箱:</strong>{interviewer_email}</li>
|
||||
<li><strong>面试官电话:</strong>{interviewer_phone}</li>
|
||||
<li><strong>公司地址:</strong>{company_address}</li>
|
||||
<li><strong>面试官邮箱:</strong>{{interviewer_email}}</li>
|
||||
<li><strong>面试官电话:</strong>{{interviewer_phone}}</li>
|
||||
<li><strong>公司地址:</strong>{{company_address}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -426,7 +424,7 @@ class GlobalTemplateCreator:
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>祝面试顺利!<br>{company_name} 人力资源部</p>
|
||||
<p>祝面试顺利!<br>{{company_name}} 人力资源部</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -435,59 +433,59 @@ class GlobalTemplateCreator:
|
||||
template_data_en = {
|
||||
"template_id": "interview_status_update",
|
||||
"region": 0,
|
||||
"subject": "Interview Status Update - {candidate_name}",
|
||||
"subject": "Interview Status Update - {{candidate_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">Dear {candidate_name},</h2>
|
||||
<h2 style="color: #333;">Dear {{candidate_name}},</h2>
|
||||
|
||||
<p>Your interview status has been updated:</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👤 Candidate Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Name: </strong>{candidate_name}</li>
|
||||
<li><strong>Position Applied: </strong>{position_name}</li>
|
||||
<li><strong>Application ID: </strong>{application_id}</li>
|
||||
<li><strong>Name: </strong>{{candidate_name}}</li>
|
||||
<li><strong>Position Applied: </strong>{{position_name}}</li>
|
||||
<li><strong>Application ID: </strong>{{application_id}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📊 Status Update</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Current Status: </strong>{current_status}</li>
|
||||
<li><strong>Update Date: </strong>{update_date}</li>
|
||||
<li><strong>Update Time: </strong>{update_time}</li>
|
||||
<li><strong>Current Status: </strong>{{current_status}}</li>
|
||||
<li><strong>Update Date: </strong>{{update_date}}</li>
|
||||
<li><strong>Update Time: </strong>{{update_time}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📋 Status Details</h3>
|
||||
<p>{status_details}</p>
|
||||
<p>{{status_details}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">📅 Next Steps</h3>
|
||||
<p>{next_steps}</p>
|
||||
<p>{{next_steps}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⏰ Important Times</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Interview Time: </strong>{interview_time}</li>
|
||||
<li><strong>Interview Location: </strong>{interview_location}</li>
|
||||
<li><strong>Interviewer: </strong>{interviewer_name}</li>
|
||||
<li><strong>Interview Time: </strong>{{interview_time}}</li>
|
||||
<li><strong>Interview Location: </strong>{{interview_location}}</li>
|
||||
<li><strong>Interviewer: </strong>{{interviewer_name}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📞 Contact Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Interviewer Email: </strong>{interviewer_email}</li>
|
||||
<li><strong>Interviewer Phone: </strong>{interviewer_phone}</li>
|
||||
<li><strong>Company Address: </strong>{company_address}</li>
|
||||
<li><strong>Interviewer Email: </strong>{{interviewer_email}}</li>
|
||||
<li><strong>Interviewer Phone: </strong>{{interviewer_phone}}</li>
|
||||
<li><strong>Company Address: </strong>{{company_address}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -496,7 +494,7 @@ class GlobalTemplateCreator:
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>Good luck with your interview!<br>{company_name} Human Resources Department</p>
|
||||
<p>Good luck with your interview!<br>{{company_name}} Human Resources Department</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -514,16 +512,16 @@ class GlobalTemplateCreator:
|
||||
template_data_cn = {
|
||||
"template_id": "welcome_email",
|
||||
"region": 1,
|
||||
"subject": "欢迎加入 {company_name} - {new_employee_name}",
|
||||
"subject": "欢迎加入 {{company_name}} - {{new_employee_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">亲爱的 {new_employee_name},</h2>
|
||||
<h2 style="color: #333;">亲爱的 {{new_employee_name}},</h2>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 20px; border-radius: 5px; margin: 20px 0; text-align: center;">
|
||||
<h1 style="color: #155724; margin: 0;">🎉 欢迎加入 {company_name}!</h1>
|
||||
<h1 style="color: #155724; margin: 0;">🎉 欢迎加入 {{company_name}}!</h1>
|
||||
</div>
|
||||
|
||||
<p>我们很高兴地通知您,您已成功加入我们的团队。以下是您的入职信息:</p>
|
||||
@ -531,58 +529,58 @@ class GlobalTemplateCreator:
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👤 员工信息</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>姓名:</strong>{new_employee_name}</li>
|
||||
<li><strong>员工编号:</strong>{employee_id}</li>
|
||||
<li><strong>部门:</strong>{department}</li>
|
||||
<li><strong>职位:</strong>{position}</li>
|
||||
<li><strong>入职日期:</strong>{start_date}</li>
|
||||
<li><strong>姓名:</strong>{{new_employee_name}}</li>
|
||||
<li><strong>员工编号:</strong>{{employee_id}}</li>
|
||||
<li><strong>部门:</strong>{{department}}</li>
|
||||
<li><strong>职位:</strong>{{position}}</li>
|
||||
<li><strong>入职日期:</strong>{{start_date}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">🏢 公司信息</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>公司名称:</strong>{company_name}</li>
|
||||
<li><strong>公司地址:</strong>{company_address}</li>
|
||||
<li><strong>联系电话:</strong>{company_phone}</li>
|
||||
<li><strong>公司名称:</strong>{{company_name}}</li>
|
||||
<li><strong>公司地址:</strong>{{company_address}}</li>
|
||||
<li><strong>联系电话:</strong>{{company_phone}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📋 入职安排</h3>
|
||||
<p>{onboarding_schedule}</p>
|
||||
<p>{{onboarding_schedule}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">🔑 系统访问信息</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>邮箱:</strong>{email_address}</li>
|
||||
<li><strong>初始密码:</strong>{initial_password}</li>
|
||||
<li><strong>系统登录地址:</strong><a href="{system_login_url}" style="color: #007bff;">{system_login_url}</a></li>
|
||||
<li><strong>邮箱:</strong>{{email_address}}</li>
|
||||
<li><strong>初始密码:</strong>{{initial_password}}</li>
|
||||
<li><strong>系统登录地址:</strong><a href="{{system_login_url}}" style="color: #007bff;">{{system_login_url}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">📚 重要资源</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>员工手册:</strong><a href="{employee_handbook_url}" style="color: #007bff;">{employee_handbook_url}</a></li>
|
||||
<li><strong>培训材料:</strong><a href="{training_materials_url}" style="color: #007bff;">{training_materials_url}</a></li>
|
||||
<li><strong>公司政策:</strong><a href="{company_policies_url}" style="color: #007bff;">{company_policies_url}</a></li>
|
||||
<li><strong>员工手册:</strong><a href="{{employee_handbook_url}}" style="color: #007bff;">{{employee_handbook_url}}</a></li>
|
||||
<li><strong>培训材料:</strong><a href="{{training_materials_url}}" style="color: #007bff;">{{training_materials_url}}</a></li>
|
||||
<li><strong>公司政策:</strong><a href="{{company_policies_url}}" style="color: #007bff;">{{company_policies_url}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👥 联系人</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>直属经理:</strong>{manager_name} ({manager_email})</li>
|
||||
<li><strong>HR联系人:</strong>{hr_contact_name} ({hr_contact_email})</li>
|
||||
<li><strong>IT支持:</strong>{it_support_email}</li>
|
||||
<li><strong>直属经理:</strong>{{manager_name}} ({{manager_email}})</li>
|
||||
<li><strong>HR联系人:</strong>{{hr_contact_name}} ({{hr_contact_email}})</li>
|
||||
<li><strong>IT支持:</strong>{{it_support_email}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">🎯 第一周安排</h3>
|
||||
<p>{first_week_schedule}</p>
|
||||
<p>{{first_week_schedule}}</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
@ -590,7 +588,7 @@ class GlobalTemplateCreator:
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>再次欢迎您的加入!<br>{company_name} 团队</p>
|
||||
<p>再次欢迎您的加入!<br>{{company_name}} 团队</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -599,16 +597,16 @@ class GlobalTemplateCreator:
|
||||
template_data_en = {
|
||||
"template_id": "welcome_email",
|
||||
"region": 0,
|
||||
"subject": "Welcome to {company_name} - {new_employee_name}",
|
||||
"subject": "Welcome to {{company_name}} - {{new_employee_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">Dear {new_employee_name},</h2>
|
||||
<h2 style="color: #333;">Dear {{new_employee_name}},</h2>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 20px; border-radius: 5px; margin: 20px 0; text-align: center;">
|
||||
<h1 style="color: #155724; margin: 0;">🎉 Welcome to {company_name}!</h1>
|
||||
<h1 style="color: #155724; margin: 0;">🎉 Welcome to {{company_name}}!</h1>
|
||||
</div>
|
||||
|
||||
<p>We are pleased to inform you that you have successfully joined our team. Here is your onboarding information:</p>
|
||||
@ -616,58 +614,58 @@ class GlobalTemplateCreator:
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👤 Employee Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Name: </strong>{new_employee_name}</li>
|
||||
<li><strong>Employee ID: </strong>{employee_id}</li>
|
||||
<li><strong>Department: </strong>{department}</li>
|
||||
<li><strong>Position: </strong>{position}</li>
|
||||
<li><strong>Start Date: </strong>{start_date}</li>
|
||||
<li><strong>Name: </strong>{{new_employee_name}}</li>
|
||||
<li><strong>Employee ID: </strong>{{employee_id}}</li>
|
||||
<li><strong>Department: </strong>{{department}}</li>
|
||||
<li><strong>Position: </strong>{{position}}</li>
|
||||
<li><strong>Start Date: </strong>{{start_date}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">🏢 Company Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Company Name: </strong>{company_name}</li>
|
||||
<li><strong>Company Address: </strong>{company_address}</li>
|
||||
<li><strong>Contact Phone: </strong>{company_phone}</li>
|
||||
<li><strong>Company Name: </strong>{{company_name}}</li>
|
||||
<li><strong>Company Address: </strong>{{company_address}}</li>
|
||||
<li><strong>Contact Phone: </strong>{{company_phone}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📋 Onboarding Schedule</h3>
|
||||
<p>{onboarding_schedule}</p>
|
||||
<p>{{onboarding_schedule}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">🔑 System Access Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Email: </strong>{email_address}</li>
|
||||
<li><strong>Initial Password: </strong>{initial_password}</li>
|
||||
<li><strong>System Login URL: </strong><a href="{system_login_url}" style="color: #007bff;">{system_login_url}</a></li>
|
||||
<li><strong>Email: </strong>{{email_address}}</li>
|
||||
<li><strong>Initial Password: </strong>{{initial_password}}</li>
|
||||
<li><strong>System Login URL: </strong><a href="{{system_login_url}}" style="color: #007bff;">{{system_login_url}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">📚 Important Resources</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Employee Handbook: </strong><a href="{employee_handbook_url}" style="color: #007bff;">{employee_handbook_url}</a></li>
|
||||
<li><strong>Training Materials: </strong><a href="{training_materials_url}" style="color: #007bff;">{training_materials_url}</a></li>
|
||||
<li><strong>Company Policies: </strong><a href="{company_policies_url}" style="color: #007bff;">{company_policies_url}</a></li>
|
||||
<li><strong>Employee Handbook: </strong><a href="{{employee_handbook_url}}" style="color: #007bff;">{{employee_handbook_url}}</a></li>
|
||||
<li><strong>Training Materials: </strong><a href="{{training_materials_url}}" style="color: #007bff;">{{training_materials_url}}</a></li>
|
||||
<li><strong>Company Policies: </strong><a href="{{company_policies_url}}" style="color: #007bff;">{{company_policies_url}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👥 Contacts</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Direct Manager: </strong>{manager_name} ({manager_email})</li>
|
||||
<li><strong>HR Contact: </strong>{hr_contact_name} ({hr_contact_email})</li>
|
||||
<li><strong>IT Support: </strong>{it_support_email}</li>
|
||||
<li><strong>Direct Manager: </strong>{{manager_name}} ({{manager_email}})</li>
|
||||
<li><strong>HR Contact: </strong>{{hr_contact_name}} ({{hr_contact_email}})</li>
|
||||
<li><strong>IT Support: </strong>{{it_support_email}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">🎯 First Week Schedule</h3>
|
||||
<p>{first_week_schedule}</p>
|
||||
<p>{{first_week_schedule}}</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
@ -675,7 +673,7 @@ class GlobalTemplateCreator:
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>Welcome aboard!<br>{company_name} Team</p>
|
||||
<p>Welcome aboard!<br>{{company_name}} Team</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -693,36 +691,36 @@ class GlobalTemplateCreator:
|
||||
template_data_cn = {
|
||||
"template_id": "password_reset_email",
|
||||
"region": 1,
|
||||
"subject": "密码重置请求 - {user_name}",
|
||||
"subject": "密码重置请求 - {{user_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">尊敬的 {user_name},</h2>
|
||||
<h2 style="color: #333;">尊敬的 {{user_name}},</h2>
|
||||
|
||||
<p>我们收到了您的密码重置请求。</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">🔐 重置信息</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>用户名:</strong>{user_name}</li>
|
||||
<li><strong>邮箱:</strong>{email_address}</li>
|
||||
<li><strong>请求时间:</strong>{request_time}</li>
|
||||
<li><strong>请求IP:</strong>{request_ip}</li>
|
||||
<li><strong>用户名:</strong>{{user_name}}</li>
|
||||
<li><strong>邮箱:</strong>{{email_address}}</li>
|
||||
<li><strong>请求时间:</strong>{{request_time}}</li>
|
||||
<li><strong>请求IP:</strong>{{request_ip}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">🔗 重置链接</h3>
|
||||
<p><a href="{reset_link}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">点击重置密码</a></p>
|
||||
<p style="font-size: 12px; color: #666;">或复制链接:{reset_link}</p>
|
||||
<p><a href="{{reset_link}}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">点击重置密码</a></p>
|
||||
<p style="font-size: 12px; color: #666;">或复制链接:{{reset_link}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⚠️ 重要提醒</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li>• 此链接将在 {expiry_hours} 小时后失效</li>
|
||||
<li>• 此链接将在 {{expiry_hours}} 小时后失效</li>
|
||||
<li>• 请勿将此链接分享给他人</li>
|
||||
<li>• 如果您没有请求重置密码,请忽略此邮件</li>
|
||||
</ul>
|
||||
@ -730,7 +728,7 @@ class GlobalTemplateCreator:
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📱 验证码</h3>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{verification_code}</p>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{{verification_code}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
@ -744,12 +742,12 @@ class GlobalTemplateCreator:
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
<p>如有任何问题,请联系技术支持:</p>
|
||||
<p><strong>邮箱:</strong>{support_email}</p>
|
||||
<p><strong>电话:</strong>{support_phone}</p>
|
||||
<p><strong>邮箱:</strong>{{support_email}}</p>
|
||||
<p><strong>电话:</strong>{{support_phone}}</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>谢谢!<br>{company_name} 技术支持团队</p>
|
||||
<p>谢谢!<br>{{company_name}} 技术支持团队</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -758,36 +756,36 @@ class GlobalTemplateCreator:
|
||||
template_data_en = {
|
||||
"template_id": "password_reset_email",
|
||||
"region": 0,
|
||||
"subject": "Password Reset Request - {user_name}",
|
||||
"subject": "Password Reset Request - {{user_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">Dear {user_name},</h2>
|
||||
<h2 style="color: #333;">Dear {{user_name}},</h2>
|
||||
|
||||
<p>We have received your password reset request.</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">🔐 Reset Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Username: </strong>{user_name}</li>
|
||||
<li><strong>Email: </strong>{email_address}</li>
|
||||
<li><strong>Request Time: </strong>{request_time}</li>
|
||||
<li><strong>Request IP: </strong>{request_ip}</li>
|
||||
<li><strong>Username: </strong>{{user_name}}</li>
|
||||
<li><strong>Email: </strong>{{email_address}}</li>
|
||||
<li><strong>Request Time: </strong>{{request_time}}</li>
|
||||
<li><strong>Request IP: </strong>{{request_ip}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">🔗 Reset Link</h3>
|
||||
<p><a href="{reset_link}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">Click to Reset Password</a></p>
|
||||
<p style="font-size: 12px; color: #666;">Or copy the link: {reset_link}</p>
|
||||
<p><a href="{{reset_link}}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">Click to Reset Password</a></p>
|
||||
<p style="font-size: 12px; color: #666;">Or copy the link: {{reset_link}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">⚠️ Important Reminder</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li>• This link will expire in {expiry_hours} hours</li>
|
||||
<li>• This link will expire in {{expiry_hours}} hours</li>
|
||||
<li>• Please do not share this link with others</li>
|
||||
<li>• If you did not request a password reset, please ignore this email</li>
|
||||
</ul>
|
||||
@ -795,7 +793,7 @@ class GlobalTemplateCreator:
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📱 Verification Code</h3>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{verification_code}</p>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{{verification_code}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
@ -809,12 +807,12 @@ class GlobalTemplateCreator:
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;">
|
||||
<p>If you have any questions, please contact technical support:</p>
|
||||
<p><strong>Email: </strong>{support_email}</p>
|
||||
<p><strong>Phone: </strong>{support_phone}</p>
|
||||
<p><strong>Email: </strong>{{support_email}}</p>
|
||||
<p><strong>Phone: </strong>{{support_phone}}</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>Thank you!<br>{company_name} Technical Support Team</p>
|
||||
<p>Thank you!<br>{{company_name}} Technical Support Team</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -832,41 +830,41 @@ class GlobalTemplateCreator:
|
||||
template_data_cn = {
|
||||
"template_id": "account_verification_email",
|
||||
"region": 1,
|
||||
"subject": "账号验证 - {user_name}",
|
||||
"subject": "账号验证 - {{user_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">尊敬的 {user_name},</h2>
|
||||
<h2 style="color: #333;">尊敬的 {{user_name}},</h2>
|
||||
|
||||
<p>感谢您注册 {company_name} 的账户。请验证您的邮箱地址以完成注册。</p>
|
||||
<p>感谢您注册 {{company_name}} 的账户。请验证您的邮箱地址以完成注册。</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👤 账户信息</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>用户名:</strong>{user_name}</li>
|
||||
<li><strong>邮箱地址:</strong>{email_address}</li>
|
||||
<li><strong>注册时间:</strong>{registration_time}</li>
|
||||
<li><strong>用户名:</strong>{{user_name}}</li>
|
||||
<li><strong>邮箱地址:</strong>{{email_address}}</li>
|
||||
<li><strong>注册时间:</strong>{{registration_time}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">🔗 验证链接</h3>
|
||||
<p><a href="{verification_link}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">点击验证邮箱</a></p>
|
||||
<p style="font-size: 12px; color: #666;">或复制链接:{verification_link}</p>
|
||||
<p><a href="{{verification_link}}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">点击验证邮箱</a></p>
|
||||
<p style="font-size: 12px; color: #666;">或复制链接:{{verification_link}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📱 验证码</h3>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{verification_code}</p>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{{verification_code}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">⏰ 验证期限</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>验证链接有效期:</strong>{expiry_hours} 小时</li>
|
||||
<li><strong>请在 {expiry_time} 前完成验证</strong></li>
|
||||
<li><strong>验证链接有效期:</strong>{{expiry_hours}} 小时</li>
|
||||
<li><strong>请在 {{expiry_time}} 前完成验证</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -874,7 +872,7 @@ class GlobalTemplateCreator:
|
||||
<h3 style="color: #155724; margin-top: 0;">✅ 验证步骤</h3>
|
||||
<ol style="padding-left: 20px;">
|
||||
<li>点击上面的验证链接,或</li>
|
||||
<li>在登录页面输入验证码:<strong>{verification_code}</strong></li>
|
||||
<li>在登录页面输入验证码:<strong>{{verification_code}}</strong></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
@ -890,8 +888,8 @@ class GlobalTemplateCreator:
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📞 需要帮助?</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>技术支持:</strong>{support_email}</li>
|
||||
<li><strong>客服热线:</strong>{support_phone}</li>
|
||||
<li><strong>技术支持:</strong>{{support_email}}</li>
|
||||
<li><strong>客服热线:</strong>{{support_phone}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -905,7 +903,7 @@ class GlobalTemplateCreator:
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>谢谢!<br>{company_name} 团队</p>
|
||||
<p>谢谢!<br>{{company_name}} 团队</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
@ -914,41 +912,41 @@ class GlobalTemplateCreator:
|
||||
template_data_en = {
|
||||
"template_id": "account_verification_email",
|
||||
"region": 0,
|
||||
"subject": "Account Verification - {user_name}",
|
||||
"subject": "Account Verification - {{user_name}}",
|
||||
"body": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<img src="{company_logo}" alt="{company_name} Logo" style="max-height: 60px;">
|
||||
<img src="{{company_logo}}" alt="{{company_name}} Logo" style="max-height: 60px;">
|
||||
</div>
|
||||
|
||||
<h2 style="color: #333;">Dear {user_name},</h2>
|
||||
<h2 style="color: #333;">Dear {{user_name}},</h2>
|
||||
|
||||
<p>Thank you for registering an account with {company_name}. Please verify your email address to complete your registration.</p>
|
||||
<p>Thank you for registering an account with {{company_name}}. Please verify your email address to complete your registration.</p>
|
||||
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">👤 Account Information</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Username: </strong>{user_name}</li>
|
||||
<li><strong>Email Address: </strong>{email_address}</li>
|
||||
<li><strong>Registration Time: </strong>{registration_time}</li>
|
||||
<li><strong>Username: </strong>{{user_name}}</li>
|
||||
<li><strong>Email Address: </strong>{{email_address}}</li>
|
||||
<li><strong>Registration Time: </strong>{{registration_time}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #856404; margin-top: 0;">🔗 Verification Link</h3>
|
||||
<p><a href="{verification_link}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">Click to Verify Email</a></p>
|
||||
<p style="font-size: 12px; color: #666;">Or copy the link: {verification_link}</p>
|
||||
<p><a href="{{verification_link}}" style="color: #007bff; text-decoration: none; padding: 10px 20px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block;">Click to Verify Email</a></p>
|
||||
<p style="font-size: 12px; color: #666;">Or copy the link: {{verification_link}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #d4edda; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #155724; margin-top: 0;">📱 Verification Code</h3>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{verification_code}</p>
|
||||
<p style="font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; color: #155724;">{{verification_code}}</p>
|
||||
</div>
|
||||
|
||||
<div style="background-color: #cce5ff; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #004085; margin-top: 0;">⏰ Verification Period</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Verification Link Valid: </strong>{expiry_hours} hours</li>
|
||||
<li><strong>Please complete verification before {expiry_time}</strong></li>
|
||||
<li><strong>Verification Link Valid: </strong>{{expiry_hours}} hours</li>
|
||||
<li><strong>Please complete verification before {{expiry_time}}</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -956,7 +954,7 @@ class GlobalTemplateCreator:
|
||||
<h3 style="color: #155724; margin-top: 0;">✅ Verification Steps</h3>
|
||||
<ol style="padding-left: 20px;">
|
||||
<li>Click the verification link above, or</li>
|
||||
<li>Enter the verification code on the login page: <strong>{verification_code}</strong></li>
|
||||
<li>Enter the verification code on the login page: <strong>{{verification_code}}</strong></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
@ -972,8 +970,8 @@ class GlobalTemplateCreator:
|
||||
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<h3 style="color: #007bff; margin-top: 0;">📞 Need Help?</h3>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li><strong>Technical Support: </strong>{support_email}</li>
|
||||
<li><strong>Customer Service: </strong>{support_phone}</li>
|
||||
<li><strong>Technical Support: </strong>{{support_email}}</li>
|
||||
<li><strong>Customer Service: </strong>{{support_phone}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -987,7 +985,7 @@ class GlobalTemplateCreator:
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 30px; color: #666; font-size: 12px;">
|
||||
<p>Thank you!<br>{company_name} Team</p>
|
||||
<p>Thank you!<br>{{company_name}} Team</p>
|
||||
</div>
|
||||
</div>"""
|
||||
}
|
||||
|
||||
@ -139,18 +139,12 @@ async def create_global_template(request: TemplateCreateRequest):
|
||||
body=request.body,
|
||||
is_active=request.is_active
|
||||
)
|
||||
# check if the template is created or skipped (already exists)
|
||||
is_skipped = hasattr(result, '_is_existing') and result._is_existing
|
||||
|
||||
return JSONResponse(
|
||||
content={
|
||||
"message": f"Global template {'skipped (already exists)' if is_skipped else 'created'} successfully",
|
||||
"template_id": request.template_id,
|
||||
"action": "skipped" if is_skipped else "created"
|
||||
},
|
||||
status_code=200 if is_skipped else 201
|
||||
content={"message": "Global template created successfully", "template_id": request.template_id},
|
||||
status_code=201
|
||||
)
|
||||
except ValueError as e:
|
||||
# duplicate or validation error
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
except Exception as e:
|
||||
import traceback
|
||||
@ -286,37 +280,19 @@ async def create_tenant_template(request: TemplateCreateRequest, payload: dict =
|
||||
tenant_id=tenant_id,
|
||||
is_active=request.is_active
|
||||
)
|
||||
|
||||
# check if the template is created or skipped (already exists)
|
||||
is_skipped = hasattr(result, '_is_existing') and result._is_existing
|
||||
|
||||
# normalize minimal response
|
||||
if hasattr(result, 'dict'):
|
||||
result_dict = result.dict()
|
||||
for key, value in result_dict.items():
|
||||
if hasattr(value, 'isoformat'):
|
||||
result_dict[key] = value.isoformat()
|
||||
elif hasattr(value, 'value'):
|
||||
result_dict[key] = value.value
|
||||
else:
|
||||
result_dict = {
|
||||
"template_id": getattr(result, 'template_id', request.template_id),
|
||||
"tenant_id": getattr(result, 'tenant_id', tenant_id),
|
||||
"region": getattr(result, 'region', request.region),
|
||||
"subject": getattr(result, 'subject', request.subject),
|
||||
"body": getattr(result, 'body', request.body),
|
||||
"is_active": getattr(result, 'is_active', request.is_active)
|
||||
}
|
||||
|
||||
result_dict = {"template_id": request.template_id, "tenant_id": tenant_id, "region": request.region}
|
||||
|
||||
return JSONResponse(
|
||||
content={
|
||||
"message": f"Tenant template {'skipped (already exists)' if is_skipped else 'created'} successfully",
|
||||
"result": result_dict,
|
||||
"action": "skipped" if is_skipped else "created"
|
||||
},
|
||||
status_code=200 if is_skipped else 201,
|
||||
content={"message": "Tenant template created successfully", "result": result_dict},
|
||||
status_code=201,
|
||||
media_type="application/json"
|
||||
)
|
||||
except ValueError as e:
|
||||
# duplicate or validation error
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
Loading…
Reference in New Issue
Block a user