可信代码库-AI大模型批量对话接口对话及对话功能开发
This commit is contained in:
@@ -36,3 +36,6 @@ VITE_USER_CENTER_HOST = 'https://test.gitcode.net/child/user-center/'
|
|||||||
VITE_COPILOT_HOST = 'https://test.gitcode.net/child/aichat-app/'
|
VITE_COPILOT_HOST = 'https://test.gitcode.net/child/aichat-app/'
|
||||||
|
|
||||||
VITE_BASE_URL=/
|
VITE_BASE_URL=/
|
||||||
|
|
||||||
|
# AI大模型接口地址
|
||||||
|
VITE_AI_API_HOST = ''http://222.20.126.208:8089'
|
||||||
|
|||||||
3
.env.loc
3
.env.loc
@@ -38,3 +38,6 @@ VITE_USER_CENTER_HOST = 'https://local.gitcode.net:8002'
|
|||||||
VITE_COPILOT_HOST = 'https://local.gitcode.net:8003/child/aichat-app'
|
VITE_COPILOT_HOST = 'https://local.gitcode.net:8003/child/aichat-app'
|
||||||
|
|
||||||
VITE_BASE_URL=/openRepoPortal/
|
VITE_BASE_URL=/openRepoPortal/
|
||||||
|
|
||||||
|
# AI大模型接口地址
|
||||||
|
VITE_AI_API_HOST = ''http://222.20.126.208:8089'
|
||||||
|
|||||||
3
.env.pre
3
.env.pre
@@ -38,3 +38,6 @@ VITE_USER_CENTER_HOST = 'https://pre-usercenter-app.gitcode.com'
|
|||||||
VITE_COPILOT_HOST = 'https://pre-copilot-app.gitcode.com'
|
VITE_COPILOT_HOST = 'https://pre-copilot-app.gitcode.com'
|
||||||
|
|
||||||
VITE_BASE_URL=/openRepoPortal/
|
VITE_BASE_URL=/openRepoPortal/
|
||||||
|
|
||||||
|
# AI大模型接口地址
|
||||||
|
VITE_AI_API_HOST = ''http://222.20.126.208:8089'
|
||||||
|
|||||||
@@ -38,3 +38,6 @@ VITE_USER_CENTER_HOST = 'https://usercenter-app.gitcode.com'
|
|||||||
VITE_COPILOT_HOST = 'https://copilot-app.gitcode.com'
|
VITE_COPILOT_HOST = 'https://copilot-app.gitcode.com'
|
||||||
|
|
||||||
VITE_BASE_URL=/openRepoPortal/
|
VITE_BASE_URL=/openRepoPortal/
|
||||||
|
|
||||||
|
# AI大模型接口地址
|
||||||
|
VITE_AI_API_HOST = ''http://222.20.126.208:8089'
|
||||||
|
|||||||
@@ -113,6 +113,115 @@
|
|||||||
</div>
|
</div>
|
||||||
</d-tab>
|
</d-tab>
|
||||||
<d-tab id="scdh" title="收藏对话">
|
<d-tab id="scdh" title="收藏对话">
|
||||||
|
<d-search icon-position="left" style="width: 100%" placeholder="请输入搜索软件名称" v-model="searchText" @change="handleSearch"></d-search>
|
||||||
|
<!-- 可滚动内容区域 -->
|
||||||
|
<div class="scrollable-content">
|
||||||
|
<d-collapse class="jyh-collapse" v-model="collapseValue">
|
||||||
|
<d-collapse-item name="today">
|
||||||
|
<template #title>
|
||||||
|
<div class="jyh-collapse-title">
|
||||||
|
<d-icon style="margin-right: 4px" name="icon-delay"></d-icon>今天
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
<!-- 循环生成卡片列表 -->
|
||||||
|
<div v-if="cardList.length>0">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in cardList"
|
||||||
|
:key="index"
|
||||||
|
:class="['mb-3 jyh-collapse-card', { 'selected-card': selectedIndex === item.id }]"
|
||||||
|
@click="selectCard(item)"
|
||||||
|
@mouseenter="hoverIndex = index"
|
||||||
|
@mouseleave="hoverIndex = null"
|
||||||
|
>
|
||||||
|
<!-- 卡片标题 -->
|
||||||
|
<div class="card-header">
|
||||||
|
<h4>{{ item.title }}</h4>
|
||||||
|
<!-- 悬停操作按钮 -->
|
||||||
|
<div class="card-actions" v-show="hoverIndex === index">
|
||||||
|
<d-tooltip content="编辑">
|
||||||
|
<d-icon style="font-size: 14px;margin-right: 2px" @click.stop="handleEdit(item)" name="icon-edit-3"></d-icon>
|
||||||
|
</d-tooltip>
|
||||||
|
<d-tooltip content="分享">
|
||||||
|
<d-icon style="font-size: 14px;margin-right: 2px" @click.stop="handleShare(item)" name="icon-redo-new"></d-icon>
|
||||||
|
</d-tooltip>
|
||||||
|
<d-tooltip content="更多">
|
||||||
|
<d-icon style="font-size: 14px;" @click.stop="handleMore(item)" name="icon-more-operate"></d-icon>
|
||||||
|
</d-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 卡片内容 -->
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="content-left">
|
||||||
|
<img width="16" style="margin-right: 4px" src="@/assets/imgs/jyh/ai/aiLogo2.png" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="content-right">
|
||||||
|
<span class="time-text">{{ formatTime(item.time) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<NoData v-else :small="false"></NoData>
|
||||||
|
</div>
|
||||||
|
</d-collapse-item>
|
||||||
|
<d-collapse-item name="yestoday">
|
||||||
|
<template #title>
|
||||||
|
<div class="jyh-collapse-title">
|
||||||
|
<d-icon style="margin-right: 4px" name="icon-delay"></d-icon>昨天
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in cardList"
|
||||||
|
:key="index"
|
||||||
|
class="mb-3 jyh-collapse-card"
|
||||||
|
>
|
||||||
|
<!-- 卡片标题 -->
|
||||||
|
<div class="card-header">
|
||||||
|
<h4>{{ item.title }}</h4>
|
||||||
|
</div>
|
||||||
|
<!-- 卡片内容 -->
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="content-left">
|
||||||
|
<img width="16" style="margin-right: 4px" src="@/assets/imgs/jyh/ai/aiLogo2.png" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="content-right">
|
||||||
|
<span class="time-text">{{ formatTime(item.time) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</d-collapse-item>
|
||||||
|
</d-collapse>
|
||||||
|
</div>
|
||||||
|
<!-- 固定在底部的控制栏 -->
|
||||||
|
<div class="bottom-control-bar">
|
||||||
|
<div class="control-left">
|
||||||
|
历史对话保存条数
|
||||||
|
<d-select
|
||||||
|
v-model="historyLimit"
|
||||||
|
style="width: 60px"
|
||||||
|
size="sm"
|
||||||
|
class="jyh-select"
|
||||||
|
>
|
||||||
|
<d-option value="10">10</d-option>
|
||||||
|
<d-option value="20">20</d-option>
|
||||||
|
<d-option value="30">30</d-option>
|
||||||
|
<d-option value="0">0</d-option>
|
||||||
|
</d-select>
|
||||||
|
</div>
|
||||||
|
<div class="control-right">
|
||||||
|
<d-button class="jyh-button2" variant="solid" @click="openBatchManageModal">
|
||||||
|
<template #icon>
|
||||||
|
<d-icon name="icon-property-setting"></d-icon>
|
||||||
|
</template>
|
||||||
|
批量管理
|
||||||
|
</d-button>
|
||||||
|
<BatchManageModal ref="BatchManageModalRef"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</d-tab>
|
</d-tab>
|
||||||
</d-tabs>
|
</d-tabs>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<!-- <ToolsFloat v-if="showToolsFloat" />-->
|
<!-- <ToolsFloat v-if="showToolsFloat" />-->
|
||||||
<!-- 在 d-layout 结束前添加返回按钮 -->
|
<!-- 在 d-layout 结束前添加返回按钮 -->
|
||||||
<div class="back-in-btn">
|
<div class="back-in-btn">
|
||||||
<div class="back-in-time-btn" @click="handleBackInTime">
|
<div class="back-in-time-btn" @click="toggleHistory" :class="{ 'active': isHistoryVisible }">
|
||||||
<i class="icon icon-history" title="查看历史"></i>
|
<i class="icon icon-history" title="查看历史"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="back-in-time-btn" @click="handleBackInTime">
|
<div class="back-in-time-btn" @click="handleBackInTime">
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ViewHistoryAside />
|
<ViewHistoryAside v-show="isHistoryVisible"/>
|
||||||
</d-layout>
|
</d-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -104,6 +104,9 @@ const refHeader: any = ref(null);
|
|||||||
const footerSize = useElementSize(refFooter);
|
const footerSize = useElementSize(refFooter);
|
||||||
const isHome = computed(() => route.name === 'home');
|
const isHome = computed(() => route.name === 'home');
|
||||||
|
|
||||||
|
// 控制 ViewHistoryAside 组件的显示状态
|
||||||
|
const isHistoryVisible = ref(false);
|
||||||
|
|
||||||
// aside 设置可见性 header有两层,有顶栏信息,两层sidebar 都不可见
|
// aside 设置可见性 header有两层,有顶栏信息,两层sidebar 都不可见
|
||||||
const asideSetShow = computed(() => {
|
const asideSetShow = computed(() => {
|
||||||
if (route.meta.asideMenu === 'drawer') return false;
|
if (route.meta.asideMenu === 'drawer') return false;
|
||||||
@@ -160,26 +163,10 @@ const handleClickMenu = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const outOfSearch = ref(true); // 在search页面隐藏footer
|
// 切换 ViewHistoryAside 组件的显示与隐藏
|
||||||
router.afterEach((to, form) => {
|
const toggleHistory = () => {
|
||||||
outOfSearch.value = to.name !== 'search';
|
isHistoryVisible.value =!isHistoryVisible.value;
|
||||||
});
|
|
||||||
microApp.router.afterEach({
|
|
||||||
'micoro-app-homeweb-app': (to, from) => {
|
|
||||||
outOfSearch.value = to.pathname !== '/search';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const checkPage = (data: any) => {
|
|
||||||
if (data.type === 'checkPage') {
|
|
||||||
return 'ready';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
|
||||||
microApp.addDataListener('micoro-app-homeweb-app', checkPage, false);
|
|
||||||
});
|
|
||||||
onUnmounted(() => {
|
|
||||||
microApp.removeDataListener('micoro-app-homeweb-app', checkPage);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -230,6 +217,14 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
|
||||||
|
.active {
|
||||||
|
background-color: #f0f0f0; /* 灰色背景 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.active .icon {
|
||||||
|
transform: translateY(-4px); /* 图标上移4px */
|
||||||
|
}
|
||||||
|
|
||||||
.back-in-time-btn {
|
.back-in-time-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
311
src/views/Jyh/AI/Home/components/AIList.vue
Normal file
311
src/views/Jyh/AI/Home/components/AIList.vue
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
<template>
|
||||||
|
<div class="secret-container">
|
||||||
|
<!-- <div class="title">以下是关于近期预警的公告:</div>-->
|
||||||
|
<div class="mt-3">
|
||||||
|
<d-table
|
||||||
|
:key="tableKey"
|
||||||
|
ref="filterTableRef"
|
||||||
|
class="jyh-table"
|
||||||
|
v-if="tableData.length"
|
||||||
|
:striped="false"
|
||||||
|
:data="tableData"
|
||||||
|
>
|
||||||
|
<template v-for="column in columns" :key="column.key">
|
||||||
|
<d-column :field="column.key" :header="column.label" :width="column.width || 120" show-overflow-tooltip></d-column>
|
||||||
|
</template>
|
||||||
|
</d-table>
|
||||||
|
|
||||||
|
<!-- <DataPanel v-else skeleton :card="false" :empty="true">-->
|
||||||
|
<!-- </DataPanel>-->
|
||||||
|
<NoData v-else :small="false"></NoData>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<d-button v-if="isLogin" class="output-btn" @click="exportResult">导出列表</d-button>
|
||||||
|
<div class="bubble-bottom-operations">
|
||||||
|
<img onclick="handleRefresh()" src="@/assets/imgs/jyh/ai/icon_generate.png" />
|
||||||
|
<i class="icon-file" title="复制" onclick="handleFile()"></i>
|
||||||
|
<i class="icon-like" title="点赞" onclick="handleLike()"></i>
|
||||||
|
<i class="icon-dislike" title="踩" onclick="handleDislike()"></i>
|
||||||
|
<i class="icon-clever-customer" title="智能客服" onclick="handleCustomerService()"></i>
|
||||||
|
<i class="icon-more-operate" title="更多操作" onclick="handleMore()"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, defineProps, onMounted, watch, nextTick } from 'vue';
|
||||||
|
|
||||||
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
|
||||||
|
import { Message } from 'vue-devui';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import NoData from '@/components/NoData/NoData.vue';
|
||||||
|
import { useAccountStore } from '@/stores/user';
|
||||||
|
const { formatTime } = useTimeFormat();
|
||||||
|
import { getHomeNoticeList, getReleaseExport, releasePage, searchLanguageList } from '@/api/jyh';
|
||||||
|
import { useTimeFormat } from '@/utils/hooks/useTimeFormat';
|
||||||
|
import { useGlobalInfoStore } from '@/stores/Global';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
const props = defineProps(['content'])
|
||||||
|
debugger
|
||||||
|
|
||||||
|
const filterTableRef = ref();
|
||||||
|
const { namespace } = getOrgInfo();
|
||||||
|
const userInfo = useAccountStore();
|
||||||
|
// 定义 tableKey,用于强制刷新表格
|
||||||
|
const tableKey = ref(0);
|
||||||
|
const tableData = ref([]);
|
||||||
|
|
||||||
|
// 定义字段名和中文翻译的映射
|
||||||
|
const fieldTranslation = {
|
||||||
|
id: '编号',
|
||||||
|
task_id: '任务ID',
|
||||||
|
software_id: '软件ID',
|
||||||
|
component_id: '组件ID',
|
||||||
|
vuln_id: '漏洞ID',
|
||||||
|
cwe_id: 'CWE编号',
|
||||||
|
severity: '严重程度',
|
||||||
|
vuln_type: '漏洞类型',
|
||||||
|
cvss_score: 'CVSS评分',
|
||||||
|
attack_vector: '攻击向量',
|
||||||
|
attack_complexity: '攻击复杂度',
|
||||||
|
user_interaction: '用户交互',
|
||||||
|
privileges_required: '所需权限',
|
||||||
|
exploitability_score: '可利用性评分',
|
||||||
|
impact_score: '影响评分',
|
||||||
|
description: '描述',
|
||||||
|
extra_info: '额外信息',
|
||||||
|
fix_issue: '修复问题',
|
||||||
|
patch_link: '补丁链接',
|
||||||
|
source: '来源',
|
||||||
|
publish_date: '发布日期',
|
||||||
|
fix_version: '修复版本',
|
||||||
|
create_time: '创建时间',
|
||||||
|
update_time: '更新时间',
|
||||||
|
exploitability: '可利用性',
|
||||||
|
ai_fix_suggestion: 'AI修复建议',
|
||||||
|
upgradeVersion: '升级版本',
|
||||||
|
vulDescription: '漏洞描述',
|
||||||
|
vulFeature: '漏洞特征'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 定义 columns 数据
|
||||||
|
const columns = ref([ ]);
|
||||||
|
// 处理数据,生成列信息
|
||||||
|
const processData = () => {
|
||||||
|
debugger
|
||||||
|
const uniqueKeys = new Set();
|
||||||
|
tableData.value.forEach((item) => {
|
||||||
|
Object.keys(item).forEach((key) => uniqueKeys.add(key));
|
||||||
|
});
|
||||||
|
|
||||||
|
columns.value = Array.from(uniqueKeys).map((key) => ({
|
||||||
|
key,
|
||||||
|
label: fieldTranslation[key] || key,
|
||||||
|
width: 120
|
||||||
|
}));
|
||||||
|
tableKey.value++;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听数据变化,重新处理数据
|
||||||
|
watch(() => props.content, (newData) => {
|
||||||
|
tableData.value = JSON.parse(newData);
|
||||||
|
debugger
|
||||||
|
processData();
|
||||||
|
}, { deep: true,immediate:true });
|
||||||
|
|
||||||
|
|
||||||
|
// 跳转
|
||||||
|
const gotoDetail = (row) => {
|
||||||
|
// 后续请换成params,暂时params传参没传过去
|
||||||
|
router.push({
|
||||||
|
path: 'repoDetail/' + row.id
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportResult = async () => {
|
||||||
|
const selectDatas = tableData.value.map((d) => d.id);
|
||||||
|
if (!tableData.value.length || selectDatas.length <= 0) {
|
||||||
|
Message.info('未选择任何数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data, error } = await getReleaseExport({
|
||||||
|
list: selectDatas,
|
||||||
|
});
|
||||||
|
if (data && !error) {
|
||||||
|
// 方法1:如果后端返回的是文件流(Blob)
|
||||||
|
const blob = new Blob([data.data]);
|
||||||
|
const downloadUrl = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
// 创建一个临时的a标签触发下载
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = downloadUrl;
|
||||||
|
|
||||||
|
// 从Content-Disposition头中获取文件名,或者使用默认文件名
|
||||||
|
const contentDisposition = data.headers['content-disposition'];
|
||||||
|
let fileName = 'export.xlsx'; // 默认文件名
|
||||||
|
// if (contentDisposition) {
|
||||||
|
// const fileNameMatch = contentDisposition.match(/filename="?(.+)"?/);
|
||||||
|
// if (fileNameMatch && fileNameMatch[1]) {
|
||||||
|
// fileName = fileNameMatch[1].replace(/^[^0-9]*|[^0-9.xlsx]*$/g, "");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
link.setAttribute('download', fileName);
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
// 清理
|
||||||
|
document.body.removeChild(link);
|
||||||
|
window.URL.revokeObjectURL(downloadUrl);
|
||||||
|
} else {
|
||||||
|
console.error('导出失败:', error);
|
||||||
|
// 这里可以添加错误提示,比如使用Element Plus的ElMessage
|
||||||
|
ElMessage.error('文件导出失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 事件处理函数
|
||||||
|
function handleRefresh() {
|
||||||
|
console.log('刷新点击');
|
||||||
|
// 实际业务代码示例:
|
||||||
|
// location.reload(); // 重新加载页面
|
||||||
|
// 或调用API刷新数据
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFile() {
|
||||||
|
console.log('文件点击');
|
||||||
|
// 示例:触发文件上传
|
||||||
|
// document.getElementById('file-input').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLike() {
|
||||||
|
console.log('点赞点击');
|
||||||
|
// 示例:切换点赞状态
|
||||||
|
const likeBtn = document.querySelector('.icon-like');
|
||||||
|
likeBtn.classList.toggle('active');
|
||||||
|
// 这里可以添加AJAX请求提交点赞状态
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDislike() {
|
||||||
|
console.log('踩点击');
|
||||||
|
// 类似点赞的逻辑
|
||||||
|
const dislikeBtn = document.querySelector('.icon-dislike');
|
||||||
|
dislikeBtn.classList.toggle('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCustomerService() {
|
||||||
|
console.log('客服点击');
|
||||||
|
// 示例:打开客服对话框
|
||||||
|
// openChatWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMore() {
|
||||||
|
console.log('更多操作点击');
|
||||||
|
// 示例:显示下拉菜单
|
||||||
|
// showDropdownMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import 'devui-theme/styles-var/devui-var.scss';
|
||||||
|
|
||||||
|
.secret-container {
|
||||||
|
position: relative;
|
||||||
|
//min-height: 600px;
|
||||||
|
background: #ffffff;
|
||||||
|
padding: 20px;
|
||||||
|
margin-top: 16px;
|
||||||
|
border-radius: 15px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #191919;
|
||||||
|
font-family: HarmonyOS Sans SC;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secret-op {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: $devui-contrast;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.devui-table__row td) {
|
||||||
|
padding-top: 16px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.devui-tag .devui-tag--default) {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-right: 8px;
|
||||||
|
border: 1px solid #e3e3ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.one-line {
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #9a9b9c;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cur-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #2d2d2e;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-btn {
|
||||||
|
border-radius: 16px;
|
||||||
|
background: #DFDFDF;
|
||||||
|
|
||||||
|
|
||||||
|
color: #191919;
|
||||||
|
font-family: HarmonyOS Sans SC;
|
||||||
|
font-weight: regular;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secret-breadcrumb {
|
||||||
|
padding: 7px 20px 12px;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble-bottom-operations {
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-left: auto;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px; /* 图标之间的间隔 */
|
||||||
|
align-items: center; /* 垂直居中图标 */
|
||||||
|
justify-content: end;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
37
src/views/Jyh/AI/Home/components/Other.vue
Normal file
37
src/views/Jyh/AI/Home/components/Other.vue
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<div class="secret-container">
|
||||||
|
<McMarkdownCard :content="props.content"></McMarkdownCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {defineProps} from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps(['content'])
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import 'devui-theme/styles-var/devui-var.scss';
|
||||||
|
|
||||||
|
.secret-container {
|
||||||
|
position: relative;
|
||||||
|
//min-height: 600px;
|
||||||
|
background: #ffffff;
|
||||||
|
padding: 20px;
|
||||||
|
margin-top: 16px;
|
||||||
|
border-radius: 15px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #191919;
|
||||||
|
font-family: HarmonyOS Sans SC;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -22,27 +22,10 @@
|
|||||||
<WarningList v-else-if="msg.type===2"/>
|
<WarningList v-else-if="msg.type===2"/>
|
||||||
<!--软件详情-->
|
<!--软件详情-->
|
||||||
<OssDetail v-else-if="msg.type===3"/>
|
<OssDetail v-else-if="msg.type===3"/>
|
||||||
|
<!--软件详情-->
|
||||||
<McMarkdownCard v-else :content="msg.content"></McMarkdownCard>
|
<AIList v-else-if="msg.type==='df'" :content="msg.content"/>
|
||||||
|
<!--text或者富文本展示-->
|
||||||
<div class="conversation-cnxw">
|
<Other v-else :content="msg.content"></Other>
|
||||||
<a class="flex conversation-cnxw-item">
|
|
||||||
<span class="span2">猜你想问</span>
|
|
||||||
<img style="height: 15px;margin-right: 8px" width="16" src="@/assets/imgs/jyh/ai/icon_generate.png" />
|
|
||||||
</a>
|
|
||||||
<div class="flex conversation-cnxw-item">
|
|
||||||
<a class="g-header-copilot" @click="onSubmit('我想看Redis的详情')">
|
|
||||||
<img style="height: 15px;" width="16" src="@/assets/imgs/jyh/ai/icon_cnxw.png" />
|
|
||||||
<span class="ml-xs">我想看Redis的详情</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="flex conversation-cnxw-item">
|
|
||||||
<a class="g-header-copilot" @click="onSubmit('Redis的可信评分是多少')">
|
|
||||||
<img style="height: 15px;" width="16" src="@/assets/imgs/jyh/ai/icon_cnxw.png" />
|
|
||||||
<span class="ml-xs">Redis的可信评分是多少</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</McBubble>
|
</McBubble>
|
||||||
|
|
||||||
<!-- <McBubble v-else :loading="msg.loading ?? false" :avatarConfig="msg.avatarConfig">-->
|
<!-- <McBubble v-else :loading="msg.loading ?? false" :avatarConfig="msg.avatarConfig">-->
|
||||||
@@ -56,6 +39,24 @@
|
|||||||
<!-- </template>-->
|
<!-- </template>-->
|
||||||
<!-- </McBubble>-->
|
<!-- </McBubble>-->
|
||||||
</template>
|
</template>
|
||||||
|
<div class="conversation-cnxw">
|
||||||
|
<a class="flex conversation-cnxw-item">
|
||||||
|
<span class="span2">猜你想问</span>
|
||||||
|
<img style="height: 15px;margin-right: 8px" width="16" src="@/assets/imgs/jyh/ai/icon_generate.png" />
|
||||||
|
</a>
|
||||||
|
<div class="flex conversation-cnxw-item">
|
||||||
|
<a class="g-header-copilot" @click="onSubmit('我想看Redis的详情')">
|
||||||
|
<img style="height: 15px;" width="16" src="@/assets/imgs/jyh/ai/icon_cnxw.png" />
|
||||||
|
<span class="ml-xs">我想看Redis的详情</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="flex conversation-cnxw-item">
|
||||||
|
<a class="g-header-copilot" @click="onSubmit('Redis的可信评分是多少')">
|
||||||
|
<img style="height: 15px;" width="16" src="@/assets/imgs/jyh/ai/icon_cnxw.png" />
|
||||||
|
<span class="ml-xs">Redis的可信评分是多少</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="welcome-page">
|
<div v-else class="welcome-page">
|
||||||
<div class="home-title">
|
<div class="home-title">
|
||||||
@@ -142,6 +143,15 @@ import GuessYouWantToAsk from './GuessYouWantToAsk.vue';
|
|||||||
import OssList from './components/OssList.vue';
|
import OssList from './components/OssList.vue';
|
||||||
import WarningList from './components/WarningList.vue';
|
import WarningList from './components/WarningList.vue';
|
||||||
import OssDetail from './components/OssDetail.vue';
|
import OssDetail from './components/OssDetail.vue';
|
||||||
|
import Other from './components/Other.vue';
|
||||||
|
import AIList from './components/AIList.vue';
|
||||||
|
import { getChat } from '@/api/jyh';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useDiscussGetUserInfo } from '@/api/discussion/hook';
|
||||||
|
|
||||||
|
// 获取当前用户信息 & 是否登录
|
||||||
|
const { isLogin = false, userInfo = {}} = useDiscussGetUserInfo();
|
||||||
|
debugger
|
||||||
|
|
||||||
const inputValue = ref('');
|
const inputValue = ref('');
|
||||||
const startChat = ref(false);
|
const startChat = ref(false);
|
||||||
@@ -201,20 +211,32 @@ const onSubmit = (e, answer = undefined) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
// getAIAnswer(answer ?? e);
|
// getAIAnswer(answer ?? e);
|
||||||
getAIAnswer(mockAnswer,1);
|
getAIAnswer(e,1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAIAnswer = (content,type) => {
|
const getAIAnswer = async (content) => {
|
||||||
messages.value.push({
|
messages.value.push({
|
||||||
from: 'ai-model',
|
from: 'ai-model',
|
||||||
type: type || 1,
|
type: '',
|
||||||
content: content,
|
content: '',
|
||||||
avatarPosition: 'side-left',
|
avatarPosition: 'side-left',
|
||||||
avatarConfig: { ...aiModelAvatar },
|
avatarConfig: { ...aiModelAvatar },
|
||||||
loading: false,
|
loading: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {data} = await axios.get('http://222.20.126.208:8089/api/v0/chat_use_sql?question='+content);
|
||||||
|
debugger
|
||||||
|
const {text,type} = data;
|
||||||
|
|
||||||
|
if(type==='text') {
|
||||||
|
messages.value[messages.value.length - 1].content = text;
|
||||||
|
messages.value[messages.value.length - 1].loading = false;
|
||||||
|
messages.value[messages.value.length - 1].type = 'text';
|
||||||
|
} else if(type==='df') {
|
||||||
|
messages.value[messages.value.length - 1].content = data[type];
|
||||||
|
messages.value[messages.value.length - 1].loading = false;
|
||||||
|
messages.value[messages.value.length - 1].type = 'df';
|
||||||
|
}
|
||||||
// messages.value.push({
|
// messages.value.push({
|
||||||
// from: 'ai-model',
|
// from: 'ai-model',
|
||||||
// content: '',
|
// content: '',
|
||||||
|
|||||||
Reference in New Issue
Block a user