Commit 266913ac by Sweet Zhang

解决刷新回到根目录下的的问题

parent 3b970b52
<template>
<div id="app" class="min-h-screen bg-gray-50 text-gray-800 flex flex-col">
<!-- 登录页面 -->
<LoginPage v-if="isLoginPage && !isAuthenticated" @login="handleLogin" />
<!-- 主应用布局 -->
<div v-else class="flex flex-1 h-screen">
<div class="flex flex-1 h-screen">
<!-- 侧边导航 -->
<Sidebar
:current-page="currentPage"
......@@ -52,7 +49,6 @@
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import LoginPage from './views/LoginPage.vue'
import Sidebar from './views/Sidebar.vue'
import MobileSidebar from './views/MobileSidebar.vue'
import { pageTitles } from '@/utils/menuConfig'
......@@ -61,8 +57,6 @@ const route = useRoute()
const router = useRouter()
// 状态管理
const isLoginPage = ref(true)
const isAuthenticated = ref(false)
const currentPage = ref('compose')
const showMobileMenu = ref(false)
const sidebarCollapsed = ref(false) // 新增:侧边栏折叠状态
......@@ -82,24 +76,21 @@ const toggleSidebar = () => {
sidebarCollapsed.value = !sidebarCollapsed.value
}
// 方法(移除页面切换相关方法)
const handleLogin = () => {
isAuthenticated.value = true
isLoginPage.value = false
/**登录成功后,跳转到写邮件页面 */
router.push('/compose')
}
// 退出登录处理
const handleLogout = () => {
isAuthenticated.value = false
isLoginPage.value = true
router.push('/login') // 退出后跳转到登录页面
// 清除本地存储的token
localStorage.removeItem('authToken')
// 跳转到登录页面
router.push('/login')
}
// 初始化
// 初始化 - 检查登录状态
onMounted(() => {
// 检查是否已登录(实际项目中应该检查本地存储或令牌)
if (isAuthenticated.value) {
// 检查是否已登录
const token = localStorage.getItem('authToken')
if (!token && route.path !== '/login') {
// 如果未登录且当前不在登录页面,重定向到登录页
router.push('/login')
}
})
</script>
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
history: createWebHistory('/yd-email/'),
routes: [
{
path: '/',
redirect: '/login',
name: 'home',
redirect: (to) => {
console.log('----', to.fullPath)
// 检查用户是否已登录
const token = localStorage.getItem('authToken')
console.log('----', token)
if (token) {
// 已登录,重定向到写邮件页面
return '/compose'
} else {
// 未登录,重定向到登录页面
return '/login'
}
},
},
{
path: '/compose',
......@@ -40,4 +53,28 @@ const router = createRouter({
],
})
// 添加路由守卫,实现条件导航
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('authToken')
// 如果用户访问登录页且已登录,重定向到首页
if (to.path === '/login' && token) {
next('/compose')
return
}
// 如果用户访问需要认证的页面且未登录,重定向到登录页
const publicPages = ['/login']
const authRequired = !publicPages.includes(to.path)
if (authRequired && !token) {
// 保存当前路径,登录后可跳转回来
localStorage.setItem('redirectPath', to.fullPath)
next('/login')
return
}
next()
})
export default router
......@@ -39,6 +39,7 @@ export interface Variable extends Pagination<Variable> {
variableNameCn?: string
variableNameEn?: string
description?: string
isGeneral?: number
}
// 变量模板类型
......
......@@ -36,6 +36,7 @@
:loading="loading"
size="large"
class="flex-auto"
@change="applyVariableTemplate"
>
<el-option value="">-- 选择模板 --</el-option>
<el-option
......@@ -141,30 +142,11 @@
<div class="border border-gray-300 rounded-md overflow-hidden">
<div class="bg-gray-50 p-2 border-b border-gray-300 flex flex-wrap gap-2">
<button
v-if="selectedVariableTemplate"
@click="showVariableSelector = true"
class="text-sm bg-blue-50 hover:bg-blue-100 text-blue-600 px-3 py-1 rounded border border-blue-200 transition-colors"
>
<i class="fas fa-plus"></i> 插入字段
</button>
<button
@click="emailForm.content += '{{name}}'"
class="text-sm bg-blue-50 hover:bg-blue-100 text-blue-600 px-3 py-1 rounded border border-blue-200 transition-colors"
>
<i class="fas fa-plus"></i> 收件人姓名
</button>
<button
@click="emailForm.content += '{{appellation}}'"
class="text-sm bg-blue-50 hover:bg-blue-100 text-blue-600 px-3 py-1 rounded border border-blue-200 transition-colors"
>
<i class="fas fa-plus"></i> 收件人称谓
</button>
<button
@click="emailForm.content += '{{compantName}}'"
class="text-sm bg-blue-50 hover:bg-blue-100 text-blue-600 px-3 py-1 rounded border border-blue-200 transition-colors"
>
<i class="fas fa-plus"></i> 公司
</button>
</div>
<textarea
v-model="emailForm.content"
......@@ -274,7 +256,14 @@ import ImportRecordManager from './ImportRecordManager.vue'
import ImportDialog from './ImportDialog.vue'
import type { Sender, Contact, Variable, VariableTemplate, ImportRecord, EmailForm } from '../types'
// 引入api接口,获取联系人列表、发件人列表、变量模版列表
import { senderApi, variableGroupApi, contactApi, sendEmailApi, importContactApi } from '../api/api'
import {
senderApi,
variableGroupApi,
contactApi,
sendEmailApi,
variableApi,
importContactApi,
} from '../api/api'
const dialogVisible = ref(false)
const handleClose = (done: () => void) => {
......@@ -411,6 +400,7 @@ onMounted(() => {
getSenders()
getContacts()
getGroups()
applyVariableTemplate()
})
const loading = ref(false)
const variablePrefix = '{{'
......@@ -418,13 +408,20 @@ const variableNextfix = '}}'
// 通过变量模版查询变量列表
const applyVariableTemplate = () => {
if (!selectedVariableTemplate.value) return
if (selectedVariableTemplate.value.variableGroupBizId) {
if (selectedVariableTemplate.value?.variableGroupBizId) {
variableGroupApi
.getEmailVariableGroupDetail(selectedVariableTemplate.value.variableGroupBizId)
.then((res) => {
variables.value = res.data?.emailVariableDtoList || []
})
} else {
variableApi
.getEmailVariableList({
isGeneral: 1,
})
.then((res) => {
variables.value = res.data?.records || []
})
}
}
// 插入变量方法
......@@ -613,6 +610,7 @@ const getImportedContacts = (sessionId?: string, type?: string) => {
import { ElMessage } from 'element-plus'
import FileUploadComponent from '@/components/FileUploadComponent.vue'
import { UploadResult } from '@/utils/fileUpload'
import { debug } from 'console'
// 上传成功的文件
const uploadedFiles = ref<any[]>([])
......
<template>
<div
class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
v-if="visible"
>
<div class="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[80vh] flex flex-col">
<div class="p-4 border-b border-gray-200 flex justify-between items-center">
<h3 class="text-lg font-semibold">
{{ editingTemplateId ? '编辑变量模板' : '创建变量模板' }}
</h3>
<button @click="closeTemplateModal">
<i class="fas fa-times text-gray-500"></i>
</button>
</div>
<div class="p-4 flex-1 overflow-y-auto">
<div class="mb-4">
<label class="block text-gray-700 mb-1 text-sm">模板名称 *</label>
<input
v-model="templateForm.groupName"
type="text"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-1 text-sm">模板描述</label>
<textarea
v-model="templateForm.description"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
rows="2"
></textarea>
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-1 text-sm">选择变量</label>
<div
class="space-y-2 max-h-[300px] overflow-y-auto p-2 border border-gray-200 rounded-md"
>
<!-- 增加搜索框 -->
<input
type="text"
v-model="searchQuery"
placeholder="搜索变量"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
<div
v-for="variable in variables"
:key="variable.variableBizId"
class="flex items-center p-2 hover:bg-blue-50 rounded"
>
<input
type="checkbox"
:id="'template-var-' + variable.variableBizId"
:checked="templateForm.variableBizIdList?.includes(variable.variableBizId || '')"
class="mr-3"
@change="toggleTemplateVariable(variable.variableBizId || '')"
/>
<label for="'template-var-' + variable.variableBizId">
<div class="text-sm text-gray-500">{{ variable.variableNameCn }}</div>
<div class="font-medium font-mono text-sm">
{{ variablePrefix }}{{ variable.variableNameEn }}{{ variableNextfix }}
</div>
</label>
</div>
</div>
<div v-if="variables.length === 0" class="p-4 text-center text-gray-500 text-sm">
<p>暂无可用变量,请先添加变量</p>
</div>
</div>
</div>
<div class="p-4 border-t border-gray-200 flex justify-end gap-3">
<button
@click="closeTemplateModal"
class="px-6 py-2 border border-gray-300 rounded-md hover:bg-gray-50 transition-colors"
>
取消
</button>
<button
@click="saveVariableTemplate"
class="px-6 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-700 transition-colors"
:disabled="
!templateForm.groupName ||
!templateForm.variableBizIdList ||
templateForm.variableBizIdList.length === 0
"
>
{{ editingTemplateId ? '更新模板' : '创建模板' }}
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { variableApi, variableGroupApi } from '@/api/api'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Action } from 'element-plus/es/components/message-box/interface'
const props = defineProps({
editingTemplateId: {
type: String,
default: '',
},
visible: {
type: Boolean,
default: false,
},
})
const templateForm = ref({
groupName: '',
description: '',
variableBizIdList: [],
})
const searchQuery = ref('')
const variables = ref([])
// 状态
const variablePrefix = '{{'
const variableNextfix = '}}'
const emit = defineEmits(['confirm', 'cancel', 'closeTemplateModal'])
const closeTemplateModal = () => {
templateForm.value = {
groupName: '',
description: '',
variableBizIdList: [],
}
// 关闭弹窗
emit('closeTemplateModal')
}
onMounted(() => {
fetchVariables()
})
const toggleTemplateVariable = (variableId: string) => {
if (!templateForm.value.variableBizIdList) {
templateForm.value.variableBizIdList = []
}
const index = templateForm.value.variableBizIdList.indexOf(variableId)
if (index > -1) {
templateForm.value.variableBizIdList.splice(index, 1)
} else {
templateForm.value.variableBizIdList.push(variableId)
}
}
const open = (msg: string, title: string) => {
ElMessageBox.alert(msg, title, {
confirmButtonText: 'OK',
callback: (action: Action) => {},
})
}
const saveVariableTemplate = () => {
if (
!templateForm.value.groupName ||
!templateForm.value.variableBizIdList ||
templateForm.value.variableBizIdList.length === 0
)
return
if (props.editingTemplateId) {
console.log('更新变量模版', templateForm.value)
// 更新现有模板
variableGroupApi
.editEmailVariableGroup({
variableGroupBizId: props.editingTemplateId || '',
groupName: templateForm.value.groupName || '',
description: templateForm.value.description || '',
variableBizIdList: templateForm.value.variableBizIdList || [],
})
.then(() => {
open('更新变量模版成功', '成功')
// 通知父组件,刷新变量模版列表
emit('confirm', props.editingTemplateId || '')
templateForm.value = {
groupName: '',
description: '',
variableBizIdList: [],
}
})
.catch((error) => {
console.error('更新变量模版失败:', error)
if (error.response?.data?.msg) {
open(error.response.data.msg, '错误')
} else {
open(error.response.data.msg, '错误')
}
})
} else {
// 调用变量组保存接口
variableGroupApi
.addEmailVariableGroup({
groupName: templateForm.value.groupName || '',
description: templateForm.value.description || '',
variableBizIdList: templateForm.value.variableBizIdList || [],
})
.then(() => {
open('创建变量模版成功', '成功')
// 通知父组件,刷新变量模版列表
emit('confirm', '')
templateForm.value = {
groupName: '',
description: '',
variableBizIdList: [],
}
})
.catch((error) => {
console.error('创建变量模版失败:', error)
if (error.response?.data?.msg) {
open(error.response.data.msg, '创建变量模版失败')
} else {
open(error.response.data.msg, '创建变量模版失败')
}
})
}
closeTemplateModal()
}
const fetchVariables = () => {
variableApi
.getEmailVariableList({
queryContent: searchQuery.value || '',
pageNum: 1,
pageSize: 1000,
})
.then((response) => {
variables.value = response.data.records || []
console.log(response.data)
})
.catch((error) => {
console.error('获取变量列表失败:', error)
if (error.response?.data?.msg) {
open(error.response.data.msg, '获取变量列表失败')
} else {
open(error.response.data.msg, '获取变量列表失败')
}
})
}
// 防抖函数
const debounce = (func: Function, delay: number) => {
let timeoutId: NodeJS.Timeout
return (...args: any[]) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => func.apply(null, args), delay)
}
}
// 防抖后的搜索函数
const debouncedFetchVariables = debounce(fetchVariables, 500)
// 监听搜索查询的变化
watch(searchQuery, (newValue) => {
if (newValue.trim() !== '') {
debouncedFetchVariables()
} else {
// 如果搜索内容为空,直接调用(不需要防抖)
fetchVariables()
}
})
</script>
......@@ -122,6 +122,7 @@ import { ref, defineEmits } from 'vue'
import { loginApi } from '@/api/api'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { Action } from 'element-plus'
import router from '@/router'
// 定义事件 - 登录成功和跳转到忘记密码页面
const emits = defineEmits(['login', 'go-to-forgot-password'])
......@@ -161,11 +162,24 @@ const handleLogin = async () => {
password: password.value,
})
// 检查登录是否成功
// 在登录成功的处理逻辑中
if (res.code === 200) {
// 登录成功,处理返回的token等信息
console.log('登录成功', res)
localStorage.setItem('authToken', `${res.data.tokenType} ${res.data.token}`)
// 触发登录事件,传递用户信息
// 检查是否有重定向路径
const redirectPath = localStorage.getItem('redirectPath')
if (redirectPath) {
// 跳转到之前访问的页面
router.push(redirectPath)
localStorage.removeItem('redirectPath')
} else {
// 默认跳转到写邮件页面
router.push('/compose')
}
// 触发登录事件
emits('login', {
username: username.value,
password: password.value,
......
......@@ -134,44 +134,6 @@
<div class="p-6 border-b border-gray-200">
<h3 class="text-lg font-semibold">变量列表</h3>
</div>
<!-- 增加搜索条件 -->
<!-- 通过变量中文名和英文名搜索 -->
<div class="bg-white rounded-lg shadow-sm p-4 mb-6">
<div class="flex flex-col md:flex-row gap-4">
<div class="relative flex-1">
<i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"></i>
<input
v-model="searchQuery.variableNameCn"
type="text"
class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg"
placeholder="输入变量中文名"
/>
</div>
<div class="relative flex-1">
<i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"></i>
<input
v-model="searchQuery.variableNameEn"
type="text"
class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg"
placeholder="输入变量英文名"
/>
</div>
<!-- 搜索按钮 -->
<button
@click="resetSearch"
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-400 transition-colors mr-2"
>
<i class="fas fa-sync mr-2"></i>重置
</button>
<button
@click="fetchVariables"
class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-700 transition-colors text-sm"
>
<i class="fas fa-search mr-2"></i> 搜索
</button>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
......@@ -239,88 +201,14 @@
/>
</div>
<!-- 变量模板弹窗 -->
<div
v-if="showTemplateModal"
class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
>
<div class="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[80vh] flex flex-col">
<div class="p-4 border-b border-gray-200 flex justify-between items-center">
<h3 class="text-lg font-semibold">
{{ editingTemplateId ? '编辑变量模板' : '创建变量模板' }}
</h3>
<button @click="closeTemplateModal">
<i class="fas fa-times text-gray-500"></i>
</button>
</div>
<div class="p-4 flex-1 overflow-y-auto">
<div class="mb-4">
<label class="block text-gray-700 mb-1 text-sm">模板名称 *</label>
<input
v-model="templateForm.groupName"
type="text"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-1 text-sm">模板描述</label>
<textarea
v-model="templateForm.description"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
rows="2"
></textarea>
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-1 text-sm">选择变量</label>
<div
class="space-y-2 max-h-[300px] overflow-y-auto p-2 border border-gray-200 rounded-md"
>
<div
v-for="variable in variables"
:key="variable.id"
class="flex items-center p-2 hover:bg-blue-50 rounded"
>
<input
type="checkbox"
:id="'template-var-' + variable.variableBizId"
:checked="templateForm.variableBizIdList?.includes(variable.variableBizId || '')"
class="mr-3"
@change="toggleTemplateVariable(variable.variableBizId || '')"
/>
<label for="'template-var-' + variable.variableBizId">
<div class="text-sm text-gray-500">{{ variable.variableNameCn }}</div>
<div class="font-medium font-mono text-sm">
{{ variablePrefix }}{{ variable.variableNameEn }}{{ variableNextfix }}
</div>
</label>
</div>
</div>
<div v-if="variables.length === 0" class="p-4 text-center text-gray-500 text-sm">
<p>暂无可用变量,请先添加变量</p>
</div>
</div>
</div>
<div class="p-4 border-t border-gray-200 flex justify-end gap-3">
<button
@click="closeTemplateModal"
class="px-6 py-2 border border-gray-300 rounded-md hover:bg-gray-50 transition-colors"
>
取消
</button>
<button
@click="saveVariableTemplate"
class="px-6 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-700 transition-colors"
:disabled="
!templateForm.groupName ||
!templateForm.variableBizIdList ||
templateForm.variableBizIdList.length === 0
"
>
{{ editingTemplateId ? '更新模板' : '创建模板' }}
</button>
</div>
</div>
</div>
<EditVariableGroup
ref="editVariableGroupRef"
:visible="showTemplateModal"
:editing-template-id="editingTemplateId"
:template-form="templateForm"
@confirm="editVariableTemplate"
@closeTemplateModal="closeTemplateModal"
/>
</div>
<CommonModal
v-model:visible="modalVisible"
......@@ -340,7 +228,7 @@ import type { Variable, VariableTemplate } from '../types'
import { variableApi, variableGroupApi } from '@/api/api'
import { ElMessage } from 'element-plus'
import EditVariableGroup from '@/views/EditVariableGroup.vue'
// 引入分页组件
import Pagination from '@/components/Pagination.vue'
......@@ -348,17 +236,7 @@ import Pagination from '@/components/Pagination.vue'
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
const searchQuery = ref({
variableNameCn: '',
variableNameEn: '',
})
const resetSearch = () => {
searchQuery.value = {
variableNameCn: '',
variableNameEn: '',
}
fetchVariables()
}
// 处理分页变化
const handlePageChange = (page: number, size: number) => {
console.log('分页变化:', page, size)
......@@ -557,7 +435,6 @@ const deleteVariable = (id: string, type?: string) => {
// 查询变量列表
const fetchVariables = () => {
const params = {
...searchQuery.value,
pageNo: currentPage.value,
pageSize: pageSize.value,
}
......@@ -612,7 +489,7 @@ const fetchVariableTemplates = () => {
// 方法 - 模板管理
const showCreateTemplateModal = (isNew: boolean) => {
showTemplateModal.value = true
console.log('===')
if (isNew) {
editingTemplateId.value = ''
templateForm.value = {
......@@ -625,10 +502,13 @@ const showCreateTemplateModal = (isNew: boolean) => {
// 方法 - 编辑变量模版
const editVariableTemplate = (template: VariableTemplate) => {
editingTemplateId.value = template.variableGroupBizId || ''
showTemplateModal.value = true
showTemplateModal.value = false
// 收到更新通知,重新查询变量模版列表
fetchVariableTemplates()
}
const closeTemplateModal = () => {
console.log('----')
showTemplateModal.value = false
editingTemplateId.value = ''
templateForm.value = {
......@@ -638,86 +518,6 @@ const closeTemplateModal = () => {
}
}
const toggleTemplateVariable = (variableId: string) => {
if (!templateForm.value.variableBizIdList) {
templateForm.value.variableBizIdList = []
}
const index = templateForm.value.variableBizIdList.indexOf(variableId)
if (index > -1) {
templateForm.value.variableBizIdList.splice(index, 1)
} else {
templateForm.value.variableBizIdList.push(variableId)
}
}
const saveVariableTemplate = () => {
if (
!templateForm.value.groupName ||
!templateForm.value.variableBizIdList ||
templateForm.value.variableBizIdList.length === 0
)
return
if (editingTemplateId.value) {
console.log('更新变量模版', templateForm.value)
// 更新现有模板
variableGroupApi
.editEmailVariableGroup({
variableGroupBizId: editingTemplateId.value,
groupName: templateForm.value.groupName || '',
description: templateForm.value.description || '',
variableBizIdList: templateForm.value.variableBizIdList || [],
})
.then(() => {
// 刷新变量模版列表
fetchVariableTemplates()
})
.catch((error) => {
console.error('更新变量模版失败:', error)
if (error.response?.data?.message) {
openModal({
title: '错误',
message: error.response.data.message,
})
} else {
openModal({
title: '错误',
message: '更新变量模版失败',
})
}
})
} else {
// 调用变量组保存接口
variableGroupApi
.addEmailVariableGroup({
groupName: templateForm.value.groupName || '',
description: templateForm.value.description || '',
variableBizIdList: templateForm.value.variableBizIdList || [],
})
.then(() => {
// 刷新变量模版列表
fetchVariableTemplates()
})
.catch((error) => {
console.error('创建变量模版失败:', error)
if (error.response?.data?.message) {
openModal({
title: '错误',
message: error.response.data.message,
})
} else {
openModal({
title: '错误',
message: '创建变量模版失败',
})
}
})
}
closeTemplateModal()
}
const deleteVariableTemplate = (id: string, type?: string) => {
editingTemplateId.value = id
if (type === 'confirmDelete') {
......@@ -751,11 +551,6 @@ const deleteVariableTemplate = (id: string, type?: string) => {
}
}
const getVariableKeyById = (id: string) => {
const variable = variables.value.find((v) => v.variableBizId === id)
return variable?.variableNameEn || ''
}
const generateExcelTemplate = (template: VariableTemplate) => {
variableGroupApi
.exportEmailVariableGroup(template.variableGroupBizId || '')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment