Files
tougao/application/api/controller/MailTemplate.php
2026-03-18 14:37:23 +08:00

262 lines
8.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\api\controller;
use think\Db;
use think\Validate;
class MailTemplate extends Base
{
/**
* Create or update a mail template (V2)
* POST fields:
* - template_id (optional)
* - journal_id, scene, language, title, subject, body_html, body_text, variables_json, version, is_active
*/
public function saveTemplate()
{
$data = $this->request->post();
$rule = new Validate([
'journal_id' => 'require|number',
'scene' => 'require',
'language' => 'require',
'title' => 'require',
'subject' => 'require',
]);
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
$payload = [
'journal_id' => intval($data['journal_id']),
'scene' => trim($data['scene']),
'language' => trim($data['language']),
'title' => trim($data['title']),
'subject' => trim($data['subject']),
'body_html' => $data['body_html'] ?? '',
'body_text' => $data['body_text'] ?? '',
'variables_json' => $data['variables_json'] ?? '',
'version' => intval($data['version'] ?? 1),
'is_active' => intval($data['is_active'] ?? 1),
'utime' => time(),
];
$templateId = intval($data['template_id'] ?? 0);
if ($templateId) {
$exists = Db::name('mail_template')->where('template_id', $templateId)->where('state', 0)->find();
if (!$exists) {
return jsonError('Template not found');
}
Db::name('mail_template')->where('template_id', $templateId)->update($payload);
return jsonSuccess(['template_id' => $templateId]);
}
$payload['ctime'] = time();
$payload['state'] = 0;
$newId = Db::name('mail_template')->insertGetId($payload);
return jsonSuccess(['template_id' => $newId]);
}
/**
* Soft delete a template
* Params: template_id
*/
public function deleteTemplate()
{
$templateId = intval($this->request->param('template_id', 0));
if (!$templateId) {
return jsonError('template_id is required');
}
Db::name('mail_template')->where('template_id', $templateId)->update(['state' => 1, 'utime' => time()]);
return jsonSuccess([]);
}
/**
* Get template detail
*/
public function getTemplate()
{
$templateId = intval($this->request->param('template_id', 0));
if (!$templateId) {
return jsonError('template_id is required');
}
$tpl = Db::name('mail_template')->where('template_id', $templateId)->where('state', 0)->find();
if (!$tpl) {
return jsonError('Template not found');
}
return jsonSuccess(['template' => $tpl]);
}
/**
* List templates
* Params: journal_id, scene(optional), language(optional), is_active(optional)
*/
public function listTemplates()
{
$journalId = intval($this->request->param('journal_id', 0));
if (!$journalId) {
return jsonError('journal_id is required');
}
$scene = trim($this->request->param('scene', ''));
$language = trim($this->request->param('language', ''));
$isActive = $this->request->param('is_active', '');
$where = ['journal_id' => $journalId, 'state' => 0];
if ($scene !== '') $where['scene'] = $scene;
if ($language !== '') $where['language'] = $language;
if ($isActive !== '') $where['is_active'] = intval($isActive);
$list = Db::name('mail_template')
->where($where)
->order('is_active desc, utime desc, template_id desc')
->select();
return jsonSuccess(['list' => $list]);
}
public function listTemplatesAll(){
$list = Db::name('mail_template')
->where('state', 0)
->order('is_active desc, utime desc, template_id desc')
->select();
return jsonSuccess(['list'=>$list]);
}
/**
* Create or update a global mail style
* 当前 style 表字段:
* - style_id, name, description, header_html, footer_html, state, ctime
*/
public function saveStyle()
{
$data = $this->request->post();
$rule = new Validate([
'name' => 'require',
]);
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
$payload = [
'name' => trim($data['name']),
'description' => trim($data['description'] ?? ''),
'header_html' => $data['header_html'] ?? '',
'footer_html' => $data['footer_html'] ?? '',
'state' => 0,
];
$styleId = intval($data['style_id'] ?? 0);
if ($styleId) {
$exists = Db::name('mail_style')->where('style_id', $styleId)->where('state', 0)->find();
if (!$exists) {
return jsonError('Style not found');
}
Db::name('mail_style')->where('style_id', $styleId)->update($payload);
return jsonSuccess(['style_id' => $styleId]);
}
$payload['ctime'] = time();
$newId = Db::name('mail_style')->insertGetId($payload);
return jsonSuccess(['style_id' => $newId]);
}
/**
* Delete a global mail style (soft delete)
*/
public function deleteStyle()
{
$styleId = intval($this->request->param('style_id', 0));
if (!$styleId) {
return jsonError('style_id is required');
}
Db::name('mail_style')->where('style_id', $styleId)->update(['state' => 1]);
return jsonSuccess([]);
}
/**
* Get style detail
*/
public function getStyle()
{
$styleId = intval($this->request->param('style_id', 0));
if (!$styleId) {
return jsonError('style_id is required');
}
$style = Db::name('mail_style')->where('style_id', $styleId)->where('state', 0)->find();
if (!$style) {
return jsonError('Style not found');
}
return jsonSuccess(['style' => $style]);
}
/**
* List styles
* 现在样式不再按 scene / language 区分,只返回全部正常状态的样式
*/
public function listStyles()
{
$where = ['state' => 0];
$list = Db::name('mail_style')
->where($where)
->order('style_id desc')
->select();
return jsonSuccess(['list' => $list]);
}
/**
* Render preview for a template预览效果没啥用
* Params: template_id, vars (json string)
*/
public function preview()
{
$templateId = intval($this->request->param('template_id', 0));
$varsJson = $this->request->param('vars', '');
if (!$templateId) {
return jsonError('template_id is required');
}
$tpl = Db::name('mail_template')->where('template_id', $templateId)->where('state', 0)->find();
if (!$tpl) {
return jsonError('Template not found');
}
$vars = [];
if ($varsJson) {
$decoded = json_decode($varsJson, true);
if (is_array($decoded)) $vars = $decoded;
}
$subject = $this->render($tpl['subject'], $vars);
$body = $this->render($tpl['body_html'], $vars);
// For preview we do not enforce a style; caller can combine with style if needed
return jsonSuccess(['subject' => $subject, 'body' => $body]);
}
private function render($tpl, $vars)
{
if (!is_string($tpl) || empty($tpl)) return '';
if (!is_array($vars) || empty($vars)) return $tpl;
$replace = [];
foreach ($vars as $k => $v) {
$key = trim((string)$k);
if ($key === '') continue;
$replace['{{' . $key . '}}'] = (string)$v;
// backward compatible placeholders
$replace['{' . $key . '}'] = (string)$v;
}
return str_replace(array_keys($replace), array_values($replace), $tpl);
}
}