123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365 |
- <template>
- <div class="project-search">
- <div class="file-categories">
- <el-button type="primary" @click="createNewFolder">
- <i class="el-icon-plus"></i> 新建目录
- </el-button>
- <p>{{ $route.query.name }}</p>
- <el-tree
- :data="folders"
- :props="defaultProps"
- @node-click="handleNodeClick"
- ref="folderTree"
- :default-expanded-keys="['0']"
- node-key="id"
- highlight-current
- >
- <span class="custom-tree-node" slot-scope="{ node, data }">
- <span class="tree_title">
- <i class="el-icon-folder"></i>
- <span class="folder-name" :title="node.label">{{
- node.label
- }}</span>
- </span>
- <span v-if="data.id !== '001'" :class="getFileCountClass(data.id)"
- >{{ data.document_count }} files</span
- >
- <span
- class="folder-actions"
- v-if="data.id !== 0 && data.id !== '001'"
- >
- <el-tooltip
- class="item"
- effect="dark"
- content="编辑"
- placement="top"
- >
- <i class="el-icon-edit" @click.stop="editFolder(data)"></i>
- </el-tooltip>
- <el-tooltip
- class="item"
- effect="dark"
- content="删除"
- placement="top"
- >
- <i class="el-icon-delete" @click.stop="deleteFolder(data.id)"></i>
- </el-tooltip>
- </span>
- </span>
- </el-tree>
- </div>
- <div class="right">
- <dataSearch
- @bindSetQuery="setQuery"
- @refreshFolders="typeList"
- ></dataSearch>
- <!-- <dataList
- :queryForm="queryForm"
- :allowEdit="checkAuth('/document/update')"
- :allowDelete="checkAuth('/document/delete')"
- ></dataList> -->
- <div
- class="data-list"
- v-loading="loading"
- element-loading-text="加载中..."
- >
- <div class="batch-actions" style="margin: 10px 0">
- <el-button
- type="primary"
- @click="batchAnalysis"
- :disabled="!selectedRows.length"
- >批量解析</el-button
- >
- <el-button
- type="primary"
- @click="batchModifyFolder"
- :disabled="!selectedRows.length"
- >批量修改目录</el-button
- >
- <el-button
- type="primary"
- @click="batchDelect"
- :disabled="!selectedRows.length"
- >批量删除</el-button
- >
- </div>
- <el-table
- ref="dataTable"
- :data="dataList"
- style="width: 100%; font-size: 12px"
- header-row-class-name="headerBg"
- empty-text="暂无数据"
- @selection-change="handleSelectionChange"
- @sort-change="handleSortChange"
- >
- <el-table-column type="selection" width="55"></el-table-column>
- <el-table-column prop="id" label="ID" align="center" width="80" />
- <el-table-column prop="name" label="文件名称" sortable width="350">
- <template #default="scope">
- <span>{{ scope.row.name }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="type" label="文件类型" align="center" />
- <el-table-column prop="chunk_num" label="分块数" align="center" />
- <el-table-column
- prop="create_time"
- label="上传时间"
- align="center"
- sortable
- width="140"
- />
- <el-table-column prop="run" label="解析状态" align="center">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.run)" size="small">
- {{ getStatusText(scope.row.run) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column
- label="操作"
- align="center"
- fixed="right"
- width="180"
- >
- <template #default="scope">
- <div class="operations-container">
- <el-tooltip
- class="item"
- effect="dark"
- content="预览"
- placement="top"
- >
- <el-button
- type="text"
- size="small"
- circle
- icon="el-icon-view"
- v-if="checkAuth('/document/update')"
- style="font-size: 15px"
- @click="getName(scope.row)"
- ></el-button>
- </el-tooltip>
- <el-tooltip
- class="item"
- effect="dark"
- content="修改文件名"
- placement="top"
- >
- <el-button
- type="text"
- size="small"
- circle
- icon="el-icon-edit"
- v-if="checkAuth('/document/update')"
- style="font-size: 15px"
- @click="btnEdit(scope.row)"
- ></el-button>
- </el-tooltip>
- <el-popover
- placement="bottom"
- trigger="click"
- popper-class="operations-popover"
- >
- <template #reference>
- <el-button
- type="text"
- size="small"
- circle
- class="operation-button"
- style="font-size: 15px; margin-left: 10px"
- icon="el-icon-more"
- ></el-button>
- </template>
- <div class="additional-operations">
- <el-tooltip
- class="item"
- effect="dark"
- :content="
- scope.row.run == 1 || scope.row.run == 5
- ? `当前状态:${getStatusText(scope.row.run)/* scope.row.progress */} 解析说明:${scope.row.progress_msg}`
- : '解析'
- "
- placement="top"
- >
- <el-button
- v-if="scope.row.run != 1 && scope.row.run != 5"
- type="text"
- icon="el-icon-caret-right"
- circle
- @click="analysis(scope.row)"
- style="font-size: 15px"
- >
- </el-button>
- <el-button
- v-else
- type="text"
- icon="el-icon-loading"
- circle
- :disabled="true"
- style="font-size: 15px"
- >
- </el-button>
- </el-tooltip>
- <el-tooltip
- class="item"
- effect="dark"
- content="解析方法"
- placement="top"
- >
- <el-button
- type="text"
- size="small"
- circle
- icon="el-icon-tickets"
- v-if="checkAuth('/document/update')"
- style="font-size: 15px"
- @click="Analytical(scope.row)"
- ></el-button>
- </el-tooltip>
- <el-tooltip
- class="item"
- effect="dark"
- content="下载"
- placement="top"
- >
- <el-button
- type="text"
- size="small"
- circle
- icon="el-icon-download"
- @click="btnDown(scope.row)"
- :loading="scope.row.downloading"
- style="font-size: 15px"
- ></el-button>
- </el-tooltip>
- <el-tooltip
- class="item"
- effect="dark"
- content="删除"
- placement="top"
- >
- <el-button
- type="text"
- size="small"
- circle
- icon="el-icon-delete"
- v-if="checkAuth('/document/delete')"
- @click="btnDelete(scope.row.id)"
- style="font-size: 15px"
- ></el-button>
- </el-tooltip>
- </div>
- </el-popover>
- </div>
- </template>
- </el-table-column>
- </el-table>
- <div class="page-info">
- <el-pagination
- :currentPage="queryForm.page"
- :page-size="queryForm.pageSize"
- :total="recordCount"
- :page-count="pageTotal"
- :page-sizes="[10, 20, 50, 100]"
- background
- layout="total,sizes, prev, pager, next"
- @current-change="ChangePage"
- @size-change="handleSizeChange"
- >
- </el-pagination>
- </div>
- <el-dialog
- title="修改名称"
- :visible.sync="dialogVisible"
- width="30%"
- :before-close="handleClose"
- >
- <el-form :model="wordForm" ref="wordRef" :rules="wordRules">
- <el-form-item label="文件名称:" prop="new_name">
- <el-input
- v-model="wordForm.new_name"
- placeholder="请输入文件名称"
- ></el-input>
- </el-form-item>
- </el-form>
- <span slot="footer" class="dialog-footer">
- <el-button @click="handleClose">取 消</el-button>
- <el-button type="primary" @click="submitBuck">确 定</el-button>
- </span>
- </el-dialog>
- <!-- 解析方法 -->
- <el-dialog
- title="解析方法"
- :visible.sync="anaDialogVisible"
- width="30%"
- :before-close="handleAnalClose"
- >
- <el-form
- :model="analForm"
- ref="analRef"
- label-position="top"
- :rules="analRules"
- >
- <el-form-item label="页码范围:" prop="new_name">
- <el-input-number
- v-model="analForm.start_page"
- controls-position="right"
- :min="1"
- ></el-input-number>
- <el-input-number
- v-model="analForm.end_page"
- controls-position="right"
- :min="1"
- style="margin-left: 10px"
- ></el-input-number>
- </el-form-item>
- <el-form-item label="块token数">
- <div class="block">
- <el-slider v-model="analForm.token_num" :max="2048" show-input>
- </el-slider>
- </div>
- </el-form-item>
- </el-form>
- <span slot="footer" class="dialog-footer">
- <el-button type="primary" @click="handleAnalClose">取 消</el-button>
- <el-button type="primary" @click="submitAnal">确 定</el-button>
- </span>
- </el-dialog>
- <el-dialog
- title="新建目录"
- :visible.sync="newFolderDialogVisible"
- width="30%"
- >
- <el-form
- :model="newFolderForm"
- :rules="newFolderRules"
- ref="newFolderFormRef"
- >
- <el-form-item label="文件夹名称" prop="name">
- <el-input v-model="newFolderForm.name"></el-input>
- </el-form-item>
- </el-form>
- <span slot="footer" class="dialog-footer">
- <el-button type="primary" @click="newFolderDialogVisible = false"
- >取 消</el-button
- >
- <el-button type="primary" @click="submitNewFolder">确 定</el-button>
- </span>
- </el-dialog>
- <!-- 批量修改目录 -->
- <el-dialog
- title="批量修改目录"
- :visible.sync="batchModifyFolderDialogVisible"
- width="30%"
- >
- <el-form
- :model="batchModifyFolderForm"
- :rules="batchModifyFolderRules"
- ref="batchModifyFolderFormRef"
- >
- <el-form-item label="选择目录" prop="folderId">
- <el-select
- v-model="batchModifyFolderForm.folderId"
- placeholder="请选择目录"
- >
- <el-option
- v-for="folder in folders.filter((f) => f.id !== 0)"
- :key="folder.id"
- :label="folder.name"
- :value="folder.id"
- >
- </el-option>
- </el-select>
- </el-form-item>
- </el-form>
- <span slot="footer" class="dialog-footer">
- <el-button
- type="primary"
- @click="batchModifyFolderDialogVisible = false"
- >取 消</el-button
- >
- <el-button type="primary" @click="submitBatchModifyFolder"
- >确 定</el-button
- >
- </span>
- </el-dialog>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- import { mapGetters } from "vuex";
- import { dataSearch, dataList } from "./components";
- import {
- getBucketContents,
- deleteFile,
- nameGetUrl,
- renameFile,
- analysis,
- batchAnalysis,
- getRunStatus,
- insertType,
- updateType,
- selectTypeList,
- deleteType,
- Info,
- batchMove,
- selectType0,
- delDocumentList,
- getdocpro,
- analysisPro,
- resultTask,
- } from "@/api/knowledge";
- export default {
- components: {
- dataSearch,
- dataList,
- },
- computed: {
- ...mapGetters(["roleInfo", "authList"]),
- },
- data() {
- return {
- queryForm: {
- page: 1,
- pageSize: 10,
- bucket_id: "",
- doc_type_id: 0,
- },
- typeForm: {
- page: 1,
- pageSize: 9999,
- kb_id: "",
- },
- folders: [{ id: "001", name: "全部", document_count: 0 }],
- defaultProps: {
- children: "children",
- label: "name",
- },
- // dataList 组件的数据
- loading: false,
- dialogVisible: false,
- currentDataId: 0,
- recordCount: 0,
- pageTotal: 1,
- dataList: [],
- currentData: {},
- wordForm: {
- document_id: "",
- new_name: "",
- },
- wordRules: {
- new_name: [
- { required: true, message: "请输入文件名称", trigger: "blur" },
- ],
- },
- anaDialogVisible: false,
- analForm: {
- start_page: 1,
- end_page: 10000,
- token_num: 0,
- },
- analRules: {},
- selectedRows: [],
- sortColumn: "",
- sortOrder: "",
- analysisStatusCheckers: {},
- newFolderDialogVisible: false,
- newFolderForm: {
- name: "",
- kb_id: "",
- status: 5,
- },
- newFolderRules: {
- name: [
- { required: true, message: "请输入文件夹名称", trigger: "blur" },
- ],
- },
- /* 批量修改目录 */
- batchModifyFolderDialogVisible: false,
- batchModifyFolderForm: {
- folderId: null,
- },
- batchModifyFolderRules: {
- folderId: [
- { required: true, message: "请选择目标目录", trigger: "change" },
- ],
- },
- };
- },
- mounted() {
- this.queryForm.bucket_id = this.$route.query.id;
- this.typeForm.kb_id = this.$route.query.id;
- this.$nextTick(() => {
- this.initializeTree();
- });
- this.typeList();
- this.search();
- },
- beforeDestroy() {
- Object.values(this.analysisStatusCheckers).forEach(clearTimeout);
- },
- methods: {
- /* 操作栏 */
- handleCommand(command, row) {
- switch (command) {
- case "analysis":
- this.analysis(row);
- break;
- case "analyticalMethod":
- this.Analytical(row);
- break;
- case "download":
- this.btnDown(row);
- break;
- case "delete":
- this.btnDelete(row.id);
- break;
- }
- },
- /* 状态展示 */
- getStatusType(status) {
- const statusMap = {
- 0: "info", // 未解析
- 1: "warning", // 解析中
- 3: "success", // 成功
- 4: "danger", // 失败
- 5: "warning", // 待处理
- 6: "danger", // 文件异常
- };
- return statusMap[status] || "info";
- },
- getStatusText(status) {
- const statusMap = {
- 0: "未解析",
- 1: "解析中",
- 3: "成功",
- 4: "失败",
- 5: "待处理",
- 6: "文件异常",
- };
- return statusMap[status] || "未知状态";
- },
- /* 判断类名 */
- getFileCountClass(id) {
- const isSpecialFolder = id === 0 || id === "001";
- console.log(
- `ID: ${id}, Class: ${isSpecialFolder ? "file-counts" : "file-count"}`
- );
- return isSpecialFolder ? "file-counts" : "file-count";
- },
- /* 批量修改目录 */
- batchModifyFolder() {
- if (this.selectedRows.length === 0) {
- this.$message.warning("请选择要修改目录的文件");
- return;
- }
- this.batchModifyFolderDialogVisible = true;
- },
- submitBatchModifyFolder() {
- this.$refs.batchModifyFolderFormRef.validate((valid) => {
- if (valid) {
- const selectedIds = this.selectedRows.map((row) => row.id);
- console.log(selectedIds);
- batchMove({
- ids: JSON.stringify(selectedIds),
- doc_type_id: this.batchModifyFolderForm.folderId,
- })
- .then((res) => {
- if (res.status === 200) {
- this.$message.success("批量修改目录成功");
- this.batchModifyFolderDialogVisible = false;
- this.search(); // Refresh the document list
- this.typeList(); // Refresh the folder list
- this.clearSelection();
- } else {
- this.$message.error("批量修改目录失败");
- }
- })
- .catch((error) => {
- console.error("批量修改目录时出错:", error);
- this.$message.error("批量修改目录时出错");
- });
- }
- });
- },
- editFolder(folder) {
- this.$prompt("请输入新的文件夹名称", "编辑文件夹", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- inputValue: folder.name,
- inputValidator: (value) => {
- if (!value) {
- return "文件夹名称不能为空";
- }
- return true;
- },
- })
- .then(({ value }) => {
- if (value !== folder.name) {
- const updatedFolder = { ...folder, name: value };
- updateType(updatedFolder)
- .then((res) => {
- if (res.status === 200) {
- this.$message.success("更新文件夹成功");
- this.typeList(); // 刷新文件夹列表
- } else {
- this.$message.error("更新文件夹失败");
- }
- })
- .catch((error) => {
- console.error("更新文件夹时出错:", error);
- this.$message.error("更新文件夹时出错");
- });
- }
- })
- .catch(() => {
- // 用户取消操作,不做任何处理
- });
- },
- deleteFolder(folderId) {
- this.$confirm("确定要删除该文件夹吗?删除后无法恢复。", "警告", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(() => {
- deleteType({ id: folderId })
- .then((res) => {
- if (res.status === 200) {
- this.$message.success("删除文件夹成功");
- this.typeList(); // 刷新文件夹列表
- } else {
- this.$message.error("删除文件夹失败");
- }
- })
- .catch((error) => {
- console.error("删除文件夹时出错:", error);
- this.$message.error("删除文件夹时出错");
- });
- })
- .catch(() => {
- // 用户取消删除操作,不做任何处理
- });
- },
- /* 目录初始化 */
- typeList() {
- this.loading = true;
- Promise.all([
- selectTypeList(this.typeForm),
- selectType0({ kb_id: this.typeForm.kb_id, type_id: 0 }),
- ])
- .then(([typeListRes, type0Res]) => {
- if (typeListRes.status === 200 && type0Res.status === 200) {
- const folderList = typeListRes.data.dataList.map((folder) => ({
- ...folder,
- id: folder.id === 0 ? "001" : folder.id.toString(),
- document_count: folder.document_count || 0,
- }));
- // Calculate total documents
- const totalDocuments = folderList.reduce(
- (sum, folder) => sum + folder.document_count,
- 0
- );
- // Get the count of "其他" documents from selectType0 response
- const otherFolderCount = type0Res.data || 0;
- this.folders = [
- {
- id: "001",
- name: "全部",
- document_count: totalDocuments + otherFolderCount,
- },
- ...folderList.filter(
- (folder) => folder.id !== "001" && folder.id !== 0
- ),
- {
- id: 0,
- name: "其他",
- document_count: otherFolderCount,
- },
- ];
- this.$nextTick(() => {
- this.initializeTree();
- });
- } else {
- this.$message.error("获取文件夹列表失败");
- }
- })
- .catch((error) => {
- console.error("获取文件夹列表时出错:", error);
- this.$message.error("获取文件夹列表时出错");
- })
- .finally(() => {
- this.loading = false;
- });
- },
- initializeTree() {
- this.$nextTick(() => {
- if (this.$refs.folderTree) {
- this.$refs.folderTree.setCurrentKey(0);
- this.handleNodeClick(this.folders[0]);
- }
- });
- },
- createNewFolder() {
- this.newFolderDialogVisible = true;
- },
- /* 新增 */
- submitNewFolder() {
- this.$refs.newFolderFormRef.validate((valid) => {
- if (valid) {
- this.newFolderForm.kb_id = this.$route.query.id;
- insertType(this.newFolderForm).then((res) => {
- if (res.status === 200) {
- this.$message.success("创建文件夹成功");
- this.newFolderDialogVisible = false;
- this.$refs.newFolderFormRef.resetFields();
- this.typeList(); // Refresh folder list
- } else {
- this.$message.error("创建文件夹失败");
- }
- });
- }
- });
- },
- initializeTree() {
- this.$nextTick(() => {
- if (this.$refs.folderTree) {
- this.$refs.folderTree.setCurrentKey("001");
- this.handleNodeClick(this.folders[0]);
- }
- });
- },
- checkAuth(path) {
- if (this.roleInfo.is_admin === 1) {
- return true;
- }
- return this.authList.some(
- (auth) => auth.type === 999 && auth.path === path
- );
- },
- setQuery(e) {
- this.queryForm = { ...this.queryForm, ...e };
- this.search();
- },
- handleNodeClick(data) {
- this.queryForm.doc_type_id = data.id === "001" ? "" : data.id;
- this.queryForm.page = 1; // Reset to first page when changing folder
- this.search();
- },
- /*列表事件 */
- /* 排序 */
- handleSortChange({ prop, order }) {
- this.sortColumn = prop;
- this.sortOrder = order;
- this.sortData();
- },
- sortData() {
- const { sortColumn, sortOrder } = this;
- if (!sortColumn || !sortOrder) {
- this.search(); // Reset to original order
- return;
- }
- this.dataList.sort((a, b) => {
- let comparison = 0;
- if (sortColumn === "name") {
- comparison = a.name.localeCompare(b.name, "zh-CN");
- } else if (sortColumn === "create_time") {
- comparison = new Date(a.create_time) - new Date(b.create_time);
- }
- return sortOrder === "ascending" ? comparison : -comparison;
- });
- },
- /* 批量解析 */
- handleSelectionChange(val) {
- this.selectedRows = val;
- },
- batchAnalysis() {
- const selectedIds = this.selectedRows.map((row) => row.id);
- if (selectedIds.length === 0) {
- this.$message.warning("请选择要解析的文件");
- return;
- }
- this.$confirm("确定要批量解析选中的文件吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(() => {
- this.loading = true;
- analysisPro({
- document_ids: JSON.stringify(selectedIds),
- }) /* { ids: JSON.stringify(selectedIds) } */
- .then((res) => {
- if (res.status === 200) {
- this.$message.success("批量解析任务已提交");
- this.updateAnalysisStatus(selectedIds);
- this.clearSelection();
- } else {
- this.$message.error("批量解析请求失败");
- }
- })
- .catch((error) => {
- console.error("批量解析错误:", error);
- this.$message.error("批量解析过程中出现错误");
- })
- .finally(() => {
- this.loading = false;
- });
- })
- .catch(() => {
- // 取消操作
- });
- },
- /* 批量删除 */
- batchDelect() {
- const selectedIds = this.selectedRows.map((row) => row.id);
- if (selectedIds.length === 0) {
- this.$message.warning("请选择要删除的文件");
- return;
- }
- this.$confirm("确定要批量删除选中的文件吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(() => {
- this.loading = true;
- delDocumentList({ document_ids: JSON.stringify(selectedIds) })
- .then((res) => {
- if (res.status === 200) {
- this.$message.success("批量删除已完成");
- this.search();
- } else {
- this.$message.error("批量删除请求失败");
- }
- })
- .catch((error) => {
- /* console.error("批量删除错误:", error);
- this.$message.error("批量删除过程中出现错误"); */
- })
- .finally(() => {
- this.loading = false;
- });
- })
- .catch(() => {
- // 取消操作
- });
- },
- updateAnalysisStatus(ids) {
- this.dataList.forEach((row) => {
- if (ids.includes(row.id)) {
- row.run = 1; // 设置状态为"解析中"
- this.startAnalysisStatusChecker(row);
- }
- });
- },
- clearSelection() {
- this.$refs.dataTable.clearSelection();
- this.selectedRows = [];
- },
- /* 跳转页面 */
- getName(e) {
- /* this.$router.push({
- path: "/knowledge/category/infoList",
- query: { id: e.id, type: e.type },
- }); */
- let _this = this;
- let a = document.createElement("a");
- a.href = `#/infoList?id=${e.id}&type=${e.type.toLowerCase()}`; // 使用 hash
- a.target = "_blank";
- a.click();
- },
- /* 解析 */
- analysis(row) {
- if (row.run == 1 || row.run == 5) return;
- // Set the status to "解析中" (1) immediately
- this.$set(row, "run", 1);
- const analysisConfig = {
- document_ids: JSON.stringify([row.id]),
- start_page: row.start_page ?? 0, // 使用空值合并运算符
- end_page: row.end_page ?? 1000, // 使用空值合并运算符
- max_tokens: row.token_num,
- };
- analysisPro(analysisConfig)
- .then((res) => {
- if (res.status === 200) {
- // Start checking the status immediately after successful API call
- this.startAnalysisStatusChecker(row);
- } else {
- this.$message.error("解析请求失败");
- this.$set(row, "run", 0);
- }
- })
- .catch((error) => {
- console.error("解析错误:", error);
- this.$message.error("解析过程中出现错误");
- this.$set(row, "run", 0);
- });
- },
- startAnalysisStatusChecker(row) {
- // Clear any existing checker for this row
- if (this.analysisStatusCheckers[row.id]) {
- clearTimeout(this.analysisStatusCheckers[row.id]);
- }
- /* 获取token数 */
- /* const checkStatus = () => {
- getdocpro({ document_id: row.id })
- .then((res) => {
- if (res.status === 200) {
- const newStatus = Number(res.data.status);
- const newProgress = Number(res.data.total_tasks);
- this.$set(row, "run", newStatus);
- this.$set(row, "progress", newProgress);
- if (newStatus === 3) {
- this.$message.success("解析成功");
- delete this.analysisStatusCheckers[row.id];
- // 在这里添加刷新列表的逻辑
- this.refreshCurrentList();
- } else if (newStatus === 4) {
- this.$message.error("解析失败");
- delete this.analysisStatusCheckers[row.id];
- } else if (newStatus === 1 || newStatus === 5) {
- // Continue checking
- this.analysisStatusCheckers[row.id] = setTimeout(
- checkStatus,
- 15000
- );
- }
- } else {
- this.$message.error("获取解析状态失败");
- delete this.analysisStatusCheckers[row.id];
- }
- })
- .catch((error) => {
- console.error("获取解析状态错误:", error);
- this.$message.error("获取解析状态时出现错误");
- delete this.analysisStatusCheckers[row.id];
- });
- }; */
- /* 监控任务 */
- const checkStatus = () => {
- resultTask(row.id)
- .then((res) => {
- if (res.status === 200) {
- const newStatus = Number(res.data.document_status);
- const newProgress = res.data.progress_msg
- this.$set(row, "run", newStatus);
- this.$set(row, "progress_msg", newProgress);
- if (newStatus === 3) {
- this.$message.success("解析成功");
- delete this.analysisStatusCheckers[row.id];
- // 在这里添加刷新列表的逻辑
- this.refreshCurrentList();
- } else if (newStatus === 4) {
- this.$message.error("解析失败");
- delete this.analysisStatusCheckers[row.id];
- } else if (newStatus === 1 || newStatus === 5) {
- // Continue checking
- this.analysisStatusCheckers[row.id] = setTimeout(
- checkStatus,
- 15000
- );
- }
- } else {
- this.$message.error("获取解析状态失败");
- delete this.analysisStatusCheckers[row.id];
- }
- })
- .catch((error) => {
- console.error("获取解析状态错误:", error);
- this.$message.error("获取解析状态时出现错误");
- delete this.analysisStatusCheckers[row.id];
- });
- };
- // Start checking immediately
- checkStatus();
- },
- // 修改 refreshCurrentList 方法
- refreshCurrentList() {
- // 保存当前页码和每页显示数量
- const currentPage = this.queryForm.page;
- const currentPageSize = this.queryForm.pageSize;
- // 重新获取数据
- return this.search()
- .then(() => {
- // 恢复之前的页码和每页显示数量
- this.queryForm.page = currentPage;
- this.queryForm.pageSize = currentPageSize;
- })
- .catch((error) => {
- console.error("刷新列表时出错:", error);
- this.$message.error("刷新列表失败,请稍后重试");
- });
- },
- handleAnalClose() {
- this.anaDialogVisible = false;
- },
- /* 确认 */
- submitAnal() {
- this.dataList.map((el) => {
- if (this.analForm.id == el.id) {
- el.start_page = this.analForm.start_page;
- el.end_page = this.analForm.end_page;
- el.token_num = this.analForm.token_num;
- }
- });
- this.anaDialogVisible = false;
- },
- /* 解析方法 */
- Analytical(e) {
- this.analForm.id = e.id;
- this.analForm.token_num = e.token_num;
- this.anaDialogVisible = true;
- },
- editWidth() {
- if (this.allowDelete && this.allowEdit) {
- return 200;
- }
- if (this.allowDelete || this.allowEdit) {
- return 120;
- }
- return 100;
- },
- onFocusVal(e) {
- let _this = this;
- _this.currentDataId = e.target.dataset.id;
- },
- onChangeVal(e) {
- let _this = this;
- let par = {
- id: _this.currentDataId,
- val: e,
- };
- },
- btnDelete(e) {
- let _this = this;
- let par = {
- document_id: e,
- };
- _this
- .$confirm("您是否确认删除该记录?", "提示", {
- confirmButtonText: "确认",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then((res) => {
- deleteFile(par).then((res) => {
- if (res.status !== 200) return;
- _this.$message.success(res.data);
- _this.search();
- });
- })
- .catch(() => {});
- },
- searchData() {
- let _this = this;
- _this.dialogVisible = false;
- _this.search();
- },
- /* 关闭 */
- handleClose(done) {
- done();
- },
- /* 修改文件名 */
- btnEdit(e) {
- this.wordForm.new_name = e.name;
- this.wordForm.document_id = e.id;
- this.dialogVisible = true;
- },
- /* 提交 */
- submitBuck() {
- this.$refs.wordRef.validate((valid) => {
- if (valid) {
- renameFile(this.wordForm).then((res) => {
- if (res.status !== 200) return;
- this.search();
- this.dialogVisible = false;
- this.wordForm = {
- new_name: "",
- document_id: "",
- };
- });
- } else {
- this.$message.error("请填写文档名称");
- }
- });
- },
- //下载
- btnDown(e) {
- // Set downloading flag for this specific row
- this.$set(e, "downloading", true);
- nameGetUrl({
- document_id: e.id,
- })
- .then((res) => {
- if (res.status !== 200) {
- this.$message.error("获取下载链接失败");
- return;
- }
- return fetch(res.data.url);
- })
- .then((response) => response.blob())
- .then((blob) => {
- const url = window.URL.createObjectURL(blob);
- const link = document.createElement("a");
- link.href = url;
- link.download = e.name;
- document.body.appendChild(link);
- link.click();
- setTimeout(() => {
- document.body.removeChild(link);
- window.URL.revokeObjectURL(url);
- }, 100);
- })
- .catch((error) => {
- console.error("下载出错:", error);
- this.$message.error("下载失败,请稍后重试");
- })
- .finally(() => {
- // Reset downloading flag when done
- this.$set(e, "downloading", false);
- });
- },
- handleClose() {
- let _this = this;
- _this.currentData = {};
- _this.dialogVisible = false;
- },
- //搜索
- search() {
- let _this = this;
- _this.loading = true;
- return new Promise((resolve, reject) => {
- getBucketContents(_this.queryForm)
- .then((res) => {
- if (res.status !== 200) {
- reject(new Error("Invalid response status"));
- return;
- }
- _this.dataList = res.data.documents.map((el) => ({
- ...el,
- token_num: 256,
- start_page: _this.analForm.start_page,
- end_page: _this.analForm.end_page,
- }));
- _this.pageTotal = res.data.pagination.total_count;
- _this.recordCount = res.data.pagination.total_count;
- _this.queryForm.pageSize = res.data.pagination.total_size;
- _this.loading = false;
- // Initialize the analysis status for each row
- _this.dataList.forEach((row) => {
- if (row.run == 1 || row.run == 5) {
- _this.startAnalysisStatusChecker(row);
- }
- });
- resolve();
- })
- .catch((error) => {
- _this.loading = false;
- reject(error);
- });
- });
- },
- //修改分页
- ChangePage(e) {
- let _this = this;
- _this.queryForm.page = e;
- _this.search();
- },
- handleSizeChange(val) {
- this.queryForm.pageSize = val;
- this.queryForm.page = 1; // Reset to first page when changing page size
- this.search();
- },
- },
- };
- </script>
-
- <style lang="scss" scoped>
- .project-search {
- display: flex;
- height: calc(100vh - 100px); // 假设顶部导航栏高度为60px
- background-color: #f9fafb;
- .custom-tree-node {
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 8px 0;
- position: relative;
- .el-icon-folder {
- color: #409eff;
- margin-right: 8px;
- }
- .file-count {
- color: #909399;
- font-size: 12px;
- padding: 2px 6px;
- border-radius: 10px;
- transition: opacity 0.3s;
- }
- .file-counts {
- color: #909399;
- font-size: 12px;
- padding: 2px 6px;
- border-radius: 10px;
- transition: opacity 0.3s;
- }
- .folder-actions {
- position: absolute;
- right: 0;
- top: 50%;
- transform: translateY(-50%);
- display: none;
- padding-left: 10px;
- i {
- font-size: 16px;
- margin-left: 8px;
- color: #606266;
- cursor: pointer;
- &:hover {
- color: #409eff;
- }
- }
- }
- &:hover {
- .file-count {
- opacity: 0;
- }
- .folder-actions {
- display: inline-block;
- }
- }
- }
- .el-tree-node__content:hover {
- background-color: #f5f7fa;
- }
- .el-tree-node__content:hover {
- background-color: #f5f7fa;
- }
- .file-categories {
- flex: 0 0 280px;
- padding: 20px;
- background-color: #ffffff;
- box-shadow: 2px 0 10px rgba(0, 0, 0, 0.05);
- overflow-y: auto;
- .el-button {
- width: 100%;
- margin-bottom: 20px;
- }
- .el-tree {
- background-color: transparent;
- }
- }
- .right {
- flex: 1;
- padding: 20px;
- overflow-y: auto;
- }
- .custom-tree-node {
- font-size: 14px;
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 8px 0;
- .el-icon-folder {
- color: #409eff;
- margin-right: 8px;
- }
- .file-count {
- color: #909399;
- font-size: 12px;
- background-color: #f0f2f5;
- padding: 2px 6px;
- border-radius: 10px;
- }
- .tree_title {
- display: flex;
- align-items: center;
- width: 140px;
- .folder-name {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: calc(100% - 24px); // 减去图标的宽度
- }
- }
- }
- }
- .el-tree {
- margin-left: 10px;
- }
- ::v-deep .el-tree-node__expand-icon {
- display: none;
- }
- @import "./components/dataList.scss";
- </style>
-
|