fix: 添加邮箱出题页面事件

This commit is contained in:
陆光LG
2025-08-17 20:03:19 +08:00
parent f148ea9938
commit 59b659f77b
17 changed files with 1160 additions and 60 deletions

View File

@@ -0,0 +1,92 @@
# Email组件外部表格保存功能测试说明
## 功能概述
已为Email组件实现了模仿Setting组件的外部表格保存功能。当用户在Email组件中进行设置时配置数据会自动保存到store中当关闭弹窗时外部的EmailForm会从store中获取这些数据并显示在表格中。
## 实现细节
### 1. 创建了Email Store (`src/store/modules/email.ts`)
- `emailFormList`: 存储邮件配置数据的数组
- `addEmailData()`: 添加邮件配置数据
- `updateEmailData()`: 更新邮件配置数据
- `removeEmailData()`: 删除邮件配置数据
- `clearEmailData()`: 清空所有邮件配置数据
### 2. 创建了Email消息发送函数 (`src/components/Email/index.ts`)
- `sendEmailMsg()`: 将邮件设置数据保存到store中
- 格式化数据支持boolean类型显示为"打开/关闭",其他类型直接显示值
- 数据结构:`{ contentIn: "设置描述", content: "category@key@value" }`
- 避免重复相同category@key的数据会被更新而不是重复添加
### 3. 修改了Email Setting组件 (`src/components/Email/components/setting.vue`)
- 导入了`sendEmailMsg`函数
- 为所有设置项的变更事件添加了数据保存调用:
- 语言设置:`common@language@value`
- 文字大小:`common@fontSize@value`
- 邮件数量:`common@emailCount@value`
- 邮件选项:`common@checkList@value`
- 天气显示:`common@weather@value`
- 生日提醒:`common@birthdayRemind@value`
- 邮件昵称:`account@nickname@value`
- 生日信息:`account@birthYear/birthMonth/birthDay@value`
- 生日可见性:`account@birthdayVisible@value`
- 默认账户:`account@defaultAccount@value`
### 4. 修改了Email子组件 (`src/components/Email/children/components/skinSettings.vue`)
- 为皮肤设置功能添加了数据保存:
- 选择皮肤:`skin@selectedSkin@value`
- 应用皮肤:`skin@appliedSkin@value`
- 恢复默认:`skin@resetSkin@default`
### 5. 修改了EmailForm组件 (`src/views/paper/question/EmailForm.vue`)
- 导入了`useEmailStore`
- 添加了`handleEmailForm()`函数在dialog关闭时从store获取数据
- 修改了dialog的`@close`事件,绑定到`handleEmailForm`
- 调整了表格显示:
- 将"试题考点"改为"邮件配置"
- 将"考点"列改为"配置项"列
- 将"权值"列改为"配置值"列
- 将"添加"按钮改为"设置"按钮
## 使用流程
1. 用户在EmailForm中点击"设置"按钮
2. 打开Email组件的设置弹窗
3. 用户在Email组件中进行各种设置语言、皮肤、账户等
4. 每次设置都会通过`sendEmailMsg()`保存到`emailStore.emailFormList`
5. 用户关闭弹窗时,触发`handleEmailForm()`函数
6. `handleEmailForm()`从store中获取数据并更新外部表格`list.value`
7. 表格显示格式化的配置信息,如:
- "设置邮件界面语言: 中文" | "common@language@zh_cn"
- "设置邮件应用皮肤: default" | "skin@appliedSkin@default"
- "设置邮件邮件昵称: demo" | "account@nickname@demo"
## 数据格式说明
每个配置项在store中的数据格式
```javascript
{
contentIn: "设置邮件界面语言: 中文", // 用户友好的描述
content: "common@language@zh_cn" // 结构化的数据标识
}
```
## 测试验证
可以按以下步骤测试功能:
1. 打开EmailForm页面
2. 点击"邮件配置"标签页中的"设置"按钮
3. 在Email组件中修改各种设置语言、皮肤等
4. 关闭设置弹窗
5. 检查外部表格是否显示了相应的配置项
6. 通过浏览器开发者工具查看console.log输出确认数据保存
这样就完成了Email组件的外部表格保存功能与Setting组件的实现模式完全一致。

View File

