Compare commits
7 Commits
3ac7e69330
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d0f216eece | |||
| ba55625181 | |||
| 0f08415f28 | |||
| 2207dbbcd2 | |||
| 7a5c81f6db | |||
| cd04abdc64 | |||
| bf5be2e832 |
@@ -47,6 +47,7 @@ export interface AiCloudFileParam extends PageParam {
|
|||||||
id?: number;
|
id?: number;
|
||||||
keywords?: string;
|
keywords?: string;
|
||||||
docId?: number;
|
docId?: number;
|
||||||
|
fileName?: string;
|
||||||
workspaceId?: number;
|
workspaceId?: number;
|
||||||
fileType?: string;
|
fileType?: string;
|
||||||
}
|
}
|
||||||
@@ -231,6 +231,8 @@ export async function generateDefaultText(params: {
|
|||||||
formCommit: number;
|
formCommit: number;
|
||||||
chapterTitle?: string;
|
chapterTitle?: string;
|
||||||
evidenceIds?: number[]; // 新增:选中的取证单 ID 列表
|
evidenceIds?: number[]; // 新增:选中的取证单 ID 列表
|
||||||
|
docList?: any[]; // 新增:选中的目录ID列表
|
||||||
|
fileList?: any[]; // 新增:选中的文件ID列表
|
||||||
}) {
|
}) {
|
||||||
const res = await request.post<ApiResult<string>>(
|
const res = await request.post<ApiResult<string>>(
|
||||||
MODULES_API_URL + '/ai/auditReport/generateDefaultText',
|
MODULES_API_URL + '/ai/auditReport/generateDefaultText',
|
||||||
@@ -238,7 +240,9 @@ export async function generateDefaultText(params: {
|
|||||||
projectId: params.projectId,
|
projectId: params.projectId,
|
||||||
formCommit: params.formCommit,
|
formCommit: params.formCommit,
|
||||||
chapterTitle: params.chapterTitle,
|
chapterTitle: params.chapterTitle,
|
||||||
evidenceIds: params.evidenceIds
|
evidenceIds: params.evidenceIds,
|
||||||
|
docList: params.docList,
|
||||||
|
fileList: params.fileList
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -253,6 +257,7 @@ export async function generateDefaultText(params: {
|
|||||||
* AI 分析用户自定义输入
|
* AI 分析用户自定义输入
|
||||||
*/
|
*/
|
||||||
export async function analyzeUserInput(params: {
|
export async function analyzeUserInput(params: {
|
||||||
|
projectId: string;
|
||||||
formCommit: number;
|
formCommit: number;
|
||||||
userQuestion: string;
|
userQuestion: string;
|
||||||
chapterContent?: string;
|
chapterContent?: string;
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ export interface OaCompany {
|
|||||||
shortName?: string;
|
shortName?: string;
|
||||||
// 企业全称
|
// 企业全称
|
||||||
companyName?: string;
|
companyName?: string;
|
||||||
|
// 归属单位
|
||||||
|
parentCompany?: string;
|
||||||
|
parentCompanyId?: number;
|
||||||
|
// 单位编号
|
||||||
|
companyNo?: string;
|
||||||
// 企业标识
|
// 企业标识
|
||||||
companyCode?: string;
|
companyCode?: string;
|
||||||
// 类型 10企业 20政府单位
|
// 类型 10企业 20政府单位
|
||||||
|
|||||||
@@ -35,6 +35,17 @@
|
|||||||
v-model:value="form.companyName"
|
v-model:value="form.companyName"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="归属单位" name="parentCompany">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.parentCompany"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
option-filter-prop="label"
|
||||||
|
placeholder="请选择归属单位"
|
||||||
|
:options="parentCompanyOptions"
|
||||||
|
@change="handleParentCompanyChange"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item label="简称" name="shortName">
|
<a-form-item label="简称" name="shortName">
|
||||||
<a-input
|
<a-input
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -49,91 +60,101 @@
|
|||||||
v-model:value="form.companyCode"
|
v-model:value="form.companyCode"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="单位编号" name="companyNo">
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
placeholder="请输入单位编号"
|
||||||
|
v-model:value="form.companyNo"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="企业性质" name="companyType">
|
<a-form-item label="企业性质" name="companyType">
|
||||||
<DictSelect
|
<DictSelect
|
||||||
dict-code="CompanyType"
|
dict-code="CompanyType"
|
||||||
:width="200"
|
:width="200"
|
||||||
:show-search="true"
|
:show-search="true"
|
||||||
placeholder="企业性质"
|
placeholder="企业性质"
|
||||||
v-model:value="form.companyType"
|
v-model:value="form.companyType"
|
||||||
:field-names="{
|
:field-names="{
|
||||||
label: 'dictDataName',
|
label: 'dictDataName',
|
||||||
value: 'dictDataCode'
|
value: 'dictDataCode'
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="所属行业" name="industryParent">
|
<a-form-item label="所属行业" name="industryParent">
|
||||||
<DictSelect
|
<DictSelect
|
||||||
dict-code="Industry"
|
dict-code="Industry"
|
||||||
:width="200"
|
:width="200"
|
||||||
:show-search="true"
|
:show-search="true"
|
||||||
placeholder="所属行业"
|
placeholder="所属行业"
|
||||||
v-model:value="form.industryParent"
|
v-model:value="form.industryParent"
|
||||||
:field-names="{
|
:field-names="{
|
||||||
label: 'dictDataName',
|
label: 'dictDataName',
|
||||||
value: 'dictDataCode'
|
value: 'dictDataCode'
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="知识库ID" name="kbId">
|
<a-form-item label="知识库ID" name="kbId">
|
||||||
<a-input
|
<a-input
|
||||||
:class="{ 'disabled-text': !form.kbId }"
|
:class="{ 'disabled-text': !form.kbId }"
|
||||||
:style="!form.kbId ? 'cursor: not-allowed; color: #999' : 'background-color: #f5f5f5'"
|
:style="
|
||||||
:placeholder="form.kbId ? '' : '未创建'"
|
!form.kbId
|
||||||
:value="form.kbId"
|
? 'cursor: not-allowed; color: #999'
|
||||||
readonly
|
: 'background-color: #f5f5f5'
|
||||||
|
"
|
||||||
|
:placeholder="form.kbId ? '' : '未创建'"
|
||||||
|
:value="form.kbId"
|
||||||
|
readonly
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<!-- 行业库 -->
|
<!-- 行业库 -->
|
||||||
<a-form-item label="行业库" name="bizLibIds">
|
<a-form-item label="行业库" name="bizLibIds">
|
||||||
<a-select
|
<a-select
|
||||||
show-search
|
show-search
|
||||||
:allow-clear="true"
|
:allow-clear="true"
|
||||||
optionFilterProp="label"
|
optionFilterProp="label"
|
||||||
v-model:value="form.bizLibIds"
|
v-model:value="form.bizLibIds"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="选择行业库"
|
placeholder="选择行业库"
|
||||||
:options="bizLibList"
|
:options="bizLibList"
|
||||||
></a-select>
|
></a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<!-- 公共库 -->
|
<!-- 公共库 -->
|
||||||
<a-form-item label="公共库" name="pubLibIds">
|
<a-form-item label="公共库" name="pubLibIds">
|
||||||
<a-select
|
<a-select
|
||||||
show-search
|
show-search
|
||||||
:allow-clear="true"
|
:allow-clear="true"
|
||||||
optionFilterProp="label"
|
optionFilterProp="label"
|
||||||
v-model:value="form.pubLibIds"
|
v-model:value="form.pubLibIds"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="选择公共库"
|
placeholder="选择公共库"
|
||||||
:options="pubLibList"
|
:options="pubLibList"
|
||||||
></a-select>
|
></a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- <a-form-item label="类型" name="companyType">-->
|
||||||
<!-- <a-form-item label="类型" name="companyType">-->
|
<!-- <a-radio-group v-model:value="form.companyType">-->
|
||||||
<!-- <a-radio-group v-model:value="form.companyType">-->
|
<!-- <a-radio :value="10">企业</a-radio>-->
|
||||||
<!-- <a-radio :value="10">企业</a-radio>-->
|
<!-- <a-radio :value="20">单位</a-radio>-->
|
||||||
<!-- <a-radio :value="20">单位</a-radio>-->
|
<!-- </a-radio-group>-->
|
||||||
<!-- </a-radio-group>-->
|
<!-- <a-input-->
|
||||||
<!-- <a-input-->
|
<!-- allow-clear-->
|
||||||
<!-- allow-clear-->
|
<!-- placeholder="请输入类型 10单位 20政府单位"-->
|
||||||
<!-- placeholder="请输入类型 10单位 20政府单位"-->
|
<!-- v-model:value="form.companyType"-->
|
||||||
<!-- v-model:value="form.companyType"-->
|
<!-- />-->
|
||||||
<!-- />-->
|
<!-- </a-form-item>-->
|
||||||
<!-- </a-form-item>-->
|
<!-- <a-form-item label="应用标识" name="companyLogo">-->
|
||||||
<!-- <a-form-item label="应用标识" name="companyLogo">-->
|
<!-- <a-input-->
|
||||||
<!-- <a-input-->
|
<!-- allow-clear-->
|
||||||
<!-- allow-clear-->
|
<!-- placeholder="请输入应用标识"-->
|
||||||
<!-- placeholder="请输入应用标识"-->
|
<!-- v-model:value="form.companyLogo"-->
|
||||||
<!-- v-model:value="form.companyLogo"-->
|
<!-- />-->
|
||||||
<!-- />-->
|
<!-- </a-form-item>-->
|
||||||
<!-- </a-form-item>-->
|
|
||||||
<a-form-item label="网站域名" name="domain">
|
<a-form-item label="网站域名" name="domain">
|
||||||
<a-input
|
<a-input
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -141,13 +162,13 @@
|
|||||||
v-model:value="form.domain"
|
v-model:value="form.domain"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- <a-form-item label="联系电话" name="phone">-->
|
<!-- <a-form-item label="联系电话" name="phone">-->
|
||||||
<!-- <a-input-->
|
<!-- <a-input-->
|
||||||
<!-- allow-clear-->
|
<!-- allow-clear-->
|
||||||
<!-- placeholder="请输入联系电话"-->
|
<!-- placeholder="请输入联系电话"-->
|
||||||
<!-- v-model:value="form.phone"-->
|
<!-- v-model:value="form.phone"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </a-form-item>-->
|
<!-- </a-form-item>-->
|
||||||
<a-form-item label="座机电话" name="tel">
|
<a-form-item label="座机电话" name="tel">
|
||||||
<a-input
|
<a-input
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -155,20 +176,20 @@
|
|||||||
v-model:value="form.tel"
|
v-model:value="form.tel"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- <a-form-item label="邮箱" name="email">-->
|
<!-- <a-form-item label="邮箱" name="email">-->
|
||||||
<!-- <a-input-->
|
<!-- <a-input-->
|
||||||
<!-- allow-clear-->
|
<!-- allow-clear-->
|
||||||
<!-- placeholder="请输入邮箱"-->
|
<!-- placeholder="请输入邮箱"-->
|
||||||
<!-- v-model:value="form.email"-->
|
<!-- v-model:value="form.email"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </a-form-item>-->
|
<!-- </a-form-item>-->
|
||||||
<!-- <a-form-item label="发票抬头" name="invoiceHeader">-->
|
<!-- <a-form-item label="发票抬头" name="invoiceHeader">-->
|
||||||
<!-- <a-input-->
|
<!-- <a-input-->
|
||||||
<!-- allow-clear-->
|
<!-- allow-clear-->
|
||||||
<!-- placeholder="请输入发票抬头"-->
|
<!-- placeholder="请输入发票抬头"-->
|
||||||
<!-- v-model:value="form.invoiceHeader"-->
|
<!-- v-model:value="form.invoiceHeader"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </a-form-item>-->
|
<!-- </a-form-item>-->
|
||||||
<a-form-item label="企业法人" name="businessEntity">
|
<a-form-item label="企业法人" name="businessEntity">
|
||||||
<a-input
|
<a-input
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -176,27 +197,27 @@
|
|||||||
v-model:value="form.businessEntity"
|
v-model:value="form.businessEntity"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- <a-form-item label="所在省份" name="province">-->
|
<!-- <a-form-item label="所在省份" name="province">-->
|
||||||
<!-- <a-input-->
|
<!-- <a-input-->
|
||||||
<!-- allow-clear-->
|
<!-- allow-clear-->
|
||||||
<!-- placeholder="请输入所在省份"-->
|
<!-- placeholder="请输入所在省份"-->
|
||||||
<!-- v-model:value="form.province"-->
|
<!-- v-model:value="form.province"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </a-form-item>-->
|
<!-- </a-form-item>-->
|
||||||
<!-- <a-form-item label="所在城市" name="city">-->
|
<!-- <a-form-item label="所在城市" name="city">-->
|
||||||
<!-- <a-input-->
|
<!-- <a-input-->
|
||||||
<!-- allow-clear-->
|
<!-- allow-clear-->
|
||||||
<!-- placeholder="请输入所在城市"-->
|
<!-- placeholder="请输入所在城市"-->
|
||||||
<!-- v-model:value="form.city"-->
|
<!-- v-model:value="form.city"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </a-form-item>-->
|
<!-- </a-form-item>-->
|
||||||
<!-- <a-form-item label="所在辖区" name="region">-->
|
<!-- <a-form-item label="所在辖区" name="region">-->
|
||||||
<!-- <a-input-->
|
<!-- <a-input-->
|
||||||
<!-- allow-clear-->
|
<!-- allow-clear-->
|
||||||
<!-- placeholder="请输入所在辖区"-->
|
<!-- placeholder="请输入所在辖区"-->
|
||||||
<!-- v-model:value="form.region"-->
|
<!-- v-model:value="form.region"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </a-form-item>-->
|
<!-- </a-form-item>-->
|
||||||
<a-form-item label="详细地址" name="address">
|
<a-form-item label="详细地址" name="address">
|
||||||
<a-input
|
<a-input
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -235,15 +256,19 @@
|
|||||||
import { ref, reactive, watch } from 'vue';
|
import { ref, reactive, watch } from 'vue';
|
||||||
import { Form, message } from 'ant-design-vue';
|
import { Form, message } from 'ant-design-vue';
|
||||||
import { assignObject, uuid } from 'ele-admin-pro';
|
import { assignObject, uuid } from 'ele-admin-pro';
|
||||||
import { addOaCompany, updateOaCompany } from '@/api/oa/oaCompany';
|
import {
|
||||||
|
addOaCompany,
|
||||||
|
updateOaCompany,
|
||||||
|
listOaCompany
|
||||||
|
} from '@/api/oa/oaCompany';
|
||||||
import { OaCompany } from '@/api/oa/oaCompany/model';
|
import { OaCompany } from '@/api/oa/oaCompany/model';
|
||||||
import { useThemeStore } from '@/store/modules/theme';
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
|
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
|
||||||
import { FormInstance } from 'ant-design-vue/es/form';
|
import { FormInstance } from 'ant-design-vue/es/form';
|
||||||
import { FileRecord } from '@/api/system/file/model';
|
import { FileRecord } from '@/api/system/file/model';
|
||||||
import {listPwlProjectLibrary} from '@/api/pwl/pwlProjectLibrary';
|
import { listPwlProjectLibrary } from '@/api/pwl/pwlProjectLibrary';
|
||||||
import DictSelect from "@/components/DictSelect/index.vue";
|
import DictSelect from '@/components/DictSelect/index.vue';
|
||||||
|
|
||||||
// 是否是修改
|
// 是否是修改
|
||||||
const isUpdate = ref(false);
|
const isUpdate = ref(false);
|
||||||
@@ -254,6 +279,13 @@
|
|||||||
// 资料库响应式数据
|
// 资料库响应式数据
|
||||||
const bizLibList = ref<any[]>([]);
|
const bizLibList = ref<any[]>([]);
|
||||||
const pubLibList = ref<any[]>([]);
|
const pubLibList = ref<any[]>([]);
|
||||||
|
const parentCompanyOptions = ref<{ label: string; value: string }[]>([
|
||||||
|
{
|
||||||
|
label: '本单位(自己)',
|
||||||
|
value: '本单位'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
const parentCompanyList = ref<OaCompany[]>([]);
|
||||||
// 存储完整的资料库数据,用于查找名称
|
// 存储完整的资料库数据,用于查找名称
|
||||||
const allLibraries = ref<any[]>([]);
|
const allLibraries = ref<any[]>([]);
|
||||||
|
|
||||||
@@ -282,7 +314,10 @@
|
|||||||
companyId: undefined,
|
companyId: undefined,
|
||||||
shortName: undefined,
|
shortName: undefined,
|
||||||
companyName: undefined,
|
companyName: undefined,
|
||||||
|
parentCompany: '本单位',
|
||||||
|
parentCompanyId: 0,
|
||||||
companyCode: undefined,
|
companyCode: undefined,
|
||||||
|
companyNo: undefined,
|
||||||
companyType: undefined,
|
companyType: undefined,
|
||||||
companyTypeMultiple: undefined,
|
companyTypeMultiple: undefined,
|
||||||
companyLogo: undefined,
|
companyLogo: undefined,
|
||||||
@@ -330,13 +365,9 @@
|
|||||||
tenantId: undefined,
|
tenantId: undefined,
|
||||||
createTime: undefined,
|
createTime: undefined,
|
||||||
updateTime: undefined,
|
updateTime: undefined,
|
||||||
oaCompanyId: undefined,
|
|
||||||
oaCompanyName: '',
|
oaCompanyName: '',
|
||||||
status: 0,
|
|
||||||
comments: '',
|
|
||||||
sortNumber: 100,
|
|
||||||
kbId: undefined,
|
kbId: undefined,
|
||||||
libraryIds: undefined,
|
libraryIds: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
/* 更新visible */
|
/* 更新visible */
|
||||||
@@ -370,26 +401,90 @@
|
|||||||
form.companyLogo = '';
|
form.companyLogo = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取归属单位下拉
|
||||||
|
const fetchParentCompanyOptions = async () => {
|
||||||
|
const list = await listOaCompany();
|
||||||
|
const currentCompanyId = props.data?.companyId;
|
||||||
|
parentCompanyList.value = list.filter(
|
||||||
|
(item) => item.companyId !== currentCompanyId
|
||||||
|
);
|
||||||
|
const options = parentCompanyList.value
|
||||||
|
.map((item) => item.companyName)
|
||||||
|
.filter((name): name is string => !!name)
|
||||||
|
.filter((name, index, arr) => arr.indexOf(name) === index)
|
||||||
|
.map((name) => ({
|
||||||
|
label: name,
|
||||||
|
value: name
|
||||||
|
}));
|
||||||
|
|
||||||
|
parentCompanyOptions.value = [
|
||||||
|
{
|
||||||
|
label: '本单位(自己)',
|
||||||
|
value: '本单位'
|
||||||
|
},
|
||||||
|
...options.filter((item) => item.value !== '本单位')
|
||||||
|
];
|
||||||
|
|
||||||
|
if (
|
||||||
|
form.parentCompany &&
|
||||||
|
!parentCompanyOptions.value.some(
|
||||||
|
(item) => item.value === form.parentCompany
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
parentCompanyOptions.value.push({
|
||||||
|
label: form.parentCompany,
|
||||||
|
value: form.parentCompany
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getParentCompanyIdByName = (name?: string) => {
|
||||||
|
if (!name || name === '本单位') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
parentCompanyList.value.find((item) => item.companyName === name)
|
||||||
|
?.companyId ?? 0
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleParentCompanyChange = (value?: string) => {
|
||||||
|
form.parentCompany = value || '本单位';
|
||||||
|
form.parentCompanyId = getParentCompanyIdByName(form.parentCompany);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ensureParentCompanyOption = (value?: string) => {
|
||||||
|
if (
|
||||||
|
value &&
|
||||||
|
!parentCompanyOptions.value.some((item) => item.value === value)
|
||||||
|
) {
|
||||||
|
parentCompanyOptions.value.push({
|
||||||
|
label: value,
|
||||||
|
value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 获取资料库列表
|
// 获取资料库列表
|
||||||
const fetchLibraries = () => {
|
const fetchLibraries = () => {
|
||||||
return listPwlProjectLibrary().then(res => {
|
return listPwlProjectLibrary().then((res) => {
|
||||||
allLibraries.value = res;
|
allLibraries.value = res;
|
||||||
|
|
||||||
// 过滤行业库 (type='biz')
|
// 过滤行业库 (type='biz')
|
||||||
bizLibList.value = res
|
bizLibList.value = res
|
||||||
.filter(item => item.type === 'biz')
|
.filter((item) => item.type === 'biz')
|
||||||
.map(item => ({
|
.map((item) => ({
|
||||||
label: item.name,
|
label: item.name,
|
||||||
value: String(item.id) // 将 ID 转换为字符串
|
value: String(item.id) // 将 ID 转换为字符串
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 过滤公共库 (type='pub')
|
// 过滤公共库 (type='pub')
|
||||||
pubLibList.value = res
|
pubLibList.value = res
|
||||||
.filter(item => item.type === 'pub')
|
.filter((item) => item.type === 'pub')
|
||||||
.map(item => ({
|
.map((item) => ({
|
||||||
label: item.name,
|
label: item.name,
|
||||||
value: String(item.id) // 将 ID 转换为字符串
|
value: String(item.id) // 将 ID 转换为字符串
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
@@ -411,12 +506,16 @@
|
|||||||
const allLibraryIds = [
|
const allLibraryIds = [
|
||||||
...(form.bizLibIds || []),
|
...(form.bizLibIds || []),
|
||||||
...(form.pubLibIds || [])
|
...(form.pubLibIds || [])
|
||||||
]
|
];
|
||||||
|
|
||||||
const formData = {
|
const formData = {
|
||||||
...form,
|
...form,
|
||||||
libraryIds: allLibraryIds.join(','), // 保存为逗号分隔的字符串
|
libraryIds: allLibraryIds.join(',') // 保存为逗号分隔的字符串
|
||||||
};
|
};
|
||||||
|
if (!formData.parentCompany) formData.parentCompany = '本单位';
|
||||||
|
formData.parentCompanyId = getParentCompanyIdByName(
|
||||||
|
formData.parentCompany
|
||||||
|
);
|
||||||
const saveOrUpdate = isUpdate.value ? updateOaCompany : addOaCompany;
|
const saveOrUpdate = isUpdate.value ? updateOaCompany : addOaCompany;
|
||||||
saveOrUpdate(formData)
|
saveOrUpdate(formData)
|
||||||
.then((msg) => {
|
.then((msg) => {
|
||||||
@@ -438,24 +537,30 @@
|
|||||||
if (props.data?.libraryIds) {
|
if (props.data?.libraryIds) {
|
||||||
// 如果是字符串,按逗号分割成数组
|
// 如果是字符串,按逗号分割成数组
|
||||||
if (typeof props.data.libraryIds === 'string') {
|
if (typeof props.data.libraryIds === 'string') {
|
||||||
const libraryIdsArray = props.data.libraryIds.split(',').filter(id => id.trim() !== '');
|
const libraryIdsArray = props.data.libraryIds
|
||||||
|
.split(',')
|
||||||
|
.filter((id) => id.trim() !== '');
|
||||||
|
|
||||||
// 清空当前的选择
|
// 清空当前的选择
|
||||||
form.bizLibIds = [];
|
form.bizLibIds = [];
|
||||||
form.pubLibIds = [];
|
form.pubLibIds = [];
|
||||||
|
|
||||||
// 根据资料库类型分别设置回显
|
// 根据资料库类型分别设置回显
|
||||||
libraryIdsArray.forEach(id => {
|
libraryIdsArray.forEach((id) => {
|
||||||
// 检查是否在行业库列表中
|
// 检查是否在行业库列表中
|
||||||
const isBizLib = bizLibList.value.some(lib => lib.value === String(id)); // 转换为字符串比较
|
const isBizLib = bizLibList.value.some(
|
||||||
|
(lib) => lib.value === String(id)
|
||||||
|
); // 转换为字符串比较
|
||||||
// 检查是否在公共库列表中
|
// 检查是否在公共库列表中
|
||||||
const isPubLib = pubLibList.value.some(lib => lib.value === String(id)); // 转换为字符串比较
|
const isPubLib = pubLibList.value.some(
|
||||||
|
(lib) => lib.value === String(id)
|
||||||
|
); // 转换为字符串比较
|
||||||
|
|
||||||
if (isBizLib) {
|
if (isBizLib) {
|
||||||
form.bizLibIds.push(String(id)); // 确保存储为字符串
|
form.bizLibIds.push(String(id)); // 确保存储为字符串
|
||||||
}
|
}
|
||||||
if (isPubLib) {
|
if (isPubLib) {
|
||||||
form.pubLibIds.push(String(id)); // 确保存储为字符串
|
form.pubLibIds.push(String(id)); // 确保存储为字符串
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -463,9 +568,13 @@
|
|||||||
form.bizLibIds = [];
|
form.bizLibIds = [];
|
||||||
form.pubLibIds = [];
|
form.pubLibIds = [];
|
||||||
|
|
||||||
props.data.libraryIds.forEach(id => {
|
props.data.libraryIds.forEach((id) => {
|
||||||
const isBizLib = bizLibList.value.some(lib => lib.value === String(id));
|
const isBizLib = bizLibList.value.some(
|
||||||
const isPubLib = pubLibList.value.some(lib => lib.value === String(id));
|
(lib) => lib.value === String(id)
|
||||||
|
);
|
||||||
|
const isPubLib = pubLibList.value.some(
|
||||||
|
(lib) => lib.value === String(id)
|
||||||
|
);
|
||||||
|
|
||||||
if (isBizLib) {
|
if (isBizLib) {
|
||||||
form.bizLibIds.push(String(id));
|
form.bizLibIds.push(String(id));
|
||||||
@@ -483,21 +592,25 @@
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.visible,
|
() => props.visible,
|
||||||
async (visible) => {
|
async (visible) => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
|
|
||||||
// 等待资料库列表加载完成后再设置回显
|
// 等待资料库列表加载完成后再设置回显
|
||||||
await fetchLibraries();
|
await Promise.all([fetchLibraries(), fetchParentCompanyOptions()]);
|
||||||
|
|
||||||
images.value = [];
|
images.value = [];
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
assignObject(form, props.data);
|
assignObject(form, props.data);
|
||||||
if(props.data.companyLogo){
|
form.parentCompany = props.data.parentCompany || '本单位';
|
||||||
|
form.parentCompanyId =
|
||||||
|
props.data.parentCompanyId ??
|
||||||
|
getParentCompanyIdByName(form.parentCompany);
|
||||||
|
ensureParentCompanyOption(form.parentCompany);
|
||||||
|
if (props.data.companyLogo) {
|
||||||
images.value.push({
|
images.value.push({
|
||||||
uid: uuid(),
|
uid: uuid(),
|
||||||
url: props.data.companyLogo,
|
url: props.data.companyLogo,
|
||||||
status: 'done'
|
status: 'done'
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置资料库回显
|
// 设置资料库回显
|
||||||
@@ -505,10 +618,14 @@
|
|||||||
|
|
||||||
isUpdate.value = true;
|
isUpdate.value = true;
|
||||||
} else {
|
} else {
|
||||||
|
form.parentCompany = '本单位';
|
||||||
|
form.parentCompanyId = 0;
|
||||||
isUpdate.value = false;
|
isUpdate.value = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resetFields();
|
resetFields();
|
||||||
|
form.parentCompany = '本单位';
|
||||||
|
form.parentCompanyId = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -108,6 +108,10 @@
|
|||||||
currentCompanyId: number;
|
currentCompanyId: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'confirm', data: { dirKeys: (string | number)[], fileKeys: (string | number)[] }): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
// 树形结构相关
|
// 树形结构相关
|
||||||
const expandedKeys = ref<(string | number)[]>([]);
|
const expandedKeys = ref<(string | number)[]>([]);
|
||||||
const selectedKeys = ref<(string | number)[]>([]);
|
const selectedKeys = ref<(string | number)[]>([]);
|
||||||
@@ -184,6 +188,12 @@
|
|||||||
lastSelectedDirKeys.value = [...checkedDirKeys.value];
|
lastSelectedDirKeys.value = [...checkedDirKeys.value];
|
||||||
lastSelectedFileKeys.value = [...selectedFileKeys.value];
|
lastSelectedFileKeys.value = [...selectedFileKeys.value];
|
||||||
|
|
||||||
|
// 传递选择的数据给父组件
|
||||||
|
emit('confirm', {
|
||||||
|
dirKeys: lastSelectedDirKeys.value,
|
||||||
|
fileKeys: lastSelectedFileKeys.value
|
||||||
|
});
|
||||||
|
|
||||||
message.success(
|
message.success(
|
||||||
`已选择 ${checkedDirKeys.value.length} 个目录和 ${selectedFileKeys.value.length} 个文件`
|
`已选择 ${checkedDirKeys.value.length} 个目录和 ${selectedFileKeys.value.length} 个文件`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ import {
|
|||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
SaveOutlined
|
SaveOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
import {generateAuditReport, downloadAuditReport, queryAuditReport, saveAuditReport} from "@/api/ai/auditReport";
|
import {generateDefaultText, downloadAuditReport, queryAuditReport, saveAuditReport} from "@/api/ai/auditReport";
|
||||||
import {getPwlProjectLibraryByIds} from '@/api/pwl/pwlProjectLibrary';
|
import {getPwlProjectLibraryByIds} from '@/api/pwl/pwlProjectLibrary';
|
||||||
|
|
||||||
const useForm = Form.useForm;
|
const useForm = Form.useForm;
|
||||||
@@ -1373,14 +1373,13 @@ const generateContent = async (sectionIndex: number, childIndex?: number) => {
|
|||||||
|
|
||||||
item.generating = true;
|
item.generating = true;
|
||||||
try {
|
try {
|
||||||
const result = await generateAuditReport({
|
// 获取章节标题
|
||||||
kbId: form.kbId || '',
|
const chapterTitle = isChild ? item.title : section.title;
|
||||||
kbIds: combinedKbIds.value,
|
|
||||||
|
const result = await generateDefaultText({
|
||||||
|
projectId: form.id,
|
||||||
formCommit: formCommit,
|
formCommit: formCommit,
|
||||||
history: item.content || '',
|
chapterTitle: chapterTitle
|
||||||
suggestion: item.suggestion || '',
|
|
||||||
// 新增:传递完整的上下文数据
|
|
||||||
...contextData
|
|
||||||
});
|
});
|
||||||
item.content = result;
|
item.content = result;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -488,7 +488,11 @@
|
|||||||
|
|
||||||
<!-- 返回顶部按钮 -->
|
<!-- 返回顶部按钮 -->
|
||||||
<a-back-top :target="getScrollContainer" />
|
<a-back-top :target="getScrollContainer" />
|
||||||
<FileModal ref="fileModal" :current-company-id="currentCompanyId" />
|
<FileModal
|
||||||
|
ref="fileModal"
|
||||||
|
:current-company-id="currentCompanyId"
|
||||||
|
@confirm="handleFileSelectConfirm"
|
||||||
|
/>
|
||||||
<HistoryModal
|
<HistoryModal
|
||||||
v-model:visible="showHistory"
|
v-model:visible="showHistory"
|
||||||
:interface-name="currentInterfaceName"
|
:interface-name="currentInterfaceName"
|
||||||
@@ -523,7 +527,7 @@
|
|||||||
RobotOutlined,
|
RobotOutlined,
|
||||||
SaveOutlined
|
SaveOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
import { generateAuditReport } from '@/api/ai/auditReport';
|
import { generateDefaultText } from '@/api/ai/auditReport';
|
||||||
import { getPwlProjectLibraryByIds } from '@/api/pwl/pwlProjectLibrary';
|
import { getPwlProjectLibraryByIds } from '@/api/pwl/pwlProjectLibrary';
|
||||||
import { addAiHistory } from '@/api/ai/aiHistory';
|
import { addAiHistory } from '@/api/ai/aiHistory';
|
||||||
import * as auditContentApi from '@/api/ai/auditContent';
|
import * as auditContentApi from '@/api/ai/auditContent';
|
||||||
@@ -593,7 +597,6 @@
|
|||||||
|
|
||||||
// ========== 文档选择相关 ==========
|
// ========== 文档选择相关 ==========
|
||||||
const fileModal = ref();
|
const fileModal = ref();
|
||||||
const showDocSelect = ref(false);
|
|
||||||
const currentSectionIndex = ref(0);
|
const currentSectionIndex = ref(0);
|
||||||
const selectedDocList = ref<string[]>([]);
|
const selectedDocList = ref<string[]>([]);
|
||||||
const selectedFileList = ref<string[]>([]);
|
const selectedFileList = ref<string[]>([]);
|
||||||
@@ -731,10 +734,19 @@
|
|||||||
message.success(`已切换到:${tableOption.title}`);
|
message.success(`已切换到:${tableOption.title}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 处理文件选择确认 */
|
||||||
|
const handleFileSelectConfirm = (data: { dirKeys: (string | number)[], fileKeys: (string | number)[] }) => {
|
||||||
|
checkedDirKeys.value = data.dirKeys;
|
||||||
|
selectedFileKeys.value = data.fileKeys;
|
||||||
|
lastSelectedDirKeys.value = [...data.dirKeys];
|
||||||
|
lastSelectedFileKeys.value = [...data.fileKeys];
|
||||||
|
selectedDocList.value = data.dirKeys.map((key) => key.toString());
|
||||||
|
selectedFileList.value = data.fileKeys.map((key) => key.toString());
|
||||||
|
};
|
||||||
|
|
||||||
/* 打开文档选择弹窗 */
|
/* 打开文档选择弹窗 */
|
||||||
const openDocSelect = (sectionIndex: number) => {
|
const openDocSelect = (sectionIndex: number) => {
|
||||||
currentSectionIndex.value = sectionIndex;
|
currentSectionIndex.value = sectionIndex;
|
||||||
showDocSelect.value = true;
|
|
||||||
|
|
||||||
const tableInfo = getTableInfo(sectionIndex);
|
const tableInfo = getTableInfo(sectionIndex);
|
||||||
if (!tableInfo) return;
|
if (!tableInfo) return;
|
||||||
@@ -748,7 +760,7 @@
|
|||||||
key.toString()
|
key.toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
fileModal.value.open(tableInfo.tableKey);
|
fileModal.value.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1267,13 +1279,17 @@
|
|||||||
|
|
||||||
section.generating = true;
|
section.generating = true;
|
||||||
try {
|
try {
|
||||||
section.content = await generateAuditReport({
|
// 获取章节标题
|
||||||
kbId: form.kbId || '',
|
const chapterTitle = childIndex !== undefined && section.children
|
||||||
kbIds: combinedKbIds.value,
|
? section.children[childIndex].title
|
||||||
|
: section.title;
|
||||||
|
|
||||||
|
section.content = await generateDefaultText({
|
||||||
|
projectId: form.id,
|
||||||
formCommit: section.formCommit || 0,
|
formCommit: section.formCommit || 0,
|
||||||
history: section.content || '',
|
chapterTitle: chapterTitle,
|
||||||
suggestion: section.suggestion || '',
|
docList: checkedDirKeys.value,
|
||||||
...contextData
|
fileList: selectedFileKeys.value
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
section.generating = false;
|
section.generating = false;
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ import { ref, reactive, watch, h } from 'vue';
|
|||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { ReloadOutlined, RobotOutlined, DownloadOutlined, HistoryOutlined, ClearOutlined, ArrowLeftOutlined } from '@ant-design/icons-vue';
|
import { ReloadOutlined, RobotOutlined, DownloadOutlined, HistoryOutlined, ClearOutlined, ArrowLeftOutlined } from '@ant-design/icons-vue';
|
||||||
import { PwlProject } from "@/api/pwl/pwlProject/model";
|
import { PwlProject } from "@/api/pwl/pwlProject/model";
|
||||||
import { queryAuditDataByProjectId, generateAuditReportByProjectId, generateAuditReportWithEvidences, generateDefaultText, saveAuditReport, generateAuditReportWithContent } from "@/api/ai/auditReport";
|
import { queryAuditDataByProjectId, generateAuditReportByProjectId, generateAuditReportWithEvidences, generateDefaultText, saveAuditReport, generateAuditReportWithContent, analyzeUserInput } from "@/api/ai/auditReport";
|
||||||
import { getPwlProject } from "@/api/pwl/pwlProject";
|
import { getPwlProject } from "@/api/pwl/pwlProject";
|
||||||
import { getLatestHistoryByInterface } from '@/api/ai/aiHistory';
|
import { getLatestHistoryByInterface } from '@/api/ai/aiHistory';
|
||||||
import HistoryModal from './components/HistoryModal.vue';
|
import HistoryModal from './components/HistoryModal.vue';
|
||||||
@@ -617,7 +617,7 @@ const initChapterStructure = (data: any, contentMap?: Record<number, string>) =>
|
|||||||
noHistory: true // 标记为不需要历史记录
|
noHistory: true // 标记为不需要历史记录
|
||||||
},
|
},
|
||||||
{ title: `(二)${projectName.value || 'XX 公司'}概况`, content: '', formCommit: 41 },
|
{ title: `(二)${projectName.value || 'XX 公司'}概况`, content: '', formCommit: 41 },
|
||||||
{ title: `(三)${personName.value || 'XX'}同志任职及分工情况`, content: '', formCommit: 42 },
|
{ title: `(三)${personName.value || 'XX'}任职及分工情况`, content: '', formCommit: 42 },
|
||||||
{ title: '(四)实施审计的基本情况', content: '', formCommit: 43 }
|
{ title: '(四)实施审计的基本情况', content: '', formCommit: 43 }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -648,6 +648,7 @@ const initChapterStructure = (data: any, contentMap?: Record<number, string>) =>
|
|||||||
{
|
{
|
||||||
title: '五、审计建议',
|
title: '五、审计建议',
|
||||||
content: suggestion,
|
content: suggestion,
|
||||||
|
formCommit: 58, // 审计建议使用 formCommit 58
|
||||||
children: [], // 移除所有子章节
|
children: [], // 移除所有子章节
|
||||||
noSubChapters: true // 标记为没有子章节
|
noSubChapters: true // 标记为没有子章节
|
||||||
},
|
},
|
||||||
@@ -696,7 +697,7 @@ const getContentTypeText = (contentType: number): string => {
|
|||||||
const typeMap: Record<number, string> = {
|
const typeMap: Record<number, string> = {
|
||||||
1: '审计依据',
|
1: '审计依据',
|
||||||
2: `${projectName.value || 'ABC 公司'}概况`,
|
2: `${projectName.value || 'ABC 公司'}概况`,
|
||||||
3: `${personName.value || 'XX'}同志任职及分工情况`,
|
3: `${personName.value || 'XX'}任职及分工情况`,
|
||||||
4: '实施审计情况',
|
4: '实施审计情况',
|
||||||
5: '主要业绩',
|
5: '主要业绩',
|
||||||
6: '贯彻执行方针政策',
|
6: '贯彻执行方针政策',
|
||||||
@@ -857,7 +858,7 @@ const exportToWord = async () => {
|
|||||||
// 特殊处理:总体评价和审计建议
|
// 特殊处理:总体评价和审计建议
|
||||||
if (chapter.formCommit === 20) {
|
if (chapter.formCommit === 20) {
|
||||||
evaluate = chapter.content || '';
|
evaluate = chapter.content || '';
|
||||||
} else if (chapter.formCommit === 40) { // 审计建议的 formCommit 应该是 40
|
} else if (chapter.formCommit === 58) { // 审计建议的 formCommit 是 58
|
||||||
suggestion = chapter.content || '';
|
suggestion = chapter.content || '';
|
||||||
} else {
|
} else {
|
||||||
chapters.push({
|
chapters.push({
|
||||||
@@ -1127,7 +1128,7 @@ const generateFullReportHtml = (
|
|||||||
html += formatParagraphs(contentMap[41]);
|
html += formatParagraphs(contentMap[41]);
|
||||||
}
|
}
|
||||||
if (contentMap[42]) {
|
if (contentMap[42]) {
|
||||||
html += `<h3>(三)${personName}同志任职及分工情况</h3>`;
|
html += `<h3>(三)${personName}任职及分工情况</h3>`;
|
||||||
html += formatParagraphs(contentMap[42]);
|
html += formatParagraphs(contentMap[42]);
|
||||||
}
|
}
|
||||||
if (contentMap[43]) {
|
if (contentMap[43]) {
|
||||||
@@ -1215,18 +1216,17 @@ const generateFromInput = async () => {
|
|||||||
|
|
||||||
aiGenerating.value = true;
|
aiGenerating.value = true;
|
||||||
try {
|
try {
|
||||||
// 模拟AI分析(实际应调用后端接口)
|
// 获取当前章节信息
|
||||||
// 这里暂时使用模拟数据,实际应该调用AI分析接口
|
const currentChapter = outlineStructure.value[currentChapterIndex.value];
|
||||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
const formCommit = currentChapter?.formCommit || getFormCommitByTitle(currentChapter?.title || '');
|
||||||
|
|
||||||
const analyzedContent = `【AI分析结果】
|
// 调用后端 AI 分析接口
|
||||||
|
const analyzedContent = await analyzeUserInput({
|
||||||
基于您输入的内容:
|
projectId: String(form.id),
|
||||||
${aiInputText.value}
|
formCommit: formCommit,
|
||||||
|
userQuestion: aiInputText.value,
|
||||||
AI分析生成的${outlineStructure.value[currentChapterIndex.value].title}内容:
|
chapterContent: currentChapter?.content || ''
|
||||||
|
});
|
||||||
这里是AI根据您的输入生成的详细内容。实际应用中,这里应该调用后端的AI分析接口,将输入内容传给AI模型,获取分析结果。`;
|
|
||||||
|
|
||||||
// 保存到历史记录
|
// 保存到历史记录
|
||||||
saveToHistory(currentChapterIndex.value, analyzedContent);
|
saveToHistory(currentChapterIndex.value, analyzedContent);
|
||||||
@@ -1256,17 +1256,16 @@ const generateFromCustomInput = async (chapter: any, chapterIndex: number) => {
|
|||||||
|
|
||||||
customGenerating.value = chapterIndex;
|
customGenerating.value = chapterIndex;
|
||||||
try {
|
try {
|
||||||
// 模拟AI分析(实际应调用后端接口)
|
// 获取 formCommit
|
||||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
const formCommit = chapter.formCommit || getFormCommitByTitle(chapter.title);
|
||||||
|
|
||||||
const analyzedContent = `【AI分析结果】
|
// 调用后端 AI 分析接口
|
||||||
|
const analyzedContent = await analyzeUserInput({
|
||||||
基于您输入的内容:
|
projectId: String(form.id),
|
||||||
${chapter.customInput}
|
formCommit: formCommit,
|
||||||
|
userQuestion: chapter.customInput,
|
||||||
AI分析生成的${chapter.title}内容:
|
chapterContent: chapter.content || ''
|
||||||
|
});
|
||||||
这里是AI根据您的输入生成的详细内容。实际应用中,这里应该调用后端的AI分析接口,将输入内容传给AI模型,获取分析结果。`;
|
|
||||||
|
|
||||||
// 保存到历史记录
|
// 保存到历史记录
|
||||||
saveToHistory(chapterIndex, analyzedContent);
|
saveToHistory(chapterIndex, analyzedContent);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<template>
|
<template>
|
||||||
<a-space :size="10" style="flex-wrap: wrap">
|
<a-space :size="10" style="flex-wrap: wrap">
|
||||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
<a-button v-if="false" type="primary" class="ele-btn-icon" @click="add">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusOutlined />
|
<PlusOutlined />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
<a-popconfirm
|
<a-popconfirm
|
||||||
title="确定要删除此记录吗?"
|
title="确定要删除此记录吗?"
|
||||||
@confirm="remove(record)"
|
@confirm="remove(record)"
|
||||||
|
v-if="false"
|
||||||
>
|
>
|
||||||
<a class="ele-text-danger">删除</a>
|
<a class="ele-text-danger">删除</a>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
@@ -63,51 +64,143 @@
|
|||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="showDocManage"
|
v-model:visible="showDocManage"
|
||||||
:title="`文档管理 - ${currentKbName}`"
|
:title="`文档管理 - ${currentKbName}`"
|
||||||
width="800px"
|
width="1200px"
|
||||||
:footer="null"
|
:footer="null"
|
||||||
|
wrap-class-name="doc-manage-modal"
|
||||||
>
|
>
|
||||||
<div style="margin-bottom: 16px;">
|
<div class="doc-manage-container">
|
||||||
<a-button type="primary" @click="openImport">新增文档</a-button>
|
<div class="doc-layout">
|
||||||
</div>
|
<!-- 左侧目录树 -->
|
||||||
<a-table
|
<div class="dir-tree-panel">
|
||||||
:dataSource="docList"
|
<div class="dir-header">
|
||||||
:columns="docColumns"
|
<span>文档目录</span>
|
||||||
:loading="docLoading"
|
<a-space>
|
||||||
rowKey="id"
|
<a-button
|
||||||
:pagination="{
|
type="link"
|
||||||
current: currentPage,
|
size="small"
|
||||||
pageSize: 10,
|
@click="openEditDir"
|
||||||
total: total,
|
title="编辑目录"
|
||||||
showSizeChanger: false,
|
:disabled="!selectedKeys.length"
|
||||||
showTotal: (total) => `共 ${total} 条`
|
>
|
||||||
}"
|
<template #icon><EditOutlined /></template>
|
||||||
@change="(pag) => { currentPage = pag.current; loadDocuments(); }"
|
</a-button>
|
||||||
>
|
<a-button
|
||||||
<template #bodyCell="{ column, record }">
|
type="link"
|
||||||
<template v-if="column.key === 'action'">
|
size="small"
|
||||||
<a-space>
|
@click="openAddDir"
|
||||||
<a-popconfirm
|
title="新增目录"
|
||||||
title="确定要删除此文档吗?"
|
>
|
||||||
@confirm="deleteDoc(record)"
|
<template #icon><PlusOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
@click="deleteSelectedDir"
|
||||||
|
title="删除目录"
|
||||||
|
:disabled="!selectedKeys.length"
|
||||||
|
class="ele-text-danger"
|
||||||
|
>
|
||||||
|
<template #icon><DeleteOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
<div class="tree-container">
|
||||||
|
<a-tree
|
||||||
|
v-if="treeData.length > 0"
|
||||||
|
:tree-data="treeData"
|
||||||
|
:expanded-keys="expandedKeys"
|
||||||
|
:selected-keys="selectedKeys"
|
||||||
|
:load-data="onLoadData"
|
||||||
|
@expand="onExpand"
|
||||||
|
@select="onSelect"
|
||||||
|
:field-names="{ title: 'name', key: 'id', children: 'children' }"
|
||||||
>
|
>
|
||||||
<a class="ele-text-danger">删除</a>
|
<template #title="{ name, id }">
|
||||||
</a-popconfirm>
|
<span :class="{ 'active-dir': selectedKeys[0] === id }">{{ name }}</span>
|
||||||
</a-space>
|
</template>
|
||||||
</template>
|
</a-tree>
|
||||||
</template>
|
<a-empty v-else :image="simpleImage" description="暂无目录" />
|
||||||
</a-table>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧文档列表 -->
|
||||||
|
<div class="doc-list-panel">
|
||||||
|
<div class="doc-header">
|
||||||
|
<div class="doc-actions">
|
||||||
|
<a-button type="primary" @click="openImport">
|
||||||
|
<template #icon><UploadOutlined /></template>
|
||||||
|
上传文档
|
||||||
|
</a-button>
|
||||||
|
<span class="doc-tips">请选择分类上传资料</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="doc-content">
|
||||||
|
<a-table
|
||||||
|
:dataSource="docList"
|
||||||
|
:columns="docColumns"
|
||||||
|
:loading="docLoading"
|
||||||
|
rowKey="id"
|
||||||
|
:scroll="{ y: 500 }"
|
||||||
|
:pagination="pagination"
|
||||||
|
@change="handleTableChange"
|
||||||
|
size="middle"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a-space>
|
||||||
|
<a-popconfirm
|
||||||
|
title="确定要删除此文档吗?"
|
||||||
|
@confirm="deleteDoc(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-danger">删除</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
<!-- 导入弹窗 -->
|
<!-- 导入弹窗 -->
|
||||||
<Import v-model:visible="showImport" @done="loadDocuments" :kbId="currentKbId"/>
|
<Import2
|
||||||
|
v-model:visible="showImport"
|
||||||
|
@done="loadCloudFiles"
|
||||||
|
:doc="selectedDoc"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 新增/编辑目录弹窗 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="showDirModal"
|
||||||
|
:title="dirModalTitle"
|
||||||
|
width="400px"
|
||||||
|
@ok="handleSaveDir"
|
||||||
|
@cancel="closeDirModal"
|
||||||
|
>
|
||||||
|
<a-form :model="dirForm" layout="vertical">
|
||||||
|
<a-form-item label="目录名称">
|
||||||
|
<a-input v-model:value="dirForm.name" placeholder="请输入目录名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="排序号">
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="dirForm.sortNumber"
|
||||||
|
placeholder="请输入排序号"
|
||||||
|
:min="0"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { createVNode, ref } from 'vue';
|
import { createVNode, ref, computed } from 'vue';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal, Empty } from 'ant-design-vue';
|
||||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
import { ExclamationCircleOutlined, PlusOutlined, UploadOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue';
|
||||||
import type { EleProTable } from 'ele-admin-pro';
|
import type { EleProTable } from 'ele-admin-pro';
|
||||||
import {toDateString} from 'ele-admin-pro';
|
import {toDateString} from 'ele-admin-pro';
|
||||||
import type {
|
import type {
|
||||||
@@ -118,8 +211,11 @@
|
|||||||
import PwlProjectLibraryEdit from './components/pwlProjectLibraryEdit.vue';
|
import PwlProjectLibraryEdit from './components/pwlProjectLibraryEdit.vue';
|
||||||
import { pagePwlProjectLibrary, removePwlProjectLibrary, removeBatchPwlProjectLibrary } from '@/api/pwl/pwlProjectLibrary';
|
import { pagePwlProjectLibrary, removePwlProjectLibrary, removeBatchPwlProjectLibrary } from '@/api/pwl/pwlProjectLibrary';
|
||||||
import type { PwlProjectLibrary, PwlProjectLibraryParam } from '@/api/pwl/pwlProjectLibrary/model';
|
import type { PwlProjectLibrary, PwlProjectLibraryParam } from '@/api/pwl/pwlProjectLibrary/model';
|
||||||
import Import from '@/views/oa/oaCompany/components/Import.vue';
|
import Import2 from '@/views/oa/oaCompany/components/Import2.vue';
|
||||||
import {getKnowledgeBaseDocuments, deleteKnowledgeBaseDocument} from '@/api/ai/knowledgeBase';
|
import { listAiCloudDoc, addAiCloudDoc, updateAiCloudDoc, removeAiCloudDoc } from '@/api/ai/aiCloudDoc';
|
||||||
|
import type { AiCloudDoc } from '@/api/ai/aiCloudDoc/model';
|
||||||
|
import { listAiCloudFile, removeAiCloudFile } from '@/api/ai/aiCloudFile';
|
||||||
|
import type { AiCloudFile } from '@/api/ai/aiCloudFile/model';
|
||||||
|
|
||||||
// 表格实例
|
// 表格实例
|
||||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
@@ -138,37 +234,129 @@
|
|||||||
// 文档管理相关响应式变量
|
// 文档管理相关响应式变量
|
||||||
const showDocManage = ref(false); // 是否显示文档管理弹窗
|
const showDocManage = ref(false); // 是否显示文档管理弹窗
|
||||||
const showImport = ref(false); // 是否显示导入弹窗
|
const showImport = ref(false); // 是否显示导入弹窗
|
||||||
// 新增分页状态变量
|
const showDirModal = ref(false); // 是否显示目录弹窗(新增/编辑)
|
||||||
const currentPage = ref(1);
|
|
||||||
const total = ref(0);
|
|
||||||
|
|
||||||
// 文档管理相关变量
|
// 文档管理相关变量
|
||||||
const currentKbId = ref(''); // 当前知识库ID
|
const currentKbId = ref(''); // 当前知识库ID
|
||||||
const currentKbName = ref(''); // 当前知识库名称
|
const currentKbName = ref(''); // 当前知识库名称
|
||||||
const docList = ref<any[]>([]); // 文档列表数据
|
const currentCompanyId = ref<number>(0); // 当前单位ID - 固定为0
|
||||||
|
const docList = ref<AiCloudFile[]>([]); // 文档列表数据
|
||||||
const docLoading = ref(false); // 文档加载状态
|
const docLoading = ref(false); // 文档加载状态
|
||||||
|
const allDirs = ref<AiCloudDoc[]>([]); // 所有目录列表
|
||||||
|
|
||||||
|
// 树形结构相关
|
||||||
|
const expandedKeys = ref<(string | number)[]>([]);
|
||||||
|
const selectedKeys = ref<(string | number)[]>([]);
|
||||||
|
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||||
|
|
||||||
|
// 目录弹窗相关
|
||||||
|
const isEditingDir = ref(false); // 是否为编辑模式
|
||||||
|
const currentDirId = ref<number>(); // 当前操作的目录ID
|
||||||
|
|
||||||
|
// 目录表单
|
||||||
|
const dirForm = ref({
|
||||||
|
name: '',
|
||||||
|
sortNumber: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算目录弹窗标题
|
||||||
|
const dirModalTitle = computed(() => {
|
||||||
|
const mode = isEditingDir.value ? '编辑' : '新增';
|
||||||
|
const location = selectedDirName.value ? `在『${selectedDirName.value}』下` : '在根目录下';
|
||||||
|
return `${mode}目录 - ${location}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 分页配置
|
||||||
|
const pagination = ref({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
showSizeChanger: false,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showTotal: (total: number) => `共 ${total} 条`,
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100']
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算树形数据
|
||||||
|
const treeData = computed(() => {
|
||||||
|
const buildTree = (parentId: number = 0): any[] => {
|
||||||
|
return allDirs.value
|
||||||
|
.filter(item => item.parentId === parentId)
|
||||||
|
.map(item => ({
|
||||||
|
...item,
|
||||||
|
key: item.id,
|
||||||
|
title: item.name,
|
||||||
|
children: buildTree(item.id),
|
||||||
|
isLeaf: allDirs.value.filter(child => child.parentId === item.id).length === 0
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
return buildTree(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 选中的目录名称
|
||||||
|
const selectedDirName = computed(() => {
|
||||||
|
if (selectedKeys.value.length === 0) return '';
|
||||||
|
const selectedId = selectedKeys.value[0];
|
||||||
|
const dir = allDirs.value.find(item => item.id === selectedId);
|
||||||
|
return dir?.name || '';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算选中的目录ID(用于文件上传)
|
||||||
|
const selectedCategoryId = computed(() => {
|
||||||
|
if (selectedKeys.value.length === 0) return '';
|
||||||
|
return selectedKeys.value[0].toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算选中的文档对象
|
||||||
|
const selectedDoc = computed(() => {
|
||||||
|
if (selectedKeys.value.length === 0) return null;
|
||||||
|
const selectedId = selectedKeys.value[0];
|
||||||
|
const doc = allDirs.value.find(item => item.id === selectedId);
|
||||||
|
return doc ? {
|
||||||
|
id: doc.id!,
|
||||||
|
categoryId: doc.categoryId || ''
|
||||||
|
} : null;
|
||||||
|
});
|
||||||
|
|
||||||
// 文档表格列配置
|
// 文档表格列配置
|
||||||
const docColumns = ref([
|
const docColumns = ref([
|
||||||
{
|
{
|
||||||
title: '文件名',
|
title: '文件名',
|
||||||
dataIndex: 'name', // 改为接口返回的name字段
|
dataIndex: 'fileName',
|
||||||
key: 'fileName',
|
key: 'fileName',
|
||||||
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '文件大小',
|
title: '文件大小',
|
||||||
dataIndex: 'size', // 改为接口返回的size字段
|
dataIndex: 'fileSize',
|
||||||
key: 'fileSize',
|
key: 'fileSize',
|
||||||
|
width: 120,
|
||||||
|
customRender: ({ text }: { text: string }) => {
|
||||||
|
if (!text) return '-';
|
||||||
|
const size = Number(text);
|
||||||
|
if (size < 1024) return size + ' B';
|
||||||
|
if (size < 1024 * 1024) return (size / 1024).toFixed(1) + ' KB';
|
||||||
|
return (size / (1024 * 1024)).toFixed(1) + ' MB';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '文件类型',
|
||||||
|
dataIndex: 'fileType',
|
||||||
|
key: 'fileType',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '上传时间',
|
title: '上传时间',
|
||||||
dataIndex: 'gmtModified', // 改为接口返回的gmtModified字段
|
dataIndex: 'uploadTime',
|
||||||
key: 'createTime',
|
key: 'uploadTime',
|
||||||
customRender: ({ text }) => toDateString(text) // 添加时间格式化
|
width: 180,
|
||||||
|
customRender: ({ text }: { text: string }) => toDateString(text)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 100,
|
width: 80
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -276,48 +464,111 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开文档管理弹窗
|
// 打开文档管理弹窗
|
||||||
const openDocManage = (record: PwlProjectLibrary) => {
|
const openDocManage = async (record: PwlProjectLibrary) => {
|
||||||
currentKbId.value = record.kbId; // 使用record中的kbId
|
currentKbId.value = record.kbId;
|
||||||
currentKbName.value = record.name; // 使用单位名称作为知识库名称
|
currentKbName.value = record.name;
|
||||||
currentPage.value = 1;
|
currentCompanyId.value = 0; // 固定为0
|
||||||
|
pagination.value.current = 1;
|
||||||
showDocManage.value = true;
|
showDocManage.value = true;
|
||||||
loadDocuments();
|
|
||||||
|
// 重置选择状态
|
||||||
|
expandedKeys.value = [];
|
||||||
|
selectedKeys.value = [];
|
||||||
|
|
||||||
|
// 加载目录列表
|
||||||
|
await loadAllCloudDocs(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载所有目录
|
||||||
|
const loadAllCloudDocs = async (resetState = false) => {
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
companyId: 0 // 固定为0
|
||||||
|
};
|
||||||
|
const result = await listAiCloudDoc(params);
|
||||||
|
allDirs.value = result || [];
|
||||||
|
|
||||||
|
if (resetState) {
|
||||||
|
// 默认展开根节点并选中第一个目录
|
||||||
|
if (allDirs.value.length > 0) {
|
||||||
|
const rootDirs = allDirs.value.filter(item => item.parentId === 0);
|
||||||
|
if (rootDirs.length > 0) {
|
||||||
|
expandedKeys.value = [rootDirs[0].id!];
|
||||||
|
selectedKeys.value = [rootDirs[0].id!];
|
||||||
|
loadCloudFiles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
message.error('加载目录列表失败');
|
||||||
|
console.error('加载目录错误:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 树节点展开
|
||||||
|
const onExpand = (keys: (string | number)[]) => {
|
||||||
|
expandedKeys.value = keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 树节点选择
|
||||||
|
const onSelect = (keys: (string | number)[], { node }: any) => {
|
||||||
|
selectedKeys.value = keys;
|
||||||
|
pagination.value.current = 1;
|
||||||
|
loadCloudFiles();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 异步加载子节点
|
||||||
|
const onLoadData = (node: any) => {
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格分页变化处理
|
||||||
|
const handleTableChange = (pag: any) => {
|
||||||
|
pagination.value.current = pag.current;
|
||||||
|
pagination.value.pageSize = pag.pageSize;
|
||||||
|
loadCloudFiles();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 加载文档列表
|
// 加载文档列表
|
||||||
const loadDocuments = async () => {
|
const loadCloudFiles = async () => {
|
||||||
docLoading.value = true;
|
docLoading.value = true;
|
||||||
try {
|
try {
|
||||||
const response = await getKnowledgeBaseDocuments(
|
if (!selectedCategoryId.value) {
|
||||||
currentKbId.value,
|
docList.value = [];
|
||||||
10,
|
pagination.value.total = 0;
|
||||||
currentPage.value
|
return;
|
||||||
);
|
}
|
||||||
docList.value = Array.isArray(response?.list) ? response.list : [];
|
|
||||||
total.value = response?.count || 0;
|
const params = {
|
||||||
|
docId: parseInt(selectedCategoryId.value),
|
||||||
|
page: pagination.value.current,
|
||||||
|
pageSize: pagination.value.pageSize
|
||||||
|
};
|
||||||
|
const result = await listAiCloudFile(params);
|
||||||
|
|
||||||
|
if (result && result.records) {
|
||||||
|
docList.value = result.records;
|
||||||
|
pagination.value.total = result.total;
|
||||||
|
} else {
|
||||||
|
docList.value = result || [];
|
||||||
|
pagination.value.total = docList.value.length;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('加载文档列表失败');
|
message.error('加载文件列表失败');
|
||||||
console.error('加载文档错误:', error);
|
console.error('加载文件错误:', error);
|
||||||
} finally {
|
} finally {
|
||||||
docLoading.value = false;
|
docLoading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除文档
|
// 删除文档
|
||||||
const deleteDoc = async (record: any) => {
|
const deleteDoc = async (record: AiCloudFile) => {
|
||||||
try {
|
try {
|
||||||
// 执行删除操作
|
await removeAiCloudFile(record.id);
|
||||||
await deleteKnowledgeBaseDocument(currentKbId.value, record.id);
|
await loadCloudFiles();
|
||||||
|
|
||||||
// 立即本地删除(核心修改)
|
|
||||||
const index = docList.value.findIndex(item => item.id === record.id);
|
|
||||||
if (index > -1) {
|
|
||||||
docList.value.splice(index, 1);
|
|
||||||
total.value -= 1;
|
|
||||||
}
|
|
||||||
message.success('删除成功');
|
message.success('删除成功');
|
||||||
// 阿里云异步删除,需等待异步删除完成再重新查询
|
|
||||||
// await loadDocuments();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('删除失败');
|
message.error('删除失败');
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -326,9 +577,150 @@
|
|||||||
|
|
||||||
// 打开导入弹窗
|
// 打开导入弹窗
|
||||||
const openImport = () => {
|
const openImport = () => {
|
||||||
|
if (selectedKeys.value.length === 0) {
|
||||||
|
message.info('请先选择一个目录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedDoc.value) {
|
||||||
|
message.info('选中的目录信息不完整');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
showImport.value = true;
|
showImport.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 打开新增目录弹窗
|
||||||
|
const openAddDir = () => {
|
||||||
|
if (selectedKeys.value.length === 0) {
|
||||||
|
message.info('请先选择一个目录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isEditingDir.value = false;
|
||||||
|
currentDirId.value = undefined;
|
||||||
|
dirForm.value.name = '';
|
||||||
|
dirForm.value.sortNumber = 0;
|
||||||
|
showDirModal.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开编辑目录弹窗
|
||||||
|
const openEditDir = () => {
|
||||||
|
if (selectedKeys.value.length === 0) {
|
||||||
|
message.info('请先选择一个目录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedDir = allDirs.value.find(item => item.id === selectedKeys.value[0]);
|
||||||
|
if (!selectedDir) {
|
||||||
|
message.error('未找到选中的目录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEditingDir.value = true;
|
||||||
|
currentDirId.value = selectedDir.id;
|
||||||
|
dirForm.value.name = selectedDir.name || '';
|
||||||
|
dirForm.value.sortNumber = selectedDir.sortNumber || 0;
|
||||||
|
showDirModal.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除选中目录
|
||||||
|
const deleteSelectedDir = async () => {
|
||||||
|
if (selectedKeys.value.length === 0) {
|
||||||
|
message.info('请先选择一个目录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedDir = allDirs.value.find(item => item.id === selectedKeys.value[0]);
|
||||||
|
if (!selectedDir) {
|
||||||
|
message.error('未找到选中的目录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await deleteDir(selectedDir.id!, selectedDir.name || '');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭目录弹窗
|
||||||
|
const closeDirModal = () => {
|
||||||
|
showDirModal.value = false;
|
||||||
|
dirForm.value.name = '';
|
||||||
|
dirForm.value.sortNumber = 0;
|
||||||
|
currentDirId.value = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理保存目录(新增/编辑)
|
||||||
|
const handleSaveDir = async () => {
|
||||||
|
if (!dirForm.value.name) {
|
||||||
|
message.error('请输入目录名称');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isEditingDir.value) {
|
||||||
|
const updateData: AiCloudDoc = {
|
||||||
|
id: currentDirId.value,
|
||||||
|
name: dirForm.value.name,
|
||||||
|
sortNumber: dirForm.value.sortNumber || 0
|
||||||
|
};
|
||||||
|
await updateAiCloudDoc(updateData);
|
||||||
|
message.success('修改目录成功');
|
||||||
|
} else {
|
||||||
|
const newDir: AiCloudDoc = {
|
||||||
|
companyId: 0, // 固定为0
|
||||||
|
parentId: selectedKeys.value[0] as number,
|
||||||
|
name: dirForm.value.name,
|
||||||
|
sortNumber: dirForm.value.sortNumber || 0
|
||||||
|
};
|
||||||
|
await addAiCloudDoc(newDir);
|
||||||
|
message.success('新增目录成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
showDirModal.value = false;
|
||||||
|
await loadAllCloudDocs(false);
|
||||||
|
|
||||||
|
if (!isEditingDir.value) {
|
||||||
|
const parentId = selectedKeys.value[0] as number;
|
||||||
|
if (!expandedKeys.value.includes(parentId)) {
|
||||||
|
expandedKeys.value = [...expandedKeys.value, parentId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
message.error(isEditingDir.value ? '修改目录失败' : '新增目录失败');
|
||||||
|
console.error('目录操作错误:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除目录
|
||||||
|
const deleteDir = async (dirId: number, dirName: string) => {
|
||||||
|
const hasChildren = allDirs.value.some(item => item.parentId === dirId);
|
||||||
|
if (hasChildren) {
|
||||||
|
message.error(`目录「${dirName}」包含子目录,无法删除。请先删除该目录下的所有子目录。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: `确定要删除目录「${dirName}」吗?`,
|
||||||
|
icon: createVNode(ExclamationCircleOutlined),
|
||||||
|
maskClosable: true,
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
await removeAiCloudDoc(dirId);
|
||||||
|
message.success('删除目录成功');
|
||||||
|
await loadAllCloudDocs(false);
|
||||||
|
|
||||||
|
if (selectedKeys.value.includes(dirId)) {
|
||||||
|
selectedKeys.value = [];
|
||||||
|
docList.value = [];
|
||||||
|
pagination.value.total = 0;
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '删除目录失败');
|
||||||
|
console.error('删除目录错误:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* 删除单个 */
|
/* 删除单个 */
|
||||||
const remove = (row: PwlProjectLibrary) => {
|
const remove = (row: PwlProjectLibrary) => {
|
||||||
@@ -399,4 +791,175 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped>
|
||||||
|
/* 文档管理布局 */
|
||||||
|
.doc-manage-container {
|
||||||
|
height: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-layout {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dir-tree-panel {
|
||||||
|
width: 280px;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
border-radius: 6px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dir-header {
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-bottom: 1px solid #e8e8e8;
|
||||||
|
background: #fafafa;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-container {
|
||||||
|
flex: 1;
|
||||||
|
padding: 8px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-list-panel {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
border-radius: 6px;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-header {
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-bottom: 1px solid #e8e8e8;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-tips {
|
||||||
|
color: #ff4d4f;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-content {
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 树节点激活样式 */
|
||||||
|
:deep(.active-dir) {
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tree-node-content-wrapper) {
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tree-node-content-wrapper:hover) {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tree .ant-tree-treenode-selected .ant-tree-node-content-wrapper) {
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 优化表格样式 */
|
||||||
|
:deep(.doc-manage-modal .ant-modal-body) {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-table-wrapper) {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-spin-nested-loading) {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-spin-container) {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-table) {
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-table-container) {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-table-body) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-table-thead > tr > th) {
|
||||||
|
background: #fafafa;
|
||||||
|
font-weight: 600;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-table-tbody > tr > td) {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文件名列特殊处理,允许换行 */
|
||||||
|
:deep(.doc-content .ant-table-tbody > tr > td:first-child) {
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
line-height: 1.4;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分页样式调整 */
|
||||||
|
:deep(.doc-content .ant-pagination) {
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.doc-content .ant-table-pagination) {
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 删除按钮样式 */
|
||||||
|
:deep(.ele-text-danger) {
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user