feat: require agent name confirmation before delete

This commit is contained in:
Tyke Chen
2026-07-09 15:03:12 +08:00
parent 8808b69303
commit 9301c1889f
17 changed files with 597 additions and 41 deletions
+6
View File
@@ -71,6 +71,12 @@ export default {
'home.inputPlaceholder': 'z.B. Kundenservice-Assistent, Sprachassistent, Wissens-F&A',
'home.createError': 'Der Name muss zwischen 1 und 64 Zeichen lang sein.',
'home.createNow': 'Jetzt erstellen',
'home.deleteConfirmTitle': 'Agent löschen',
'home.confirmDeleteAgent': 'Das Löschen kann nicht rückgängig gemacht werden. Geben Sie den Agentennamen "{agentName}" ein, um zu bestätigen.',
'home.deleteAgentNamePlaceholder': 'Agentennamen eingeben',
'home.deleteAgentNameMismatch': 'Der Agentenname stimmt nicht überein',
'home.deleteAgentPasteForbidden': 'Bitte geben Sie den Agentennamen manuell ein. Einfügen ist nicht erlaubt.',
'home.deleteAgentMissingInfo': 'Agenteninformationen konnten nicht bestätigt werden. Bitte aktualisieren und erneut versuchen.',
'home.justNow': 'Gerade eben',
'home.minutesAgo': 'Minuten her',
'home.hoursAgo': 'Stunden her',
+6
View File
@@ -71,6 +71,12 @@ export default {
'home.inputPlaceholder': 'e.g. Customer Service Assistant, Voice Assistant, Knowledge Q&A',
'home.createError': 'The name length must be between 1 and 64 characters',
'home.createNow': 'Create Now',
'home.deleteConfirmTitle': 'Delete Agent',
'home.confirmDeleteAgent': 'Deletion cannot be undone. Type the agent name "{agentName}" to confirm.',
'home.deleteAgentNamePlaceholder': 'Enter agent name',
'home.deleteAgentNameMismatch': 'The agent name does not match',
'home.deleteAgentPasteForbidden': 'Please type the agent name manually. Pasting is not allowed.',
'home.deleteAgentMissingInfo': 'Unable to confirm agent information. Please refresh and try again.',
'home.justNow': 'Just now',
'home.minutesAgo': 'minutes ago',
'home.hoursAgo': 'hours ago',
+6
View File
@@ -71,6 +71,12 @@ export default {
'home.inputPlaceholder': 'ex: Assistente de Atendimento, Assistente de Voz, Perguntas e Respostas',
'home.createError': 'O comprimento do nome deve estar entre 1 e 64 caracteres',
'home.createNow': 'Criar Agora',
'home.deleteConfirmTitle': 'Excluir Agente',
'home.confirmDeleteAgent': 'A exclusão não pode ser desfeita. Digite o nome do agente "{agentName}" para confirmar.',
'home.deleteAgentNamePlaceholder': 'Digite o nome do agente',
'home.deleteAgentNameMismatch': 'O nome do agente não corresponde',
'home.deleteAgentPasteForbidden': 'Digite o nome do agente manualmente. Colar não é permitido.',
'home.deleteAgentMissingInfo': 'Não foi possível confirmar as informações do agente. Atualize a página e tente novamente.',
'home.justNow': 'Agora mesmo',
'home.minutesAgo': 'minutos atrás',
'home.hoursAgo': 'horas atrás',
+6
View File
@@ -71,6 +71,12 @@ export default {
'home.inputPlaceholder': 'ví dụ: Trợ lý chăm sóc khách hàng, Trợ lý giọng nói, Hỏi đáp kiến thức',
'home.createError': 'Độ dài tên phải từ 1 đến 64 ký tự',
'home.createNow': 'Tạo ngay',
'home.deleteConfirmTitle': 'Xóa đại lý',
'home.confirmDeleteAgent': 'Không thể hoàn tác sau khi xóa. Nhập tên đại lý "{agentName}" để xác nhận.',
'home.deleteAgentNamePlaceholder': 'Nhập tên đại lý',
'home.deleteAgentNameMismatch': 'Tên đại lý không khớp',
'home.deleteAgentPasteForbidden': 'Vui lòng nhập thủ công tên đại lý. Không được dán.',
'home.deleteAgentMissingInfo': 'Không thể xác nhận thông tin đại lý. Vui lòng tải lại rồi thử lại.',
'home.justNow': 'Vừa xong',
'home.minutesAgo': 'phút trước',
'home.hoursAgo': 'giờ trước',
+6
View File
@@ -71,6 +71,12 @@ export default {
'home.inputPlaceholder': '例如:客服助手、语音助理、知识问答',
'home.createError': '名称长度必须在 1 到 64 个字符之间',
'home.createNow': '立即创建',
'home.deleteConfirmTitle': '删除智能体',
'home.confirmDeleteAgent': '删除后无法恢复。请输入智能体名称“{agentName}”确认删除。',
'home.deleteAgentNamePlaceholder': '请输入智能体名称',
'home.deleteAgentNameMismatch': '输入的智能体名称不匹配',
'home.deleteAgentPasteForbidden': '请手动输入智能体名称,不允许粘贴',
'home.deleteAgentMissingInfo': '无法确认智能体信息,请刷新后重试',
'home.justNow': '刚刚',
'home.minutesAgo': '分钟前',
'home.hoursAgo': '小时前',
+6
View File
@@ -92,6 +92,12 @@ export default {
'home.inputPlaceholder': '例如:客服助手、語音助理、知識問答',
'home.createError': '暱稱長度必須在 1 到 64 個字元之間。',
'home.createNow': '立即創建',
'home.deleteConfirmTitle': '刪除智能體',
'home.confirmDeleteAgent': '刪除後無法復原。請輸入智能體名稱「{agentName}」確認刪除。',
'home.deleteAgentNamePlaceholder': '請輸入智能體名稱',
'home.deleteAgentNameMismatch': '輸入的智能體名稱不匹配',
'home.deleteAgentPasteForbidden': '請手動輸入智能體名稱,不允許貼上',
'home.deleteAgentMissingInfo': '無法確認智能體資訊,請重新整理後再試',
'home.justNow': '剛剛',
'home.minutesAgo': '分鐘前',
'home.hoursAgo': '小時前',
+218 -4
View File
@@ -12,7 +12,7 @@
<script lang="ts" setup>
import type { Agent } from '@/api/agent/types'
import { onMounted, ref } from 'vue'
import { computed, onMounted, ref } from 'vue'
// 在组件挂载后设置导航栏标题
import { useMessage } from 'wot-design-uni'
import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
@@ -53,6 +53,14 @@ const pagingRef = ref()
useZPaging(pagingRef)
// 消息组件
const message = useMessage()
const deleteDialogVisible = ref(false)
const deleteTargetAgent = ref<Agent | null>(null)
const deleteConfirmText = ref('')
const deleteAgentLoading = ref(false)
const isDeleteAgentNameMatched = computed(() => {
return !!deleteTargetAgent.value?.agentName && deleteConfirmText.value === deleteTargetAgent.value.agentName
})
// z-paging查询列表数据
async function queryList(pageNo: number, pageSize: number) {
@@ -89,19 +97,53 @@ async function handleCreateAgent(agentName: string) {
}
}
function openDeleteAgentDialog(agent: Agent) {
if (!agent.id || !agent.agentName) {
toast.error(t('home.deleteAgentMissingInfo'))
return
}
deleteTargetAgent.value = agent
deleteConfirmText.value = ''
deleteDialogVisible.value = true
}
function closeDeleteAgentDialog() {
if (deleteAgentLoading.value)
return
deleteDialogVisible.value = false
deleteTargetAgent.value = null
deleteConfirmText.value = ''
}
function handleDeleteAgentPaste() {
toast.warning(t('home.deleteAgentPasteForbidden'))
}
// 删除智能体
async function handleDeleteAgent(agent: Agent) {
async function handleDeleteAgent() {
if (!deleteTargetAgent.value || !isDeleteAgentNameMatched.value || deleteAgentLoading.value)
return
try {
await deleteAgent(agent.id)
deleteAgentLoading.value = true
await deleteAgent(deleteTargetAgent.value.id)
// 删除成功后刷新列表
pagingRef.value.reload()
toast.success(`${t('home.agentName')}${t('message.deleteSuccess')}`)
deleteDialogVisible.value = false
deleteTargetAgent.value = null
deleteConfirmText.value = ''
}
catch (error: any) {
console.error('删除智能体失败:', error)
const errorMessage = error?.message || t('message.deleteFail')
toast.error(errorMessage)
}
finally {
deleteAgentLoading.value = false
}
}
// 进入编辑页面
@@ -254,7 +296,7 @@ onMounted(() => {
<template #right>
<view class="swipe-actions">
<view class="action-btn delete-btn" @click.stop="handleDeleteAgent(agent)">
<view class="action-btn delete-btn" @click.stop="openDeleteAgentDialog(agent)">
<wd-icon name="delete" />
<text>{{ t('home.delete') }}</text>
</view>
@@ -283,6 +325,79 @@ onMounted(() => {
<!-- MessageBox 组件 -->
<wd-message-box />
</z-paging>
<wd-popup
v-model="deleteDialogVisible"
position="center"
custom-style="width: 88%; max-width: 420px; border-radius: 16px;"
:close-on-click-modal="!deleteAgentLoading"
safe-area-inset-bottom
@close="closeDeleteAgentDialog"
>
<view class="delete-agent-dialog">
<view class="delete-agent-header">
<text class="delete-agent-title">
{{ t('home.deleteConfirmTitle') }}
</text>
</view>
<view class="delete-agent-body">
<view class="delete-agent-content">
<wd-icon name="warning" custom-class="delete-agent-warning" />
<view class="delete-agent-message">
<text
class="delete-agent-copy-guard delete-agent-tip"
@copy.stop.prevent
@cut.stop.prevent
@contextmenu.stop.prevent
@longpress.stop.prevent
>
{{ t('home.confirmDeleteAgent', { agentName: deleteTargetAgent?.agentName || '' }) }}
</text>
<view
class="delete-agent-copy-guard delete-agent-target"
@copy.stop.prevent
@cut.stop.prevent
@contextmenu.stop.prevent
@longpress.stop.prevent
>
<text>{{ deleteTargetAgent?.agentName || '' }}</text>
</view>
<input
v-model="deleteConfirmText"
class="delete-agent-input"
type="text"
:maxlength="deleteTargetAgent?.agentName?.length || 64"
:placeholder="t('home.deleteAgentNamePlaceholder')"
:disabled="deleteAgentLoading"
@paste.stop.prevent="handleDeleteAgentPaste"
@drop.stop.prevent="handleDeleteAgentPaste"
@contextmenu.stop.prevent
>
<text v-if="deleteConfirmText && !isDeleteAgentNameMatched" class="delete-agent-helper">
{{ t('home.deleteAgentNameMismatch') }}
</text>
</view>
</view>
</view>
<view class="delete-agent-footer">
<wd-button type="info" custom-class="delete-agent-button" :disabled="deleteAgentLoading" @click="closeDeleteAgentDialog">
{{ t('common.cancel') }}
</wd-button>
<wd-button
type="primary"
custom-class="delete-agent-button"
:loading="deleteAgentLoading"
:disabled="!isDeleteAgentNameMatched"
@click="handleDeleteAgent"
>
{{ t('common.confirm') }}
</wd-button>
</view>
</view>
</wd-popup>
</template>
<style lang="scss" scoped>
@@ -587,4 +702,103 @@ onMounted(() => {
text-align: center;
border-top: 1rpx solid #eeeeee;
}
.delete-agent-dialog {
overflow: hidden;
background: #ffffff;
}
.delete-agent-header {
padding: 32rpx 32rpx 20rpx;
border-bottom: 1rpx solid #f0f0f0;
text-align: center;
}
.delete-agent-title {
font-size: 32rpx;
font-weight: 600;
color: #232338;
}
.delete-agent-body {
padding: 32rpx;
}
.delete-agent-content {
display: flex;
align-items: flex-start;
gap: 16rpx;
}
:deep(.delete-agent-warning) {
margin-top: 4rpx;
color: #e6a23c;
font-size: 40rpx;
}
.delete-agent-message {
flex: 1;
min-width: 0;
}
.delete-agent-tip {
display: block;
color: #606266;
font-size: 28rpx;
line-height: 1.6;
}
.delete-agent-target {
box-sizing: border-box;
width: 100%;
margin-top: 20rpx;
padding: 18rpx 20rpx;
border: 1rpx solid #ebeef5;
border-radius: 12rpx;
background: #f5f7fa;
color: #303133;
font-size: 30rpx;
font-weight: 600;
line-height: 1.5;
word-break: break-all;
}
.delete-agent-copy-guard {
user-select: none;
-webkit-user-select: none;
}
.delete-agent-input {
box-sizing: border-box;
width: 100%;
height: 80rpx;
margin-top: 28rpx;
padding: 0 20rpx;
border: 1rpx solid #eeeeee;
border-radius: 12rpx;
background: #f5f7fb;
color: #232338;
font-size: 28rpx;
outline: none;
}
.delete-agent-helper {
display: block;
min-height: 32rpx;
margin-top: 10rpx;
color: #f56c6c;
font-size: 24rpx;
line-height: 1.4;
}
.delete-agent-footer {
display: flex;
gap: 16rpx;
padding: 24rpx 32rpx 32rpx;
border-top: 1rpx solid #eeeeee;
}
:deep(.delete-agent-button) {
flex: 1;
}
</style>