Commit f7789154 by Sweet Zhang

联系人管理页面不能滑动处理

parent 0fee6a3f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<html lang=""> <html lang="">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.gif" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>银盾邮件系统</title> <title>银盾邮件系统</title>
</head> </head>
......
...@@ -20,13 +20,13 @@ ...@@ -20,13 +20,13 @@
<!-- 弹窗内容 --> <!-- 弹窗内容 -->
<div class="modal-content"> <div class="modal-content">
<!-- 图标区域 --> <!-- 图标区域 -->
<div <!-- <div
v-if="type && showIcon" v-if="type && showIcon"
class="icon-container mr-4 flex-shrink-0" class="icon-container mr-4 flex-shrink-0"
:class="iconContainerClass" :class="iconContainerClass"
> >
<component :is="getIconComponent" class="w-6 h-6" /> <component :is="getIconComponent" class="w-6 h-6" />
</div> </div> -->
<!-- 内容区域 --> <!-- 内容区域 -->
<div class="content-container flex-1"> <div class="content-container flex-1">
...@@ -260,43 +260,6 @@ const getButtonType = computed(() => { ...@@ -260,43 +260,6 @@ const getButtonType = computed(() => {
} }
}) })
// 获取图标组件
const getIconComponent = computed<Component>(() => {
switch (props.type) {
case 'success':
return Check
case 'warning':
return Warning
case 'error':
return CircleClose
case 'info':
return InfoFilled
case 'confirm':
return QuestionFilled
default:
return InfoFilled
}
})
// 图标容器样式
const iconContainerClass = computed(() => {
const base = 'rounded-full p-2'
switch (props.type) {
case 'success':
return `${base} bg-green-100 text-green-600`
case 'warning':
return `${base} bg-yellow-100 text-yellow-600`
case 'error':
return `${base} bg-red-100 text-red-600`
case 'info':
return `${base} bg-blue-100 text-blue-600`
case 'confirm':
return `${base} bg-gray-100 text-gray-600`
default:
return `${base} bg-gray-100 text-gray-600`
}
})
// 处理关闭事件 - 传递triggerKey // 处理关闭事件 - 传递triggerKey
const handleClose = () => { const handleClose = () => {
dialogVisible.value = false dialogVisible.value = false
......
...@@ -228,7 +228,7 @@ ...@@ -228,7 +228,7 @@
@close="showVariableSelector = false" @close="showVariableSelector = false"
/> />
<!-- 发送邮件弹窗 --> <!-- 发送邮件弹窗 -->
<el-dialog v-model="dialogVisible" title="提示" width="500" :before-close="handleClose"> <el-dialog v-model="dialogVisible" title="提示" width="500">
<span>邮件发送任务已提交,请前往邮件记录中查看发送状态</span> <span>邮件发送任务已提交,请前往邮件记录中查看发送状态</span>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
...@@ -267,16 +267,6 @@ import { ...@@ -267,16 +267,6 @@ import {
} from '../api/api' } from '../api/api'
const dialogVisible = ref(false) const dialogVisible = ref(false)
const handleClose = (done: () => void) => {
ElMessageBox.confirm('邮件发送任务已提交,请前往邮件记录中查看发送状态')
.then(() => {
done()
})
.catch(() => {
// catch error
})
}
// 远程搜索方法 // 远程搜索方法
const remoteSearch = async (query: string, type: string) => { const remoteSearch = async (query: string, type: string) => {
console.log(query, type) console.log(query, type)
......
...@@ -83,111 +83,49 @@ ...@@ -83,111 +83,49 @@
<!-- 联系人列表 --> <!-- 联系人列表 -->
<div class="bg-white rounded-lg shadow-sm overflow-hidden"> <div class="bg-white rounded-lg shadow-sm overflow-hidden">
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<table class="w-full"> <el-table :data="filteredContacts" max-height="500" style="width: 100%" table-layout="auto">
<thead> <el-table-column label="姓名">
<tr class="bg-gray-50 border-b border-gray-200"> <template #default="scope">
<th <div style="display: flex; align-items: center">
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" <div
> class="w-8 h-8 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-3"
姓名 >
</th> <span class="text-sm font-medium">{{ scope.row.name?.charAt(0) || '-' }}</span>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
称谓
</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
公司
</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
收件人邮箱
</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
抄送人邮箱
</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
其他信息
</th>
<th
class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"
>
操作
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr
v-for="contact in filteredContacts"
:key="contact.contactBizId"
class="hover:bg-gray-50 transition-colors"
>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div
class="w-8 h-8 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-3"
>
<span class="text-sm font-medium">{{ contact.name?.charAt(0) || '-' }}</span>
</div>
<div>
<div class="text-sm font-medium text-gray-900">{{ contact.name || '-' }}</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-500">{{ contact.appellation || '-' }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-500">{{ contact.companyName || '-' }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-500">{{ contact.email || '-' }}</div>
</td>
<td class="px-6 py-4">
<div class="flex flex-wrap gap-1">
<span
v-for="(email, index) in contact.ccEmailList || []"
:key="index"
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800"
>
{{ email }}
</span>
<span v-if="contact.ccEmailList?.length === 0" class="text-sm text-gray-500"
>-</span
>
</div>
</td>
<td class="px-6 py-4">
<div class="text-sm text-gray-500 line-clamp-2">
{{ contact.other || '-' }}
</div> </div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> <span style="margin-left: 10px">{{ scope.row.name }}</span>
<button </div>
@click="editContactModal(contact)" </template>
class="text-blue-600 hover:text-blue-900 mr-4" </el-table-column>
title="编辑" <el-table-column prop="title" label="称谓" />
<el-table-column prop="companyName" label="公司" />
<el-table-column prop="email" label="收件人邮箱" />
<el-table-column label="抄送人邮箱">
<template #default="scope">
<div class="flex flex-wrap gap-1">
<span
v-for="(email, index) in scope.row.ccEmailList || []"
:key="index"
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800"
> >
<i class="fas fa-edit"></i> {{ email }}
</button> </span>
<button <span v-if="scope.row.ccEmailList?.length === 0" class="text-sm text-gray-500"
@click="deleteContactModal(contact)" >-</span
class="text-red-600 hover:text-red-900"
title="删除"
> >
<i class="fas fa-trash"></i> </div>
</button> </template>
</td> </el-table-column>
</tr> <el-table-column prop="other" label="其他信息" />
</tbody> <el-table-column label="操作">
</table> <template #default="scope">
<el-button size="small" @click="editContactModal(scope.row)"> 编辑 </el-button>
<el-button size="small" type="danger" @click="deleteContactModal(scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div> </div>
<!-- 分页组件 --> <!-- 分页组件 -->
<Pagination <Pagination
...@@ -404,6 +342,8 @@ const handleImportSuccess = (file: File) => { ...@@ -404,6 +342,8 @@ const handleImportSuccess = (file: File) => {
title: '成功', title: '成功',
message: '联系人导入成功', message: '联系人导入成功',
}) })
// 刷新联系人列表
fetchContacts()
} }
const handleImportCancel = (triggerKey: string) => { const handleImportCancel = (triggerKey: string) => {
......
...@@ -84,10 +84,10 @@ const handleDocumentUploadSuccess = (results: UploadResult[]) => { ...@@ -84,10 +84,10 @@ const handleDocumentUploadSuccess = (results: UploadResult[]) => {
const handleDocumentUploadError = (error: string) => { const handleDocumentUploadError = (error: string) => {
emit('error', error, props.triggerKey) emit('error', error, props.triggerKey)
} }
const emit = defineEmits(['success', 'error', 'close', 'confirm']) const emit = defineEmits(['success', 'error', 'cancel', 'confirm'])
const handleCancel = () => { const handleCancel = () => {
emit('close', props.triggerKey) emit('cancel', props.triggerKey)
} }
const handleConfirm = () => { const handleConfirm = () => {
emit('confirm', result.value, props.triggerKey) emit('confirm', result.value, props.triggerKey)
......
...@@ -370,12 +370,12 @@ const saveSender = () => { ...@@ -370,12 +370,12 @@ const saveSender = () => {
if (res.code === 200) { if (res.code === 200) {
getSenders() getSenders()
openModal({ openModal({
title: '更新确认', title: '提示',
message: '发件人更新成功', message: '发件人信息更新成功',
}) })
} else { } else {
openModal({ openModal({
title: '更新失败', title: '提示',
message: res.msg || '更新失败', message: res.msg || '更新失败',
}) })
} }
......
...@@ -167,10 +167,7 @@ ...@@ -167,10 +167,7 @@
{{ variablePrefix }}{{ variable.variableNameEn }}{{ variableNextfix }} {{ variablePrefix }}{{ variable.variableNameEn }}{{ variableNextfix }}
</td> </td>
<td class="px-6 py-4">{{ variable.description || '-' }}</td> <td class="px-6 py-4">{{ variable.description || '-' }}</td>
<td <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
v-if="variable.isGeneral !== 1"
>
<button <button
@click="editVariable(variable)" @click="editVariable(variable)"
class="text-blue-600 hover:text-blue-900 mr-3" class="text-blue-600 hover:text-blue-900 mr-3"
...@@ -204,14 +201,88 @@ ...@@ -204,14 +201,88 @@
/> />
</div> </div>
<EditVariableGroup <!-- 变量模板弹窗 -->
ref="editVariableGroupRef" <div
:visible="showTemplateModal" v-if="showTemplateModal"
:editing-template-id="editingTemplateId" class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
:template-form="templateForm" >
@confirm="editVariableTemplate" <div class="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[80vh] flex flex-col">
@closeTemplateModal="closeTemplateModal" <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>
</div> </div>
<CommonModal <CommonModal
v-model:visible="modalVisible" v-model:visible="modalVisible"
...@@ -231,14 +302,14 @@ import type { Variable, VariableTemplate } from '../types' ...@@ -231,14 +302,14 @@ import type { Variable, VariableTemplate } from '../types'
import { variableApi, variableGroupApi } from '@/api/api' import { variableApi, variableGroupApi } from '@/api/api'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import EditVariableGroup from '@/views/EditVariableGroup.vue'
// 引入分页组件 // 引入分页组件
import Pagination from '@/components/Pagination.vue' import Pagination from '@/components/Pagination.vue'
// 初始数据 // 初始数据
const total = ref(0) const total = ref(0)
const currentPage = ref(1) const currentPage = ref(1)
const pageSize = ref(100) const pageSize = ref(10)
// 处理分页变化 // 处理分页变化
const handlePageChange = (page: number, size: number) => { const handlePageChange = (page: number, size: number) => {
...@@ -492,7 +563,7 @@ const fetchVariableTemplates = () => { ...@@ -492,7 +563,7 @@ const fetchVariableTemplates = () => {
// 方法 - 模板管理 // 方法 - 模板管理
const showCreateTemplateModal = (isNew: boolean) => { const showCreateTemplateModal = (isNew: boolean) => {
showTemplateModal.value = true showTemplateModal.value = true
console.log('===')
if (isNew) { if (isNew) {
editingTemplateId.value = '' editingTemplateId.value = ''
templateForm.value = { templateForm.value = {
...@@ -505,13 +576,10 @@ const showCreateTemplateModal = (isNew: boolean) => { ...@@ -505,13 +576,10 @@ const showCreateTemplateModal = (isNew: boolean) => {
// 方法 - 编辑变量模版 // 方法 - 编辑变量模版
const editVariableTemplate = (template: VariableTemplate) => { const editVariableTemplate = (template: VariableTemplate) => {
editingTemplateId.value = template.variableGroupBizId || '' editingTemplateId.value = template.variableGroupBizId || ''
showTemplateModal.value = false showTemplateModal.value = true
// 收到更新通知,重新查询变量模版列表
fetchVariableTemplates()
} }
const closeTemplateModal = () => { const closeTemplateModal = () => {
console.log('----')
showTemplateModal.value = false showTemplateModal.value = false
editingTemplateId.value = '' editingTemplateId.value = ''
templateForm.value = { templateForm.value = {
...@@ -521,6 +589,86 @@ const closeTemplateModal = () => { ...@@ -521,6 +589,86 @@ 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) => { const deleteVariableTemplate = (id: string, type?: string) => {
editingTemplateId.value = id editingTemplateId.value = id
if (type === 'confirmDelete') { if (type === 'confirmDelete') {
...@@ -554,6 +702,11 @@ const deleteVariableTemplate = (id: string, type?: string) => { ...@@ -554,6 +702,11 @@ 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) => { const generateExcelTemplate = (template: VariableTemplate) => {
variableGroupApi variableGroupApi
.exportEmailVariableGroup(template.variableGroupBizId || '') .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