Browse Source

导入文件夹

small-tupu
hanyuqing 6 months ago
parent
commit
faeeaf5e79
  1. 87
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/FolderUploadController.java
  2. 36
      ruoyi-api/src/main/java/com/ruoyi/api/service/impl/BuildService.java
  3. 10
      ruoyi-ui/src/api/system/file.js
  4. 206
      ruoyi-ui/src/views/system/fileManage/index.vue

87
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/FolderUploadController.java

@ -1,5 +1,6 @@
package com.ruoyi.web.controller.tool;
import com.ruoyi.api.domain.ESDao;
import com.ruoyi.api.service.impl.ESService;
import com.ruoyi.common.utils.Neo4jUtil;
import com.ruoyi.system.domain.ZhyArticle;
@ -50,6 +51,10 @@ public class FolderUploadController {
if (file.isEmpty()) continue;
String relativePath = file.getOriginalFilename();
if (!relativePath.toLowerCase().endsWith(".txt")) {
System.out.println("⚠️ 跳过非 txt 文件: " + relativePath);
continue; // 跳过非 txt 文件
}
File destFile = new File(UPLOAD_DIR + relativePath);
destFile.getParentFile().mkdirs();
@ -87,7 +92,7 @@ public class FolderUploadController {
}
}
public void create(String filePath){
public void create(String filePath) throws IOException {
System.out.println("start");
// 1. 获取文件路径
String filePath1 =ARTICLE_DIR;
@ -232,7 +237,7 @@ public class FolderUploadController {
String[] keywords=nameWithoutExt.split("_");
return Arrays.asList(keywords);
}
public void createRelation1(String parentValue,String childValue,ZhyArticle data,String local){
public void createRelation1(String parentValue,String childValue,ZhyArticle data,String local) throws IOException {
ZhyDoc doc1 = test1Mapper.selectDocByTitle(parentValue);
ZhyDoc doc2 = test1Mapper.selectDocByTitle(childValue);
if (doc1 != null && doc2 != null) {
@ -275,7 +280,37 @@ public class FolderUploadController {
zz.setArticleId(article.getId());
System.out.println(zz);
zhyDocRelationMapper.insertZhyRelationship(zz);
List<String> ids = new ArrayList<>();
ids.add(String.valueOf(zz.getId()));
ESDao esDao = new ESDao();
esDao.id = article.getId().toString();
esDao.DBid = article.getId().toString();
esDao.type = "line";
if(article.getLocalUrl()!=null){
System.out.println("333333");
try {
String txt=article.getLocalUrl().replace("pdf", "txt");
List<String> content = extractContentUntilSecondPage(txt);
if (content != null) {
// 打印结果
for (String line : content) {
System.out.println(line);
}
String result = String.join("", content);
esDao.abstracts = result;
} else {
System.out.println("未找到相关内容或文件不存在。");
esDao.abstracts = article.getName()+article.getKeywords()+article.getSummary();
}
} catch (IOException e) {
e.printStackTrace();
esDao.abstracts = article.getName()+article.getKeywords()+article.getSummary();
}
}else{
esDao.abstracts = article.getName()+article.getKeywords()+article.getSummary();
}
esDao.data = ids.toString();
esService.insertDocById("links",esDao);
}
// 4. 批量创建 Neo4j 关系
List<ZhyDocRelation> listR = zhyDocRelationMapper.getAllRelation();
@ -289,5 +324,51 @@ public class FolderUploadController {
}
}
public List<String> extractContentUntilSecondPage(String filePath) throws IOException {
File file = new File(filePath);
// 检查文件是否存在
if (!file.exists() || !file.isFile()) {
System.out.println("文件不存在: " + filePath);
return null;
}
List<String> lines = new ArrayList<>();
boolean foundFirstPage = false;
boolean reachedSecondPage = false;
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("【第 1 页】")) {
foundFirstPage = true;
}
if (foundFirstPage && line.contains("【第 2 页】")) {
reachedSecondPage = true;
break; // 停止读取
}
if (foundFirstPage) {
lines.add(line);
}
}
}
if (!foundFirstPage) {
System.out.println("未找到【第 1 页】标记");
return null;
}
if (!reachedSecondPage) {
System.out.println("未找到【第 2 页】标记");
return null;
}
// 移除最后一行(即【第 2 页】这一行)
lines.remove(lines.size() - 1);
return lines;
}
}

36
ruoyi-api/src/main/java/com/ruoyi/api/service/impl/BuildService.java

@ -213,7 +213,7 @@ public class BuildService {
}
public void create1(Map<String,String> thesis){
public void create1(Map<String,String> thesis) throws IOException {
// 1. 获取文件路径
String filePath = (String) thesis.get("url");
String filePath1 =ARTICLE_DIR;
@ -349,7 +349,7 @@ public class BuildService {
}
public void createRelation1(String parentValue,String childValue,ZhyArticle data,String local){
public void createRelation1(String parentValue,String childValue,ZhyArticle data,String local) throws IOException {
ZhyDoc doc1 = test1Mapper.selectDocByTitle(parentValue);
ZhyDoc doc2 = test1Mapper.selectDocByTitle(childValue);
if (doc1 != null && doc2 != null) {
@ -392,7 +392,37 @@ public class BuildService {
zz.setArticleId(article.getId());
System.out.println(zz);
zhyDocRelationMapper.insertZhyRelationship(zz);
List<String> ids = new ArrayList<>();
ids.add(String.valueOf(zz.getId()));
ESDao esDao = new ESDao();
esDao.id = article.getId().toString();
esDao.DBid = article.getId().toString();
esDao.type = "line";
if(article.getLocalUrl()!=null){
System.out.println("333333");
try {
String txt=article.getLocalUrl().replace("pdf", "txt");
List<String> content = extractContentUntilSecondPage(txt);
if (content != null) {
// 打印结果
for (String line : content) {
System.out.println(line);
}
String result = String.join("", content);
esDao.abstracts = result;
} else {
System.out.println("未找到相关内容或文件不存在。");
esDao.abstracts = article.getName()+article.getKeywords()+article.getSummary();
}
} catch (IOException e) {
e.printStackTrace();
esDao.abstracts = article.getName()+article.getKeywords()+article.getSummary();
}
}else{
esDao.abstracts = article.getName()+article.getKeywords()+article.getSummary();
}
esDao.data = ids.toString();
esService.insertDocById("links",esDao);
}
// 4. 批量创建 Neo4j 关系
List<ZhyDocRelation> listR = zhyDocRelationMapper.getAllRelation();

10
ruoyi-ui/src/api/system/file.js

@ -207,3 +207,13 @@ export function selectRemark() {
method: 'get',
})
}
export function uploadFolder(data) {
return request({
url: '/api/upload-folder',
method: 'POST',
data,
headers: {
'Content-Type': 'multipart/form-data'
}
});
}

206
ruoyi-ui/src/views/system/fileManage/index.vue

@ -60,17 +60,82 @@
<el-button v-hasPermi="['system:tupupoint:lock']" v-if="userRemark=='解锁'" type="danger" plain style="float: left" size="mini" @click="lockall">
一键锁定
</el-button>
<h3>选择并上传文件夹</h3>
<input
type="file"
ref="folderInput"
webkitdirectory
directory
multiple
@change="handleFolderSelect"
/>
<button @click="uploadFolder">上传文件夹</button>
<!-- <input-->
<!-- type="file"-->
<!-- ref="folderInput"-->
<!-- webkitdirectory-->
<!-- directory-->
<!-- multiple-->
<!-- @change="handleFolderSelect"-->
<!-- />-->
<!-- <button @click="uploadFolder">上传文件夹</button>-->
<el-button type="primary" size="mini" @click="dialogVisible = true">
选择并上传文件夹
</el-button>
<!-- 文件夹上传弹窗 -->
<el-dialog
title="选择文件夹"
:visible.sync="dialogVisible"
width="50%"
:close-on-click-modal="false"
:destroy-on-close="true"
>
<div class="folder-upload-container">
<!-- 隐藏的原生 input -->
<input
type="file"
ref="folderInput"
webkitdirectory
directory
multiple
@change="handleFolderSelect"
style="display: none"
/>
<!-- 美观的上传区域 -->
<el-card shadow="hover" class="upload-card">
<div
class="upload-area"
@click="triggerFileInput"
v-if="selectedFiles.length === 0"
>
<i class="el-icon-folder-opened upload-icon"></i>
<p class="tip">点击选择文件夹或拖拽文件夹到此处</p>
<p class="sub-tip">支持文件夹上传Chrome/Edge/Firefox</p>
</div>
<!-- 已选择文件列表 -->
<div v-else>
<p class="selected-title">已选择 {{ selectedFiles.length }} 个文件</p>
<el-scrollbar style="max-height: 300px">
<div class="file-list">
<div
class="file-item"
v-for="(file, index) in selectedFiles"
:key="index"
>
<i class="el-icon-document"></i>
<span class="file-name">{{ file.webkitRelativePath }}</span>
</div>
</div>
</el-scrollbar>
</div>
</el-card>
</div>
<!-- 操作按钮 -->
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button
type="primary"
@click="uploadFolder"
:disabled="selectedFiles.length === 0"
>
开始上传
</el-button>
</div>
</el-dialog>
<!-- <el-button type="danger" plain style="float: left" size="mini" @click="opendeletOly=true">-->
<!-- 删除指定实体-->
<!-- </el-button>-->
@ -315,7 +380,7 @@
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许导入docdocx格式文件</span>
<span>仅允许导入docx格式文件</span>
<span>{{ upload.tip }}</span>
</div>
</el-upload>
@ -509,7 +574,7 @@ import {
getAllTxtListP,
insertNode,
reset,
getAllTxtListByGroupAndLevel, lockAll, selectRemark
getAllTxtListByGroupAndLevel, lockAll, selectRemark, uploadFolder
} from "../../../api/system/file";
import {updateTemplate} from "../../../api/system/titleTemplate";
@ -882,43 +947,61 @@ export default {
}
},
methods: {
//
triggerFileInput() {
this.$refs.folderInput.click();
},
//
handleFolderSelect(e) {
const files = e.target.files; // FileList
const files = e.target.files;
this.selectedFiles = Array.from(files);
console.log('选中的文件:', this.selectedFiles);
this.$message({
message: `已选择 ${files.length} 个文件`,
type: 'success'
});
},
//
async uploadFolder() {
if (this.selectedFiles.length === 0) {
alert("请先选择一个文件夹");
this.$message.warning('请先选择一个文件夹');
return;
}
const formData = new FormData();
this.selectedFiles.forEach(file => {
// 使 webkitRelativePath
formData.append('files', file, file.webkitRelativePath);
});
try {
const response = await fetch('http://localhost:10031/api/upload-folder', {
method: 'POST',
body: formData
});
const response = await uploadFolder(formData);
if (response.ok) {
const result = await response.json();
console.log('上传成功:', result);
alert('文件夹上传成功!');
// code
if (response.code === 200) {
this.$message.success(response.data.message || '上传成功!');
this.dialogVisible = false;
this.selectedFiles = [];
} else {
console.error('上传失败');
alert('上传失败');
this.$message.error(response.data.message || '上传失败');
}
} catch (error) {
console.error('请求出错:', error);
alert('网络错误');
console.error('上传出错:', error);
//
if (error.response) {
// 2xx
this.$message.error(`服务器错误: ${error.response.status}`);
} else if (error.request) {
//
this.$message.error('网络错误');
} else {
this.$message.error('请求异常');
}
}
},
lockall(){
lockAll().then((res)=>{
@ -1884,5 +1967,72 @@ export default {
font-size: 1vw !important;
color: #67C23A;
}
.upload-card {
border: 1px dashed #d9d9d9;
border-radius: 8px;
}
.upload-area {
text-align: center;
padding: 40px 20px;
cursor: pointer;
color: #606266;
}
.upload-area:hover {
background: #f5f7fa;
}
.upload-icon {
font-size: 48px;
color: #409eff;
margin-bottom: 10px;
}
.tip {
font-size: 16px;
margin: 0;
color: #303133;
}
.sub-tip {
font-size: 13px;
color: #909399;
margin-top: 5px;
}
.selected-title {
font-size: 14px;
color: #303133;
margin-bottom: 10px;
}
.file-list {
padding: 0;
list-style: none;
}
.file-item {
display: flex;
align-items: center;
padding: 6px 10px;
font-size: 14px;
color: #606266;
border-bottom: 1px solid #eee;
}
.file-item i {
color: #909399;
margin-right: 8px;
}
.file-name {
font-size: 13px;
color: #333;
word-break: break-all;
}
.dialog-footer {
text-align: right;
}
</style>

Loading…
Cancel
Save