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 }],
|
||||
},
|
||||
},
|
||||
nitro: {
|
||||
prerender: {
|
||||
crawlLinks: true,
|
||||
routes: ["/sitemap.xml", "/rss.xml"],
|
||||
},
|
||||
},
|
||||
// nitro: {
|
||||
// prerender: {
|
||||
// crawlLinks: true,
|
||||
// routes: ["/sitemap.xml", "/rss.xml"],
|
||||
// },
|
||||
// },
|
||||
runtimeConfig: {
|
||||
smtpHost: process.env.SMTP_HOST ?? "",
|
||||
smtpPort: Number(process.env.SMTP_PORT ?? 465),
|
||||
|
||||
@@ -26,6 +26,13 @@
|
||||
头像链接
|
||||
<input v-model="form.avatar" type="url" placeholder="可选,展示头像" />
|
||||
</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">
|
||||
<button type="submit" class="primary" :disabled="loading">
|
||||
{{ loading ? "提交中..." : "提交申请" }}
|
||||
@@ -75,6 +82,7 @@ const form = reactive({
|
||||
desc: "",
|
||||
email: "",
|
||||
avatar: "",
|
||||
message: "",
|
||||
});
|
||||
const displayedFriends = ref([]);
|
||||
|
||||
@@ -108,6 +116,7 @@ const submitForm = async () => {
|
||||
desc: form.desc,
|
||||
email: form.email,
|
||||
avatar: form.avatar,
|
||||
message: form.message,
|
||||
}),
|
||||
});
|
||||
if (!resp.ok) throw new Error("send failed");
|
||||
@@ -192,15 +201,41 @@ h2 {
|
||||
color: inherit;
|
||||
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);
|
||||
}
|
||||
.friend-form input:focus {
|
||||
.friend-form input:focus,
|
||||
.friend-form textarea:focus {
|
||||
outline: none;
|
||||
border-color: rgba(124, 193, 255, 0.8);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
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 {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
|
||||
@@ -19,6 +19,7 @@ type SendMailPayload = {
|
||||
desc?: string;
|
||||
email?: string;
|
||||
avatar?: string;
|
||||
message?: string;
|
||||
};
|
||||
|
||||
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 { name, url, desc, email, avatar } = payload;
|
||||
const { name, url, desc, email, avatar, message } = payload;
|
||||
|
||||
if (!name?.trim() || !url?.trim() || !email?.trim()) {
|
||||
throw createError({
|
||||
@@ -45,15 +46,7 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
|
||||
const config = useRuntimeConfig() as MailConfig;
|
||||
const {
|
||||
smtpHost,
|
||||
smtpPort: configSmtpPort,
|
||||
smtpUser,
|
||||
smtpPass,
|
||||
senderEmail,
|
||||
adminEmail,
|
||||
smtpSecure,
|
||||
} = config;
|
||||
const { smtpHost, smtpPort: configSmtpPort, smtpUser, smtpPass, senderEmail, adminEmail, smtpSecure } = config;
|
||||
|
||||
const smtpPort = Number(configSmtpPort ?? 465);
|
||||
if (!smtpHost || !smtpUser || !smtpPass || !senderEmail || !adminEmail) {
|
||||
@@ -72,12 +65,26 @@ export default defineEventHandler(async (event) => {
|
||||
};
|
||||
|
||||
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 = `
|
||||
<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(email)}</p>
|
||||
<p><strong>站点:</strong><a href="${ensureValue(url)}">${ensureValue(url)}</a></p>
|
||||
<p><strong>描述:</strong>${ensureValue(desc)}</p>
|
||||
<p><strong>头像:</strong>${ensureValue(avatar)}</p>
|
||||
<p><strong>想说的话:</strong>${ensureValue(message)}</p>
|
||||
<p><strong>时间:</strong>${new Date().toISOString()}</p>
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"framework": "vite",
|
||||
"buildCommand": "nuxt generate",
|
||||
"routes": [
|
||||
{
|
||||
"src": "/api/(.*)",
|
||||
|
||||
Reference in New Issue
Block a user