Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
frontend-yd-email
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Sweet Zhang
frontend-yd-email
Commits
266913ac
Commit
266913ac
authored
Sep 30, 2025
by
Sweet Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
解决刷新回到根目录下的的问题
parent
3b970b52
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
361 additions
and
266 deletions
+361
-266
src/App.vue
+12
-21
src/router/index.ts
+39
-2
src/types/index.ts
+1
-0
src/views/ComposeEmail.vue
+20
-22
src/views/EditVariableGroup.vue
+259
-0
src/views/LoginPage.vue
+15
-1
src/views/VariableManagement.vue
+15
-220
No files found.
src/App.vue
View file @
266913ac
<
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
>
src/router/index.ts
View file @
266913ac
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
src/types/index.ts
View file @
266913ac
...
...
@@ -39,6 +39,7 @@ export interface Variable extends Pagination<Variable> {
variableNameCn
?:
string
variableNameEn
?:
string
description
?:
string
isGeneral
?:
number
}
// 变量模板类型
...
...
src/views/ComposeEmail.vue
View file @
266913ac
...
...
@@ -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
[]
>
([])
...
...
src/views/EditVariableGroup.vue
0 → 100644
View file @
266913ac
<
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
>
src/views/LoginPage.vue
View file @
266913ac
...
...
@@ -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
,
...
...
src/views/VariableManagement.vue
View file @
266913ac
...
...
@@ -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
||
''
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment