修改开场白和推荐问题,修复菜单栏布局问题

This commit is contained in:
WangJing 2025-07-28 14:53:59 +08:00
parent c44b4d2728
commit 8abc3e1883
14 changed files with 396 additions and 182 deletions

View File

@ -2,14 +2,14 @@
# 此文件修改后需要重启项目 # 此文件修改后需要重启项目
NODE_ENV=development NODE_ENV=development
#VUE_APP_BASE_URL='/vab-mock-server' #VUE_APP_BASE_URL='/vab-mock-server'
# VUE_APP_BASE_URL='http://localhost:10001' VUE_APP_BASE_URL='http://localhost:10001'
# VUE_APP_API_BASE_URL='http://localhost:8080' VUE_APP_API_BASE_URL='http://localhost:8080'
#北京服务器配置 #北京服务器配置
# VUE_APP_BASE_URL='http://192.168.1.211:80/brichat' # VUE_APP_BASE_URL='http://192.168.1.211:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.1.211:80/brichat' # VUE_APP_API_BASE_URL='http://192.168.1.211:80/brichat'
# #武汉公司服务器 # #武汉公司服务器
VUE_APP_BASE_URL='http://192.168.8.253:80/brichat' # VUE_APP_BASE_URL='http://192.168.8.253:80/brichat'
VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat' # VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat'
#总部服务器配置 #总部服务器配置
# VUE_APP_BASE_URL='http://192.168.0.33:80/brichat' # VUE_APP_BASE_URL='http://192.168.0.33:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.0.33:80/brichat' # VUE_APP_API_BASE_URL='http://192.168.0.33:80/brichat'

View File

@ -8,8 +8,8 @@ VUE_APP_API_BASE_URL='http://localhost:10001'
# VUE_APP_BASE_URL='http://192.168.1.211:80/brichat' # VUE_APP_BASE_URL='http://192.168.1.211:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.1.211:80/brichat' # VUE_APP_API_BASE_URL='http://192.168.1.211:80/brichat'
#武汉公司服务器 #武汉公司服务器
VUE_APP_BASE_URL='http://192.168.8.253:80/brichat' # VUE_APP_BASE_URL='http://192.168.8.253:80/brichat'
VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat' # VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat'
# 总部服务器 # 总部服务器
# VUE_APP_BASE_URL='http://192.168.0.33:80/brichat' # VUE_APP_BASE_URL='http://192.168.0.33:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.0.33:80/brichat' # VUE_APP_API_BASE_URL='http://192.168.0.33:80/brichat'

View File