@@ -0,0 +1,34 @@
<template>
<div class="anti-spam-page">
<div class="outer-frame">
<div class="content">
<div class="title">反垃圾</div>
<p>此功能暂未开放敬请期待</p>
</div>
</div>
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.anti-spam-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="placeholder-page"
><div class="outer-frame"
><div class="content"
><div class="title">体验室</div><p>此功能暂未开放敬请期待</p></div
></div
></div
>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.placeholder-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="placeholder-page"
><div class="outer-frame"
><div class="content"
><div class="title">文件夹和标签</div><p>此功能暂未开放敬请期待</p></div
></div
></div
>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.placeholder-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="placeholder-page"
><div class="outer-frame"
><div class="content"
><div class="title">信纸</div><p>此功能暂未开放敬请期待</p></div
></div
></div
>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.placeholder-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,34 @@
<template>
<div class="mail-rules-page">
<div class="outer-frame">
<div class="content">
<div class="title">收信规则</div>
<p>此功能暂未开放敬请期待</p>
</div>
</div>
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.mail-rules-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="placeholder-page"
><div class="outer-frame"
><div class="content"
><div class="title">其他邮箱</div><p>此功能暂未开放敬请期待</p></div
></div
></div
>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.placeholder-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,160 @@
<template>
<div class="register-english-page">
<div class="outer-frame">
<div class="content">
<div class="title">注册英文邮箱账号</div>
<div class="description">
<p>你可以注册一个英文邮箱账号例如john@qq.com这将使你的邮箱地址更简洁专业</p>
</div>
<el-form :model="form" label-width="120px" style="margin-top: 20px">
<el-form-item label="英文账号:">
<div class="flex items-center">
<el-input
v-model="form.englishName"
placeholder="请输入英文账号名"
@input="checkAvailability"
/>
<span style="margin-left: 8px">@qq.com</span>
</div>
<p class="hint">只能使用英文字母和数字长度在3-16位之间</p>
</el-form-item>
<el-form-item label="可用性:">
<div class="availability-status">
<span v-if="checkingAvailability" class="checking">检查中...</span>
<span v-else-if="isAvailable === true" class="available"> 该账号可用</span>
<span v-else-if="isAvailable === false" class="unavailable"> 该账号已被占用</span>
<span v-else class="default">请输入账号名进行检查</span>
</div>
</el-form-item>
</el-form>
<div class="action-buttons">
<el-button type="primary" :disabled="!isAvailable" @click="handleRegister">
注册账号
</el-button>
<el-button @click="handleCancel">取消</el-button>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const form = ref({
englishName: ''
})
const checkingAvailability = ref(false)
const isAvailable = ref<boolean | null>(null)
// 检查账号可用性
const checkAvailability = async () => {
const name = form.value.englishName.trim()
if (!name) {
isAvailable.value = null
return
}
// 验证格式
if (!/^[a-zA-Z0-9]{3,16}$/.test(name)) {
isAvailable.value = false
return
}
checkingAvailability.value = true
// 模拟API调用
setTimeout(() => {
// 简单的模拟逻辑以admin、test等常见名称为已占用
const unavailableNames = ['admin', 'test', 'user', 'demo', 'root', 'system']
isAvailable.value = !unavailableNames.includes(name.toLowerCase())
checkingAvailability.value = false
}, 1000)
}
// 注册账号
const handleRegister = () => {
if (!isAvailable.value) {
ElMessage.error('请选择一个可用的账号名')
return
}
ElMessage.success(`英文邮箱账号 ${form.value.englishName}@qq.com 注册成功!`)
console.log('注册英文账号:', form.value.englishName)
// 这里可以添加实际的注册逻辑
setTimeout(() => {
handleCancel()
}, 2000)
}
// 取消注册
const handleCancel = () => {
form.value.englishName = ''
isAvailable.value = null
ElMessage.info('已取消注册')
}
</script>
<style lang="scss" scoped>
.register-english-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
.description {
margin-bottom: 20px;
color: #666;
}
.hint {
font-size: 12px;
color: #999;
margin-top: 4px;
}
.availability-status {
.checking {
color: #409eff;
}
.available {
color: #67c23a;
}
.unavailable {
color: #f56c6c;
}
.default {
color: #999;
}
}
.action-buttons {
margin-top: 24px;
display: flex;
gap: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,192 @@
<template>
<div class="skin-settings-page">
<div class="outer-frame">
<div class="content">
<div class="title">换肤设置</div>
<div class="description">
<p>个性化你的邮箱界面选择喜欢的主题皮肤</p>
</div>
<div class="skin-options">
<div
v-for="skin in skinOptions"
:key="skin.id"
class="skin-option"
:class="{ active: selectedSkin === skin.id }"
@click="selectSkin(skin.id)"
>
<div class="skin-preview">
<div :style="{ backgroundColor: skin.primaryColor }" class="color-bar"></div>
<div class="preview-content">
<div class="mock-header" :style="{ backgroundColor: skin.headerColor }"></div>
<div class="mock-content" :style="{ backgroundColor: skin.bgColor }"></div>
</div>
</div>
<div class="skin-name">{{ skin.name }}</div>
</div>
</div>
<div class="action-buttons">
<el-button type="primary" @click="applySkin">应用皮肤</el-button>
<el-button @click="resetToDefault">恢复默认</el-button>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { sendEmailMsg } from '../../index'
const name = ref('邮件')
const selectedSkin = ref('default')
const skinOptions = [
{
id: 'default',
name: '经典蓝',
primaryColor: '#409eff',
headerColor: '#f5f7fa',
bgColor: '#ffffff'
},
{
id: 'green',
name: '清新绿',
primaryColor: '#67c23a',
headerColor: '#f0f9ff',
bgColor: '#ffffff'
},
{
id: 'purple',
name: '典雅紫',
primaryColor: '#722ed1',
headerColor: '#f9f0ff',
bgColor: '#ffffff'
},
{
id: 'red',
name: '热情红',
primaryColor: '#f5222d',
headerColor: '#fff1f0',
bgColor: '#ffffff'
},
{
id: 'dark',
name: '深邃黑',
primaryColor: '#434343',
headerColor: '#2f2f2f',
bgColor: '#1f1f1f'
}
]
const selectSkin = (skinId: string) => {
selectedSkin.value = skinId
sendEmailMsg(name.value, '选择皮肤', 'skin', 'selectedSkin', skinId)
}
const applySkin = () => {
const skin = skinOptions.find((s) => s.id === selectedSkin.value)
sendEmailMsg(name.value, '应用皮肤', 'skin', 'appliedSkin', selectedSkin.value)
ElMessage.success(`已应用 ${skin?.name} 皮肤`)
console.log('应用皮肤:', selectedSkin.value)
}
const resetToDefault = () => {
selectedSkin.value = 'default'
sendEmailMsg(name.value, '恢复默认皮肤', 'skin', 'resetSkin', 'default')
ElMessage.success('已恢复默认皮肤')
}
</script>
<style lang="scss" scoped>
.skin-settings-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
.description {
margin-bottom: 20px;
color: #666;
}
.skin-options {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin: 24px 0;
.skin-option {
width: 120px;
cursor: pointer;
border: 2px solid transparent;
border-radius: 8px;
padding: 8px;
transition: all 0.2s;
&:hover {
border-color: #409eff;
}
&.active {
border-color: #409eff;
background-color: #f0f9ff;
}
.skin-preview {
position: relative;
height: 80px;
border-radius: 4px;
overflow: hidden;
border: 1px solid #e4e7ed;
.color-bar {
height: 8px;
width: 100%;
}
.preview-content {
height: 72px;
.mock-header {
height: 20px;
width: 100%;
}
.mock-content {
height: 52px;
width: 100%;
}
}
}
.skin-name {
text-align: center;
margin-top: 8px;
font-size: 14px;
color: #333;
}
}
}
.action-buttons {
display: flex;
gap: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="placeholder-page"
><div class="outer-frame"
><div class="content"
><div class="title">我的订阅</div><p>此功能暂未开放敬请期待</p></div
></div
></div
>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.placeholder-page {
.outer-frame {
background: #ffffff;
border-radius: 4px;
box-shadow:
0px 1.6px 3.6px rgba(0, 0, 0, 0.13),
0px 0px 2.9px rgba(0, 0, 0, 0.11);
.content {
padding: 24px;
.title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
}
}
}
</style>

View File

@@ -0,0 +1,72 @@
<template>
<div class="email-children-page common-page">
<div class="back flex" style="margin-bottom: 20px">
<img src="../../Setting/img/back_icon_blue.png" @click="goBack" />
<p style="color: #0072c9">{{ parentTitle }}</p>
&nbsp;&nbsp;/&nbsp;&nbsp;
<p style="color: #262626">{{ childTitle }}</p>
</div>
<RegisterEnglish v-if="childType === 'registerEnglish'" />
<SkinSettings v-if="childType === 'skin'" />
<MailRules v-if="childType === 'rules'" />
<AntiSpam v-if="childType === 'spam'" />
<FolderSettings v-if="childType === 'folders'" />
<OtherMailbox v-if="childType === 'other'" />
<Subscription v-if="childType === 'subscribe'" />
<Letterhead v-if="childType === 'letter'" />
<ExperimentLab v-if="childType === 'trial'" />
</div>
</template>
<script lang="ts" setup>
import RegisterEnglish from './components/registerEnglish.vue'
import SkinSettings from './components/skinSettings.vue'
import MailRules from './components/mailRules.vue'
import AntiSpam from './components/antiSpam.vue'
import FolderSettings from './components/folderSettings.vue'
import OtherMailbox from './components/otherMailbox.vue'
import Subscription from './components/subscription.vue'
import Letterhead from './components/letterhead.vue'
import ExperimentLab from './components/experimentLab.vue'
const props = defineProps({
parentTitle: {
type: String,
default: ''
},
childTitle: {
type: String,
default: ''
},
childType: {
type: String,
default: ''
}
})
const emit = defineEmits(['back'])
const goBack = () => {
emit('back')
}
</script>
<style lang="scss" scoped>
.email-children-page {
padding: 20px;
.back {
cursor: default;
font-weight: 600;
font-size: 20px;
line-height: 28px;
> img {
width: 20px;
height: 20px;
margin-right: 16px;
cursor: pointer;
}
}
}
</style>

View File

@@ -5,14 +5,14 @@
<el-tabs v-model="activeName" type="border-card" @tab-click="handleClick">
<el-tab-pane label="常规" name="common" />
<el-tab-pane label="账户" name="account" />
<el-tab-pane label="换肤" name="skin" />
<el-tab-pane label="收信规则" name="rules" />
<el-tab-pane label="反垃圾" name="spam" />
<el-tab-pane label="文件夹和标签" name="folders" />
<el-tab-pane label="其他邮箱" name="other" />
<el-tab-pane label="我的订阅" name="subscribe" />
<el-tab-pane label="信纸" name="letter" />
<el-tab-pane label="体验室" name="trial" />
<el-tab-pane label="换肤" name="skin" :disabled="true" />
<el-tab-pane label="收信规则" name="rules" :disabled="true" />
<el-tab-pane label="反垃圾" name="spam" :disabled="true" />
<el-tab-pane label="文件夹和标签" name="folders" :disabled="true" />
<el-tab-pane label="其他邮箱" name="other" :disabled="true" />
<el-tab-pane label="我的订阅" name="subscribe" :disabled="true" />
<el-tab-pane label="信纸" name="letter" :disabled="true" />
<el-tab-pane label="体验室" name="trial" :disabled="true" />
</el-tabs>
</div>
@@ -21,13 +21,14 @@
<el-form :model="commonForm" label-width="200px">
<div class="form-title">显示</div>
<el-form-item label="语言:" prop="language">
<el-select v-model="commonForm.language">
<el-option label="自动选择" value="anto " />
<el-select v-model="commonForm.language" @change="handleLanguageChange">
<el-option label="自动选择" value="auto" />
<el-option label="中文" value="zh_cn" />
<el-option label="English" value="en" />
</el-select>
</el-form-item>
<el-form-item label="文字大小:" prop="size">
<el-radio-group v-model="commonForm.size">
<el-radio-group v-model="commonForm.size" @change="handleFontSizeChange">
<el-radio :label="0">标准</el-radio>
<el-radio :label="1">中号</el-radio>
<el-radio :label="2">大号</el-radio>
@@ -36,30 +37,37 @@
<el-form-item label="在邮件列表中:">
<div>
每页显示 &nbsp;
<el-select v-model="commonForm.number">
<el-select v-model="commonForm.number" @change="handleEmailCountChange">
<el-option label="25" value="25" />
<el-option label="50" value="50" />
<el-option label="100" value="100" />
</el-select>
&nbsp;封邮件
</div>
<el-checkbox-group v-model="commonForm.checkList">
<el-checkbox-group v-model="commonForm.checkList" @change="handleCheckboxChange">
<el-checkbox label="main">显示邮件摘要</el-checkbox>
<el-checkbox label="size">显示邮件大小</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="在首页上:">
<el-checkbox v-model="commonForm.checked1">显示天气</el-checkbox>
<el-checkbox v-model="commonForm.checked1" @change="handleWeatherChange"
>显示天气</el-checkbox
>
<div>
所在地 &nbsp;
<el-select v-model="commonForm.addr">
<el-option label="25" value="25" />
<el-option label="50" value="50" />
<el-option label="北京" value="beijing" />
<el-option label="上海" value="shanghai" />
<el-option label="广州" value="guangzhou" />
<el-option label="深圳" value="shenzhen" />
</el-select>
<p style="color: #b4b4b4"
>自动选择系统将根据你的IP自动显示你所在的城市的今明两天天气情况</p
>
</div>
<el-checkbox v-model="commonForm.checked2">在首页显示好友的生日提醒</el-checkbox>
<el-checkbox v-model="commonForm.checked2" @change="handleBirthdayChange"
>在首页显示好友的生日提醒</el-checkbox
>
</el-form-item>
</el-form>
</div>
@@ -67,14 +75,22 @@
<el-form :model="accountForm" label-width="200px">
<div class="form-title">显示</div>
<el-form-item label="默认账户昵称:">
<el-input v-model="accountForm.name" />
<el-input
v-model="accountForm.name"
@blur="handleNicknameChange"
@keyup.enter="handleNicknameChange"
/>
<p style="color: #b4b4b4"
>你发出的所有邮件发件人将显示你的邮件昵称你还可以给每个账户单独设置昵称</p
>
</el-form-item>
<el-form-item label="我的生日:">
<div style="margin-bottom: 10px">
<el-select v-model="accountForm.value1" style="margin-right: 5px">
<el-select
v-model="accountForm.value1"
style="margin-right: 5px"
@change="handleBirthdayYearChange"
>
<el-option
v-for="item in options1"
:key="item.value"
@@ -82,7 +98,11 @@
:value="item.value"
/>
</el-select>
<el-select v-model="accountForm.value2" style="margin-right: 5px">
<el-select
v-model="accountForm.value2"
style="margin-right: 5px"
@change="handleBirthdayMonthChange"
>
<el-option
v-for="item in options2"
:key="item.value"
@@ -91,7 +111,7 @@
/>
</el-select>
<el-select v-model="accountForm.value3">
<el-select v-model="accountForm.value3" @change="handleBirthdayDayChange">
<el-option
v-for="item in options3"
:key="item.value"
@@ -101,14 +121,20 @@
</el-select>
</div>
<el-checkbox v-model="accountForm.checked3">好友可见我的生日</el-checkbox>
<el-checkbox v-model="accountForm.checked3" @change="handleBirthdayVisibilityChange"
>好友可见我的生日</el-checkbox
>
<p style="color: #b4b4b4">快过生日时你的好友可以在邮箱首页看到你的生日信息</p>
</el-form-item>
<div class="form-title">默认发信帐号</div>
<el-form-item>
<el-select v-model="accountForm.value4" class="account-select">
<el-select
v-model="accountForm.value4"
class="account-select"
@change="handleDefaultAccountChange"
>
<el-option
v-for="item in options1"
v-for="item in defaultAccountOptions"
:key="item.value"
:label="item.label"
:value="item.value"
@@ -117,7 +143,7 @@
</el-form-item>
<div class="form-title">邮箱帐号</div>
<el-form-item label="英文邮箱账号:">
<el-button>注册@qq.com英文账号</el-button>
<el-button @click="handleRegisterEnglishAccount">注册@qq.com英文账号</el-button>
<p style="color: #b4b4b4"
>你还可以注册一个英文邮箱账号例如chen@qq.com并以此登录</p
>
@@ -129,8 +155,8 @@
<div class="foot">
<div class="btn-line">
<div class="flex">
<el-button type="info">保存更改</el-button>
<el-button type="info">取消</el-button>
<el-button type="info" @click="handleSave">保存更改</el-button>
<el-button type="info" @click="handleCancel">取消</el-button>
</div>
</div>
</div>
@@ -139,12 +165,211 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { sendEmailMsg } from '../index'
const emit = defineEmits(['routeHandle'])
const name = ref('邮件')
let disabledTabs = ['skin', 'rules', 'spam', 'folders', 'other', 'subscribe', 'letter', 'trial']
const activeName = ref('common')
const handleClick = (tab: any) => {
activeName.value = tab.paneName.name
const tabName = tab.paneName || tab.props?.name
if (disabledTabs.includes(tabName)) {
// 对于禁用的选项卡,跳转到子页面
const tabTitleMap: { [key: string]: string } = {
skin: '换肤',
rules: '收信规则',
spam: '反垃圾',
folders: '文件夹和标签',
other: '其他邮箱',
subscribe: '我的订阅',
letter: '信纸',
trial: '体验室'
}
const title = tabTitleMap[tabName] || tabName
goChildPage(tabName, '邮箱设置', title)
return
}
activeName.value = tabName
}
// 子页面跳转处理
const goChildPage = (val: string, pTitle: string, cTitle: string) => {
emit('routeHandle', val, pTitle, cTitle)
}
// 保存更改
const handleSave = () => {
ElMessage.success('设置已保存')
console.log('保存邮箱设置', {
activeName: activeName.value,
commonForm: commonForm.value,
accountForm: accountForm.value
})
}
// 取消更改
const handleCancel = () => {
ElMessage.info('已取消更改')
// 重置表单到初始状态
resetForms()
}
// 重置表单
const resetForms = () => {
commonForm.value = {
language: '',
size: 0,
number: '25',
checkList: [],
checked1: false,
addr: '',
checked2: false
}
accountForm.value = {
name: 'demo',
value1: '',
value2: '',
value3: '',
checked3: false,
value4: ''
}
}
// 注册英文账号
const handleRegisterEnglishAccount = () => {
ElMessage.info('正在跳转到英文账号注册页面...')
goChildPage('registerEnglish', '邮箱设置', '注册英文账号')
}
// 语言变更处理
const handleLanguageChange = (value: string) => {
sendEmailMsg(name.value, '界面语言', 'common', 'language', value)
ElMessage.success(
`语言已切换到: ${value === 'auto' ? '自动选择' : value === 'zh_cn' ? '中文' : 'English'}`
)
console.log('语言变更:', value)
}
// 文字大小变更处理
const handleFontSizeChange = (value: number) => {
const sizeText = ['标准', '中号', '大号'][value]
sendEmailMsg(name.value, '文字大小', 'common', 'fontSize', value)
ElMessage.success(`文字大小已设置为: ${sizeText}`)
console.log('文字大小变更:', value, sizeText)
}
// 邮件数量变更处理
const handleEmailCountChange = (value: string) => {
sendEmailMsg(name.value, '每页显示邮件数', 'common', 'emailCount', value)
ElMessage.success(`每页显示邮件数已设置为: ${value}`)
console.log('邮件数量变更:', value)
}
// 复选框变更处理
const handleCheckboxChange = (checkList: string[]) => {
sendEmailMsg(name.value, '邮件选项', 'common', 'checkList', checkList.join(','))
console.log('复选框变更:', checkList)
}
// 天气显示变更处理
const handleWeatherChange = (value: boolean) => {
sendEmailMsg(name.value, '天气显示', 'common', 'weather', value)
ElMessage.success(value ? '已开启天气显示' : '已关闭天气显示')
console.log('天气显示变更:', value)
}
// 生日提醒变更处理
const handleBirthdayChange = (value: boolean) => {
sendEmailMsg(name.value, '生日提醒', 'common', 'birthdayRemind', value)
ElMessage.success(value ? '已开启生日提醒' : '已关闭生日提醒')
console.log('生日提醒变更:', value)
}
// 昵称变更处理
const handleNicknameChange = () => {
sendEmailMsg(name.value, '邮件昵称', 'account', 'nickname', accountForm.value.name)
ElMessage.success(`昵称已更新为: ${accountForm.value.name}`)
console.log('昵称变更:', accountForm.value.name)
}
// 生日年份变更处理
const handleBirthdayYearChange = (value: string) => {
sendEmailMsg(name.value, '生日年份', 'account', 'birthYear', value)
console.log('生日年份变更:', value)
}
// 生日月份变更处理
const handleBirthdayMonthChange = (value: string) => {
sendEmailMsg(name.value, '生日月份', 'account', 'birthMonth', value)
console.log('生日月份变更:', value)
}
// 生日日期变更处理
const handleBirthdayDayChange = (value: string) => {
sendEmailMsg(name.value, '生日日期', 'account', 'birthDay', value)
console.log('生日日期变更:', value)
}
// 生日可见性变更处理
const handleBirthdayVisibilityChange = (value: boolean) => {
sendEmailMsg(name.value, '生日可见性', 'account', 'birthdayVisible', value)
ElMessage.success(value ? '好友现在可以看到你的生日' : '已隐藏生日信息')
console.log('生日可见性变更:', value)
}
// 默认账户变更处理
const handleDefaultAccountChange = (value: string) => {
sendEmailMsg(name.value, '默认发信账户', 'account', 'defaultAccount', value)
ElMessage.success(`默认发信账户已设置为: ${value}`)
console.log('默认账户变更:', value)
}
// 默认账户选项
const defaultAccountOptions = [
{ label: 'demo@qq.com', value: 'demo@qq.com' },
{ label: '123456@qq.com', value: '123456@qq.com' }
]
// 生成年份选项
const generateYears = () => {
const currentYear = new Date().getFullYear()
const years: Array<{ label: string; value: string }> = []
for (let i = currentYear; i >= currentYear - 100; i--) {
years.push({ label: i.toString(), value: i.toString() })
}
return years
}
// 生成月份选项
const generateMonths = () => {
const months: Array<{ label: string; value: string }> = []
for (let i = 1; i <= 12; i++) {
months.push({ label: i.toString(), value: i.toString() })
}
return months
}
// 生成日期选项
const generateDays = () => {
const days: Array<{ label: string; value: string }> = []
for (let i = 1; i <= 31; i++) {
days.push({ label: i.toString(), value: i.toString() })
}
return days
}
// 初始化选项数据
const options1 = generateYears()
const options2 = generateMonths()
const options3 = generateDays()
const commonForm = ref({
language: '',
size: 0,
@@ -162,9 +387,6 @@ const accountForm = ref({
checked3: false,
value4: ''
})
const options1 = []
const options2 = []
const options3 = []
</script>
<style lang="scss" scoped>

View File

@@ -0,0 +1,45 @@
import { useEmailStore } from '@/store/modules/email'
/**
* 通用的邮件消息发送函数,用于将设置更改添加到全局状态
* @param pageName 设置页面的顶级标题, e.g., '邮件'
* @param description 更改项的具体描述, e.g., '界面语言'
* @param category 更改项的分类, e.g., 'common'
* @param key 更改项的唯一标识, e.g., 'language'
* @param value 更改项的值 (可以是 boolean, string, number 等)
*/
export function sendEmailMsg(pageName: string, description: string, category: string, key: string, value: any) {
const emailStore = useEmailStore()
let displayValue: string;
// 根据值的类型格式化显示文本
if (typeof value === 'boolean') {
displayValue = value ? '打开' : '关闭';
} else {
displayValue = value;
}
// 拼接 contentIn 字符串
const contentIn = `设置${pageName}${description}: ${displayValue}`
// 拼接 content 字符串
const content = `${category}@${key}@${value}`
// 创建数据对象并添加到 store
const data = { contentIn, content };
// 为了避免重复,可以先查找并更新,如果不存在再添加
const existingIndex = emailStore.emailFormList.findIndex(item => item.content.startsWith(`${category}@${key}@`));
if (existingIndex !== -1) {
// 如果已存在,则替换
emailStore.emailFormList[existingIndex] = data;
} else {
// 如果不存在,则添加
emailStore.emailFormList.push(data);
}
console.log('Updated email settings data:', data);
console.log('Current email form list:', emailStore.emailFormList);
}

View File

@@ -8,14 +8,17 @@
<div class="text">
<p style="font-size: 12px">demo(123456@qq.com)</p>
<div style="font-size: 12px; margin-top: 5px">
<span style="cursor: pointer;">邮箱首页</span> | <span style="cursor: pointer;" @click="setting">设置-换肤</span>
<span style="cursor: pointer">邮箱首页</span> |
<span style="cursor: pointer" @click="setting">设置-换肤</span>
</div>
</div>
</div>
<div class="right">
<div class="text">
<div style="font-size: 12px">
<span style="cursor: pointer;">反馈建议</span> | <span style="cursor: pointer;">帮助中心</span> | <span style="cursor: pointer;" @click="exitEmail">退出</span>
<span style="cursor: pointer">反馈建议</span> |
<span style="cursor: pointer">帮助中心</span> |
<span style="cursor: pointer" @click="exitEmail">退出</span>
</div>
</div>
<el-input v-model="searchVal" placeholder="邮件全文搜索……" :prefix-icon="Search" />
@@ -68,10 +71,18 @@
</div>
</div>
<div class="operation">
<Home v-if="selectSidebar === 'home'" />
<Setting v-if="selectSidebar === 'setting'" />
<Write v-if="selectSidebar === '写信'" />
<Sent v-if="selectSidebar === '已发送'" />
<Home v-if="selectSidebar === 'home' && !goChild" />
<Setting v-if="selectSidebar === 'setting' && !goChild" @route-handle="goChildHandle" />
<Write v-if="selectSidebar === '写信' && !goChild" />
<Sent v-if="selectSidebar === '已发送' && !goChild" />
<Children
v-if="goChild"
:parent-title="parentTitle"
:child-title="childTitle"
:child-type="childType"
@back="goBack"
/>
</div>
</div>
</div>
@@ -84,7 +95,8 @@ import Home from './components/home.vue'
import Setting from './components/setting.vue'
import Write from './components/write.vue'
import Sent from './components/sent.vue'
import { ElMessageBox } from 'element-plus'
import Children from './children/index.vue'
import { ElMessageBox, ElMessage } from 'element-plus'
import '../Setting/style/common.scss'
@@ -152,15 +164,51 @@ const exitEmail = () => {
cancelButtonText: '否(N)',
type: 'warning'
})
.then(() => {})
.catch(() => {})
.then(() => {
ElMessage.success('已退出邮箱')
})
.catch(() => {
ElMessage.info('取消退出')
})
}
// 子页面路由处理
const goChild = ref(false)
const parentTitle = ref('')
const childTitle = ref('')
const childType = ref('')
const goChildHandle = (val: string, pTitle: string, cTitle: string) => {
console.log('邮箱设置子页面跳转:', { val, pTitle, cTitle })
goChild.value = true
parentTitle.value = pTitle
childTitle.value = cTitle
childType.value = val
// 可以根据不同的子页面类型进行特定处理
switch (val) {
case 'registerEnglish':
ElMessage.info('正在打开英文账号注册页面...')
break
case 'skin':
ElMessage.info('正在打开换肤设置页面...')
break
default:
ElMessage.info(`正在打开${cTitle}页面...`)
break
}
}
const goBack = () => {
goChild.value = false
ElMessage.success('已返回设置主页')
}
</script>
<style lang="scss" scoped>
.email-page {
width: 100%;
height: 100%;
height: 600px;
overflow: hidden;
box-sizing: border-box;
display: flex;

View File

@@ -0,0 +1,38 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useEmailStore = defineStore('email', () => {
const emailFormList = ref<any[]>([])
// 添加邮件配置数据
const addEmailData = (data: any) => {
emailFormList.value.push(data)
}
// 更新邮件配置数据
const updateEmailData = (index: number, data: any) => {
if (index >= 0 && index < emailFormList.value.length) {
emailFormList.value[index] = data
}
}
// 删除邮件配置数据
const removeEmailData = (index: number) => {
if (index >= 0 && index < emailFormList.value.length) {
emailFormList.value.splice(index, 1)
}
}
// 清除所有 email 相关数据
const clearEmailData = () => {
emailFormList.value = []
}
return {
emailFormList,
addEmailData,
updateEmailData,
removeEmailData,
clearEmailData
}
})

View File

@@ -198,13 +198,13 @@
</div>
<div>
<el-checkbox
v-model="formData.questionScores.isResult"
v-model="formData.questionScores.isCompile"
label="使用测试用例"
size="large"
true-value="0"
false-value="1"
/>
<div v-if="formData.questionScores.isResult === '0'">
<div v-if="formData.questionScores.isCompile === '0'">
<div class="flex" style="margin-left: 20px">
测试用例得分比例
<el-input

View File

@@ -118,7 +118,7 @@
<el-tab-pane name="answer">
<template #label>
<div class="custom-tabs-label">
<p>试题考点</p>
<p>邮件配置</p>
<el-dropdown>
<span class="el-dropdown-link" @click.stop="false">
<div class="setting_icon"></div>
@@ -126,7 +126,7 @@
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>
<el-button @click="addEmailInfo">添加</el-button>
<el-button @click="addEmailInfo">设置</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</template>
@@ -141,8 +141,13 @@
@selection-change="handleSelectionChange"
>
<!-- <el-table-column type="selection" width="55" /> -->
<el-table-column label="考点" align="center" prop="contentIn" width="360px" />
<el-table-column label="权值" align="center" prop="scoreRate" width="100px" />
<el-table-column
label="配置项"
align="center"
prop="contentIn"
width="360px"
/>
<el-table-column label="配置值" align="center" prop="content" width="100px" />
<el-table-column label="操作" align="center" width="100px">
<template #default="scope">
<el-button type="primary" link @click="handleDelete(scope.row)">
@@ -278,7 +283,13 @@
</div>
<!-- 表单弹窗添加/修改 -->
<FileForm ref="FileRef" @success="handleUploadSuccess" />
<el-dialog v-model="dialogFormVisibleWordInfo" title="考点设置" width="1500px" style="overflow: scroll;">
<el-dialog
v-model="dialogFormVisibleWordInfo"
title="邮件设置"
width="1500px"
style="overflow: scroll"
@close="handleEmailForm"
>
<Email />
</el-dialog>
</template>
@@ -292,12 +303,15 @@ import Email from '@/components/Email/index.vue'
import * as SpecialtyApi from '@/api/points'
import { defaultProps, handleTree } from '@/utils/tree'
import { cloneDeep } from 'lodash-es'
import { useEmailStore } from '@/store/modules/email'
const emailStore = useEmailStore()
defineOptions({ name: 'WpsWordFrom' })
const wordPointsList = ref<Tree[]>([]) // 树形结构
const wordPointsInfoList = ref<Tree[]>([]) // 树形结构
const list = ref([]) // 列表的数
const list = ref<any[]>([]) // 列表的数
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const loading = ref(false) // 列表的加载中
@@ -306,7 +320,7 @@ const isLoading = ref(false)
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
const formData = ref<any>({
pointNamesVo: '',
chapteridDictTextVo: '',
content: '',
@@ -395,10 +409,14 @@ const documentList = ref([
])
const dialogFormVisibleWordInfo = ref(false)
const addEmailInfo = async () => {
dialogFormVisibleWordInfo.value = true
}
const handleEmailForm = () => {
list.value = [...emailStore.emailFormList]
// emailStore.clearEmailData() // 如果需要清空数据,可以取消注释
}
const handleDelete = (row) => {
console.log(row)
for (let i = 0; i < list.value.length; i++) {
@@ -519,15 +537,15 @@ const open = async (queryParams: any, type: string, id?: number) => {
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
// 转换函数:将大写字母 A-Z 映射为 0-25
const mappedNumber = computed(() => {
const char = radio.value.toUpperCase()
const code = char.charCodeAt(0)
if (code >= 65 && code <= 90) {
return code - 65
} else {
return '请输入 A-Z 的字母'
}
})
// const mappedNumber = computed(() => {
// const char = radio.value.toUpperCase()
// const code = char.charCodeAt(0)
// if (code >= 65 && code <= 90) {
// return code - 65
// } else {
// return '请输入 A-Z 的字母'
// }
// })
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {