zj-plugin-intelligent 1.2.12-beta.14 → 1.2.12-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -976,7 +976,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n
976
976
  /***/ (function(module, exports, __webpack_require__) {
977
977
 
978
978
  "use strict";
979
- eval("\n\nvar _interopRequireWildcard = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireWildcard */ \"./node_modules/@babel/runtime/helpers/interopRequireWildcard.js\").default;\n\nvar _interopRequireDefault = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireDefault */ \"./node_modules/@babel/runtime/helpers/interopRequireDefault.js\").default;\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _createForOfIteratorHelper2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/createForOfIteratorHelper */ \"./node_modules/@babel/runtime/helpers/createForOfIteratorHelper.js\"));\n\nvar _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/asyncToGenerator.js\"));\n\nvar _objectSpread2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/objectSpread2 */ \"./node_modules/@babel/runtime/helpers/objectSpread2.js\"));\n\nvar _marked = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n\nvar XLSX = _interopRequireWildcard(__webpack_require__(/*! xlsx */ \"./node_modules/xlsx/xlsx.mjs\"));\n\nvar _mammoth = _interopRequireDefault(__webpack_require__(/*! mammoth */ \"./node_modules/mammoth/lib/index.js\"));\n\nvar _docx = __webpack_require__(/*! docx */ \"./node_modules/docx/build/index.mjs\");\n\nvar _knowledgeBase = __webpack_require__(/*! ./api/knowledgeBase */ \"./src/lib/knowledgeBase/api/knowledgeBase.js\");\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n// 单文件大小上限:50MB\nvar MAX_SIZE = 50 * 1024 * 1024;\nvar ALLOWED_TYPES = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'md', 'markdown', 'jpg', 'jpeg', 'png', 'gif', 'webp']; // 支持在线编辑的文本文件类型\n\nvar TEXT_EDITABLE_TYPES = ['txt', 'md', 'markdown', 'json', 'xml', 'yaml', 'yml', 'ini', 'cfg', 'env', 'js', 'ts', 'jsx', 'tsx', 'css', 'scss', 'less', 'html', 'htm', 'vue', 'py', 'java', 'rb', 'go', 'rs', 'sh', 'bat', 'ps1', 'sql', 'php', 'c', 'cpp', 'h', 'hpp', 'swift', 'kt', 'groovy'];\nvar _default2 = {\n name: 'DocumentForm',\n props: {\n companyId: {\n type: String,\n default: ''\n },\n folderList: {\n type: Array,\n default: function _default() {\n return [];\n }\n }\n },\n data: function data() {\n return {\n visible: false,\n isEdit: false,\n editingId: null,\n submitting: false,\n fileList: [],\n formData: {\n title: '',\n folderId: '',\n fileName: ''\n },\n resolvePromise: null,\n editingFileType: '',\n originalIndexStatus: 0,\n mdTab: 'edit',\n xlsxData: {\n sheetNames: [],\n currentSheet: '',\n rows: [],\n cols: [],\n workbook: null,\n loading: false\n },\n wordHtml: '',\n wordLoading: false,\n folderTreeProps: {\n children: 'children',\n label: 'name'\n },\n folderPopoverVisible: false\n };\n },\n watch: {\n /**\n * wordLoading 变为 false 时,编辑器 DOM 已渲染,将 wordHtml 写入编辑器\n */\n wordLoading: function wordLoading(val) {\n var _this = this;\n\n if (!val && this.wordHtml) {\n this.$nextTick(function () {\n var editor = _this.$refs && _this.$refs.wordEditor;\n\n if (editor) {\n editor.innerHTML = _this.wordHtml;\n }\n });\n }\n }\n },\n computed: {\n dialogTitle: function dialogTitle() {\n if (this.isXlsxType) return '编辑表格数据';\n if (this.isWordType) return '编辑 Word 文档';\n if (this.isTextEditable) return '编辑文件内容';\n return '编辑文档';\n },\n dialogWidth: function dialogWidth() {\n if (this.isXlsxType) return '960px';\n if (this.isWordType) return '900px';\n if (this.isTextEditable) return '860px';\n return '560px';\n },\n\n /**\n * 当前编辑的文件是否为文本可编辑类型\n */\n isTextEditable: function isTextEditable() {\n var t = (this.editingFileType || '').toLowerCase();\n return TEXT_EDITABLE_TYPES.includes(t);\n },\n\n /**\n * 当前编辑的文件是否为 Excel 类型\n */\n isXlsxType: function isXlsxType() {\n var t = (this.editingFileType || '').toLowerCase();\n return t === 'xlsx' || t === 'xls';\n },\n\n /**\n * 当前编辑的文件是否为 Markdown 类型(支持预览)\n */\n isMarkdownType: function isMarkdownType() {\n var t = (this.editingFileType || '').toLowerCase();\n return t === 'md' || t === 'markdown';\n },\n\n /**\n * 当前编辑的文件是否为 Word 类型\n */\n isWordType: function isWordType() {\n var t = (this.editingFileType || '').toLowerCase();\n return t === 'docx' || t === 'doc';\n },\n\n /**\n * Word 编辑器字符数\n */\n wordCharCount: function wordCharCount() {\n var editor = this.$refs && this.$refs.wordEditor;\n\n if (editor) {\n return (editor.innerText || '').replace(/\\s/g, '').length;\n }\n\n return (this.wordHtml || '').replace(/<[^>]+>/g, '').length;\n },\n\n /**\n * Markdown 预览 HTML\n */\n previewHtml: function previewHtml() {\n if (!this.formData.content) return '';\n return _marked.marked.parse(this.formData.content, {\n breaks: true,\n gfm: true\n });\n },\n\n /**\n * 所属文件夹树(由平铺列表组装,不污染 prop)\n */\n folderTree: function folderTree() {\n var nodes = this.folderList.map(function (f) {\n return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, f), {}, {\n children: []\n });\n });\n var map = {};\n nodes.forEach(function (n) {\n map[n.id] = n;\n });\n var roots = [];\n nodes.forEach(function (n) {\n var pid = n.parentId || 0;\n\n if (map[pid]) {\n map[pid].children.push(n);\n } else {\n roots.push(n);\n }\n });\n return roots;\n },\n\n /**\n * 当前所选文件夹的名称(用于下拉框显示)\n */\n selectedFolderName: function selectedFolderName() {\n var _this2 = this;\n\n if (!this.formData.folderId) return '';\n var f = this.folderList.find(function (x) {\n return x.id === _this2.formData.folderId;\n });\n return f ? f.name : '';\n }\n },\n methods: {\n handleFolderSelect: function handleFolderSelect(data) {\n this.formData.folderId = data.id;\n this.folderPopoverVisible = false;\n },\n handleFolderPopoverShow: function handleFolderPopoverShow() {\n var _this3 = this;\n\n this.$nextTick(function () {\n if (_this3.$refs.folderTreeRef) _this3.$refs.folderTreeRef.setCurrentKey(_this3.formData.folderId || null);\n });\n },\n clearFolderSelect: function clearFolderSelect() {\n this.formData.folderId = '';\n this.folderPopoverVisible = false;\n },\n\n /**\n * 打开上传对话框(新增)\n * @param {string} folderId - 预选文件夹ID\n * @returns {Promise}\n */\n openAdd: function openAdd(folderId) {\n var _this4 = this;\n\n this.isEdit = false;\n this.editingId = null;\n this.fileList = [];\n this.formData = {\n title: '',\n folderId: folderId || '',\n fileName: ''\n };\n this.visible = true;\n this.$nextTick(function () {\n if (_this4.$refs.folderTreeRef) _this4.$refs.folderTreeRef.setCurrentKey(_this4.formData.folderId || null);\n });\n return new Promise(function (resolve) {\n _this4.resolvePromise = resolve;\n });\n },\n\n /**\n * 打开编辑对话框\n * @param {object} file - 文件对象\n * @returns {Promise}\n */\n openEdit: function openEdit(file) {\n var _this5 = this;\n\n this.isEdit = true;\n this.editingId = file.id;\n this.editingFileType = file.fileType || '';\n this.originalIndexStatus = file.indexStatus || 0;\n this.fileList = [];\n this.mdTab = 'edit';\n this.resetXlsxData();\n this.formData = {\n title: file.title || '',\n folderId: file.folderId || '',\n fileName: file.fileName || '',\n content: ''\n };\n var t = (file.fileType || '').toLowerCase(); // 如果是文本可编辑类型,异步加载文件内容\n\n if (TEXT_EDITABLE_TYPES.includes(t)) {\n (0, _knowledgeBase.getFileDetail)(file.id).then(function (d) {\n _this5.formData.content = d.content || '';\n }).catch(function () {\n _this5.formData.content = '(内容加载失败)';\n });\n } // 如果是 Excel 类型,下载原文件并解析\n\n\n if (t === 'xlsx' || t === 'xls') {\n this.loadXlsxFile(file);\n }\n\n this.visible = true;\n this.$nextTick(function () {\n if (_this5.$refs.folderTreeRef) _this5.$refs.folderTreeRef.setCurrentKey(_this5.formData.folderId || null);\n }); // 如果是 Word 类型,下载原文件并解析(visible 先置为 true 确保 DOM 已渲染)\n\n if (t === 'docx' || t === 'doc') {\n this.loadWordFile(file);\n }\n\n return new Promise(function (resolve) {\n _this5.resolvePromise = resolve;\n });\n },\n // ==================== Excel 编辑 ====================\n resetXlsxData: function resetXlsxData() {\n this.xlsxData = {\n sheetNames: [],\n currentSheet: '',\n rows: [],\n cols: [],\n workbook: null,\n loading: false\n };\n },\n loadXlsxFile: function loadXlsxFile(file) {\n var _this6 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n var detail, fileUrl, response, ab, workbook;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _this6.xlsxData.loading = true;\n _context.prev = 1;\n _context.next = 4;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 4:\n detail = _context.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context.next = 9;\n break;\n }\n\n _this6.$message.warning('无法获取文件下载地址');\n\n return _context.abrupt(\"return\");\n\n case 9:\n _context.next = 11;\n return fetch(fileUrl);\n\n case 11:\n response = _context.sent;\n\n if (response.ok) {\n _context.next = 14;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 14:\n _context.next = 16;\n return response.arrayBuffer();\n\n case 16:\n ab = _context.sent;\n workbook = XLSX.read(ab, {\n type: 'array'\n });\n _this6.xlsxData.workbook = workbook;\n _this6.xlsxData.sheetNames = workbook.SheetNames;\n\n if (workbook.SheetNames.length > 0) {\n _this6.xlsxData.currentSheet = workbook.SheetNames[0];\n\n _this6.buildXlsxSheetData(workbook.SheetNames[0]);\n }\n\n _context.next = 27;\n break;\n\n case 23:\n _context.prev = 23;\n _context.t0 = _context[\"catch\"](1);\n console.error('加载 Excel 文件失败', _context.t0);\n\n _this6.$message.error('加载 Excel 文件失败');\n\n case 27:\n _context.prev = 27;\n _this6.xlsxData.loading = false;\n return _context.finish(27);\n\n case 30:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, null, [[1, 23, 27, 30]]);\n }))();\n },\n buildXlsxSheetData: function buildXlsxSheetData(sheetName) {\n var workbook = this.xlsxData.workbook;\n if (!workbook) return;\n var sheet = workbook.Sheets[sheetName];\n\n if (!sheet) {\n this.xlsxData.rows = [];\n this.xlsxData.cols = [];\n return;\n } // 转为二维数组(defval 补齐空单元格,保证各列取值一致)\n\n\n var data = XLSX.utils.sheet_to_json(sheet, {\n header: 1,\n defval: ''\n });\n\n if (data.length === 0) {\n this.xlsxData.rows = [];\n this.xlsxData.cols = [];\n return;\n } // 列数以「所有行的最大宽度」为准:表头行可能只填了第一格,若直接按第一行长度定列会丢失后续列\n\n\n var maxCols = Math.max.apply(null, data.map(function (row) {\n return row && row.length || 0;\n })); // 第一行作为列名,未填表头的列用「列N」补齐\n\n this.xlsxData.cols = Array.from({\n length: maxCols\n }, function (_, i) {\n var v = data[0] && data[0][i];\n return v != null && String(v).trim() !== '' ? String(v) : \"\\u5217\".concat(i + 1);\n }); // 剩余行作为数据:过滤全空行,避免出现多余空白行\n\n this.xlsxData.rows = data.slice(1).filter(function (row) {\n return row && row.some(function (c) {\n return c != null && String(c).trim() !== '';\n });\n }).map(function (row) {\n var obj = {};\n\n for (var ci = 0; ci < maxCols; ci++) {\n obj[ci] = row[ci] != null ? String(row[ci]) : '';\n }\n\n return obj;\n });\n },\n switchXlsxSheet: function switchXlsxSheet(name) {\n // 先保存当前 sheet 的编辑数据到 workbook\n this.saveCurrentSheetData();\n this.xlsxData.currentSheet = name;\n this.buildXlsxSheetData(name);\n },\n addXlsxRow: function addXlsxRow() {\n var row = {};\n this.xlsxData.cols.forEach(function (col, ci) {\n row[ci] = '';\n });\n this.xlsxData.rows.push(row);\n },\n addXlsxCol: function addXlsxCol() {\n var _this7 = this;\n\n var newColName = \"\\u5217\".concat(this.xlsxData.cols.length + 1);\n this.xlsxData.cols.push(newColName);\n this.xlsxData.rows.forEach(function (row) {\n row[_this7.xlsxData.cols.length - 1] = '';\n });\n },\n deleteXlsxRow: function deleteXlsxRow() {\n if (this.xlsxData.rows.length === 0) return;\n this.xlsxData.rows.pop();\n },\n deleteXlsxCol: function deleteXlsxCol() {\n if (this.xlsxData.cols.length === 0) return;\n this.xlsxData.cols.pop();\n var ci = this.xlsxData.cols.length;\n this.xlsxData.rows.forEach(function (row) {\n delete row[ci];\n });\n },\n removeXlsxRow: function removeXlsxRow(index) {\n this.xlsxData.rows.splice(index, 1);\n },\n onXlsxCellChange: function onXlsxCellChange() {// 数据变更标记(将来可用于 dirty 判断)\n },\n\n /**\n * 将当前编辑的 rows/cols 写回 workbook.Sheets[currentSheet]\n */\n saveCurrentSheetData: function saveCurrentSheetData() {\n var _this8 = this;\n\n var workbook = this.xlsxData.workbook;\n var sheetName = this.xlsxData.currentSheet;\n if (!workbook || !sheetName || !this.xlsxData.cols.length) return;\n var aoa = [this.xlsxData.cols];\n this.xlsxData.rows.forEach(function (row) {\n // 用列索引取数,避免列名重复时 indexOf 定位错位\n var rowData = [];\n\n for (var ci = 0; ci < _this8.xlsxData.cols.length; ci++) {\n rowData.push(row[ci] != null ? row[ci] : '');\n }\n\n aoa.push(rowData);\n });\n workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet(aoa);\n },\n\n /**\n * 生成新的 xlsx 文件并上传替换\n */\n replaceXlsxFile: function replaceXlsxFile() {\n var _this9 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {\n var workbook, origExt, isXls, bookType, mime, wbout, blob, originalName, file, formData, newFile;\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n // 先保存当前 sheet 的编辑数据\n _this9.saveCurrentSheetData();\n\n workbook = _this9.xlsxData.workbook; // 写出所有 sheet 到新文件,保持与原文件扩展名一致(xls → biff8, xlsx → xlsx)\n\n origExt = ((_this9.formData.fileName || '').split('.').pop() || 'xlsx').toLowerCase();\n isXls = origExt === 'xls';\n bookType = isXls ? 'biff8' : 'xlsx';\n mime = isXls ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\n wbout = XLSX.write(workbook, {\n bookType: bookType,\n type: 'array'\n });\n blob = new Blob([wbout], {\n type: mime\n });\n originalName = (_this9.formData.fileName || 'export.xlsx').replace(/\\.(xls|xlsx)$/i, isXls ? '.xls' : '.xlsx');\n file = new File([blob], originalName, {\n type: mime\n }); // 上传新文件\n\n formData = new FormData();\n formData.append('file', file);\n formData.append('companyId', _this9.companyId);\n\n if (_this9.formData.folderId) {\n formData.append('folderId', _this9.formData.folderId);\n }\n\n _context2.next = 16;\n return (0, _knowledgeBase.uploadFile)(formData);\n\n case 16:\n newFile = _context2.sent;\n _context2.next = 19;\n return (0, _knowledgeBase.deleteFile)(_this9.editingId);\n\n case 19:\n return _context2.abrupt(\"return\", newFile);\n\n case 20:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2);\n }))();\n },\n // ==================== Word 编辑 ====================\n loadWordFile: function loadWordFile(file) {\n var _this10 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {\n var detail, fileUrl, response, ab, result;\n return regeneratorRuntime.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _this10.wordLoading = true;\n _this10.wordHtml = '';\n _context3.prev = 2;\n _context3.next = 5;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 5:\n detail = _context3.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context3.next = 10;\n break;\n }\n\n _this10.$message.warning('无法获取文件下载地址');\n\n return _context3.abrupt(\"return\");\n\n case 10:\n _context3.next = 12;\n return fetch(fileUrl);\n\n case 12:\n response = _context3.sent;\n\n if (response.ok) {\n _context3.next = 15;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 15:\n _context3.next = 17;\n return response.arrayBuffer();\n\n case 17:\n ab = _context3.sent;\n\n if (ab.byteLength) {\n _context3.next = 21;\n break;\n }\n\n _this10.wordHtml = '<p>(空文档)</p>';\n return _context3.abrupt(\"return\");\n\n case 21:\n _context3.next = 23;\n return _mammoth.default.convertToHtml({\n arrayBuffer: ab\n });\n\n case 23:\n result = _context3.sent;\n _this10.wordHtml = result.value || '<p>(空文档)</p>';\n _context3.next = 31;\n break;\n\n case 27:\n _context3.prev = 27;\n _context3.t0 = _context3[\"catch\"](2);\n console.error('加载 Word 文件失败', _context3.t0);\n\n _this10.$message.error('加载 Word 文件失败:文件可能为空或格式不支持在线编辑(仅支持 .docx)');\n\n case 31:\n _context3.prev = 31;\n _this10.wordLoading = false;\n return _context3.finish(31);\n\n case 34:\n case \"end\":\n return _context3.stop();\n }\n }\n }, _callee3, null, [[2, 27, 31, 34]]);\n }))();\n },\n execFormat: function execFormat(command, value) {\n document.execCommand(command, false, value || null);\n this.$refs.wordEditor && this.$refs.wordEditor.focus();\n },\n onWordInput: function onWordInput() {\n // 触发 wordCharCount 重新计算\n this.$forceUpdate();\n },\n\n /**\n * 将编辑后的 HTML 转为 .docx 文件并上传替换\n */\n replaceWordFile: function replaceWordFile() {\n var _this11 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {\n var editor, html, paragraphs, doc, blob, originalName, file, formData, newFile;\n return regeneratorRuntime.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n editor = _this11.$refs.wordEditor;\n html = editor ? editor.innerHTML : _this11.wordHtml; // 用 docx 包生成新文档\n\n paragraphs = _this11.htmlToDocxParagraphs(html);\n doc = new _docx.Document({\n sections: [{\n children: paragraphs\n }]\n });\n _context4.next = 6;\n return _docx.Packer.toBlob(doc);\n\n case 6:\n blob = _context4.sent;\n originalName = _this11.formData.fileName || 'document.docx';\n file = new File([blob], originalName, {\n type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n }); // 上传新文件\n\n formData = new FormData();\n formData.append('file', file);\n formData.append('companyId', _this11.companyId);\n\n if (_this11.formData.folderId) {\n formData.append('folderId', _this11.formData.folderId);\n }\n\n _context4.next = 15;\n return (0, _knowledgeBase.uploadFile)(formData);\n\n case 15:\n newFile = _context4.sent;\n _context4.next = 18;\n return (0, _knowledgeBase.deleteFile)(_this11.editingId);\n\n case 18:\n return _context4.abrupt(\"return\", newFile);\n\n case 19:\n case \"end\":\n return _context4.stop();\n }\n }\n }, _callee4);\n }))();\n },\n\n /**\n * 将 HTML 内容解析为 docx Paragraph 数组\n */\n htmlToDocxParagraphs: function htmlToDocxParagraphs(html) {\n var _this12 = this;\n\n var div = document.createElement('div');\n div.innerHTML = html;\n var children = div.childNodes;\n var paragraphs = [];\n\n var _iterator = (0, _createForOfIteratorHelper2.default)(children),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var node = _step.value;\n\n if (node.nodeType === 3) {\n // 纯文本节点\n var text = (node.textContent || '').trim();\n\n if (text) {\n paragraphs.push(new _docx.Paragraph({\n children: [new _docx.TextRun(text)]\n }));\n }\n\n continue;\n }\n\n if (node.nodeType !== 1) continue;\n var tag = node.tagName.toLowerCase(); // 标题 h1-h6\n\n if (/^h[1-6]$/.test(tag)) {\n var level = parseInt(tag[1]);\n var headingMap = {\n 1: _docx.HeadingLevel.HEADING_1,\n 2: _docx.HeadingLevel.HEADING_2,\n 3: _docx.HeadingLevel.HEADING_3,\n 4: _docx.HeadingLevel.HEADING_4,\n 5: _docx.HeadingLevel.HEADING_5,\n 6: _docx.HeadingLevel.HEADING_6\n };\n\n var _text = node.textContent || '';\n\n paragraphs.push(new _docx.Paragraph({\n heading: headingMap[level] || _docx.HeadingLevel.HEADING_1,\n spacing: {\n before: 200,\n after: 100\n },\n children: [new _docx.TextRun({\n text: _text,\n bold: level <= 3,\n size: level <= 1 ? 32 : level <= 2 ? 28 : 24\n })]\n }));\n continue;\n } // 段落、div、引用\n\n\n if (tag === 'p' || tag === 'div' || tag === 'blockquote') {\n var _runs = this.buildTextRuns(node);\n\n var opts = {\n children: _runs,\n spacing: {\n after: 80\n }\n };\n\n if (tag === 'blockquote') {\n opts.indent = {\n left: 400\n };\n }\n\n paragraphs.push(new _docx.Paragraph(opts));\n continue;\n } // 无序列表\n\n\n if (tag === 'ul') {\n var items = node.querySelectorAll('li');\n items.forEach(function (li) {\n var runs = _this12.buildTextRuns(li);\n\n paragraphs.push(new _docx.Paragraph({\n children: runs,\n bullet: {\n level: 0\n },\n spacing: {\n after: 40\n }\n }));\n });\n continue;\n } // 有序列表\n\n\n if (tag === 'ol') {\n var _ret = function () {\n var items = node.querySelectorAll('li');\n var num = 1;\n items.forEach(function (li) {\n var runs = _this12.buildTextRuns(li);\n\n paragraphs.push(new _docx.Paragraph({\n children: runs,\n numbering: {\n reference: 1,\n level: 0\n },\n spacing: {\n after: 40\n }\n }));\n num++;\n });\n return \"continue\";\n }();\n\n if (_ret === \"continue\") continue;\n } // 其他标签(pre, hr 等)当作段落处理\n\n\n var runs = this.buildTextRuns(node);\n\n if (runs.length > 0) {\n paragraphs.push(new _docx.Paragraph({\n children: runs\n }));\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return paragraphs;\n },\n\n /**\n * 从 DOM 节点构建 TextRun 数组\n */\n buildTextRuns: function buildTextRuns(node) {\n var runs = [];\n\n var walk = function walk(el) {\n el.childNodes.forEach(function (child) {\n if (child.nodeType === 3) {\n var text = (child.textContent || '').trim();\n\n if (text) {\n runs.push(new _docx.TextRun({\n text: text\n }));\n }\n } else if (child.nodeType === 1) {\n var t = child.tagName.toLowerCase();\n\n var _text2 = child.textContent || '';\n\n if (t === 'br') {// 换行不处理\n } else if (t === 'strong' || t === 'b') {\n runs.push(new _docx.TextRun({\n text: _text2,\n bold: true\n }));\n } else if (t === 'em' || t === 'i') {\n runs.push(new _docx.TextRun({\n text: _text2,\n italics: true\n }));\n } else if (t === 'u') {\n runs.push(new _docx.TextRun({\n text: _text2,\n underline: {\n type: 'single'\n }\n }));\n } else if (t === 'a') {\n runs.push(new _docx.TextRun({\n text: _text2\n }));\n } else {\n walk(child);\n }\n }\n });\n };\n\n walk(node);\n return runs;\n },\n // ==================== 表单提交 ====================\n handleFileChange: function handleFileChange(file, fileList) {\n this.fileList = fileList;\n },\n handleFileRemove: function handleFileRemove(file, fileList) {\n this.fileList = fileList;\n },\n handleFileExceed: function handleFileExceed() {\n this.$message.warning('最多只能上传 5 个文件');\n },\n\n /**\n * 上传前校验:大小 50MB、类型白名单\n */\n beforeUpload: function beforeUpload(file) {\n if (file.size > MAX_SIZE) {\n this.$message.error(\"\\u6587\\u4EF6\\u300C\".concat(file.name, \"\\u300D\\u5927\\u5C0F\\u4E0D\\u80FD\\u8D85\\u8FC7 50MB\"));\n return false;\n }\n\n var ext = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();\n\n if (!ALLOWED_TYPES.includes(ext)) {\n this.$message.error(\"\\u6587\\u4EF6\\u300C\".concat(file.name, \"\\u300D\\u7C7B\\u578B\\u4E0D\\u652F\\u6301: .\").concat(ext));\n return false;\n }\n\n return true;\n },\n handleSubmit: function handleSubmit() {\n if (this.isEdit) {\n this.handleSubmitEdit();\n } else {\n this.handleSubmitUpload();\n }\n },\n\n /**\n * 上传模式提交:逐个文件构造 FormData 调用上传接口\n */\n handleSubmitUpload: function handleSubmitUpload() {\n var _this13 = this;\n\n if (!this.companyId) {\n this.$message.warning('公司ID不能为空');\n return;\n }\n\n if (!this.formData.folderId) {\n this.$message.warning('请选择所属文件夹');\n return;\n }\n\n var files = this.fileList.filter(function (f) {\n return f.status !== 'success';\n });\n\n if (files.length === 0) {\n this.$message.warning('请先选择文件');\n return;\n } // 空文件直接拦截,避免上传后预览/解析失败\n\n\n var emptyFile = files.find(function (f) {\n return f.raw && f.raw.size === 0;\n });\n\n if (emptyFile) {\n this.$message.error(\"\\u6587\\u4EF6\\u300C\".concat(emptyFile.name, \"\\u300D\\u5185\\u5BB9\\u4E3A\\u7A7A\\uFF0C\\u8BF7\\u4E0A\\u4F20\\u6709\\u6548\\u6587\\u4EF6\"));\n return;\n }\n\n this.submitting = true; // 逐个上传(后端单文件接口)\n\n var tasks = files.map(function (file) {\n var formData = new FormData();\n formData.append('file', file.raw);\n formData.append('companyId', _this13.companyId);\n console.log('[DocumentForm] 上传文件:', file.name, ', companyId:', _this13.companyId);\n\n if (_this13.formData.folderId) {\n formData.append('folderId', _this13.formData.folderId);\n }\n\n return (0, _knowledgeBase.uploadFile)(formData);\n });\n Promise.all(tasks).then(function () {\n _this13.$message.success(\"\\u6210\\u529F\\u4E0A\\u4F20 \".concat(files.length, \" \\u4E2A\\u6587\\u4EF6\"));\n\n _this13.visible = false;\n\n if (_this13.resolvePromise) {\n _this13.resolvePromise(true);\n\n _this13.resolvePromise = null;\n }\n }).catch(function () {}).finally(function () {\n _this13.submitting = false;\n });\n },\n\n /**\n * 编辑模式提交\n */\n handleSubmitEdit: function handleSubmitEdit() {\n var _this14 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {\n var newFile, _newFile, data;\n\n return regeneratorRuntime.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n _this14.submitting = true;\n _context5.prev = 1;\n\n if (!_this14.isXlsxType) {\n _context5.next = 10;\n break;\n }\n\n _context5.next = 5;\n return _this14.replaceXlsxFile();\n\n case 5:\n newFile = _context5.sent;\n _context5.next = 8;\n return _this14.syncEditedMeta(newFile);\n\n case 8:\n _context5.next = 23;\n break;\n\n case 10:\n if (!_this14.isWordType) {\n _context5.next = 18;\n break;\n }\n\n _context5.next = 13;\n return _this14.replaceWordFile();\n\n case 13:\n _newFile = _context5.sent;\n _context5.next = 16;\n return _this14.syncEditedMeta(_newFile);\n\n case 16:\n _context5.next = 23;\n break;\n\n case 18:\n // 普通文件:更新元数据 + 文本内容\n data = {\n title: _this14.formData.title\n };\n\n if (_this14.formData.folderId) {\n data.folderId = _this14.formData.folderId;\n }\n\n if (_this14.isTextEditable && _this14.formData.content) {\n data.content = _this14.formData.content;\n }\n\n _context5.next = 23;\n return (0, _knowledgeBase.updateFile)(_this14.editingId, data);\n\n case 23:\n if (!(_this14.originalIndexStatus === 1)) {\n _context5.next = 33;\n break;\n }\n\n _context5.prev = 24;\n _context5.next = 27;\n return (0, _knowledgeBase.deleteFileIndex)(_this14.editingId);\n\n case 27:\n _this14.$message.info('文件已修改,原索引已删除,请重新执行索引');\n\n _context5.next = 33;\n break;\n\n case 30:\n _context5.prev = 30;\n _context5.t0 = _context5[\"catch\"](24);\n console.error('删除旧索引失败', _context5.t0);\n\n case 33:\n _this14.$message.success('修改成功');\n\n _this14.visible = false;\n\n if (_this14.resolvePromise) {\n _this14.resolvePromise(true);\n\n _this14.resolvePromise = null;\n }\n\n _context5.next = 42;\n break;\n\n case 38:\n _context5.prev = 38;\n _context5.t1 = _context5[\"catch\"](1);\n console.error('保存失败', _context5.t1);\n\n _this14.$message.error('保存失败');\n\n case 42:\n _context5.prev = 42;\n _this14.submitting = false;\n return _context5.finish(42);\n\n case 45:\n case \"end\":\n return _context5.stop();\n }\n }\n }, _callee5, null, [[1, 38, 42, 45], [24, 30]]);\n }))();\n },\n\n /**\n * Word/Excel 替换保存后,同步标题与所属文件夹元数据\n */\n syncEditedMeta: function syncEditedMeta(newFile) {\n var _this15 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {\n var id, data, title;\n return regeneratorRuntime.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n id = newFile && newFile.id || _this15.editingId;\n data = {};\n title = (_this15.formData.title || '').trim();\n if (title) data.title = title;\n if (_this15.formData.folderId) data.folderId = _this15.formData.folderId;\n\n if (!Object.keys(data).length) {\n _context6.next = 8;\n break;\n }\n\n _context6.next = 8;\n return (0, _knowledgeBase.updateFile)(id, data);\n\n case 8:\n case \"end\":\n return _context6.stop();\n }\n }\n }, _callee6);\n }))();\n },\n onDialogOpened: function onDialogOpened() {\n // dialog 完全打开后,尝试将 wordHtml 写入编辑器\n if (this.isWordType && this.wordHtml && this.$refs && this.$refs.wordEditor) {\n this.$refs.wordEditor.innerHTML = this.wordHtml;\n }\n },\n handleClosed: function handleClosed() {\n // 关闭后清空上传列表,避免下次打开残留\n if (this.$refs.uploadRef) {\n this.$refs.uploadRef.clearFiles();\n }\n\n this.fileList = [];\n this.resetXlsxData();\n this.wordHtml = '';\n\n if (this.resolvePromise) {\n this.resolvePromise(null);\n this.resolvePromise = null;\n }\n }\n }\n};\nexports.default = _default2;\n\n//# sourceURL=webpack://ZjPluginIntelligent/./src/lib/knowledgeBase/DocumentForm.vue?./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options");
979
+ eval("\n\nvar _interopRequireWildcard = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireWildcard */ \"./node_modules/@babel/runtime/helpers/interopRequireWildcard.js\").default;\n\nvar _interopRequireDefault = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireDefault */ \"./node_modules/@babel/runtime/helpers/interopRequireDefault.js\").default;\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _createForOfIteratorHelper2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/createForOfIteratorHelper */ \"./node_modules/@babel/runtime/helpers/createForOfIteratorHelper.js\"));\n\nvar _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/asyncToGenerator.js\"));\n\nvar _objectSpread2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/objectSpread2 */ \"./node_modules/@babel/runtime/helpers/objectSpread2.js\"));\n\nvar _marked = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n\nvar XLSX = _interopRequireWildcard(__webpack_require__(/*! xlsx */ \"./node_modules/xlsx/xlsx.mjs\"));\n\nvar _mammoth = _interopRequireDefault(__webpack_require__(/*! mammoth */ \"./node_modules/mammoth/lib/index.js\"));\n\nvar _docx = __webpack_require__(/*! docx */ \"./node_modules/docx/build/index.mjs\");\n\nvar _knowledgeBase = __webpack_require__(/*! ./api/knowledgeBase */ \"./src/lib/knowledgeBase/api/knowledgeBase.js\");\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n// 单文件大小上限:50MB\nvar MAX_SIZE = 50 * 1024 * 1024;\nvar ALLOWED_TYPES = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'md', 'markdown', 'jpg', 'jpeg', 'png', 'gif', 'webp']; // 支持在线编辑的文本文件类型\n\nvar TEXT_EDITABLE_TYPES = ['txt', 'md', 'markdown', 'json', 'xml', 'yaml', 'yml', 'ini', 'cfg', 'env', 'js', 'ts', 'jsx', 'tsx', 'css', 'scss', 'less', 'html', 'htm', 'vue', 'py', 'java', 'rb', 'go', 'rs', 'sh', 'bat', 'ps1', 'sql', 'php', 'c', 'cpp', 'h', 'hpp', 'swift', 'kt', 'groovy'];\nvar _default2 = {\n name: 'DocumentForm',\n props: {\n companyId: {\n type: String,\n default: ''\n },\n folderList: {\n type: Array,\n default: function _default() {\n return [];\n }\n }\n },\n data: function data() {\n return {\n visible: false,\n isEdit: false,\n editingId: null,\n submitting: false,\n fileList: [],\n formData: {\n title: '',\n folderId: '',\n fileName: ''\n },\n resolvePromise: null,\n editingFileType: '',\n originalIndexStatus: 0,\n mdTab: 'edit',\n xlsxData: {\n sheetNames: [],\n currentSheet: '',\n rows: [],\n cols: [],\n workbook: null,\n loading: false\n },\n wordHtml: '',\n wordLoading: false,\n folderTreeProps: {\n children: 'children',\n label: 'name'\n },\n folderPopoverVisible: false\n };\n },\n watch: {\n /**\n * wordLoading 变为 false 时,编辑器 DOM 已渲染,将 wordHtml 写入编辑器\n */\n wordLoading: function wordLoading(val) {\n var _this = this;\n\n if (!val && this.wordHtml) {\n this.$nextTick(function () {\n var editor = _this.$refs && _this.$refs.wordEditor;\n\n if (editor) {\n editor.innerHTML = _this.wordHtml;\n }\n });\n }\n }\n },\n computed: {\n dialogTitle: function dialogTitle() {\n if (this.isXlsxType) return '编辑表格数据';\n if (this.isWordType) return '编辑 Word 文档';\n if (this.isTextEditable) return '编辑文件内容';\n return '编辑文档';\n },\n dialogWidth: function dialogWidth() {\n if (this.isXlsxType) return '960px';\n if (this.isWordType) return '900px';\n if (this.isTextEditable) return '860px';\n return '560px';\n },\n\n /**\n * 当前编辑的文件是否为文本可编辑类型\n */\n isTextEditable: function isTextEditable() {\n var t = (this.editingFileType || '').toLowerCase();\n return TEXT_EDITABLE_TYPES.includes(t);\n },\n\n /**\n * 当前编辑的文件是否为 Excel 类型\n */\n isXlsxType: function isXlsxType() {\n var t = (this.editingFileType || '').toLowerCase();\n return t === 'xlsx' || t === 'xls';\n },\n\n /**\n * 当前编辑的文件是否为 Markdown 类型(支持预览)\n */\n isMarkdownType: function isMarkdownType() {\n var t = (this.editingFileType || '').toLowerCase();\n return t === 'md' || t === 'markdown';\n },\n\n /**\n * 当前编辑的文件是否为 Word 类型\n */\n isWordType: function isWordType() {\n var t = (this.editingFileType || '').toLowerCase();\n return t === 'docx' || t === 'doc';\n },\n\n /**\n * Word 编辑器字符数\n */\n wordCharCount: function wordCharCount() {\n var editor = this.$refs && this.$refs.wordEditor;\n\n if (editor) {\n return (editor.innerText || '').replace(/\\s/g, '').length;\n }\n\n return (this.wordHtml || '').replace(/<[^>]+>/g, '').length;\n },\n\n /**\n * Markdown 预览 HTML\n */\n previewHtml: function previewHtml() {\n if (!this.formData.content) return '';\n return _marked.marked.parse(this.formData.content, {\n breaks: true,\n gfm: true\n });\n },\n\n /**\n * 所属文件夹树(由平铺列表组装,不污染 prop)\n */\n folderTree: function folderTree() {\n var nodes = this.folderList.map(function (f) {\n return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, f), {}, {\n children: []\n });\n });\n var map = {};\n nodes.forEach(function (n) {\n map[n.id] = n;\n });\n var roots = [];\n nodes.forEach(function (n) {\n var pid = n.parentId || 0;\n\n if (map[pid]) {\n map[pid].children.push(n);\n } else {\n roots.push(n);\n }\n });\n return roots;\n },\n\n /**\n * 当前所选文件夹的名称(用于下拉框显示)\n */\n selectedFolderName: function selectedFolderName() {\n var _this2 = this;\n\n if (!this.formData.folderId) return '';\n var f = this.folderList.find(function (x) {\n return x.id === _this2.formData.folderId;\n });\n return f ? f.name : '';\n }\n },\n methods: {\n handleFolderSelect: function handleFolderSelect(data) {\n this.formData.folderId = data.id;\n this.folderPopoverVisible = false;\n },\n handleFolderPopoverShow: function handleFolderPopoverShow() {\n var _this3 = this;\n\n this.$nextTick(function () {\n if (_this3.$refs.folderTreeRef) _this3.$refs.folderTreeRef.setCurrentKey(_this3.formData.folderId || null);\n });\n },\n clearFolderSelect: function clearFolderSelect() {\n this.formData.folderId = '';\n this.folderPopoverVisible = false;\n },\n\n /**\n * 打开上传对话框(新增)\n * @param {string} folderId - 预选文件夹ID\n * @returns {Promise}\n */\n openAdd: function openAdd(folderId) {\n var _this4 = this;\n\n this.isEdit = false;\n this.editingId = null;\n this.fileList = [];\n this.formData = {\n title: '',\n folderId: folderId || '',\n fileName: ''\n };\n this.visible = true;\n this.$nextTick(function () {\n if (_this4.$refs.folderTreeRef) _this4.$refs.folderTreeRef.setCurrentKey(_this4.formData.folderId || null);\n });\n return new Promise(function (resolve) {\n _this4.resolvePromise = resolve;\n });\n },\n\n /**\n * 打开编辑对话框\n * @param {object} file - 文件对象\n * @returns {Promise}\n */\n openEdit: function openEdit(file) {\n var _this5 = this;\n\n this.isEdit = true;\n this.editingId = file.id;\n this.editingFileType = file.fileType || '';\n this.originalIndexStatus = file.indexStatus || 0;\n this.fileList = [];\n this.mdTab = 'edit';\n this.resetXlsxData();\n this.formData = {\n title: file.title || '',\n folderId: file.folderId || '',\n fileName: file.fileName || '',\n content: ''\n };\n var t = (file.fileType || '').toLowerCase(); // 如果是文本可编辑类型,异步加载文件内容\n\n if (TEXT_EDITABLE_TYPES.includes(t)) {\n (0, _knowledgeBase.getFileDetail)(file.id).then(function (d) {\n _this5.formData.content = d.content || '';\n }).catch(function () {\n _this5.formData.content = '(内容加载失败)';\n });\n } // 如果是 Excel 类型,下载原文件并解析\n\n\n if (t === 'xlsx' || t === 'xls') {\n this.loadXlsxFile(file);\n }\n\n this.visible = true;\n this.$nextTick(function () {\n if (_this5.$refs.folderTreeRef) _this5.$refs.folderTreeRef.setCurrentKey(_this5.formData.folderId || null);\n }); // 如果是 Word 类型,下载原文件并解析(visible 先置为 true 确保 DOM 已渲染)\n\n if (t === 'docx' || t === 'doc') {\n this.loadWordFile(file);\n }\n\n return new Promise(function (resolve) {\n _this5.resolvePromise = resolve;\n });\n },\n // ==================== Excel 编辑 ====================\n resetXlsxData: function resetXlsxData() {\n this.xlsxData = {\n sheetNames: [],\n currentSheet: '',\n rows: [],\n cols: [],\n workbook: null,\n loading: false\n };\n },\n loadXlsxFile: function loadXlsxFile(file) {\n var _this6 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n var detail, fileUrl, response, ab, workbook;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _this6.xlsxData.loading = true;\n _context.prev = 1;\n _context.next = 4;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 4:\n detail = _context.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context.next = 9;\n break;\n }\n\n _this6.$message.warning('无法获取文件下载地址');\n\n return _context.abrupt(\"return\");\n\n case 9:\n _context.next = 11;\n return fetch(fileUrl);\n\n case 11:\n response = _context.sent;\n\n if (response.ok) {\n _context.next = 14;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 14:\n _context.next = 16;\n return response.arrayBuffer();\n\n case 16:\n ab = _context.sent;\n workbook = XLSX.read(ab, {\n type: 'array'\n });\n _this6.xlsxData.workbook = workbook;\n _this6.xlsxData.sheetNames = workbook.SheetNames;\n\n if (workbook.SheetNames.length > 0) {\n _this6.xlsxData.currentSheet = workbook.SheetNames[0];\n\n _this6.buildXlsxSheetData(workbook.SheetNames[0]);\n }\n\n _context.next = 27;\n break;\n\n case 23:\n _context.prev = 23;\n _context.t0 = _context[\"catch\"](1);\n console.error('加载 Excel 文件失败', _context.t0);\n\n _this6.$message.error('加载 Excel 文件失败');\n\n case 27:\n _context.prev = 27;\n _this6.xlsxData.loading = false;\n return _context.finish(27);\n\n case 30:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, null, [[1, 23, 27, 30]]);\n }))();\n },\n buildXlsxSheetData: function buildXlsxSheetData(sheetName) {\n var workbook = this.xlsxData.workbook;\n if (!workbook) return;\n var sheet = workbook.Sheets[sheetName];\n\n if (!sheet) {\n this.xlsxData.rows = [];\n this.xlsxData.cols = [];\n return;\n } // 转为二维数组(defval 补齐空单元格,保证各列取值一致)\n\n\n var data = XLSX.utils.sheet_to_json(sheet, {\n header: 1,\n defval: ''\n });\n\n if (data.length === 0) {\n this.xlsxData.rows = [];\n this.xlsxData.cols = [];\n return;\n } // 列数以「所有行的最大宽度」为准:表头行可能只填了第一格,若直接按第一行长度定列会丢失后续列\n\n\n var maxCols = Math.max.apply(null, data.map(function (row) {\n return row && row.length || 0;\n })); // 第一行作为列名,未填表头的列用「列N」补齐\n\n this.xlsxData.cols = Array.from({\n length: maxCols\n }, function (_, i) {\n var v = data[0] && data[0][i];\n return v != null && String(v).trim() !== '' ? String(v) : \"\\u5217\".concat(i + 1);\n }); // 剩余行作为数据:过滤全空行,避免出现多余空白行\n\n this.xlsxData.rows = data.slice(1).filter(function (row) {\n return row && row.some(function (c) {\n return c != null && String(c).trim() !== '';\n });\n }).map(function (row) {\n var obj = {};\n\n for (var ci = 0; ci < maxCols; ci++) {\n obj[ci] = row[ci] != null ? String(row[ci]) : '';\n }\n\n return obj;\n });\n },\n switchXlsxSheet: function switchXlsxSheet(name) {\n // 先保存当前 sheet 的编辑数据到 workbook\n this.saveCurrentSheetData();\n this.xlsxData.currentSheet = name;\n this.buildXlsxSheetData(name);\n },\n addXlsxRow: function addXlsxRow() {\n var row = {};\n this.xlsxData.cols.forEach(function (col, ci) {\n row[ci] = '';\n });\n this.xlsxData.rows.push(row);\n },\n addXlsxCol: function addXlsxCol() {\n var _this7 = this;\n\n var newColName = \"\\u5217\".concat(this.xlsxData.cols.length + 1);\n this.xlsxData.cols.push(newColName);\n this.xlsxData.rows.forEach(function (row) {\n row[_this7.xlsxData.cols.length - 1] = '';\n });\n },\n deleteXlsxRow: function deleteXlsxRow() {\n if (this.xlsxData.rows.length === 0) return;\n this.xlsxData.rows.pop();\n },\n deleteXlsxCol: function deleteXlsxCol() {\n if (this.xlsxData.cols.length === 0) return;\n this.xlsxData.cols.pop();\n var ci = this.xlsxData.cols.length;\n this.xlsxData.rows.forEach(function (row) {\n delete row[ci];\n });\n },\n removeXlsxRow: function removeXlsxRow(index) {\n this.xlsxData.rows.splice(index, 1);\n },\n onXlsxCellChange: function onXlsxCellChange() {// 数据变更标记(将来可用于 dirty 判断)\n },\n\n /**\n * 将当前编辑的 rows/cols 写回 workbook.Sheets[currentSheet]\n */\n saveCurrentSheetData: function saveCurrentSheetData() {\n var _this8 = this;\n\n var workbook = this.xlsxData.workbook;\n var sheetName = this.xlsxData.currentSheet;\n if (!workbook || !sheetName || !this.xlsxData.cols.length) return;\n var aoa = [this.xlsxData.cols];\n this.xlsxData.rows.forEach(function (row) {\n // 用列索引取数,避免列名重复时 indexOf 定位错位\n var rowData = [];\n\n for (var ci = 0; ci < _this8.xlsxData.cols.length; ci++) {\n rowData.push(row[ci] != null ? row[ci] : '');\n }\n\n aoa.push(rowData);\n });\n workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet(aoa);\n },\n\n /**\n * 生成新的 xlsx 文件并上传替换\n */\n replaceXlsxFile: function replaceXlsxFile() {\n var _this9 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {\n var workbook, origExt, isXls, bookType, mime, wbout, blob, originalName, file, formData, newFile;\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n // 先保存当前 sheet 的编辑数据\n _this9.saveCurrentSheetData();\n\n workbook = _this9.xlsxData.workbook; // 写出所有 sheet 到新文件,保持与原文件扩展名一致(xls → biff8, xlsx → xlsx)\n\n origExt = ((_this9.formData.fileName || '').split('.').pop() || 'xlsx').toLowerCase();\n isXls = origExt === 'xls';\n bookType = isXls ? 'biff8' : 'xlsx';\n mime = isXls ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\n wbout = XLSX.write(workbook, {\n bookType: bookType,\n type: 'array'\n });\n blob = new Blob([wbout], {\n type: mime\n });\n originalName = (_this9.formData.fileName || 'export.xlsx').replace(/\\.(xls|xlsx)$/i, isXls ? '.xls' : '.xlsx');\n file = new File([blob], originalName, {\n type: mime\n }); // 上传新文件(携带 editId 原地替换原文件,保留原 id,避免删旧建新后旧 id 失效)\n\n formData = new FormData();\n formData.append('file', file);\n formData.append('companyId', _this9.companyId);\n\n if (_this9.formData.folderId) {\n formData.append('folderId', _this9.formData.folderId);\n }\n\n if (_this9.editingId) {\n formData.append('editId', _this9.editingId);\n }\n\n _context2.next = 17;\n return (0, _knowledgeBase.uploadFile)(formData);\n\n case 17:\n newFile = _context2.sent;\n return _context2.abrupt(\"return\", newFile);\n\n case 19:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2);\n }))();\n },\n // ==================== Word 编辑 ====================\n loadWordFile: function loadWordFile(file) {\n var _this10 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {\n var detail, fileUrl, response, ab, result;\n return regeneratorRuntime.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _this10.wordLoading = true;\n _this10.wordHtml = '';\n _context3.prev = 2;\n _context3.next = 5;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 5:\n detail = _context3.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context3.next = 10;\n break;\n }\n\n _this10.$message.warning('无法获取文件下载地址');\n\n return _context3.abrupt(\"return\");\n\n case 10:\n _context3.next = 12;\n return fetch(fileUrl);\n\n case 12:\n response = _context3.sent;\n\n if (response.ok) {\n _context3.next = 15;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 15:\n _context3.next = 17;\n return response.arrayBuffer();\n\n case 17:\n ab = _context3.sent;\n\n if (ab.byteLength) {\n _context3.next = 21;\n break;\n }\n\n _this10.wordHtml = '<p>(空文档)</p>';\n return _context3.abrupt(\"return\");\n\n case 21:\n _context3.next = 23;\n return _mammoth.default.convertToHtml({\n arrayBuffer: ab\n });\n\n case 23:\n result = _context3.sent;\n _this10.wordHtml = result.value || '<p>(空文档)</p>';\n _context3.next = 31;\n break;\n\n case 27:\n _context3.prev = 27;\n _context3.t0 = _context3[\"catch\"](2);\n console.error('加载 Word 文件失败', _context3.t0);\n\n _this10.$message.error('加载 Word 文件失败:文件可能为空或格式不支持在线编辑(仅支持 .docx)');\n\n case 31:\n _context3.prev = 31;\n _this10.wordLoading = false;\n return _context3.finish(31);\n\n case 34:\n case \"end\":\n return _context3.stop();\n }\n }\n }, _callee3, null, [[2, 27, 31, 34]]);\n }))();\n },\n execFormat: function execFormat(command, value) {\n document.execCommand(command, false, value || null);\n this.$refs.wordEditor && this.$refs.wordEditor.focus();\n },\n onWordInput: function onWordInput() {\n // 触发 wordCharCount 重新计算\n this.$forceUpdate();\n },\n\n /**\n * 将编辑后的 HTML 转为 .docx 文件并上传替换\n */\n replaceWordFile: function replaceWordFile() {\n var _this11 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {\n var editor, html, paragraphs, doc, blob, originalName, file, formData, newFile;\n return regeneratorRuntime.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n editor = _this11.$refs.wordEditor;\n html = editor ? editor.innerHTML : _this11.wordHtml; // 用 docx 包生成新文档\n\n paragraphs = _this11.htmlToDocxParagraphs(html);\n doc = new _docx.Document({\n sections: [{\n children: paragraphs\n }]\n });\n _context4.next = 6;\n return _docx.Packer.toBlob(doc);\n\n case 6:\n blob = _context4.sent;\n originalName = _this11.formData.fileName || 'document.docx';\n file = new File([blob], originalName, {\n type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n }); // 上传新文件(携带 editId 原地替换原文件,保留原 id,避免删旧建新后旧 id 失效)\n\n formData = new FormData();\n formData.append('file', file);\n formData.append('companyId', _this11.companyId);\n\n if (_this11.formData.folderId) {\n formData.append('folderId', _this11.formData.folderId);\n }\n\n if (_this11.editingId) {\n formData.append('editId', _this11.editingId);\n }\n\n _context4.next = 16;\n return (0, _knowledgeBase.uploadFile)(formData);\n\n case 16:\n newFile = _context4.sent;\n return _context4.abrupt(\"return\", newFile);\n\n case 18:\n case \"end\":\n return _context4.stop();\n }\n }\n }, _callee4);\n }))();\n },\n\n /**\n * 将 HTML 内容解析为 docx Paragraph 数组\n */\n htmlToDocxParagraphs: function htmlToDocxParagraphs(html) {\n var _this12 = this;\n\n var div = document.createElement('div');\n div.innerHTML = html;\n var children = div.childNodes;\n var paragraphs = [];\n\n var _iterator = (0, _createForOfIteratorHelper2.default)(children),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var node = _step.value;\n\n if (node.nodeType === 3) {\n // 纯文本节点\n var text = (node.textContent || '').trim();\n\n if (text) {\n paragraphs.push(new _docx.Paragraph({\n children: [new _docx.TextRun(text)]\n }));\n }\n\n continue;\n }\n\n if (node.nodeType !== 1) continue;\n var tag = node.tagName.toLowerCase(); // 标题 h1-h6\n\n if (/^h[1-6]$/.test(tag)) {\n var level = parseInt(tag[1]);\n var headingMap = {\n 1: _docx.HeadingLevel.HEADING_1,\n 2: _docx.HeadingLevel.HEADING_2,\n 3: _docx.HeadingLevel.HEADING_3,\n 4: _docx.HeadingLevel.HEADING_4,\n 5: _docx.HeadingLevel.HEADING_5,\n 6: _docx.HeadingLevel.HEADING_6\n };\n\n var _text = node.textContent || '';\n\n paragraphs.push(new _docx.Paragraph({\n heading: headingMap[level] || _docx.HeadingLevel.HEADING_1,\n spacing: {\n before: 200,\n after: 100\n },\n children: [new _docx.TextRun({\n text: _text,\n bold: level <= 3,\n size: level <= 1 ? 32 : level <= 2 ? 28 : 24\n })]\n }));\n continue;\n } // 段落、div、引用\n\n\n if (tag === 'p' || tag === 'div' || tag === 'blockquote') {\n var _runs = this.buildTextRuns(node);\n\n var opts = {\n children: _runs,\n spacing: {\n after: 80\n }\n };\n\n if (tag === 'blockquote') {\n opts.indent = {\n left: 400\n };\n }\n\n paragraphs.push(new _docx.Paragraph(opts));\n continue;\n } // 无序列表\n\n\n if (tag === 'ul') {\n var items = node.querySelectorAll('li');\n items.forEach(function (li) {\n var runs = _this12.buildTextRuns(li);\n\n paragraphs.push(new _docx.Paragraph({\n children: runs,\n bullet: {\n level: 0\n },\n spacing: {\n after: 40\n }\n }));\n });\n continue;\n } // 有序列表\n\n\n if (tag === 'ol') {\n var _ret = function () {\n var items = node.querySelectorAll('li');\n var num = 1;\n items.forEach(function (li) {\n var runs = _this12.buildTextRuns(li);\n\n paragraphs.push(new _docx.Paragraph({\n children: runs,\n numbering: {\n reference: 1,\n level: 0\n },\n spacing: {\n after: 40\n }\n }));\n num++;\n });\n return \"continue\";\n }();\n\n if (_ret === \"continue\") continue;\n } // 其他标签(pre, hr 等)当作段落处理\n\n\n var runs = this.buildTextRuns(node);\n\n if (runs.length > 0) {\n paragraphs.push(new _docx.Paragraph({\n children: runs\n }));\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return paragraphs;\n },\n\n /**\n * 从 DOM 节点构建 TextRun 数组\n */\n buildTextRuns: function buildTextRuns(node) {\n var runs = [];\n\n var walk = function walk(el) {\n el.childNodes.forEach(function (child) {\n if (child.nodeType === 3) {\n var text = (child.textContent || '').trim();\n\n if (text) {\n runs.push(new _docx.TextRun({\n text: text\n }));\n }\n } else if (child.nodeType === 1) {\n var t = child.tagName.toLowerCase();\n\n var _text2 = child.textContent || '';\n\n if (t === 'br') {// 换行不处理\n } else if (t === 'strong' || t === 'b') {\n runs.push(new _docx.TextRun({\n text: _text2,\n bold: true\n }));\n } else if (t === 'em' || t === 'i') {\n runs.push(new _docx.TextRun({\n text: _text2,\n italics: true\n }));\n } else if (t === 'u') {\n runs.push(new _docx.TextRun({\n text: _text2,\n underline: {\n type: 'single'\n }\n }));\n } else if (t === 'a') {\n runs.push(new _docx.TextRun({\n text: _text2\n }));\n } else {\n walk(child);\n }\n }\n });\n };\n\n walk(node);\n return runs;\n },\n // ==================== 表单提交 ====================\n handleFileChange: function handleFileChange(file, fileList) {\n this.fileList = fileList;\n },\n handleFileRemove: function handleFileRemove(file, fileList) {\n this.fileList = fileList;\n },\n handleFileExceed: function handleFileExceed() {\n this.$message.warning('最多只能上传 5 个文件');\n },\n\n /**\n * 上传前校验:大小 50MB、类型白名单\n */\n beforeUpload: function beforeUpload(file) {\n if (file.size > MAX_SIZE) {\n this.$message.error(\"\\u6587\\u4EF6\\u300C\".concat(file.name, \"\\u300D\\u5927\\u5C0F\\u4E0D\\u80FD\\u8D85\\u8FC7 50MB\"));\n return false;\n }\n\n var ext = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();\n\n if (!ALLOWED_TYPES.includes(ext)) {\n this.$message.error(\"\\u6587\\u4EF6\\u300C\".concat(file.name, \"\\u300D\\u7C7B\\u578B\\u4E0D\\u652F\\u6301: .\").concat(ext));\n return false;\n }\n\n return true;\n },\n handleSubmit: function handleSubmit() {\n if (this.isEdit) {\n this.handleSubmitEdit();\n } else {\n this.handleSubmitUpload();\n }\n },\n\n /**\n * 上传模式提交:逐个文件构造 FormData 调用上传接口\n */\n handleSubmitUpload: function handleSubmitUpload() {\n var _this13 = this;\n\n if (!this.companyId) {\n this.$message.warning('公司ID不能为空');\n return;\n }\n\n if (!this.formData.folderId) {\n this.$message.warning('请选择所属文件夹');\n return;\n }\n\n var files = this.fileList.filter(function (f) {\n return f.status !== 'success';\n });\n\n if (files.length === 0) {\n this.$message.warning('请先选择文件');\n return;\n } // 空文件直接拦截,避免上传后预览/解析失败\n\n\n var emptyFile = files.find(function (f) {\n return f.raw && f.raw.size === 0;\n });\n\n if (emptyFile) {\n this.$message.error(\"\\u6587\\u4EF6\\u300C\".concat(emptyFile.name, \"\\u300D\\u5185\\u5BB9\\u4E3A\\u7A7A\\uFF0C\\u8BF7\\u4E0A\\u4F20\\u6709\\u6548\\u6587\\u4EF6\"));\n return;\n }\n\n this.submitting = true; // 逐个上传(后端单文件接口)\n\n var tasks = files.map(function (file) {\n var formData = new FormData();\n formData.append('file', file.raw);\n formData.append('companyId', _this13.companyId);\n console.log('[DocumentForm] 上传文件:', file.name, ', companyId:', _this13.companyId);\n\n if (_this13.formData.folderId) {\n formData.append('folderId', _this13.formData.folderId);\n }\n\n return (0, _knowledgeBase.uploadFile)(formData);\n });\n Promise.all(tasks).then(function () {\n _this13.$message.success(\"\\u6210\\u529F\\u4E0A\\u4F20 \".concat(files.length, \" \\u4E2A\\u6587\\u4EF6\"));\n\n _this13.visible = false;\n\n if (_this13.resolvePromise) {\n _this13.resolvePromise(true);\n\n _this13.resolvePromise = null;\n }\n }).catch(function () {}).finally(function () {\n _this13.submitting = false;\n });\n },\n\n /**\n * 编辑模式提交\n */\n handleSubmitEdit: function handleSubmitEdit() {\n var _this14 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {\n var newFile, _newFile, data;\n\n return regeneratorRuntime.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n _this14.submitting = true;\n _context5.prev = 1;\n\n if (!_this14.isXlsxType) {\n _context5.next = 10;\n break;\n }\n\n _context5.next = 5;\n return _this14.replaceXlsxFile();\n\n case 5:\n newFile = _context5.sent;\n _context5.next = 8;\n return _this14.syncEditedMeta(newFile);\n\n case 8:\n _context5.next = 23;\n break;\n\n case 10:\n if (!_this14.isWordType) {\n _context5.next = 18;\n break;\n }\n\n _context5.next = 13;\n return _this14.replaceWordFile();\n\n case 13:\n _newFile = _context5.sent;\n _context5.next = 16;\n return _this14.syncEditedMeta(_newFile);\n\n case 16:\n _context5.next = 23;\n break;\n\n case 18:\n // 普通文件:更新元数据 + 文本内容\n data = {\n title: _this14.formData.title\n };\n\n if (_this14.formData.folderId) {\n data.folderId = _this14.formData.folderId;\n }\n\n if (_this14.isTextEditable && _this14.formData.content) {\n data.content = _this14.formData.content;\n }\n\n _context5.next = 23;\n return (0, _knowledgeBase.updateFile)(_this14.editingId, data);\n\n case 23:\n if (!(_this14.originalIndexStatus === 1)) {\n _context5.next = 33;\n break;\n }\n\n _context5.prev = 24;\n _context5.next = 27;\n return (0, _knowledgeBase.deleteFileIndex)(_this14.editingId);\n\n case 27:\n _this14.$message.info('文件已修改,原索引已删除,请重新执行索引');\n\n _context5.next = 33;\n break;\n\n case 30:\n _context5.prev = 30;\n _context5.t0 = _context5[\"catch\"](24);\n console.error('删除旧索引失败', _context5.t0);\n\n case 33:\n _this14.$message.success('修改成功');\n\n _this14.visible = false;\n\n if (_this14.resolvePromise) {\n _this14.resolvePromise(true);\n\n _this14.resolvePromise = null;\n }\n\n _context5.next = 42;\n break;\n\n case 38:\n _context5.prev = 38;\n _context5.t1 = _context5[\"catch\"](1);\n console.error('保存失败', _context5.t1);\n\n _this14.$message.error('保存失败');\n\n case 42:\n _context5.prev = 42;\n _this14.submitting = false;\n return _context5.finish(42);\n\n case 45:\n case \"end\":\n return _context5.stop();\n }\n }\n }, _callee5, null, [[1, 38, 42, 45], [24, 30]]);\n }))();\n },\n\n /**\n * Word/Excel 替换保存后,同步标题与所属文件夹元数据\n */\n syncEditedMeta: function syncEditedMeta(newFile) {\n var _this15 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {\n var id, data, title;\n return regeneratorRuntime.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n id = newFile && newFile.id || _this15.editingId;\n data = {};\n title = (_this15.formData.title || '').trim();\n if (title) data.title = title;\n if (_this15.formData.folderId) data.folderId = _this15.formData.folderId;\n\n if (!Object.keys(data).length) {\n _context6.next = 8;\n break;\n }\n\n _context6.next = 8;\n return (0, _knowledgeBase.updateFile)(id, data);\n\n case 8:\n case \"end\":\n return _context6.stop();\n }\n }\n }, _callee6);\n }))();\n },\n onDialogOpened: function onDialogOpened() {\n // dialog 完全打开后,尝试将 wordHtml 写入编辑器\n if (this.isWordType && this.wordHtml && this.$refs && this.$refs.wordEditor) {\n this.$refs.wordEditor.innerHTML = this.wordHtml;\n }\n },\n handleClosed: function handleClosed() {\n // 关闭后清空上传列表,避免下次打开残留\n if (this.$refs.uploadRef) {\n this.$refs.uploadRef.clearFiles();\n }\n\n this.fileList = [];\n this.resetXlsxData();\n this.wordHtml = '';\n\n if (this.resolvePromise) {\n this.resolvePromise(null);\n this.resolvePromise = null;\n }\n }\n }\n};\nexports.default = _default2;\n\n//# sourceURL=webpack://ZjPluginIntelligent/./src/lib/knowledgeBase/DocumentForm.vue?./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options");
980
980
 
981
981
  /***/ }),
982
982
 
@@ -988,7 +988,7 @@ eval("\n\nvar _interopRequireWildcard = __webpack_require__(/*! ./node_modules/@
988
988
  /***/ (function(module, exports, __webpack_require__) {
989
989
 
990
990
  "use strict";
991
- eval("\n\nvar _interopRequireWildcard = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireWildcard */ \"./node_modules/@babel/runtime/helpers/interopRequireWildcard.js\").default;\n\nvar _interopRequireDefault = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireDefault */ \"./node_modules/@babel/runtime/helpers/interopRequireDefault.js\").default;\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/asyncToGenerator.js\"));\n\nvar _objectSpread2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/objectSpread2 */ \"./node_modules/@babel/runtime/helpers/objectSpread2.js\"));\n\nvar _marked = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n\nvar XLSX = _interopRequireWildcard(__webpack_require__(/*! xlsx */ \"./node_modules/xlsx/xlsx.mjs\"));\n\nvar _mammoth = _interopRequireDefault(__webpack_require__(/*! mammoth */ \"./node_modules/mammoth/lib/index.js\"));\n\nvar _knowledgeBase = __webpack_require__(/*! ./api/knowledgeBase */ \"./src/lib/knowledgeBase/api/knowledgeBase.js\");\n\nvar _DocumentForm = _interopRequireDefault(__webpack_require__(/*! ./DocumentForm */ \"./src/lib/knowledgeBase/DocumentForm.vue\"));\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n// 预览最多显示的行数(防止大文件卡死)\nvar MAX_PREVIEW_ROWS = 500;\nvar _default2 = {\n name: 'DocumentList',\n components: {\n DocumentForm: _DocumentForm.default\n },\n props: {\n selectedCategory: {\n type: Object,\n default: null\n },\n categoryList: {\n type: Array,\n default: function _default() {\n return [];\n }\n },\n companyId: {\n type: String,\n default: ''\n }\n },\n data: function data() {\n return {\n list: [],\n loading: false,\n total: 0,\n page: 1,\n pageSize: 10,\n searchKeyword: '',\n // 批量删除选中的文件\n selectedRows: [],\n // 批量移动\n moveVisible: false,\n moveFolderId: null,\n moving: false,\n folderList: [],\n folderTreeProps: {\n children: 'children',\n label: 'name'\n },\n // 在线预览\n previewVisible: false,\n previewFile: null,\n previewType: 'none',\n previewText: '',\n // PDF 预览(Blob URL 避免下载)\n pdfBlobUrl: '',\n // Excel 预览\n xlsxLoading: false,\n xlsxWorkbook: null,\n xlsxSheetNames: [],\n xlsxCurrentSheet: '',\n xlsxCols: [],\n xlsxTableData: [],\n hasMoreRows: false,\n // Word 预览\n docxLoading: false,\n docxHtml: ''\n };\n },\n computed: {\n /**\n * Markdown 渲染后的 HTML(使用 marked)\n */\n previewHtml: function previewHtml() {\n if (!this.previewText) return '';\n return _marked.marked.parse(this.previewText, {\n breaks: true,\n gfm: true\n });\n },\n maxPreviewRows: function maxPreviewRows() {\n return MAX_PREVIEW_ROWS;\n },\n\n /**\n * 批量移动的文件夹树(由平铺列表组装)\n */\n moveFolderTree: function moveFolderTree() {\n var nodes = this.folderList.map(function (f) {\n return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, f), {}, {\n children: []\n });\n });\n var map = {};\n nodes.forEach(function (n) {\n map[n.id] = n;\n });\n var roots = [];\n nodes.forEach(function (n) {\n var pid = n.parentId || 0;\n if (map[pid]) map[pid].children.push(n);else roots.push(n);\n });\n return roots;\n },\n\n /**\n * 目标文件夹名称\n */\n moveTargetName: function moveTargetName() {\n var _this = this;\n\n if (!this.moveFolderId) return '';\n var f = this.folderList.find(function (x) {\n return x.id === _this.moveFolderId;\n });\n return f ? f.name : '';\n }\n },\n watch: {\n selectedCategory: function selectedCategory() {\n this.page = 1;\n this.loadList();\n },\n companyId: function companyId() {\n this.page = 1;\n this.searchKeyword = '';\n this.list = [];\n this.total = 0;\n this.loadList();\n },\n\n /**\n * 预览弹窗关闭时清理 PDF Blob URL\n */\n previewVisible: function previewVisible(val) {\n if (!val && this.pdfBlobUrl) {\n URL.revokeObjectURL(this.pdfBlobUrl);\n this.pdfBlobUrl = '';\n }\n }\n },\n created: function created() {\n this.loadList();\n },\n methods: {\n loadList: function loadList() {\n var _this2 = this;\n\n if (!this.companyId) return;\n this.loading = true;\n var params = {\n companyId: this.companyId,\n pageNum: this.page,\n pageSize: this.pageSize\n }; // 选中具体文件夹时按文件夹过滤(\"显示全部文件\"时 id 为空串,不传)\n\n if (this.selectedCategory && this.selectedCategory.id) {\n params.folderId = this.selectedCategory.id;\n }\n\n if (this.searchKeyword) {\n params.keyword = this.searchKeyword;\n }\n\n (0, _knowledgeBase.getFileList)(params).then(function (data) {\n _this2.list = data.records || [];\n _this2.total = data.total || 0; // 列表刷新后清空勾选\n\n _this2.selectedRows = [];\n\n _this2.$nextTick(function () {\n if (_this2.$refs.tableRef) _this2.$refs.tableRef.clearSelection();\n });\n }).catch(function () {}).finally(function () {\n _this2.loading = false;\n });\n },\n handleSearch: function handleSearch() {\n this.page = 1;\n this.loadList();\n },\n handleSizeChange: function handleSizeChange(size) {\n this.pageSize = size;\n this.page = 1;\n this.loadList();\n },\n handleCurrentChange: function handleCurrentChange(page) {\n this.page = page;\n this.loadList();\n },\n handleAdd: function handleAdd() {\n var _this3 = this;\n\n if (!this.companyId) {\n this.$message.warning('公司数据未加载,请稍后刷新');\n return;\n }\n\n if (!this.categoryList || this.categoryList.length === 0) {\n this.$message.warning('暂无根目录,请先创建文件夹再新增文档');\n return;\n }\n\n var folderId = this.selectedCategory && this.selectedCategory.id ? this.selectedCategory.id : '';\n this.$refs.docFormRef.openAdd(folderId).then(function (res) {\n if (res) _this3.loadList();\n });\n },\n handleEdit: function handleEdit(row) {\n var _this4 = this;\n\n this.$refs.docFormRef.openEdit(row).then(function (res) {\n if (res) _this4.loadList();\n });\n },\n\n /**\n * 在线预览:图片 / PDF / Excel / Word / 文本\n */\n handlePreview: function handlePreview(row) {\n var _this5 = this;\n\n this.previewFile = row;\n this.previewText = '';\n this.docxHtml = '';\n this.xlsxWorkbook = null;\n this.xlsxSheetNames = [];\n this.xlsxCurrentSheet = '';\n this.xlsxCols = [];\n this.xlsxTableData = []; // 清理上一次的 PDF Blob URL\n\n if (this.pdfBlobUrl) {\n URL.revokeObjectURL(this.pdfBlobUrl);\n this.pdfBlobUrl = '';\n }\n\n var t = (row.fileType || '').toLowerCase();\n\n if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].includes(t)) {\n this.previewType = 'image';\n } else if (t === 'pdf') {\n this.previewType = 'pdf';\n this.loadPdfPreview(row);\n } else if (t === 'xlsx' || t === 'xls') {\n this.previewType = 'xlsx';\n this.loadXlsxPreview(row);\n } else if (t === 'docx' || t === 'doc') {\n this.previewType = 'docx';\n this.loadDocxPreview(row);\n } else if (['txt', 'md', 'markdown', 'html', 'htm'].includes(t)) {\n this.previewType = 'text';\n (0, _knowledgeBase.getFileDetail)(row.id).then(function (d) {\n _this5.previewText = d.content || '(该文件暂无可预览的文本内容)';\n }).catch(function () {\n _this5.previewText = '(文本内容加载失败)';\n });\n } else {\n this.previewType = 'none';\n }\n\n this.previewVisible = true;\n },\n // ==================== Excel 预览 ====================\n loadXlsxPreview: function loadXlsxPreview(file) {\n var _this6 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n var detail, fileUrl, response, ab, workbook;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _this6.xlsxLoading = true;\n _context.prev = 1;\n _context.next = 4;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 4:\n detail = _context.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context.next = 9;\n break;\n }\n\n _this6.$message.warning('无法获取文件下载地址');\n\n return _context.abrupt(\"return\");\n\n case 9:\n _context.next = 11;\n return fetch(fileUrl);\n\n case 11:\n response = _context.sent;\n\n if (response.ok) {\n _context.next = 14;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 14:\n _context.next = 16;\n return response.arrayBuffer();\n\n case 16:\n ab = _context.sent;\n _context.next = 19;\n return new Promise(function (r) {\n return setTimeout(r, 0);\n });\n\n case 19:\n workbook = XLSX.read(ab, {\n type: 'array'\n });\n _this6.xlsxWorkbook = workbook;\n _this6.xlsxSheetNames = workbook.SheetNames;\n\n if (workbook.SheetNames.length > 0) {\n _this6.xlsxCurrentSheet = workbook.SheetNames[0];\n\n _this6.renderXlsxSheet();\n }\n\n _context.next = 29;\n break;\n\n case 25:\n _context.prev = 25;\n _context.t0 = _context[\"catch\"](1);\n console.error('加载 Excel 文件失败', _context.t0);\n\n _this6.$message.error('Excel 文件加载失败');\n\n case 29:\n _context.prev = 29;\n _this6.xlsxLoading = false;\n return _context.finish(29);\n\n case 32:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, null, [[1, 25, 29, 32]]);\n }))();\n },\n renderXlsxSheet: function renderXlsxSheet() {\n var workbook = this.xlsxWorkbook;\n var sheetName = this.xlsxCurrentSheet;\n if (!workbook || !sheetName) return;\n var sheet = workbook.Sheets[sheetName];\n\n if (!sheet) {\n this.xlsxCols = [];\n this.xlsxTableData = [];\n return;\n } // 让出主线程,防止 sheet_to_json 阻塞 UI\n\n\n var data = XLSX.utils.sheet_to_json(sheet, {\n header: 1,\n defval: ''\n });\n\n if (data.length === 0) {\n this.xlsxCols = [];\n this.xlsxTableData = [];\n return;\n } // 列数以「所有行的最大宽度」为准:表头行可能只填了第一格,若直接按第一行长度定列会丢失后续列\n\n\n var maxCols = Math.max.apply(null, data.map(function (row) {\n return row && row.length || 0;\n }));\n this.xlsxCols = Array.from({\n length: maxCols\n }, function (_, i) {\n var v = data[0] && data[0][i];\n return v != null && String(v).trim() !== '' ? String(v) : \"\\u5217\".concat(i + 1);\n }); // 限制预览行数,防止渲染过多 DOM 卡死;同时过滤全空行\n\n var allRows = data.slice(1).filter(function (row) {\n return row && row.some(function (c) {\n return c != null && String(c).trim() !== '';\n });\n });\n this.hasMoreRows = allRows.length > MAX_PREVIEW_ROWS;\n this.xlsxTableData = allRows.slice(0, MAX_PREVIEW_ROWS).map(function (row) {\n var obj = {};\n\n for (var ci = 0; ci < maxCols; ci++) {\n obj[ci] = row[ci] != null ? String(row[ci]) : '';\n }\n\n return obj;\n });\n },\n // ==================== Word 预览 ====================\n loadDocxPreview: function loadDocxPreview(file) {\n var _this7 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {\n var detail, fileUrl, response, ab, result;\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _this7.docxLoading = true;\n _context2.prev = 1;\n _context2.next = 4;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 4:\n detail = _context2.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context2.next = 9;\n break;\n }\n\n _this7.$message.warning('无法获取文件下载地址');\n\n return _context2.abrupt(\"return\");\n\n case 9:\n _context2.next = 11;\n return fetch(fileUrl);\n\n case 11:\n response = _context2.sent;\n\n if (response.ok) {\n _context2.next = 14;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 14:\n _context2.next = 16;\n return response.arrayBuffer();\n\n case 16:\n ab = _context2.sent;\n\n if (ab.byteLength) {\n _context2.next = 20;\n break;\n }\n\n _this7.docxHtml = '<p>(空文档)</p>';\n return _context2.abrupt(\"return\");\n\n case 20:\n _context2.next = 22;\n return _mammoth.default.convertToHtml({\n arrayBuffer: ab\n });\n\n case 22:\n result = _context2.sent;\n _this7.docxHtml = result.value || '<p>(空文档)</p>';\n _context2.next = 30;\n break;\n\n case 26:\n _context2.prev = 26;\n _context2.t0 = _context2[\"catch\"](1);\n console.error('加载 Word 文件失败', _context2.t0);\n\n _this7.$message.error('Word 文件加载失败');\n\n case 30:\n _context2.prev = 30;\n _this7.docxLoading = false;\n return _context2.finish(30);\n\n case 33:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2, null, [[1, 26, 30, 33]]);\n }))();\n },\n // ==================== PDF 预览 ====================\n loadPdfPreview: function loadPdfPreview(file) {\n var _this8 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {\n var detail, fileUrl, response, blob;\n return regeneratorRuntime.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _context3.prev = 0;\n _context3.next = 3;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 3:\n detail = _context3.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context3.next = 8;\n break;\n }\n\n _this8.$message.warning('无法获取文件下载地址');\n\n return _context3.abrupt(\"return\");\n\n case 8:\n _context3.next = 10;\n return fetch(fileUrl);\n\n case 10:\n response = _context3.sent;\n\n if (response.ok) {\n _context3.next = 13;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 13:\n _context3.next = 15;\n return response.blob();\n\n case 15:\n blob = _context3.sent;\n _this8.pdfBlobUrl = URL.createObjectURL(blob);\n _context3.next = 23;\n break;\n\n case 19:\n _context3.prev = 19;\n _context3.t0 = _context3[\"catch\"](0);\n console.error('加载 PDF 文件失败', _context3.t0);\n\n _this8.$message.error('PDF 文件加载失败');\n\n case 23:\n case \"end\":\n return _context3.stop();\n }\n }\n }, _callee3, null, [[0, 19]]);\n }))();\n },\n\n /**\n * 索引 / 重建索引(二次确认)\n */\n handleIndex: function handleIndex(row) {\n var _this9 = this;\n\n var isRebuild = row.indexStatus === 1;\n console.log('[DocumentList] 索引文件:', row.id, row.title, 'companyId:', this.companyId);\n this.$confirm(\"\\u786E\\u8BA4\\u5BF9\\u6587\\u4EF6\\u300C\".concat(row.title || row.fileName, \"\\u300D\").concat(isRebuild ? '重建' : '创建', \"\\u7D22\\u5F15\\uFF1F\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定',\n cancelButtonText: '取消'\n }).then(function () {\n var request = isRebuild ? (0, _knowledgeBase.reindexFile)(row.id) : (0, _knowledgeBase.indexFile)(row.id);\n request.then(function () {\n _this9.$message.success(isRebuild ? '已开始重建索引' : '已开始索引');\n\n _this9.loadList();\n }).catch(function () {});\n }).catch(function () {});\n },\n\n /**\n * 删除索引(二次确认)\n */\n handleDeleteIndex: function handleDeleteIndex(row) {\n var _this10 = this;\n\n this.$confirm(\"\\u786E\\u8BA4\\u5220\\u9664\\u6587\\u4EF6\\u300C\".concat(row.title || row.fileName, \"\\u300D\\u7684\\u7D22\\u5F15\\uFF1F\\u5220\\u9664\\u540E\\u65E0\\u6CD5\\u6062\\u590D\\u3002\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定删除',\n cancelButtonText: '取消'\n }).then(function () {\n (0, _knowledgeBase.deleteFileIndex)(row.id).then(function () {\n _this10.$message.success('索引已删除');\n\n _this10.loadList();\n }).catch(function () {});\n }).catch(function () {});\n },\n handleDelete: function handleDelete(row) {\n var _this11 = this;\n\n // 索引中的文件不允许删除\n if (row.indexStatus === 2) {\n this.$message.warning('该文件正在索引中,无法删除');\n return;\n }\n\n var hasIndex = row.indexStatus === 1;\n this.$confirm(\"\\u786E\\u8BA4\\u5220\\u9664\\u6587\\u4EF6\\u300C\".concat(row.title || row.fileName, \"\\u300D\\uFF1F\").concat(hasIndex ? '删除文件前会先删除该文件的索引。' : '', \"\\u5220\\u9664\\u540E\\u65E0\\u6CD5\\u6062\\u590D\\u3002\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定删除',\n cancelButtonText: '取消'\n }).then( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {\n return regeneratorRuntime.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.prev = 0;\n\n if (!hasIndex) {\n _context4.next = 4;\n break;\n }\n\n _context4.next = 4;\n return (0, _knowledgeBase.deleteFileIndex)(row.id);\n\n case 4:\n _context4.next = 6;\n return (0, _knowledgeBase.deleteFile)(row.id);\n\n case 6:\n _this11.$message.success('文件已删除');\n\n _this11.loadList();\n\n _context4.next = 12;\n break;\n\n case 10:\n _context4.prev = 10;\n _context4.t0 = _context4[\"catch\"](0);\n\n case 12:\n case \"end\":\n return _context4.stop();\n }\n }\n }, _callee4, null, [[0, 10]]);\n }))).catch(function () {});\n },\n\n /**\n * 表格勾选变化\n */\n handleSelectionChange: function handleSelectionChange(rows) {\n this.selectedRows = rows || [];\n },\n\n /**\n * 索引中的文件不可勾选删除\n */\n rowSelectable: function rowSelectable(row) {\n return row.indexStatus !== 2;\n },\n\n /**\n * 批量删除勾选的文件\n */\n handleBatchDelete: function handleBatchDelete() {\n var _this12 = this;\n\n var selected = this.selectedRows || [];\n\n if (!selected.length) {\n this.$message.warning('请先勾选要删除的文件');\n return;\n } // 索引中的文件不允许删除\n\n\n var indexingFiles = selected.filter(function (f) {\n return f.indexStatus === 2;\n });\n var deletable = selected.filter(function (f) {\n return f.indexStatus !== 2;\n });\n\n if (!deletable.length) {\n this.$message.warning('所选文件均正在索引中,无法删除');\n return;\n }\n\n if (indexingFiles.length) {\n this.$message.warning(\"\\u6709 \".concat(indexingFiles.length, \" \\u4E2A\\u6587\\u4EF6\\u6B63\\u5728\\u7D22\\u5F15\\u4E2D\\uFF0C\\u672C\\u6B21\\u5C06\\u8DF3\\u8FC7\"));\n } // 已索引的文件需先删除索引,再删除文件\n\n\n var indexed = deletable.filter(function (f) {\n return f.indexStatus === 1;\n });\n var ids = deletable.map(function (f) {\n return f.id;\n });\n this.$confirm(\"\\u786E\\u8BA4\\u5220\\u9664\\u9009\\u4E2D\\u7684 \".concat(deletable.length, \" \\u4E2A\\u6587\\u4EF6\\uFF1F\").concat(indexed.length ? '删除前会先删除这些文件的索引。' : '', \"\\u5220\\u9664\\u540E\\u65E0\\u6CD5\\u6062\\u590D\\u3002\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定删除',\n cancelButtonText: '取消',\n customClass: 'kb-message-box'\n }).then( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {\n return regeneratorRuntime.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n _context5.prev = 0;\n\n if (!indexed.length) {\n _context5.next = 4;\n break;\n }\n\n _context5.next = 4;\n return Promise.all(indexed.map(function (f) {\n return (0, _knowledgeBase.deleteFileIndex)(f.id);\n }));\n\n case 4:\n _context5.next = 6;\n return (0, _knowledgeBase.deleteFiles)(ids);\n\n case 6:\n _this12.$message.success('批量删除成功');\n\n _this12.loadList();\n\n _context5.next = 12;\n break;\n\n case 10:\n _context5.prev = 10;\n _context5.t0 = _context5[\"catch\"](0);\n\n case 12:\n case \"end\":\n return _context5.stop();\n }\n }\n }, _callee5, null, [[0, 10]]);\n }))).catch(function () {});\n },\n\n /**\n * 批量移动:打开目标文件夹选择弹窗\n */\n handleBatchMove: function handleBatchMove() {\n var _this13 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {\n var selected, folders;\n return regeneratorRuntime.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n selected = _this13.selectedRows || [];\n\n if (selected.length) {\n _context6.next = 4;\n break;\n }\n\n _this13.$message.warning('请先勾选要移动的文件');\n\n return _context6.abrupt(\"return\");\n\n case 4:\n if (_this13.companyId) {\n _context6.next = 7;\n break;\n }\n\n _this13.$message.warning('公司数据未加载');\n\n return _context6.abrupt(\"return\");\n\n case 7:\n _this13.moveFolderId = null;\n _this13.moveVisible = true; // 每次打开都重新加载文件夹列表,确保新建/重命名/删除文件夹后看到最新目录\n\n _context6.prev = 9;\n _context6.next = 12;\n return (0, _knowledgeBase.getFolderList)(_this13.companyId);\n\n case 12:\n folders = _context6.sent;\n _this13.folderList = folders || [];\n _context6.next = 18;\n break;\n\n case 16:\n _context6.prev = 16;\n _context6.t0 = _context6[\"catch\"](9);\n\n case 18:\n _this13.$nextTick(function () {\n if (_this13.$refs.moveTreeRef) _this13.$refs.moveTreeRef.setCurrentKey(null);\n });\n\n case 19:\n case \"end\":\n return _context6.stop();\n }\n }\n }, _callee6, null, [[9, 16]]);\n }))();\n },\n\n /**\n * 选择目标文件夹\n */\n handleMoveFolderSelect: function handleMoveFolderSelect(data) {\n this.moveFolderId = data.id;\n },\n\n /**\n * 确认批量移动\n */\n handleMoveConfirm: function handleMoveConfirm() {\n var _this14 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {\n var ids, targetFolder;\n return regeneratorRuntime.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n if (_this14.moveFolderId) {\n _context7.next = 3;\n break;\n }\n\n _this14.$message.warning('请选择目标文件夹');\n\n return _context7.abrupt(\"return\");\n\n case 3:\n ids = _this14.selectedRows.map(function (f) {\n return f.id;\n });\n _this14.moving = true;\n _context7.prev = 5;\n _context7.next = 8;\n return (0, _knowledgeBase.moveFiles)(ids, _this14.moveFolderId);\n\n case 8:\n _this14.$message.success('批量移动成功');\n\n _this14.moveVisible = false; // 移动成功后,通知父级定位并高亮左侧树到目标文件夹\n\n targetFolder = _this14.folderList.find(function (f) {\n return String(f.id) === String(_this14.moveFolderId);\n }) || null;\n if (targetFolder) _this14.$emit('move-target', targetFolder);else _this14.$emit('move-target', {\n id: _this14.moveFolderId,\n name: _this14.moveTargetName\n });\n\n _this14.loadList();\n\n _context7.next = 17;\n break;\n\n case 15:\n _context7.prev = 15;\n _context7.t0 = _context7[\"catch\"](5);\n\n case 17:\n _context7.prev = 17;\n _this14.moving = false;\n return _context7.finish(17);\n\n case 20:\n case \"end\":\n return _context7.stop();\n }\n }\n }, _callee7, null, [[5, 15, 17, 20]]);\n }))();\n },\n\n /**\n * 通过 folderId 映射文件夹名称\n */\n folderName: function folderName(folderId) {\n if (!folderId) return '根目录';\n var found = this.categoryList.find(function (f) {\n return String(f.id) === String(folderId);\n });\n return found ? found.name : '-';\n },\n\n /**\n * 根据文件类型返回对应图标\n */\n getFileIcon: function getFileIcon(fileType) {\n var type = (fileType || '').toLowerCase();\n var iconMap = {\n pdf: 'el-icon-document',\n doc: 'el-icon-document',\n docx: 'el-icon-document',\n xls: 'el-icon-tickets',\n xlsx: 'el-icon-tickets',\n ppt: 'el-icon-data-line',\n pptx: 'el-icon-data-line',\n txt: 'el-icon-document',\n md: 'el-icon-edit-outline',\n png: 'el-icon-picture',\n jpg: 'el-icon-picture',\n jpeg: 'el-icon-picture',\n gif: 'el-icon-picture',\n zip: 'el-icon-folder-opened',\n rar: 'el-icon-folder-opened'\n };\n return iconMap[type] || 'el-icon-document';\n },\n\n /**\n * 根据文件类型返回对应的图标 URL\n */\n getFileIconUrl: function getFileIconUrl(fileType) {\n var type = (fileType || '').toLowerCase();\n var base = 'https://qiguanbang-client.obs.cn-east-3.myhuaweicloud.com/fileimgdoc';\n var generic = \"\".concat(base, \"/\\u901A\\u7528.png\"); // 通用文档 / 云文档(无专属图标时使用通用图片兜底)\n\n var genericTypes = ['md', 'markdown', 'html', 'htm', 'docx2', 'rtf'];\n var urlMap = {\n // 图片格式(jpg/png/jpeg 等)\n jpg: \"\".concat(base, \"/png.png\"),\n jpeg: \"\".concat(base, \"/png.png\"),\n png: \"\".concat(base, \"/png.png\"),\n gif: \"\".concat(base, \"/png.png\"),\n webp: \"\".concat(base, \"/png.png\"),\n bmp: \"\".concat(base, \"/png.png\"),\n // Excel 表格(xlsx/xls)\n xlsx: \"\".concat(base, \"/xlsx.png\"),\n xls: \"\".concat(base, \"/xlsx.png\"),\n csv: \"\".concat(base, \"/xlsx.png\"),\n // PDF 文档\n pdf: \"\".concat(base, \"/pdf.png\"),\n // 压缩包(zip/rar)\n zip: \"\".concat(base, \"/zip.png\"),\n rar: \"\".concat(base, \"/zip.png\"),\n '7z': \"\".concat(base, \"/zip.png\"),\n gz: \"\".concat(base, \"/zip.png\"),\n tar: \"\".concat(base, \"/zip.png\"),\n // Word 文档(docx/doc)\n docx: \"\".concat(base, \"/word.png\"),\n doc: \"\".concat(base, \"/word.png\"),\n // TXT 文本文件\n txt: \"\".concat(base, \"/txt.png\"),\n // PPT 演示文稿(pptx/ppt)\n pptx: \"\".concat(base, \"/ppt.png\"),\n ppt: \"\".concat(base, \"/ppt.png\"),\n // 视频文件\n mp4: \"\".concat(base, \"/mp4.png\"),\n avi: \"\".concat(base, \"/mp4.png\"),\n mov: \"\".concat(base, \"/mp4.png\"),\n wmv: \"\".concat(base, \"/mp4.png\"),\n flv: \"\".concat(base, \"/mp4.png\"),\n mkv: \"\".concat(base, \"/mp4.png\"),\n // 音频文件(mp3 等)\n mp3: \"\".concat(base, \"/mp3.png\"),\n wav: \"\".concat(base, \"/mp3.png\"),\n flac: \"\".concat(base, \"/mp3.png\"),\n aac: \"\".concat(base, \"/mp3.png\"),\n ogg: \"\".concat(base, \"/mp3.png\"),\n m4a: \"\".concat(base, \"/mp3.png\")\n };\n return (genericTypes.includes(type) ? generic : urlMap[type]) || generic;\n },\n\n /**\n * 文件大小格式化(字节 → B/KB/MB/GB)\n */\n formatSize: function formatSize(bytes) {\n if (!bytes && bytes !== 0) return '-';\n if (bytes === 0) return '0 B';\n var units = ['B', 'KB', 'MB', 'GB', 'TB'];\n var size = bytes;\n var idx = 0;\n\n while (size >= 1024 && idx < units.length - 1) {\n size /= 1024;\n idx++;\n }\n\n return \"\".concat(idx === 0 ? size : size.toFixed(2), \" \").concat(units[idx]);\n },\n\n /**\n * 时间展示:ISO 本地时间去掉 T 分隔符\n */\n formatTime: function formatTime(time) {\n if (!time) return '-';\n return String(time).replace('T', ' ').replace(/\\+08:00$/, '').replace(/\\.\\d{3}/, '');\n },\n\n /**\n * 索引状态标签:0 未索引 / 1 已索引 / 2 索引中 / 3 失败\n */\n indexTagType: function indexTagType(status) {\n var map = {\n 0: 'info',\n 1: 'success',\n 2: 'warning',\n 3: 'danger'\n };\n return map[status] || 'info';\n },\n indexTagText: function indexTagText(status) {\n var map = {\n 0: '未索引',\n 1: '已索引',\n 2: '索引中',\n 3: '索引失败'\n };\n return map[status] || '未知';\n }\n }\n};\nexports.default = _default2;\n\n//# sourceURL=webpack://ZjPluginIntelligent/./src/lib/knowledgeBase/DocumentList.vue?./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options");
991
+ eval("\n\nvar _interopRequireWildcard = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireWildcard */ \"./node_modules/@babel/runtime/helpers/interopRequireWildcard.js\").default;\n\nvar _interopRequireDefault = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/interopRequireDefault */ \"./node_modules/@babel/runtime/helpers/interopRequireDefault.js\").default;\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/asyncToGenerator.js\"));\n\nvar _objectSpread2 = _interopRequireDefault(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/objectSpread2 */ \"./node_modules/@babel/runtime/helpers/objectSpread2.js\"));\n\nvar _marked = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n\nvar XLSX = _interopRequireWildcard(__webpack_require__(/*! xlsx */ \"./node_modules/xlsx/xlsx.mjs\"));\n\nvar _mammoth = _interopRequireDefault(__webpack_require__(/*! mammoth */ \"./node_modules/mammoth/lib/index.js\"));\n\nvar _knowledgeBase = __webpack_require__(/*! ./api/knowledgeBase */ \"./src/lib/knowledgeBase/api/knowledgeBase.js\");\n\nvar _DocumentForm = _interopRequireDefault(__webpack_require__(/*! ./DocumentForm */ \"./src/lib/knowledgeBase/DocumentForm.vue\"));\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n// 预览最多显示的行数(防止大文件卡死)\nvar MAX_PREVIEW_ROWS = 500;\nvar _default2 = {\n name: 'DocumentList',\n components: {\n DocumentForm: _DocumentForm.default\n },\n props: {\n selectedCategory: {\n type: Object,\n default: null\n },\n categoryList: {\n type: Array,\n default: function _default() {\n return [];\n }\n },\n companyId: {\n type: String,\n default: ''\n }\n },\n data: function data() {\n return {\n list: [],\n loading: false,\n total: 0,\n page: 1,\n pageSize: 10,\n searchKeyword: '',\n // 批量删除选中的文件\n selectedRows: [],\n // 批量移动\n moveVisible: false,\n moveFolderId: null,\n moving: false,\n folderList: [],\n folderTreeProps: {\n children: 'children',\n label: 'name'\n },\n // 在线预览\n previewVisible: false,\n previewFile: null,\n previewType: 'none',\n previewText: '',\n // PDF 预览(Blob URL 避免下载)\n pdfBlobUrl: '',\n // Excel 预览\n xlsxLoading: false,\n xlsxWorkbook: null,\n xlsxSheetNames: [],\n xlsxCurrentSheet: '',\n xlsxCols: [],\n xlsxTableData: [],\n hasMoreRows: false,\n // Word 预览\n docxLoading: false,\n docxHtml: ''\n };\n },\n computed: {\n /**\n * Markdown 渲染后的 HTML(使用 marked)\n */\n previewHtml: function previewHtml() {\n if (!this.previewText) return '';\n return _marked.marked.parse(this.previewText, {\n breaks: true,\n gfm: true\n });\n },\n maxPreviewRows: function maxPreviewRows() {\n return MAX_PREVIEW_ROWS;\n },\n\n /**\n * 批量移动的文件夹树(由平铺列表组装)\n */\n moveFolderTree: function moveFolderTree() {\n var nodes = this.folderList.map(function (f) {\n return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, f), {}, {\n children: []\n });\n });\n var map = {};\n nodes.forEach(function (n) {\n map[n.id] = n;\n });\n var roots = [];\n nodes.forEach(function (n) {\n var pid = n.parentId || 0;\n if (map[pid]) map[pid].children.push(n);else roots.push(n);\n });\n return roots;\n },\n\n /**\n * 目标文件夹名称\n */\n moveTargetName: function moveTargetName() {\n var _this = this;\n\n if (!this.moveFolderId) return '';\n var f = this.folderList.find(function (x) {\n return x.id === _this.moveFolderId;\n });\n return f ? f.name : '';\n }\n },\n watch: {\n selectedCategory: function selectedCategory() {\n this.page = 1;\n this.loadList();\n },\n companyId: function companyId() {\n this.page = 1;\n this.searchKeyword = '';\n this.list = [];\n this.total = 0;\n this.loadList();\n },\n\n /**\n * 预览弹窗关闭时清理 PDF Blob URL\n */\n previewVisible: function previewVisible(val) {\n if (!val && this.pdfBlobUrl) {\n URL.revokeObjectURL(this.pdfBlobUrl);\n this.pdfBlobUrl = '';\n }\n }\n },\n created: function created() {\n this.loadList();\n },\n methods: {\n loadList: function loadList() {\n var _this2 = this;\n\n if (!this.companyId) return;\n this.loading = true;\n var params = {\n companyId: this.companyId,\n pageNum: this.page,\n pageSize: this.pageSize\n }; // 选中具体文件夹时按文件夹过滤(\"显示全部文件\"时 id 为空串,不传)\n\n if (this.selectedCategory && this.selectedCategory.id) {\n params.folderId = this.selectedCategory.id;\n }\n\n if (this.searchKeyword) {\n params.keyword = this.searchKeyword;\n }\n\n (0, _knowledgeBase.getFileList)(params).then(function (data) {\n _this2.list = data.records || [];\n _this2.total = data.total || 0; // 列表刷新后清空勾选\n\n _this2.selectedRows = [];\n\n _this2.$nextTick(function () {\n if (_this2.$refs.tableRef) _this2.$refs.tableRef.clearSelection();\n });\n }).catch(function () {}).finally(function () {\n _this2.loading = false;\n });\n },\n handleSearch: function handleSearch() {\n this.page = 1;\n this.loadList();\n },\n handleSizeChange: function handleSizeChange(size) {\n this.pageSize = size;\n this.page = 1;\n this.loadList();\n },\n handleCurrentChange: function handleCurrentChange(page) {\n this.page = page;\n this.loadList();\n },\n\n /**\n * 删除文件后刷新列表:若当前页因删除而超出最大页数(如某页只剩 1 条被删掉),\n * 自动回退到最后一页(即上一页),避免停留在空白页。\n */\n handleDeleted: function handleDeleted() {\n var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n var newTotal = Math.max(0, this.total - count);\n var maxPage = Math.max(1, Math.ceil(newTotal / this.pageSize));\n\n if (this.page > maxPage) {\n this.page = maxPage;\n }\n\n this.loadList();\n },\n handleAdd: function handleAdd() {\n var _this3 = this;\n\n if (!this.companyId) {\n this.$message.warning('公司数据未加载,请稍后刷新');\n return;\n }\n\n if (!this.categoryList || this.categoryList.length === 0) {\n this.$message.warning('暂无根目录,请先创建文件夹再新增文档');\n return;\n }\n\n var folderId = this.selectedCategory && this.selectedCategory.id ? this.selectedCategory.id : '';\n this.$refs.docFormRef.openAdd(folderId).then(function (res) {\n if (res) _this3.loadList();\n });\n },\n handleEdit: function handleEdit(row) {\n var _this4 = this;\n\n this.$refs.docFormRef.openEdit(row).then(function (res) {\n if (res) _this4.loadList();\n });\n },\n\n /**\n * 在线预览:图片 / PDF / Excel / Word / 文本\n */\n handlePreview: function handlePreview(row) {\n var _this5 = this;\n\n this.previewFile = row;\n this.previewText = '';\n this.docxHtml = '';\n this.xlsxWorkbook = null;\n this.xlsxSheetNames = [];\n this.xlsxCurrentSheet = '';\n this.xlsxCols = [];\n this.xlsxTableData = []; // 清理上一次的 PDF Blob URL\n\n if (this.pdfBlobUrl) {\n URL.revokeObjectURL(this.pdfBlobUrl);\n this.pdfBlobUrl = '';\n }\n\n var t = (row.fileType || '').toLowerCase();\n\n if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].includes(t)) {\n this.previewType = 'image';\n } else if (t === 'pdf') {\n this.previewType = 'pdf';\n this.loadPdfPreview(row);\n } else if (t === 'xlsx' || t === 'xls') {\n this.previewType = 'xlsx';\n this.loadXlsxPreview(row);\n } else if (t === 'docx' || t === 'doc') {\n this.previewType = 'docx';\n this.loadDocxPreview(row);\n } else if (['txt', 'md', 'markdown', 'html', 'htm'].includes(t)) {\n this.previewType = 'text';\n (0, _knowledgeBase.getFileDetail)(row.id).then(function (d) {\n _this5.previewText = d.content || '(该文件暂无可预览的文本内容)';\n }).catch(function () {\n _this5.previewText = '(文本内容加载失败)';\n });\n } else {\n this.previewType = 'none';\n }\n\n this.previewVisible = true;\n },\n // ==================== Excel 预览 ====================\n loadXlsxPreview: function loadXlsxPreview(file) {\n var _this6 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n var detail, fileUrl, response, ab, workbook;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _this6.xlsxLoading = true;\n _context.prev = 1;\n _context.next = 4;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 4:\n detail = _context.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context.next = 9;\n break;\n }\n\n _this6.$message.warning('无法获取文件下载地址');\n\n return _context.abrupt(\"return\");\n\n case 9:\n _context.next = 11;\n return fetch(fileUrl);\n\n case 11:\n response = _context.sent;\n\n if (response.ok) {\n _context.next = 14;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 14:\n _context.next = 16;\n return response.arrayBuffer();\n\n case 16:\n ab = _context.sent;\n _context.next = 19;\n return new Promise(function (r) {\n return setTimeout(r, 0);\n });\n\n case 19:\n workbook = XLSX.read(ab, {\n type: 'array'\n });\n _this6.xlsxWorkbook = workbook;\n _this6.xlsxSheetNames = workbook.SheetNames;\n\n if (workbook.SheetNames.length > 0) {\n _this6.xlsxCurrentSheet = workbook.SheetNames[0];\n\n _this6.renderXlsxSheet();\n }\n\n _context.next = 29;\n break;\n\n case 25:\n _context.prev = 25;\n _context.t0 = _context[\"catch\"](1);\n console.error('加载 Excel 文件失败', _context.t0);\n\n _this6.$message.error('Excel 文件加载失败');\n\n case 29:\n _context.prev = 29;\n _this6.xlsxLoading = false;\n return _context.finish(29);\n\n case 32:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, null, [[1, 25, 29, 32]]);\n }))();\n },\n renderXlsxSheet: function renderXlsxSheet() {\n var workbook = this.xlsxWorkbook;\n var sheetName = this.xlsxCurrentSheet;\n if (!workbook || !sheetName) return;\n var sheet = workbook.Sheets[sheetName];\n\n if (!sheet) {\n this.xlsxCols = [];\n this.xlsxTableData = [];\n return;\n } // 让出主线程,防止 sheet_to_json 阻塞 UI\n\n\n var data = XLSX.utils.sheet_to_json(sheet, {\n header: 1,\n defval: ''\n });\n\n if (data.length === 0) {\n this.xlsxCols = [];\n this.xlsxTableData = [];\n return;\n } // 列数以「所有行的最大宽度」为准:表头行可能只填了第一格,若直接按第一行长度定列会丢失后续列\n\n\n var maxCols = Math.max.apply(null, data.map(function (row) {\n return row && row.length || 0;\n }));\n this.xlsxCols = Array.from({\n length: maxCols\n }, function (_, i) {\n var v = data[0] && data[0][i];\n return v != null && String(v).trim() !== '' ? String(v) : \"\\u5217\".concat(i + 1);\n }); // 限制预览行数,防止渲染过多 DOM 卡死;同时过滤全空行\n\n var allRows = data.slice(1).filter(function (row) {\n return row && row.some(function (c) {\n return c != null && String(c).trim() !== '';\n });\n });\n this.hasMoreRows = allRows.length > MAX_PREVIEW_ROWS;\n this.xlsxTableData = allRows.slice(0, MAX_PREVIEW_ROWS).map(function (row) {\n var obj = {};\n\n for (var ci = 0; ci < maxCols; ci++) {\n obj[ci] = row[ci] != null ? String(row[ci]) : '';\n }\n\n return obj;\n });\n },\n // ==================== Word 预览 ====================\n loadDocxPreview: function loadDocxPreview(file) {\n var _this7 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {\n var detail, fileUrl, response, ab, result;\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _this7.docxLoading = true;\n _context2.prev = 1;\n _context2.next = 4;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 4:\n detail = _context2.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context2.next = 9;\n break;\n }\n\n _this7.$message.warning('无法获取文件下载地址');\n\n return _context2.abrupt(\"return\");\n\n case 9:\n _context2.next = 11;\n return fetch(fileUrl);\n\n case 11:\n response = _context2.sent;\n\n if (response.ok) {\n _context2.next = 14;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 14:\n _context2.next = 16;\n return response.arrayBuffer();\n\n case 16:\n ab = _context2.sent;\n\n if (ab.byteLength) {\n _context2.next = 20;\n break;\n }\n\n _this7.docxHtml = '<p>(空文档)</p>';\n return _context2.abrupt(\"return\");\n\n case 20:\n _context2.next = 22;\n return _mammoth.default.convertToHtml({\n arrayBuffer: ab\n });\n\n case 22:\n result = _context2.sent;\n _this7.docxHtml = result.value || '<p>(空文档)</p>';\n _context2.next = 30;\n break;\n\n case 26:\n _context2.prev = 26;\n _context2.t0 = _context2[\"catch\"](1);\n console.error('加载 Word 文件失败', _context2.t0);\n\n _this7.$message.error('Word 文件加载失败');\n\n case 30:\n _context2.prev = 30;\n _this7.docxLoading = false;\n return _context2.finish(30);\n\n case 33:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2, null, [[1, 26, 30, 33]]);\n }))();\n },\n // ==================== PDF 预览 ====================\n loadPdfPreview: function loadPdfPreview(file) {\n var _this8 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {\n var detail, fileUrl, response, blob;\n return regeneratorRuntime.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _context3.prev = 0;\n _context3.next = 3;\n return (0, _knowledgeBase.getFileDetail)(file.id);\n\n case 3:\n detail = _context3.sent;\n fileUrl = detail.fileUrl || file.fileUrl;\n\n if (fileUrl) {\n _context3.next = 8;\n break;\n }\n\n _this8.$message.warning('无法获取文件下载地址');\n\n return _context3.abrupt(\"return\");\n\n case 8:\n _context3.next = 10;\n return fetch(fileUrl);\n\n case 10:\n response = _context3.sent;\n\n if (response.ok) {\n _context3.next = 13;\n break;\n }\n\n throw new Error('下载文件失败');\n\n case 13:\n _context3.next = 15;\n return response.blob();\n\n case 15:\n blob = _context3.sent;\n _this8.pdfBlobUrl = URL.createObjectURL(blob);\n _context3.next = 23;\n break;\n\n case 19:\n _context3.prev = 19;\n _context3.t0 = _context3[\"catch\"](0);\n console.error('加载 PDF 文件失败', _context3.t0);\n\n _this8.$message.error('PDF 文件加载失败');\n\n case 23:\n case \"end\":\n return _context3.stop();\n }\n }\n }, _callee3, null, [[0, 19]]);\n }))();\n },\n\n /**\n * 索引 / 重建索引(二次确认)\n */\n handleIndex: function handleIndex(row) {\n var _this9 = this;\n\n var isRebuild = row.indexStatus === 1;\n console.log('[DocumentList] 索引文件:', row.id, row.title, 'companyId:', this.companyId);\n this.$confirm(\"\\u786E\\u8BA4\\u5BF9\\u6587\\u4EF6\\u300C\".concat(row.title || row.fileName, \"\\u300D\").concat(isRebuild ? '重建' : '创建', \"\\u7D22\\u5F15\\uFF1F\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定',\n cancelButtonText: '取消'\n }).then(function () {\n var request = isRebuild ? (0, _knowledgeBase.reindexFile)(row.id) : (0, _knowledgeBase.indexFile)(row.id);\n request.then(function () {\n _this9.$message.success(isRebuild ? '已开始重建索引' : '已开始索引');\n\n _this9.loadList();\n }).catch(function () {});\n }).catch(function () {});\n },\n\n /**\n * 删除索引(二次确认)\n */\n handleDeleteIndex: function handleDeleteIndex(row) {\n var _this10 = this;\n\n this.$confirm(\"\\u786E\\u8BA4\\u5220\\u9664\\u6587\\u4EF6\\u300C\".concat(row.title || row.fileName, \"\\u300D\\u7684\\u7D22\\u5F15\\uFF1F\\u5220\\u9664\\u540E\\u65E0\\u6CD5\\u6062\\u590D\\u3002\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定删除',\n cancelButtonText: '取消'\n }).then(function () {\n (0, _knowledgeBase.deleteFileIndex)(row.id).then(function () {\n _this10.$message.success('索引已删除');\n\n _this10.loadList();\n }).catch(function () {});\n }).catch(function () {});\n },\n handleDelete: function handleDelete(row) {\n var _this11 = this;\n\n // 索引中的文件不允许删除\n if (row.indexStatus === 2) {\n this.$message.warning('该文件正在索引中,无法删除');\n return;\n }\n\n var hasIndex = row.indexStatus === 1;\n this.$confirm(\"\\u786E\\u8BA4\\u5220\\u9664\\u6587\\u4EF6\\u300C\".concat(row.title || row.fileName, \"\\u300D\\uFF1F\").concat(hasIndex ? '删除文件前会先删除该文件的索引。' : '', \"\\u5220\\u9664\\u540E\\u65E0\\u6CD5\\u6062\\u590D\\u3002\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定删除',\n cancelButtonText: '取消'\n }).then( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {\n return regeneratorRuntime.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.prev = 0;\n\n if (!hasIndex) {\n _context4.next = 4;\n break;\n }\n\n _context4.next = 4;\n return (0, _knowledgeBase.deleteFileIndex)(row.id);\n\n case 4:\n _context4.next = 6;\n return (0, _knowledgeBase.deleteFile)(row.id);\n\n case 6:\n _this11.$message.success('文件已删除');\n\n _this11.handleDeleted(1);\n\n _context4.next = 12;\n break;\n\n case 10:\n _context4.prev = 10;\n _context4.t0 = _context4[\"catch\"](0);\n\n case 12:\n case \"end\":\n return _context4.stop();\n }\n }\n }, _callee4, null, [[0, 10]]);\n }))).catch(function () {});\n },\n\n /**\n * 表格勾选变化\n */\n handleSelectionChange: function handleSelectionChange(rows) {\n this.selectedRows = rows || [];\n },\n\n /**\n * 索引中的文件不可勾选删除\n */\n rowSelectable: function rowSelectable(row) {\n return row.indexStatus !== 2;\n },\n\n /**\n * 批量删除勾选的文件\n */\n handleBatchDelete: function handleBatchDelete() {\n var _this12 = this;\n\n var selected = this.selectedRows || [];\n\n if (!selected.length) {\n this.$message.warning('请先勾选要删除的文件');\n return;\n } // 索引中的文件不允许删除\n\n\n var indexingFiles = selected.filter(function (f) {\n return f.indexStatus === 2;\n });\n var deletable = selected.filter(function (f) {\n return f.indexStatus !== 2;\n });\n\n if (!deletable.length) {\n this.$message.warning('所选文件均正在索引中,无法删除');\n return;\n }\n\n if (indexingFiles.length) {\n this.$message.warning(\"\\u6709 \".concat(indexingFiles.length, \" \\u4E2A\\u6587\\u4EF6\\u6B63\\u5728\\u7D22\\u5F15\\u4E2D\\uFF0C\\u672C\\u6B21\\u5C06\\u8DF3\\u8FC7\"));\n } // 已索引的文件需先删除索引,再删除文件\n\n\n var indexed = deletable.filter(function (f) {\n return f.indexStatus === 1;\n });\n var ids = deletable.map(function (f) {\n return f.id;\n });\n this.$confirm(\"\\u786E\\u8BA4\\u5220\\u9664\\u9009\\u4E2D\\u7684 \".concat(deletable.length, \" \\u4E2A\\u6587\\u4EF6\\uFF1F\").concat(indexed.length ? '删除前会先删除这些文件的索引。' : '', \"\\u5220\\u9664\\u540E\\u65E0\\u6CD5\\u6062\\u590D\\u3002\"), '提示', {\n type: 'warning',\n confirmButtonText: '确定删除',\n cancelButtonText: '取消',\n customClass: 'kb-message-box'\n }).then( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {\n return regeneratorRuntime.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n _context5.prev = 0;\n\n if (!indexed.length) {\n _context5.next = 4;\n break;\n }\n\n _context5.next = 4;\n return Promise.all(indexed.map(function (f) {\n return (0, _knowledgeBase.deleteFileIndex)(f.id);\n }));\n\n case 4:\n _context5.next = 6;\n return (0, _knowledgeBase.deleteFiles)(ids);\n\n case 6:\n _this12.$message.success('批量删除成功');\n\n _this12.handleDeleted(deletable.length);\n\n _context5.next = 12;\n break;\n\n case 10:\n _context5.prev = 10;\n _context5.t0 = _context5[\"catch\"](0);\n\n case 12:\n case \"end\":\n return _context5.stop();\n }\n }\n }, _callee5, null, [[0, 10]]);\n }))).catch(function () {});\n },\n\n /**\n * 批量移动:打开目标文件夹选择弹窗\n */\n handleBatchMove: function handleBatchMove() {\n var _this13 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {\n var selected, folders;\n return regeneratorRuntime.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n selected = _this13.selectedRows || [];\n\n if (selected.length) {\n _context6.next = 4;\n break;\n }\n\n _this13.$message.warning('请先勾选要移动的文件');\n\n return _context6.abrupt(\"return\");\n\n case 4:\n if (_this13.companyId) {\n _context6.next = 7;\n break;\n }\n\n _this13.$message.warning('公司数据未加载');\n\n return _context6.abrupt(\"return\");\n\n case 7:\n _this13.moveFolderId = null;\n _this13.moveVisible = true; // 每次打开都重新加载文件夹列表,确保新建/重命名/删除文件夹后看到最新目录\n\n _context6.prev = 9;\n _context6.next = 12;\n return (0, _knowledgeBase.getFolderList)(_this13.companyId);\n\n case 12:\n folders = _context6.sent;\n _this13.folderList = folders || [];\n _context6.next = 18;\n break;\n\n case 16:\n _context6.prev = 16;\n _context6.t0 = _context6[\"catch\"](9);\n\n case 18:\n _this13.$nextTick(function () {\n if (_this13.$refs.moveTreeRef) _this13.$refs.moveTreeRef.setCurrentKey(null);\n });\n\n case 19:\n case \"end\":\n return _context6.stop();\n }\n }\n }, _callee6, null, [[9, 16]]);\n }))();\n },\n\n /**\n * 选择目标文件夹\n */\n handleMoveFolderSelect: function handleMoveFolderSelect(data) {\n this.moveFolderId = data.id;\n },\n\n /**\n * 确认批量移动\n */\n handleMoveConfirm: function handleMoveConfirm() {\n var _this14 = this;\n\n return (0, _asyncToGenerator2.default)( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {\n var ids, targetFolder;\n return regeneratorRuntime.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n if (_this14.moveFolderId) {\n _context7.next = 3;\n break;\n }\n\n _this14.$message.warning('请选择目标文件夹');\n\n return _context7.abrupt(\"return\");\n\n case 3:\n ids = _this14.selectedRows.map(function (f) {\n return f.id;\n });\n _this14.moving = true;\n _context7.prev = 5;\n _context7.next = 8;\n return (0, _knowledgeBase.moveFiles)(ids, _this14.moveFolderId);\n\n case 8:\n _this14.$message.success('批量移动成功');\n\n _this14.moveVisible = false; // 移动成功后,通知父级定位并高亮左侧树到目标文件夹\n\n targetFolder = _this14.folderList.find(function (f) {\n return String(f.id) === String(_this14.moveFolderId);\n }) || null;\n if (targetFolder) _this14.$emit('move-target', targetFolder);else _this14.$emit('move-target', {\n id: _this14.moveFolderId,\n name: _this14.moveTargetName\n });\n\n _this14.loadList();\n\n _context7.next = 17;\n break;\n\n case 15:\n _context7.prev = 15;\n _context7.t0 = _context7[\"catch\"](5);\n\n case 17:\n _context7.prev = 17;\n _this14.moving = false;\n return _context7.finish(17);\n\n case 20:\n case \"end\":\n return _context7.stop();\n }\n }\n }, _callee7, null, [[5, 15, 17, 20]]);\n }))();\n },\n\n /**\n * 通过 folderId 映射文件夹名称\n */\n folderName: function folderName(folderId) {\n if (!folderId) return '根目录';\n var found = this.categoryList.find(function (f) {\n return String(f.id) === String(folderId);\n });\n return found ? found.name : '-';\n },\n\n /**\n * 根据文件类型返回对应图标\n */\n getFileIcon: function getFileIcon(fileType) {\n var type = (fileType || '').toLowerCase();\n var iconMap = {\n pdf: 'el-icon-document',\n doc: 'el-icon-document',\n docx: 'el-icon-document',\n xls: 'el-icon-tickets',\n xlsx: 'el-icon-tickets',\n ppt: 'el-icon-data-line',\n pptx: 'el-icon-data-line',\n txt: 'el-icon-document',\n md: 'el-icon-edit-outline',\n png: 'el-icon-picture',\n jpg: 'el-icon-picture',\n jpeg: 'el-icon-picture',\n gif: 'el-icon-picture',\n zip: 'el-icon-folder-opened',\n rar: 'el-icon-folder-opened'\n };\n return iconMap[type] || 'el-icon-document';\n },\n\n /**\n * 根据文件类型返回对应的图标 URL\n */\n getFileIconUrl: function getFileIconUrl(fileType) {\n var type = (fileType || '').toLowerCase();\n var base = 'https://qiguanbang-client.obs.cn-east-3.myhuaweicloud.com/fileimgdoc';\n var generic = \"\".concat(base, \"/\\u901A\\u7528.png\"); // 通用文档 / 云文档(无专属图标时使用通用图片兜底)\n\n var genericTypes = ['md', 'markdown', 'html', 'htm', 'docx2', 'rtf'];\n var urlMap = {\n // 图片格式(jpg/png/jpeg 等)\n jpg: \"\".concat(base, \"/png.png\"),\n jpeg: \"\".concat(base, \"/png.png\"),\n png: \"\".concat(base, \"/png.png\"),\n gif: \"\".concat(base, \"/png.png\"),\n webp: \"\".concat(base, \"/png.png\"),\n bmp: \"\".concat(base, \"/png.png\"),\n // Excel 表格(xlsx/xls)\n xlsx: \"\".concat(base, \"/xlsx.png\"),\n xls: \"\".concat(base, \"/xlsx.png\"),\n csv: \"\".concat(base, \"/xlsx.png\"),\n // PDF 文档\n pdf: \"\".concat(base, \"/pdf.png\"),\n // 压缩包(zip/rar)\n zip: \"\".concat(base, \"/zip.png\"),\n rar: \"\".concat(base, \"/zip.png\"),\n '7z': \"\".concat(base, \"/zip.png\"),\n gz: \"\".concat(base, \"/zip.png\"),\n tar: \"\".concat(base, \"/zip.png\"),\n // Word 文档(docx/doc)\n docx: \"\".concat(base, \"/word.png\"),\n doc: \"\".concat(base, \"/word.png\"),\n // TXT 文本文件\n txt: \"\".concat(base, \"/txt.png\"),\n // PPT 演示文稿(pptx/ppt)\n pptx: \"\".concat(base, \"/ppt.png\"),\n ppt: \"\".concat(base, \"/ppt.png\"),\n // 视频文件\n mp4: \"\".concat(base, \"/mp4.png\"),\n avi: \"\".concat(base, \"/mp4.png\"),\n mov: \"\".concat(base, \"/mp4.png\"),\n wmv: \"\".concat(base, \"/mp4.png\"),\n flv: \"\".concat(base, \"/mp4.png\"),\n mkv: \"\".concat(base, \"/mp4.png\"),\n // 音频文件(mp3 等)\n mp3: \"\".concat(base, \"/mp3.png\"),\n wav: \"\".concat(base, \"/mp3.png\"),\n flac: \"\".concat(base, \"/mp3.png\"),\n aac: \"\".concat(base, \"/mp3.png\"),\n ogg: \"\".concat(base, \"/mp3.png\"),\n m4a: \"\".concat(base, \"/mp3.png\")\n };\n return (genericTypes.includes(type) ? generic : urlMap[type]) || generic;\n },\n\n /**\n * 文件大小格式化(字节 → B/KB/MB/GB)\n */\n formatSize: function formatSize(bytes) {\n if (!bytes && bytes !== 0) return '-';\n if (bytes === 0) return '0 B';\n var units = ['B', 'KB', 'MB', 'GB', 'TB'];\n var size = bytes;\n var idx = 0;\n\n while (size >= 1024 && idx < units.length - 1) {\n size /= 1024;\n idx++;\n }\n\n return \"\".concat(idx === 0 ? size : size.toFixed(2), \" \").concat(units[idx]);\n },\n\n /**\n * 时间展示:ISO 本地时间去掉 T 分隔符\n */\n formatTime: function formatTime(time) {\n if (!time) return '-';\n return String(time).replace('T', ' ').replace(/\\+08:00$/, '').replace(/\\.\\d{3}/, '');\n },\n\n /**\n * 索引状态标签:0 未索引 / 1 已索引 / 2 索引中 / 3 失败\n */\n indexTagType: function indexTagType(status) {\n var map = {\n 0: 'info',\n 1: 'success',\n 2: 'warning',\n 3: 'danger'\n };\n return map[status] || 'info';\n },\n indexTagText: function indexTagText(status) {\n var map = {\n 0: '未索引',\n 1: '已索引',\n 2: '索引中',\n 3: '索引失败'\n };\n return map[status] || '未知';\n }\n }\n};\nexports.default = _default2;\n\n//# sourceURL=webpack://ZjPluginIntelligent/./src/lib/knowledgeBase/DocumentList.vue?./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options");
992
992
 
993
993
  /***/ }),
994
994
 
@@ -14633,7 +14633,7 @@ eval("// Generated by CoffeeScript 1.12.7\n(function() {\n var XMLDocument, XML
14633
14633
  /*! exports provided: name, version, main, private, scripts, dependencies, devDependencies, browserslist, directories, keywords, license, files, default */
14634
14634
  /***/ (function(module) {
14635
14635
 
14636
- eval("module.exports = JSON.parse(\"{\\\"name\\\":\\\"zj-plugin-intelligent\\\",\\\"version\\\":\\\"1.2.12-beta.14\\\",\\\"main\\\":\\\"lib/ZjPluginIntelligent.umd.min.js\\\",\\\"private\\\":false,\\\"scripts\\\":{\\\"serve\\\":\\\"set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve\\\",\\\"build\\\":\\\"set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build\\\",\\\"lib\\\":\\\"node scripts/build-lib.js\\\",\\\"lib:test\\\":\\\"node scripts/build-lib.js test\\\"},\\\"dependencies\\\":{\\\"@jboltai/tokui\\\":\\\"^0.1.6\\\",\\\"crypto-js\\\":\\\"^4.2.0\\\",\\\"docx\\\":\\\"^8.5.0\\\",\\\"html2canvas\\\":\\\"^1.4.1\\\",\\\"mammoth\\\":\\\"^1.6.0\\\",\\\"markdown-it\\\":\\\"^13.0.2\\\",\\\"marked\\\":\\\"^4.3.0\\\",\\\"xlsx\\\":\\\"^0.18.5\\\"},\\\"devDependencies\\\":{\\\"@babel/preset-env\\\":\\\"^7.14.9\\\",\\\"@vue/cli-plugin-babel\\\":\\\"~4.5.0\\\",\\\"@vue/cli-plugin-eslint\\\":\\\"~4.5.0\\\",\\\"@vue/cli-plugin-vuex\\\":\\\"~4.5.0\\\",\\\"@vue/cli-service\\\":\\\"~4.5.0\\\",\\\"axios\\\":\\\"^0.27.2\\\",\\\"babel-eslint\\\":\\\"^10.1.0\\\",\\\"babel-plugin-component\\\":\\\"^1.1.1\\\",\\\"compression-webpack-plugin\\\":\\\"^6.0.3\\\",\\\"core-js\\\":\\\"^3.6.5\\\",\\\"element-ui\\\":\\\"^2.15.4\\\",\\\"eslint\\\":\\\"^6.8.0\\\",\\\"eslint-plugin-vue\\\":\\\"^7.13.0\\\",\\\"js-cookie\\\":\\\"^2.2.1\\\",\\\"obs-upload\\\":\\\"^1.0.4\\\",\\\"pako\\\":\\\"^2.1.0\\\",\\\"reconnecting-websocket\\\":\\\"^4.4.0\\\",\\\"sass\\\":\\\"^1.71.0\\\",\\\"sass-loader\\\":\\\"^8.0.2\\\",\\\"snowflake-id\\\":\\\"^1.1.0\\\",\\\"vue\\\":\\\"^2.6.11\\\",\\\"vue-template-compiler\\\":\\\"^2.6.11\\\",\\\"vuex\\\":\\\"^3.4.0\\\",\\\"webpack-bundle-analyzer\\\":\\\"^4.4.2\\\"},\\\"browserslist\\\":[\\\"> 1%\\\",\\\"last 2 versions\\\",\\\"not dead\\\"],\\\"directories\\\":{\\\"lib\\\":\\\"lib\\\"},\\\"keywords\\\":[],\\\"license\\\":\\\"ISC\\\",\\\"files\\\":[\\\"lib\\\"]}\");\n\n//# sourceURL=webpack://ZjPluginIntelligent/./package.json?");
14636
+ eval("module.exports = JSON.parse(\"{\\\"name\\\":\\\"zj-plugin-intelligent\\\",\\\"version\\\":\\\"1.2.12-beta.15\\\",\\\"main\\\":\\\"lib/ZjPluginIntelligent.umd.min.js\\\",\\\"private\\\":false,\\\"scripts\\\":{\\\"serve\\\":\\\"set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve\\\",\\\"build\\\":\\\"set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build\\\",\\\"lib\\\":\\\"node scripts/build-lib.js\\\",\\\"lib:test\\\":\\\"node scripts/build-lib.js test\\\"},\\\"dependencies\\\":{\\\"@jboltai/tokui\\\":\\\"^0.1.6\\\",\\\"crypto-js\\\":\\\"^4.2.0\\\",\\\"docx\\\":\\\"^8.5.0\\\",\\\"html2canvas\\\":\\\"^1.4.1\\\",\\\"mammoth\\\":\\\"^1.6.0\\\",\\\"markdown-it\\\":\\\"^13.0.2\\\",\\\"marked\\\":\\\"^4.3.0\\\",\\\"xlsx\\\":\\\"^0.18.5\\\"},\\\"devDependencies\\\":{\\\"@babel/preset-env\\\":\\\"^7.14.9\\\",\\\"@vue/cli-plugin-babel\\\":\\\"~4.5.0\\\",\\\"@vue/cli-plugin-eslint\\\":\\\"~4.5.0\\\",\\\"@vue/cli-plugin-vuex\\\":\\\"~4.5.0\\\",\\\"@vue/cli-service\\\":\\\"~4.5.0\\\",\\\"axios\\\":\\\"^0.27.2\\\",\\\"babel-eslint\\\":\\\"^10.1.0\\\",\\\"babel-plugin-component\\\":\\\"^1.1.1\\\",\\\"compression-webpack-plugin\\\":\\\"^6.0.3\\\",\\\"core-js\\\":\\\"^3.6.5\\\",\\\"element-ui\\\":\\\"^2.15.4\\\",\\\"eslint\\\":\\\"^6.8.0\\\",\\\"eslint-plugin-vue\\\":\\\"^7.13.0\\\",\\\"js-cookie\\\":\\\"^2.2.1\\\",\\\"obs-upload\\\":\\\"^1.0.4\\\",\\\"pako\\\":\\\"^2.1.0\\\",\\\"reconnecting-websocket\\\":\\\"^4.4.0\\\",\\\"sass\\\":\\\"^1.71.0\\\",\\\"sass-loader\\\":\\\"^8.0.2\\\",\\\"snowflake-id\\\":\\\"^1.1.0\\\",\\\"vue\\\":\\\"^2.6.11\\\",\\\"vue-template-compiler\\\":\\\"^2.6.11\\\",\\\"vuex\\\":\\\"^3.4.0\\\",\\\"webpack-bundle-analyzer\\\":\\\"^4.4.2\\\"},\\\"browserslist\\\":[\\\"> 1%\\\",\\\"last 2 versions\\\",\\\"not dead\\\"],\\\"directories\\\":{\\\"lib\\\":\\\"lib\\\"},\\\"keywords\\\":[],\\\"license\\\":\\\"ISC\\\",\\\"files\\\":[\\\"lib\\\"]}\");\n\n//# sourceURL=webpack://ZjPluginIntelligent/./package.json?");
14637
14637
 
14638
14638
  /***/ }),
14639
14639