@ -5,7 +5,9 @@
import { handleActivePath, handleTabs } from '@/utils/routes' import { handleActivePath, handleTabs } from '@/utils/routes'
import { translate } from '@/i18n' import { translate } from '@/i18n'
import { VabRoute, VabRouteRecord } from '/#/router' import { VabRoute, VabRouteRecord } from '/#/router'
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n()
defineProps({ defineProps({
layout: { layout: {
type: String, type: String,
@ -24,14 +26,7 @@
const { getRoutes: routes } = storeToRefs(routesStore) const { getRoutes: routes } = storeToRefs(routesStore)
const tabsStore = useTabsStore() const tabsStore = useTabsStore()
const { getVisitedRoutes: visitedRoutes } = storeToRefs(tabsStore) const { getVisitedRoutes: visitedRoutes } = storeToRefs(tabsStore)
const { const { addVisitedRoute, delVisitedRoute, delOthersVisitedRoutes, delLeftVisitedRoutes, delRightVisitedRoutes, delAllVisitedRoutes } = tabsStore
addVisitedRoute,
delVisitedRoute,
delOthersVisitedRoutes,
delLeftVisitedRoutes,
delRightVisitedRoutes,
delAllVisitedRoutes,
} = tabsStore
const tabActive = ref('') const tabActive = ref('')
const active = ref(false) const active = ref(false)
@ -148,9 +143,7 @@
* 跳转最后一个标签页 * 跳转最后一个标签页
*/ */
const toLastTab = async () => { const toLastTab = async () => {
const latestView = visitedRoutes.value const latestView = visitedRoutes.value.filter((_: any) => _.path !== handleActivePath(route, true)).slice(-1)[0]
.filter((_: any) => _.path !== handleActivePath(route, true))
.slice(-1)[0]
if (latestView) await router.push(latestView) if (latestView) await router.push(latestView)
else await router.push('/') else await router.push('/')
} }
@ -196,20 +189,11 @@
@tab-click="handleTabClick" @tab-click="handleTabClick"
@tab-remove="handleTabRemove" @tab-remove="handleTabRemove"
> >
<el-tab-pane <el-tab-pane v-for="item in visitedRoutes" :key="item.path" :closable="!isNoCLosable(item)" :name="item.path">
v-for="item in visitedRoutes"
:key="item.path"
:closable="!isNoCLosable(item)"
:name="item.path"
>
<template #label> <template #label>
<span style="display: inline-block" @contextmenu.prevent="openMenu"> <span style="display: inline-block" @contextmenu.prevent="openMenu">
<template v-if="theme.showTabsIcon"> <template v-if="theme.showTabsIcon">
<vab-icon <vab-icon v-if="item.meta && item.meta.icon" :icon="item.meta.icon" :is-custom-svg="item.meta.isCustomSvg" />
v-if="item.meta && item.meta.icon"
:icon="item.meta.icon"
:is-custom-svg="item.meta.isCustomSvg"
/>
<!-- 如果没有图标那么取第二级的图标 --> <!-- 如果没有图标那么取第二级的图标 -->
<vab-icon v-else :icon="item.parentIcon" /> <vab-icon v-else :icon="item.parentIcon" />
</template> </template>
@ -221,12 +205,7 @@
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-dropdown <el-dropdown placement="bottom-end" popper-class="vab-tabs-more-dropdown" @command="handleCommand" @visible-change="handleVisibleChange">
placement="bottom-end"
popper-class="vab-tabs-more-dropdown"
@command="handleCommand"
@visible-change="handleVisibleChange"
>
<span class="vab-tabs-more" :class="{ 'vab-tabs-more-active': active }"> <span class="vab-tabs-more" :class="{ 'vab-tabs-more-active': active }">
<span class="vab-tabs-more-icon"> <span class="vab-tabs-more-icon">
<i class="box box-t"></i> <i class="box box-t"></i>
@ -238,75 +217,62 @@
<el-dropdown-item command="refreshThisTab"> <el-dropdown-item command="refreshThisTab">
<vab-icon icon="refresh-line" /> <vab-icon icon="refresh-line" />
<span> <span>
{{ translate('刷新') }} {{ t('vabI18n.vabtabs.refresh') }}
</span> </span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="closeOthersTabs"> <el-dropdown-item command="closeOthersTabs">
<vab-icon icon="close-line" /> <vab-icon icon="close-line" />
<span> <span>
{{ translate('关闭其他') }} {{ t('vabI18n.vabtabs.closeOthers') }}
</span> </span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="closeLeftTabs"> <el-dropdown-item command="closeLeftTabs">
<vab-icon icon="arrow-left-line" /> <vab-icon icon="arrow-left-line" />
<span> <span>
{{ translate('关闭左侧') }} {{ t('vabI18n.vabtabs.closeLeft') }}
</span> </span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="closeRightTabs"> <el-dropdown-item command="closeRightTabs">
<vab-icon icon="arrow-right-line" /> <vab-icon icon="arrow-right-line" />
<span> <span>
{{ translate('关闭右侧') }} {{ t('vabI18n.vabtabs.closeRight') }}
</span> </span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="closeAllTabs"> <el-dropdown-item command="closeAllTabs">
<vab-icon icon="close-line" /> <vab-icon icon="close-line" />
<span> <span>
{{ translate('关闭全部') }} {{ t('vabI18n.vabtabs.closeAll') }}
</span> </span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
<ul <ul v-if="visible" class="contextmenu el-dropdown-menu" :style="{ left: left + 'px', top: top + 'px' }">
v-if="visible"
class="contextmenu el-dropdown-menu"
:style="{ left: left + 'px', top: top + 'px' }"
>
<li class="el-dropdown-menu__item" @click="refreshThisTab"> <li class="el-dropdown-menu__item" @click="refreshThisTab">
<vab-icon icon="refresh-line" /> <vab-icon icon="refresh-line" />
<span>{{ translate('刷新') }}</span> <span>{{ t('vabI18n.vabtabs.refresh') }}</span>
</li> </li>
<li <li class="el-dropdown-menu__item" :class="{ 'is-disabled': visitedRoutes.length === 1 }" @click="closeOthersTabs">
class="el-dropdown-menu__item"
:class="{ 'is-disabled': visitedRoutes.length === 1 }"
@click="closeOthersTabs"
>
<vab-icon icon="close-line" /> <vab-icon icon="close-line" />
<span>{{ translate('关闭其他') }}</span> <span>{{ t('vabI18n.vabtabs.closeOthers') }}</span>
</li> </li>
<li <li class="el-dropdown-menu__item" :class="{ 'is-disabled': !visitedRoutes.indexOf(hoverRoute) }" @click="closeLeftTabs">
class="el-dropdown-menu__item"
:class="{ 'is-disabled': !visitedRoutes.indexOf(hoverRoute) }"
@click="closeLeftTabs"
>
<vab-icon icon="arrow-left-line" /> <vab-icon icon="arrow-left-line" />
<span>{{ translate('关闭左侧') }}</span> <span>{{ t('vabI18n.vabtabs.closeLeft') }}</span>
</li> </li>
<li <li
class="el-dropdown-menu__item" class="el-dropdown-menu__item"
:class="{ :class="{
'is-disabled': 'is-disabled': visitedRoutes.indexOf(hoverRoute) === visitedRoutes.length - 1,
visitedRoutes.indexOf(hoverRoute) === visitedRoutes.length - 1,
}" }"
@click="closeRightTabs" @click="closeRightTabs"
> >
<vab-icon icon="arrow-right-line" /> <vab-icon icon="arrow-right-line" />
<span>{{ translate('关闭右侧') }}</span> <span>{{ t('vabI18n.vabtabs.closeRight') }}</span>
</li> </li>
<li class="el-dropdown-menu__item" @click="closeAllTabs"> <li class="el-dropdown-menu__item" @click="closeAllTabs">
<vab-icon icon="close-line" /> <vab-icon icon="close-line" />
<span>{{ translate('关闭全部') }}</span> <span>{{ t('vabI18n.vabtabs.closeAll') }}</span>
</li> </li>
</ul> </ul>
</div> </div>
@ -337,9 +303,9 @@
margin-right: 3px; margin-right: 3px;
} }
.vab-icon { // .vab-icon {
vertical-align: -3px; // vertical-align: -3px;
} // }
} }
&-content { &-content {
@ -466,10 +432,7 @@
.el-tabs__item { .el-tabs__item {
height: $base-tag-item-height + 4; height: $base-tag-item-height + 4;
padding: 0 30px 0 30px; padding: 0 30px 0 30px;
margin-top: #{math.div( margin-top: #{math.div($base-tabs-height - $base-tag-item-height - 4.1, 2)};
$base-tabs-height - $base-tag-item-height - 4.1,
2
)};
margin-right: -18px; margin-right: -18px;
line-height: $base-tag-item-height + 4; line-height: $base-tag-item-height + 4;
text-align: center; text-align: center;
@ -598,4 +561,20 @@
} }
} }
} }
:deep(.el-tabs__nav-wrap.is-top) {
padding-top: 0 !important;
margin-top: 0 !important;
display: flex;
align-items: center;
height: $base-tabs-height;
}
:deep(.el-tabs__header.is-top) {
padding-top: 0 !important;
margin-top: 0 !important;
height: $base-tabs-height;
display: flex;
align-items: center;
}
</style> </style>

View File

@ -26,7 +26,7 @@ export function getRecommendations(chatType: string) {
} }
// 编辑推荐问题 // 编辑推荐问题
export function eidtRecommendation(data: any) { export function editRecommendation(data: any) {
return request({ return request({
url: '/brichat-service/prologue/eidtRecommendation', url: '/brichat-service/prologue/eidtRecommendation',
method: 'post', method: 'post',
@ -42,3 +42,12 @@ export function deleteRecommendation(id: string) {
params: { id }, params: { id },
}) })
} }
// 新增推荐问题
export function addRecommendation(data: any) {
return request({
url: '/brichat-service/prologue/addRecommendation',
method: 'post',
data,
})
}

View File

@ -515,35 +515,70 @@ export default {
Tip: 'Tip', Tip: 'Tip',
selectDeleteData: 'Please select the data to be deleted', selectDeleteData: 'Please select the data to be deleted',
confirmDeleteApiKeys: 'This operation will permanently delete selected ', confirmDeleteApiKeys: 'This operation will permanently delete selected ',
confirmDeleteApiKeysEnd:' API key, are you sure?', confirmDeleteApiKeysEnd: ' API key, are you sure?',
confirmDeleteApiKeysEndPlural:' API keys, are you sure?', confirmDeleteApiKeysEndPlural: ' API keys, are you sure?',
confirmRefreshCache: 'This operation will refresh Redis cache, reloading all API keys, are you sure?', confirmRefreshCache: 'This operation will refresh Redis cache, reloading all API keys, are you sure?',
updateSuccess: 'Update Successfully', updateSuccess: 'Update Successfully',
updateFail: 'Update Failed', updateFail: 'Update Failed',
addSuccess: 'Add Successfully', addSuccess: 'Add Successfully',
addFail:'Add Failed' addFail: 'Add Failed',
}, },
prologue:{ prologue: {
title: 'Opening Statement Management',
query: 'Query',
save: 'Save',
chatType: 'Chat Type', chatType: 'Chat Type',
selectChatType: 'Select Chat Type', chatTypes: {
prologueContent: 'Prologue Content', '1': 'Fault Diagnosis',
addRecommend: 'Add Recommendation', '2': 'Intelligent Q&A',
recommendQuestion: 'Recommended Question', '3': 'Chart Report',
actions: 'Actions', '4': 'Emergency Assistant Q&A',
'5': 'Diagnostic Code Lookup',
},
openingContent: 'Opening Statement Content',
addRecommend: 'Add Recommended Question',
recommendation: 'Recommended Question',
action: 'Action',
edit: 'Edit', edit: 'Edit',
delete: 'Delete', delete: 'Delete',
confirmDelete: 'Are you sure you want to delete this recommendation?', dialog: {
confirmSave: 'Are you sure you want to save the changes?', addTitle: 'Add Recommended Question',
deleteSuccess: 'Deleted successfully', editTitle: 'Edit Recommended Question',
deleteFailure: 'Failed to delete, please try again later', questionContent: 'Recommended Question',
saveSuccess: 'Saved successfully', cancel: 'Cancel',
saveFailure: 'Failed to save, please try again later', confirm: 'Confirm',
loadSuccess: 'Loaded successfully', save: 'Save',
loadFailure: 'Failed to load, please try again later', },
noContent: 'No content found', message: {
loading: 'Loading...', loadSuccess: 'Loaded successfully',
updateRecommendation: 'Update Recommendation', loadFailed: 'Load failed, please try again later',
addRecommendation: 'Add Recommendation', loadFailedMess: 'Failed to load recommended questions',
} notFound: 'Opening statement not found',
saveSuccess: 'Saved successfully',
saveFailed: 'Save failed, please try again later',
addSuccess: 'Recommended question added successfully',
addFailed: 'Failed to add recommended question',
editSuccess: 'Recommended question edited successfully',
editFailed: 'Failed to edit recommended question, please try again later',
deleteSuccess: 'Deleted successfully',
deleteFailed: 'Deletion failed',
},
confirm: {
save: 'Are you sure you want to save the changes?',
tips: 'Tips',
delete: 'Are you sure you want to delete this recommended question?',
deleteConfirm: 'Delete Confirmation',
},
placeholder: {
selectType: 'Select chat type',
},
},
vabtabs: {
refresh: 'Refresh',
closeOthers: 'Close Others',
closeLeft: 'Close Left',
closeRight: 'Close Right',
closeAll: 'Close All',
},
}, },
} }

