mirror of
https://github.com/RhenCloud/Cloud-Home.git
synced 2026-01-22 17:39:07 +08:00
feat(ui): 添加友链申请表单中想说的话字段
在 `FriendsSection.vue` 中添加了新的表单字段“想说的话”,用户可以输入最多50字的信息。同时更新了相关的样式,以支持 `textarea` 的显示和交互,包括输入框的样式和字符计数的显示。 在 `send-mail.ts` 中添加了对新字段 `message` 的处理,确保其在邮件内容中正确显示,并在邮件的HTML部分增加了对 `message` 字段的引用。 在生成的邮件内容中增加了友链申请者的“想说的话”信息,方便接收者查看。
This commit is contained in:
@@ -11,12 +11,12 @@ export default defineNuxtConfig({
|
|||||||
link: [{ rel: "icon", href: siteConfig.siteMeta.icon }],
|
link: [{ rel: "icon", href: siteConfig.siteMeta.icon }],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nitro: {
|
// nitro: {
|
||||||
prerender: {
|
// prerender: {
|
||||||
crawlLinks: true,
|
// crawlLinks: true,
|
||||||
routes: ["/sitemap.xml", "/rss.xml"],
|
// routes: ["/sitemap.xml", "/rss.xml"],
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
smtpHost: process.env.SMTP_HOST ?? "",
|
smtpHost: process.env.SMTP_HOST ?? "",
|
||||||
smtpPort: Number(process.env.SMTP_PORT ?? 465),
|
smtpPort: Number(process.env.SMTP_PORT ?? 465),
|
||||||
|
|||||||
@@ -26,6 +26,13 @@
|
|||||||
头像链接
|
头像链接
|
||||||
<input v-model="form.avatar" type="url" placeholder="可选,展示头像" />
|
<input v-model="form.avatar" type="url" placeholder="可选,展示头像" />
|
||||||
</label>
|
</label>
|
||||||
|
<label>
|
||||||
|
想说的话
|
||||||
|
<div class="textarea-wrapper">
|
||||||
|
<textarea v-model="form.message" placeholder="可选,最多50字" maxlength="50"></textarea>
|
||||||
|
<span class="char-count">{{ form.message?.length || 0 }}/50</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="primary" :disabled="loading">
|
<button type="submit" class="primary" :disabled="loading">
|
||||||
{{ loading ? "提交中..." : "提交申请" }}
|
{{ loading ? "提交中..." : "提交申请" }}
|
||||||
@@ -75,6 +82,7 @@ const form = reactive({
|
|||||||
desc: "",
|
desc: "",
|
||||||
email: "",
|
email: "",
|
||||||
avatar: "",
|
avatar: "",
|
||||||
|
message: "",
|
||||||
});
|
});
|
||||||
const displayedFriends = ref([]);
|
const displayedFriends = ref([]);
|
||||||
|
|
||||||
@@ -108,6 +116,7 @@ const submitForm = async () => {
|
|||||||
desc: form.desc,
|
desc: form.desc,
|
||||||
email: form.email,
|
email: form.email,
|
||||||
avatar: form.avatar,
|
avatar: form.avatar,
|
||||||
|
message: form.message,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
if (!resp.ok) throw new Error("send failed");
|
if (!resp.ok) throw new Error("send failed");
|
||||||
@@ -192,15 +201,41 @@ h2 {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
|
transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
|
||||||
}
|
}
|
||||||
.friend-form input::placeholder {
|
.textarea-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.friend-form textarea {
|
||||||
|
flex: 1;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
color: inherit;
|
||||||
|
transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
|
||||||
|
font-family: inherit;
|
||||||
|
height: 36px;
|
||||||
|
resize: none;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.friend-form input::placeholder,
|
||||||
|
.friend-form textarea::placeholder {
|
||||||
color: rgba(232, 238, 252, 0.7);
|
color: rgba(232, 238, 252, 0.7);
|
||||||
}
|
}
|
||||||
.friend-form input:focus {
|
.friend-form input:focus,
|
||||||
|
.friend-form textarea:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: rgba(124, 193, 255, 0.8);
|
border-color: rgba(124, 193, 255, 0.8);
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
box-shadow: 0 0 0 2px rgba(124, 193, 255, 0.25);
|
box-shadow: 0 0 0 2px rgba(124, 193, 255, 0.25);
|
||||||
}
|
}
|
||||||
|
.char-count {
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(232, 238, 252, 0.6);
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
.form-actions {
|
.form-actions {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type SendMailPayload = {
|
|||||||
desc?: string;
|
desc?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
|
message?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ensureValue = (value?: string, fallback = "未填写") => (value?.trim() ? value.trim() : fallback);
|
const ensureValue = (value?: string, fallback = "未填写") => (value?.trim() ? value.trim() : fallback);
|
||||||
@@ -35,7 +36,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const payload = (await readBody<SendMailPayload>(event)) || {};
|
const payload = (await readBody<SendMailPayload>(event)) || {};
|
||||||
const { name, url, desc, email, avatar } = payload;
|
const { name, url, desc, email, avatar, message } = payload;
|
||||||
|
|
||||||
if (!name?.trim() || !url?.trim() || !email?.trim()) {
|
if (!name?.trim() || !url?.trim() || !email?.trim()) {
|
||||||
throw createError({
|
throw createError({
|
||||||
@@ -45,15 +46,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const config = useRuntimeConfig() as MailConfig;
|
const config = useRuntimeConfig() as MailConfig;
|
||||||
const {
|
const { smtpHost, smtpPort: configSmtpPort, smtpUser, smtpPass, senderEmail, adminEmail, smtpSecure } = config;
|
||||||
smtpHost,
|
|
||||||
smtpPort: configSmtpPort,
|
|
||||||
smtpUser,
|
|
||||||
smtpPass,
|
|
||||||
senderEmail,
|
|
||||||
adminEmail,
|
|
||||||
smtpSecure,
|
|
||||||
} = config;
|
|
||||||
|
|
||||||
const smtpPort = Number(configSmtpPort ?? 465);
|
const smtpPort = Number(configSmtpPort ?? 465);
|
||||||
if (!smtpHost || !smtpUser || !smtpPass || !senderEmail || !adminEmail) {
|
if (!smtpHost || !smtpUser || !smtpPass || !senderEmail || !adminEmail) {
|
||||||
@@ -72,12 +65,26 @@ export default defineEventHandler(async (event) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport(smtpOptions);
|
const transporter = nodemailer.createTransport(smtpOptions);
|
||||||
|
const friendEntry = `{
|
||||||
|
name: "${ensureValue(name).replace(/"/g, '\\"')}",
|
||||||
|
url: "${ensureValue(url).replace(/"/g, '\\"')}",
|
||||||
|
desc: "${ensureValue(desc).replace(/"/g, '\\"')}",
|
||||||
|
avatar: "${ensureValue(avatar).replace(/"/g, '\\"')}",
|
||||||
|
},`;
|
||||||
|
|
||||||
const htmlMessage = `
|
const htmlMessage = `
|
||||||
|
<p>一个新的友链申请已提交,以下是可直接复制到项目中的配置:</p>
|
||||||
|
<pre style="background: #f5f5f5; padding: 12px; border-radius: 4px; overflow: auto;">
|
||||||
|
<code>${friendEntry}</code>
|
||||||
|
</pre>
|
||||||
|
<hr style="margin: 20px 0;" />
|
||||||
|
<p><strong>申请者信息:</strong></p>
|
||||||
<p><strong>名称:</strong>${ensureValue(name)}</p>
|
<p><strong>名称:</strong>${ensureValue(name)}</p>
|
||||||
<p><strong>邮箱:</strong>${ensureValue(email)}</p>
|
<p><strong>邮箱:</strong>${ensureValue(email)}</p>
|
||||||
<p><strong>站点:</strong><a href="${ensureValue(url)}">${ensureValue(url)}</a></p>
|
<p><strong>站点:</strong><a href="${ensureValue(url)}">${ensureValue(url)}</a></p>
|
||||||
<p><strong>描述:</strong>${ensureValue(desc)}</p>
|
<p><strong>描述:</strong>${ensureValue(desc)}</p>
|
||||||
<p><strong>头像:</strong>${ensureValue(avatar)}</p>
|
<p><strong>头像:</strong>${ensureValue(avatar)}</p>
|
||||||
|
<p><strong>想说的话:</strong>${ensureValue(message)}</p>
|
||||||
<p><strong>时间:</strong>${new Date().toISOString()}</p>
|
<p><strong>时间:</strong>${new Date().toISOString()}</p>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"framework": "vite",
|
"buildCommand": "nuxt generate",
|
||||||
"routes": [
|
"routes": [
|
||||||
{
|
{
|
||||||
"src": "/api/(.*)",
|
"src": "/api/(.*)",
|
||||||
|
|||||||
Reference in New Issue
Block a user