feat(pwl): 新增材料库资料库管理功能- 添加材料库资料库表的增删改查接口

- 实现材料库资料库表的分页查询和列表查询功能
- 新增材料库资料库表的添加、修改、删除和批量删除接口
- 创建材料库资料库管理页面,包含表格展示和操作功能- 添加材料库资料库编辑弹窗,支持新增和修改操作- 实现材料库资料库的类型、状态、推荐等字段的展示和编辑
- 集成文件选择组件,支持资料库图标和关联文件的选择
- 添加搜索组件,支持材料库资料库的搜索功能
- 更新开发环境API地址配置
-修复SelectDocsBook组件相关类型引用问题
- 优化AI审计方案生成器界面样式和交互
This commit is contained in:
2025-09-28 11:22:37 +08:00
parent 02ccc0a21d
commit a3a2493df7
10 changed files with 865 additions and 88 deletions

View File

@@ -1,34 +1,34 @@
<!-- 用户编辑弹窗 -->
<template>
<a-drawer
:width="`80%`"
:visible="visible"
:confirm-loading="loading"
:maxable="maxAble"
title="AI审计方案生成器"
:body-style="{ paddingBottom: '8px', background: '#f3f3f3' }"
@update:visible="updateVisible"
:maskClosable="false"
:footer="null"
@ok="save"
:width="`70%`"
:visible="visible"
:confirm-loading="loading"
:maxable="maxAble"
title="AI审计方案生成器"
:body-style="{ paddingBottom: '8px', background: '#f3f3f3' }"
@update:visible="updateVisible"
:maskClosable="false"
:footer="null"
@ok="save"
>
<a-card title="基本信息" style="margin-bottom: 20px" :bordered="false">
<a-descriptions>
<a-descriptions-item
label="公司名称"
:labelStyle="{ width: '90px', color: '#808080' }"
label="公司名称"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<span @click="copyText(form.name)">{{ form.name }}</span>
</a-descriptions-item>
<a-descriptions-item
label="被审计人"
:labelStyle="{ width: '90px', color: '#808080' }"
label="被审计人"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<span>{{ form.nickname || '暂无' }}</span>
</a-descriptions-item>
<a-descriptions-item
label="审计时间"
:labelStyle="{ width: '90px', color: '#808080' }"
label="审计时间"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<span>{{ form.expirationTime }}</span>
</a-descriptions-item>
@@ -78,13 +78,13 @@
<div class="navigation-container">
<div class="nav-grid">
<a-button
v-for="(item, index) in navigationItems"
:key="index"
:type="currentSection === index ? 'primary' : 'default'"
size="small"
@click="scrollToSection(index)"
class="nav-button"
:class="{ 'active': currentSection === index }"
v-for="(item, index) in navigationItems"
:key="index"
:type="currentSection === index ? 'primary' : 'default'"
size="small"
@click="scrollToSection(index)"
class="nav-button"
:class="{ 'active': currentSection === index }"
>
<span class="nav-number">{{ item.number }}</span>
<span class="nav-text">{{ item.name }}</span>
@@ -95,8 +95,8 @@
<div class="progress-container">
<div class="progress-bar">
<div
class="progress-fill"
:style="{ width: `${((currentSection + 1) / navigationItems.length) * 100}%` }"
class="progress-fill"
:style="{ width: `${((currentSection + 1) / navigationItems.length) * 100}%` }"
></div>
</div>
<div class="progress-text">
@@ -109,22 +109,22 @@
<!-- 审计方案内容 -->
<div class="audit-content">
<div
v-for="(item, index) in navigationItems"
:key="index"
:id="`section-${index}`"
class="audit-section"
v-for="(item, index) in navigationItems"
:key="index"
:id="`section-${index}`"
class="audit-section"
>
<a-card
:title="`${item.number}、${item.name}`"
style="margin-bottom: 20px"
:bordered="false"
:title="`${item.number}、${item.name}`"
style="margin-bottom: 20px"
:bordered="false"
>
<template #extra>
<a-button
type="text"
size="small"
@click="generateContent(index)"
:loading="item.generating"
type="text"
size="small"
@click="generateContent(index)"
:loading="item.generating"
>
<template #icon>
<RobotOutlined/>
@@ -140,21 +140,36 @@
<!-- 单内容部分 -->
<template v-if="!item.children">
<a-textarea
v-model:value="item.content"
:rows="item.rows || 8"
:placeholder="item.placeholder"
class="content-textarea"
style="margin-top: 16px"
v-model:value="item.content"
:rows="item.rows || 8"
:placeholder="item.placeholder"
class="content-textarea"
style="margin-top: 16px; background-color: #f0fdf4"
/>
<div style="margin-top: 12px">
<div class="question-prompt">点此开始提问</div>
<a-textarea
<div class="question-prompt">AI小助手</div>
<div class="flex flex-col gap-2 justify-center items-start">
<a-textarea
v-model:value="item.suggestion"
:rows="3"
placeholder="请在此输入您的优化建议或疑问..."
class="suggestion-textarea"
/>
style="flex: 1;"
@pressEnter="generateContent(index)"
/>
<a-button
type="primary"
@click="generateContent(index)"
:loading="item.generating"
style="align-self: flex-end; margin-bottom: 4px;"
>
<template #icon>
<RobotOutlined/>
</template>
发送
</a-button>
</div>
</div>
</template>
@@ -164,11 +179,11 @@
<div class="child-title">
{{ child.name }}
<a-button
type="text"
size="small"
@click.stop="generateContent(index, childIndex)"
:loading="child.generating"
style="margin-left: 12px"
type="text"
size="small"
@click.stop="generateContent(index, childIndex)"
:loading="child.generating"
style="margin-left: 12px"
>
<template #icon>
<RobotOutlined/>
@@ -177,11 +192,11 @@
</a-button>
</div>
<a-textarea
v-model:value="child.content"
:rows="child.rows || 6"
:placeholder="child.placeholder"
class="content-textarea"
style="margin-top: 12px"
v-model:value="child.content"
:rows="child.rows || 6"
:placeholder="child.placeholder"
class="content-textarea"
style="margin-top: 12px; background-color: #f0fdf4"
/>
</div>
</template>
@@ -733,7 +748,7 @@ const generateContent = async (sectionIndex: number, childIndex?: number) => {
section.generating = true;
try {
await Promise.all(section.children.map((_, i) =>
generateContent(sectionIndex, i)
generateContent(sectionIndex, i)
));
} finally {
section.generating = false;
@@ -776,7 +791,7 @@ const generateContent = async (sectionIndex: number, childIndex?: number) => {
/* 监听滚动位置更新当前章节 */
const handleScroll = () => {
const sections = navigationItems.value.map((_, index) =>
document.getElementById(`section-${index}`)
document.getElementById(`section-${index}`)
);
const scrollContainer = getScrollContainer();
@@ -845,19 +860,19 @@ onUnmounted(() => {
});
watch(
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
loading.value = true;
assignObject(form, props.data);
// 重置到第一个章节
currentSection.value = 0;
}
} else {
resetFields();
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
loading.value = true;
assignObject(form, props.data);
// 重置到第一个章节
currentSection.value = 0;
}
} else {
resetFields();
}
}
);
</script>
@@ -908,7 +923,6 @@ export default {
&:hover {
color: #0958d9;
text-decoration: underline;
}
}
@@ -1060,4 +1074,4 @@ export default {
bottom: 30px;
}
</style>
</style>