View File

@ -472,7 +472,7 @@ export default {
enterApiValue: '請輸入密鑰值', enterApiValue: '請輸入密鑰值',
createBy: '創建人', createBy: '創建人',
placeCreateby: '請輸入創建人', placeCreateby: '請輸入創建人',
search:'查詢', search: '查詢',
index: '序號', index: '序號',
createTime: '創建時間', createTime: '創建時間',
updateBy: '更新人', updateBy: '更新人',
@ -495,8 +495,8 @@ export default {
batchDeleteFail: '批量刪除失敗', batchDeleteFail: '批量刪除失敗',
dictionaryKey: '密鑰名稱', dictionaryKey: '密鑰名稱',
dictionaryValue: '密鑰值', dictionaryValue: '密鑰值',
show:'顯示', show: '顯示',
hide:'隱藏', hide: '隱藏',
operation: '操作', operation: '操作',
remark: '備註', remark: '備註',
enterRemark: '請輸入備註信息', enterRemark: '請輸入備註信息',
@ -507,7 +507,7 @@ export default {
refreshCacheFail: '快取刷新失敗', refreshCacheFail: '快取刷新失敗',
copySuccess: '複製成功', copySuccess: '複製成功',
copyFail: '複製失敗', copyFail: '複製失敗',
copy:'複製', copy: '複製',
dictionaryKeyLength: '密鑰名稱長度在 1 到 255 個字符', dictionaryKeyLength: '密鑰名稱長度在 1 到 255 個字符',
dictionaryValueLength: '密鑰值長度在 1 到 255 個字符', dictionaryValueLength: '密鑰值長度在 1 到 255 個字符',
getApiKeysFail: '获取API密鑰列表失败', getApiKeysFail: '获取API密鑰列表失败',
@ -515,35 +515,70 @@ export default {
Tip: '提示', Tip: '提示',
selectDeleteData: '請選擇要刪除的數據', selectDeleteData: '請選擇要刪除的數據',
confirmDeleteApiKeys: '此操作將永久删除选中的 ', confirmDeleteApiKeys: '此操作將永久删除选中的 ',
confirmDeleteApiKeysEnd:' 條API密鑰是否繼續', confirmDeleteApiKeysEnd: ' 條API密鑰是否繼續',
confirmDeleteApiKeysEndPlural:' 條API密鑰是否繼續', confirmDeleteApiKeysEndPlural: ' 條API密鑰是否繼續',
confirmRefreshCache: '此操作將刷新Redis缓存重新加载所有API密鑰是否繼續', confirmRefreshCache: '此操作將刷新Redis缓存重新加载所有API密鑰是否繼續',
updateSuccess: '更新成功', updateSuccess: '更新成功',
updateFail:'更新失敗', updateFail: '更新失敗',
addSuccess:'新增成功', addSuccess: '新增成功',
addFail:'新增失敗', addFail: '新增失敗',
}, },
prologue:{ prologue: {
title: '開場白管理',
query: '查詢',
save: '儲存',
chatType: '聊天類型', chatType: '聊天類型',
selectChatType: '選擇聊天類型', chatTypes: {
prologueContent: '開場白內容', '1': '故障診斷',
'2': '智慧問答',
'3': '圖表報告',
'4': '應急助手問答',
'5': '診斷代碼查詢',
},
openingContent: '開場白內容',
addRecommend: '新增推薦問題', addRecommend: '新增推薦問題',
recommendQuestion: '推薦問題', recommendation: '推薦問題',
actions: '操作', action: '操作',
edit: '編輯', edit: '編輯',
delete: '刪除', delete: '刪除',
confirmDelete: '確定要刪除該推薦問題嗎?', dialog: {
confirmSave: '是否確認保存修改?', addTitle: '新增推薦問題',
deleteSuccess: '刪除成功', editTitle: '編輯推薦問題',
deleteFailure: '刪除失敗,請稍後重試', questionContent: '推薦問題',
saveSuccess: '保存成功', cancel: '取消',
saveFailure: '保存失敗,請稍後重試', confirm: '確認',
loadSuccess: '加載成功', save: '儲存',
loadFailure: '加載失敗,請稍後重試', },
noContent: '未找到內容', message: {
loading: '加載中...', loadSuccess: '加載成功',
updateRecommendation: '更新推薦問題', loadFailed: '加載失敗,請稍後重試',
addRecommendation: '新增推薦問題', loadFailedMess: '加載推薦問題失敗',
} notFound: '未找到開場白內容',
saveSuccess: '儲存成功',
saveFailed: '儲存失敗,請稍後重試',
addSuccess: '推薦問題新增成功',
addFailed: '新增推薦問題失敗',
editSuccess: '推薦問題編輯成功',
editFailed: '編輯推薦問題失敗,請稍後重試',
deleteSuccess: '刪除成功',
deleteFailed: '刪除失敗',
},
confirm: {
save: '是否確認儲存修改?',
tips: '提示',
delete: '確定要刪除該推薦問題嗎?',
deleteConfirm: '刪除確認',
},
placeholder: {
selectType: '選擇聊天類型',
},
},
vabtabs: {
refresh: '刷新',
closeOthers: '關閉其他',
closeLeft: '關閉左側',
closeRight: '關閉右側',
closeAll: '關閉全部',
},
}, },
} }

View File

@ -481,7 +481,7 @@ export default {
enterApiValue: '请输入密钥值', enterApiValue: '请输入密钥值',
createBy: '创建人', createBy: '创建人',
placeCreateby: '请输入创建人', placeCreateby: '请输入创建人',
search:'查询', search: '查询',
index: '序号', index: '序号',
createTime: '创建时间', createTime: '创建时间',
updateBy: '更新人', updateBy: '更新人',
@ -503,8 +503,8 @@ export default {
batchDeleteFail: '批量删除失败', batchDeleteFail: '批量删除失败',
dictionaryKey: '密钥名称', dictionaryKey: '密钥名称',
dictionaryValue: '密钥值', dictionaryValue: '密钥值',
show:'显示', show: '显示',
hide:'隐藏', hide: '隐藏',
operation: '操作', operation: '操作',
remark: '备注', remark: '备注',
enterRemark: '请输入备注信息', enterRemark: '请输入备注信息',
@ -513,7 +513,7 @@ export default {
cancel: '取消', cancel: '取消',
refreshCacheSuccess: '缓存刷新成功', refreshCacheSuccess: '缓存刷新成功',
refreshCacheFail: '缓存刷新失败', refreshCacheFail: '缓存刷新失败',
copy:'复制', copy: '复制',
copySuccess: '复制成功', copySuccess: '复制成功',
copyFail: '复制失败', copyFail: '复制失败',
dictionaryKeyLength: '密钥名称长度在 1 到 255 个字符', dictionaryKeyLength: '密钥名称长度在 1 到 255 个字符',
@ -523,35 +523,70 @@ export default {
Tip: '提示', Tip: '提示',
selectDeleteData: '请选择要删除的数据', selectDeleteData: '请选择要删除的数据',
confirmDeleteApiKeys: '此操作将永久删除选中的 ', confirmDeleteApiKeys: '此操作将永久删除选中的 ',
confirmDeleteApiKeysEnd:' 条API密钥是否继续', confirmDeleteApiKeysEnd: ' 条API密钥是否继续',
confirmDeleteApiKeysEndPlural:' 条API密钥是否继续', confirmDeleteApiKeysEndPlural: ' 条API密钥是否继续',
confirmRefreshCache: '此操作将刷新Redis缓存重新加载所有API密钥是否继续', confirmRefreshCache: '此操作将刷新Redis缓存重新加载所有API密钥是否继续',
updateSuccess: '更新成功', updateSuccess: '更新成功',
updateFail: '更新失败', updateFail: '更新失败',
addSuccess: '新增成功', addSuccess: '新增成功',
addFail: '新增失败', addFail: '新增失败',
}, },
prologue:{ prologue: {
title: '开场白管理',
query: '查询',
save: '保存',
chatType: '聊天类型', chatType: '聊天类型',
selectChatType: '选择聊天类型', chatTypes: {
prologueContent: '开场白内容', '1': '故障诊断',
'2': '智能问答',
'3': '图表报告',
'4': '应急助手问答',
'5': '诊断代码查询',
},
openingContent: '开场白内容',
addRecommend: '新增推荐问题', addRecommend: '新增推荐问题',
recommendQuestion: '推荐问题', recommendation: '推荐问题',
actions: '操作', action: '操作',
edit: '编辑', edit: '编辑',
delete: '删除', delete: '删除',
confirmDelete: '确定要删除该推荐问题吗?', dialog: {
confirmSave: '是否确认保存修改?', addTitle: '新增推荐问题',
deleteSuccess: '删除成功', editTitle: '编辑推荐问题',
deleteFailure: '删除失败,请稍后重试', questionContent: '推荐问题',
saveSuccess: '保存成功', cancel: '取消',
saveFailure: '保存失败,请稍后重试', confirm: '确认',
loadSuccess: '加载成功', save: '保存',
loadFailure: '加载失败,请稍后重试', },
noContent: '未找到内容', message: {
loading: '加载中...', loadSuccess: '加载成功',
updateRecommendation: '更新推荐问题', loadFailed: '加载失败,请稍后重试',
addRecommendation: '新增推荐问题', loadFailedMess: '加载推荐问题失败',
notFound: '未找到开场白内容',
saveSuccess: '保存成功',
saveFailed: '保存失败,请稍后重试',
addSuccess: '推荐问题新增成功',
addFailed: '新增推荐问题失败',
editSuccess: '推荐问题编辑成功',
editFailed: '编辑推荐问题失败,请稍后重试',
deleteSuccess: '删除成功',
deleteFailed: '删除失败',
},
confirm: {
save: '是否确认保存修改?',
tips: '提示',
delete: '确定要删除该推荐问题吗?',
deleteConfirm:'删除确认'
},
placeholder: {
selectType: '选择聊天类型',
},
},
vabtabs:{
refresh:'刷新',
closeOthers:'关闭其他',
closeLeft:'关闭左侧',
closeRight:'关闭右侧',
closeAll:'关闭全部'
} }
}, },
} }

View File

@ -340,9 +340,13 @@ const renameForm = reactive({
const getFileTypeIcon = (fileType: string) => { const getFileTypeIcon = (fileType: string) => {
// 使 // 使
// const getIconUrl = (iconName: string) => {
// return new URL(require(`@/assets/img/filetype-icon/${iconName}.png`), import.meta.url).href
// }
const getIconUrl = (iconName: string) => { const getIconUrl = (iconName: string) => {
return new URL(require(`@/assets/img/filetype-icon/${iconName}.png`), import.meta.url).href return new URL(`/src/assets/img/filetype-icon/${iconName}.png`, import.meta.url).href
} }
const iconMap: Record<string, string> = { const iconMap: Record<string, string> = {
'pdf': getIconUrl('pdf'), 'pdf': getIconUrl('pdf'),

View File

@ -2,46 +2,73 @@
<el-card> <el-card>
<el-form :model="form" label-width="120px"> <el-form :model="form" label-width="120px">
<el-form-item> <el-form-item>
<el-button type="primary" @click="load">查询</el-button> <el-button type="primary" @click="load">{{t('vabI18n.prologue.query')}}</el-button>
<el-button type="success" @click="save">保存</el-button> <el-button type="success" @click="save">{{t('vabI18n.prologue.save')}}</el-button>
</el-form-item> </el-form-item>
<el-form-item :label="聊天类型"> <el-form-item :label="t('vabI18n.prologue.chatType')">
<el-select v-model="form.chatType" placeholder="选择聊天类型"> <el-select v-model="form.chatType" :placeholder="t('vabI18n.prologue.placeholder.selectType')">
<el-option label="故障诊断" value="1" /> <el-option :label="t('vabI18n.prologue.chatTypes.1')" value="1" />
<el-option label="智能问答" value="2" /> <el-option :label="t('vabI18n.prologue.chatTypes.2')" value="2" />
<el-option label="图表报告" value="3" /> <el-option :label="t('vabI18n.prologue.chatTypes.3')" value="3" />
<el-option label="应急助手问答" value="4" /> <el-option :label="t('vabI18n.prologue.chatTypes.4')" value="4" />
<el-option label="诊断代码查询" value="5" /> <el-option :label="t('vabI18n.prologue.chatTypes.5')" value="5" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="开场白内容"> <el-form-item :label="t('vabI18n.prologue.openingContent')">
<el-input type="textarea" v-model="form.content" rows="8"></el-input> <el-input type="textarea" v-model="form.content" rows="8"></el-input>
</el-form-item> </el-form-item>
<!-- 新增推荐问题 --> <!-- 新增推荐问题 -->
<el-form-item> <el-form-item>
<el-button type="primary" @click="addRecommend">新增推荐问题</el-button> <el-button type="primary" @click="addRecommend">{{t('vabI18n.prologue.addRecommend')}}</el-button>
</el-form-item> </el-form-item>
<!-- 推荐问题列表 --> <!-- 推荐问题列表 -->
<el-table :data="recommendations" style="width: 100%" border> <el-table :data="recommendations" style="width: 100%" border>
<el-table-column label="推荐问题" prop="questionContent" /> <el-table-column :label="t('vabI18n.prologue.recommendation')" prop="questionContent" />
<el-table-column label="操作" width="180"> <el-table-column :label="t('vabI18n.prologue.action')" width="180">
<template v-slot="scope"> <template v-slot="scope">
<el-button size="mini" @click="editRecommend(scope.row)">编辑</el-button> <el-button size="mini" @click="editRecommend(scope.row)">{{t('vabI18n.prologue.edit')}}</el-button>
<el-button size="mini" type="danger" @click="deleteRecommend(scope.row)">删除</el-button> <el-button size="mini" type="danger" @click="deleteRecommend(scope.row)">{{t('vabI18n.prologue.delete')}}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-form> </el-form>
</el-card> </el-card>
<!-- 新增推荐问题弹窗 -->
<el-dialog v-model="dialogVisible" :title="t('vabI18n.prologue.dialog.addTitle')">
<el-form :model="newRecommendForm" label-width="120px">
<el-form-item :label="t('vabI18n.prologue.dialog.questionContent')">
<el-input v-model="newRecommendForm.questionContent" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">{{t('vabI18n.prologue.dialog.cancel')}}</el-button>
<el-button type="primary" @click="saveNewRecommend">{{t('vabI18n.prologue.dialog.save')}}</el-button>
</span>
</el-dialog>
<!-- 编辑推荐问题弹窗 -->
<el-dialog v-model="editdialogVisible" :title="t('vabI18n.prologue.dialog.editTitle')">
<el-form :model="currentRecommendation" label-width="120px">
<el-form-item label="t('vabI18n.prologue.dialog.questionContent')">
<el-input v-model="currentRecommendation.questionContent" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editdialogVisible = false">{{t('vabI18n.prologue.dialog.cancel')}}</el-button>
<el-button type="primary" @click="saveEditRecommend">{{t('vabI18n.prologue.dialog.save')}}</el-button>
</span>
</el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, onMounted } from 'vue' import { ref, watch, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { getRemark, saveRemark, getRecommendations, editRecommendation, deleteRecommendation } from '@/api/prologue' import { getRemark, saveRemark, getRecommendations, editRecommendation, deleteRecommendation, addRecommendation } from '@/api/prologue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n() const { t, locale } = useI18n()
@ -57,6 +84,12 @@
const recommendations = ref([]) // const recommendations = ref([]) //
const currentRecommendation = ref({ questionContent: '' }) // const currentRecommendation = ref({ questionContent: '' }) //
const dialogVisible = ref(false) //
const editdialogVisible = ref(false) //
const newRecommendForm = ref({ //
questionContent: '',
chatType: form.value.chatType,
})
// //
const load = async () => { const load = async () => {
@ -64,14 +97,14 @@
const res = await getRemark(form.value.chatType) // chatType const res = await getRemark(form.value.chatType) // chatType
if (res.data) { if (res.data) {
form.value.content = res.data.content form.value.content = res.data.content
ElMessage.success('加载成功') ElMessage.success(t('vabI18n.prologue.message.loadSuccess'))
await loadRecommendations() // await loadRecommendations() //
} else { } else {
form.value.content = '' form.value.content = ''
ElMessage.error('未找到开场白内容') ElMessage.error(t('vabI18n.prologue.message.notFound'))
} }
} catch (error) { } catch (error) {
ElMessage.error('加载失败,请稍后重试') ElMessage.error(t('vabI18n.prologue.message.loadFail'))
} }
} }
@ -84,7 +117,7 @@
recommendations.value = res.data // res.data recommendations.value = res.data // res.data
} }
} catch (error) { } catch (error) {
ElMessage.error('加载推荐问题失败') ElMessage.error(t('vabI18n.prologue.message.loadFailedMess'))
} }
} }
@ -98,46 +131,71 @@
// //
const save = () => { const save = () => {
ElMessageBox.confirm('是否确认保存修改?', '提示', { ElMessageBox.confirm(t('vabI18n.prologue.confirm.save'), t('vabI18n.prologue.confirm.tips'), {
confirmButtonText: '确认', confirmButtonText: t('vabI18n.prologue.dialog.confirm'),
cancelButtonText: '取消', cancelButtonText: t('vabI18n.prologue.dialog.cancel'),
type: 'warning', type: 'warning',
}).then(async () => { }).then(async () => {
try { try {
await saveRemark(form.value) await saveRemark(form.value)
ElMessage.success('保存成功') ElMessage.success(t('vabI18n.prologue.message.saveSuccess'))
} catch (error) { } catch (error) {
ElMessage.error('保存失败,请稍后重试') ElMessage.error(t('vabI18n.prologue.message.saveFailed'))
} }
}) })
} }
// //
const addRecommend = () => { const addRecommend = () => {
// currentRecommendation.value = { questionContent: '' } // newRecommendForm.value = { questionContent: '', chatType: form.value.chatType } // chatType
// dialogVisible.value = true // dialogVisible.value = true //
}
//
const saveNewRecommend = async () => {
try {
// chatType
await addRecommendation(newRecommendForm.value) // API
ElMessage.success(t('vabI18n.prologue.message.addSuccess'))
dialogVisible.value = false //
await loadRecommendations() //
} catch (error) {
ElMessage.error(t('vabI18n.prologue.message.addFailed'))
}
} }
// //
const editRecommend = (row: any) => { const editRecommend = (row: any) => {
// currentRecommendation.value = { ...row } // currentRecommendation.value = { ...row } //
// dialogVisible.value = true // editdialogVisible.value = true
}
//
const saveEditRecommend = async () => {
try {
// chatType
await editRecommendation(currentRecommendation.value) // API
ElMessage.success(t('vabI18n.prologue.message.editSuccess'))
editdialogVisible.value = false //
await loadRecommendations() //
} catch (error) {
ElMessage.error(t('vabI18n.prologue.message.editFailed'))
}
} }
// //
const deleteRecommend = (row: any) => { const deleteRecommend = (row: any) => {
ElMessageBox.confirm('确定要删除该推荐问题吗?', '删除确认', { ElMessageBox.confirm(t('vabI18n.prologue.confirm.delete'), t('vabI18n.prologue.confirm.tips'), {
confirmButtonText: '确定', confirmButtonText: t('vabI18n.prologue.dialog.confirm'),
cancelButtonText: '取消', cancelButtonText: t('vabI18n.prologue.dialog.cancel'),
type: 'warning', type: 'warning',
}).then(async () => { }).then(async () => {
try { try {
await deleteRecommendation(row.id) // id await deleteRecommendation(row.id) // id
console.log('待删除的row.id',row.id) ElMessage.success(t('vabI18n.prologue.message.deleteSuccess'))
ElMessage.success('删除成功')
await loadRecommendations() // await loadRecommendations() //
} catch (error) { } catch (error) {
ElMessage.error('删除失败') ElMessage.error(t('vabI18n.prologue.message.deleteFailed'))
} }
}) })
} }

View File

@ -48,4 +48,24 @@ public class PrologueController {
return ResultUtils.success(prologueService.deleteRecommendQuestionById(id)); return ResultUtils.success(prologueService.deleteRecommendQuestionById(id));
} }
@PostMapping("/addRecommendation")
public ResultUtils post(@RequestBody PrologueQuestion prologueQuestion) {
try {
prologueService.addRecommendation(prologueQuestion);
return ResultUtils.success("推荐问题新增成功");
} catch (Exception e) {
return ResultUtils.error("新增推荐问题失败: ");
}
}
@PostMapping("/eidtRecommendation")
public ResultUtils eidtRecommendation(@RequestBody PrologueQuestion prologueQuestion) {
try {
prologueService.editRecommendation(prologueQuestion);
return ResultUtils.success("推荐问题修改成功");
}catch (Exception e) {
return ResultUtils.error("推荐问题修改失败: ");
}
}
} }

View File

@ -16,4 +16,8 @@ public interface PrologueMapper {
List<PrologueQuestion> getQuestionsbyChatType(String chatType); List<PrologueQuestion> getQuestionsbyChatType(String chatType);
Boolean deleteQuesById(Integer id); Boolean deleteQuesById(Integer id);
Boolean addQues(PrologueQuestion ques);
Boolean editQues(PrologueQuestion ques);
} }

View File

@ -3,6 +3,7 @@ package com.bjtds.brichat.service;
import com.bjtds.brichat.entity.sys.PrologueQuestion; import com.bjtds.brichat.entity.sys.PrologueQuestion;
import com.bjtds.brichat.entity.sys.SystemRemark; import com.bjtds.brichat.entity.sys.SystemRemark;
import com.sun.org.apache.xpath.internal.operations.Bool;
import java.util.List; import java.util.List;
@ -15,4 +16,8 @@ public interface PrologueService {
List<PrologueQuestion> getRecommendations(String chatType); List<PrologueQuestion> getRecommendations(String chatType);
Boolean deleteRecommendQuestionById(Integer id); Boolean deleteRecommendQuestionById(Integer id);
Boolean addRecommendation(PrologueQuestion prologueQuestion);
Boolean editRecommendation(PrologueQuestion prologueQuestion);
} }

View File

@ -5,6 +5,7 @@ import com.bjtds.brichat.entity.sys.SystemRemark;
import com.bjtds.brichat.mapper.opengauss.PrologueMapper; import com.bjtds.brichat.mapper.opengauss.PrologueMapper;
import com.bjtds.brichat.service.PrologueService; import com.bjtds.brichat.service.PrologueService;
import com.netflix.discovery.converters.Auto; import com.netflix.discovery.converters.Auto;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -42,4 +43,23 @@ public class PrologueServiceImpl implements PrologueService {
public Boolean deleteRecommendQuestionById(Integer id) { public Boolean deleteRecommendQuestionById(Integer id) {
return prologueMapper.deleteQuesById(id); return prologueMapper.deleteQuesById(id);
} }
@Override
public Boolean addRecommendation(PrologueQuestion prologueQuestion) {
PrologueQuestion ques=new PrologueQuestion();
ques.setChatType(prologueQuestion.getChatType());
ques.setQuestionContent(prologueQuestion.getQuestionContent());
ques.setUpdatedAt(LocalDateTime.now());
return prologueMapper.addQues(ques);
}
@Override
public Boolean editRecommendation(PrologueQuestion prologueQuestion) {
PrologueQuestion ques=new PrologueQuestion();
ques.setId(prologueQuestion.getId());
ques.setChatType(prologueQuestion.getChatType());
ques.setQuestionContent(prologueQuestion.getQuestionContent());
ques.setUpdatedAt(LocalDateTime.now());
return prologueMapper.editQues(ques);
}
} }

View File

@ -16,12 +16,22 @@
<result column="question_content" property="questionContent" /> <result column="question_content" property="questionContent" />
<result column="updated_at" property="updatedAt" /> <result column="updated_at" property="updatedAt" />
</resultMap> </resultMap>
<insert id="addQues" >
INSERT INTO bripg.t_chat_recommendations (chat_type, question_content, updated_at)
VALUES (#{chatType}, #{questionContent}, #{updatedAt})
</insert>
<update id="updateRemark"> <update id="updateRemark">
update bripg.t_chat_prologue update bripg.t_chat_prologue
set content= #{content} , updated_at =#{updatedAt} set content= #{content} , updated_at =#{updatedAt}
where chat_type = #{chatType} where chat_type = #{chatType}
</update> </update>
<update id="editQues">
update bripg.t_chat_recommendations
set question_content=#{questionContent}
where id =#{id}
</update>
<delete id="deleteQuesById"> <delete id="deleteQuesById">
DELETE FROM bripg.t_chat_recommendations DELETE FROM bripg.t_chat_recommendations
WHERE id = #{id} WHERE id = #{id}