档案管理
This commit is contained in:
parent
095b9006b4
commit
a41394d8bd
|
|
@ -117,11 +117,11 @@ export function getFileManageByIdApi(params) {
|
|||
}
|
||||
|
||||
// 档案移交确认
|
||||
export function updateIntegrityStatusApi(params) {
|
||||
export function updateIntegrityStatusApi(data) {
|
||||
return request({
|
||||
url: '/smartArchives/fileManage/updateIntegrityStatus',
|
||||
method: 'get',
|
||||
params
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -133,3 +133,12 @@ export function fileExtractApi(data) {
|
|||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 文件预览
|
||||
export function getFileAsBase64Api(params) {
|
||||
return request({
|
||||
url: '/smartArchives/fileManage/getFileAsBase64',
|
||||
method: 'get',
|
||||
params:params
|
||||
})
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
查询
|
||||
</el-button>
|
||||
<el-button plain size="small" type="primary" icon="el-icon-plus"
|
||||
v-hasPermi="['archive:catalogue:add']" @click="addTree">
|
||||
v-hasPermi="['archive:catalogue:add']" @click="addTree" v-if="fileStatus === '0'">
|
||||
新增
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
|
@ -31,14 +31,14 @@
|
|||
<span class="node-label">{{ node.label }}</span>
|
||||
</template>
|
||||
<span class="btn-box">
|
||||
<el-button type="text" icon="el-icon-plus" v-if="(data.level > 1 && Number(data.isUnique) === 1) || (data.level === 1 && Number(data.isUnique) === 0)"
|
||||
<el-button type="text" icon="el-icon-plus" v-if="(data.level > 1 && Number(data.isUnique) === 1) || (data.level === 1 && Number(data.isUnique) === 0) && fileStatus === '0'"
|
||||
@click.stop="() => addTree(data)" v-hasPermi="['file:manage:add']">
|
||||
</el-button>
|
||||
<el-button type="text" v-if="data.level > 1 && Number(data.isUnique) === 1" icon="el-icon-edit-outline"
|
||||
<el-button type="text" v-if="data.level > 1 && Number(data.isUnique) === 1 && fileStatus === '0'" icon="el-icon-edit-outline"
|
||||
style="color: #007ce0" @click.stop="() => editTree(data, data)"
|
||||
v-hasPermi="['file:manage:update']">
|
||||
</el-button>
|
||||
<el-button type="text" v-if="data.level > 1 && Number(data.isUnique) === 1" icon="el-icon-delete" style="color: #f00000;"
|
||||
<el-button type="text" v-if="data.level > 1 && Number(data.isUnique) === 1 && fileStatus === '0'" icon="el-icon-delete" style="color: #f00000;"
|
||||
@click.stop="() => delTree(node, data)" v-hasPermi="['file:manage:del']">
|
||||
</el-button>
|
||||
</span>
|
||||
|
|
@ -59,7 +59,7 @@ import FileAddTreeData from './addTreeData.vue'
|
|||
export default {
|
||||
name: 'FileLeftTree',
|
||||
components: { FileAddTreeData },
|
||||
props: ["projectId"],
|
||||
props: ["projectId", "fileStatus"],
|
||||
data() {
|
||||
return {
|
||||
treeDataList: [],
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<!-- 档案目录管理 -->
|
||||
<div>
|
||||
<el-card style="min-height: calc(100vh - 190px);">
|
||||
<TableModel :formLabel="formLabel" :showOperation="true" :showRightTools="true" ref="tableRef"
|
||||
<TableModel :formLabel="formLabel" :showOperation="fileStatus === '0'" :showRightTools="true" ref="tableRef"
|
||||
:columnsList="columnsList" :request-api="getFileManageApi" :send-params="defaultParams">
|
||||
<template slot="dataSource" slot-scope="{ data }">
|
||||
<span>{{ data.dataSource === '1' ? '本系统上传' : '智慧现场' }}</span>
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
</template>
|
||||
<template slot="btn">
|
||||
<el-button plain size="mini" type="primary" icon="el-icon-plus" v-hasPermi="['file:manage:add']"
|
||||
@click="handleAdd" :disabled="addBtnIsShow">
|
||||
@click="handleAdd" :disabled="addBtnIsShow" v-if="fileStatus === '0'">
|
||||
新增
|
||||
</el-button>
|
||||
</template>
|
||||
|
|
@ -58,6 +58,10 @@ export default {
|
|||
selectedNode:{
|
||||
type:Object,
|
||||
default:null
|
||||
},
|
||||
fileStatus:{
|
||||
type:String,
|
||||
default:''
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
<el-card class="toolbar-card">
|
||||
<div class="toolbar">
|
||||
<div class="toolbar-left">
|
||||
<el-button type="warning" plain icon="el-icon-bottom" size="mini"
|
||||
@click="handleFileExtract">档案抽取</el-button>
|
||||
<el-button type="success" plain icon="el-icon-finished" size="mini"
|
||||
@click="handleUpdateIntegrityStatus">移交清单确认</el-button>
|
||||
<el-button type="warning" plain icon="el-icon-bottom" size="mini" @click="handleFileExtract"
|
||||
v-if="fileStatus === '0' && !integrityStatus">档案抽取</el-button>
|
||||
<el-button type="success" plain icon="el-icon-finished" size="mini" @click="moveListConfirm"
|
||||
v-if="fileStatus === '0' && !integrityStatus">移交清单确认</el-button>
|
||||
<el-button type="success" plain icon="el-icon-finished" size="mini" @click="handleIntegrityStatus"
|
||||
v-if="fileStatus === '0' && integrityStatus">完整性确认</el-button>
|
||||
<el-button type="danger" plain icon="el-icon-close" size="mini" @click="handleClose">返回</el-button>
|
||||
</div>
|
||||
|
||||
|
|
@ -14,12 +16,57 @@
|
|||
</el-card>
|
||||
<el-row :gutter="24" class="content-row">
|
||||
<el-col :span="8" class="pane-left">
|
||||
<LeftTree @handleNodeClick="handleNodeClick" :projectId="projectId" />
|
||||
<LeftTree @handleNodeClick="handleNodeClick" :projectId="projectId" :fileStatus="fileStatus" />
|
||||
</el-col>
|
||||
<el-col :span="16" class="pane-right">
|
||||
<RightTable :selectedNode="selectedNode" :projectId="projectId" />
|
||||
<RightTable :selectedNode="selectedNode" :projectId="projectId" :fileStatus="fileStatus" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 档案同步进度弹框 -->
|
||||
<el-dialog :visible.sync="syncDialogVisible" :close-on-click-modal="false" :close-on-press-escape="false"
|
||||
:show-close="false" width="400px">
|
||||
<div slot="title" class="dialog-title">
|
||||
<span>档案同步</span>
|
||||
</div>
|
||||
<div class="sync-content">
|
||||
<div class="sync-icon">
|
||||
<i class="el-icon-loading" v-if="isSyncing"></i>
|
||||
<i class="el-icon-success" v-else-if="syncSuccess"></i>
|
||||
<i class="el-icon-error" v-else-if="syncError"></i>
|
||||
</div>
|
||||
<div class="sync-text">
|
||||
<p v-if="isSyncing">档案同步中,请稍候...</p>
|
||||
<p v-else-if="syncSuccess" class="success-text">同步档案已完成</p>
|
||||
<p v-else-if="syncError" class="error-text">档案同步失败</p>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button class="clear-btn" @click="closeSyncDialog" v-if="!isSyncing">取消</el-button>
|
||||
<el-button type="primary" class="search-btn" @click="closeSyncDialog" v-if="!isSyncing">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 完整性确认弹框 -->
|
||||
<el-dialog :visible.sync="confirmDialogVisible" :close-on-click-modal="false" :close-on-press-escape="false"
|
||||
:show-close="true" width="450px">
|
||||
<div slot="title" class="dialog-title">
|
||||
<span>操作确认</span>
|
||||
</div>
|
||||
<div class="confirm-content">
|
||||
<div class="confirm-icon">
|
||||
<i class="el-icon-question"></i>
|
||||
</div>
|
||||
<div class="confirm-text">
|
||||
<p class="main-message">确认所有档案已完整,可以进行移交?</p>
|
||||
<p class="sub-message">确认后不可再上传文件。</p>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button class="clear-btn" @click="confirmDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" class="search-btn" @click="confirmIntegrityStatus">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -27,6 +74,7 @@
|
|||
import LeftTree from './components/leftTree.vue'
|
||||
import RightTable from './components/rightTable.vue'
|
||||
import { fileExtractApi, updateIntegrityStatusApi } from '@/api/archivesManagement/fileManager/fileManager'
|
||||
import { decryptWithSM4 } from '@/utils/sm'
|
||||
export default {
|
||||
name: 'FileData',
|
||||
components: {
|
||||
|
|
@ -36,14 +84,23 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
projectId: null,
|
||||
fileStatus: null,
|
||||
// 选中的节点
|
||||
selectedNode: null,
|
||||
// 档案同步弹框相关
|
||||
syncDialogVisible: false,
|
||||
isSyncing: false,
|
||||
syncSuccess: false,
|
||||
syncError: false,
|
||||
integrityStatus: false,
|
||||
// 确认弹框相关
|
||||
confirmDialogVisible: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 获取传递的项目ID
|
||||
this.projectId = this.$route.query.id
|
||||
console.log('接收到的项目ID:', this.projectId)
|
||||
this.projectId = decryptWithSM4(this.$route.query.id)
|
||||
this.fileStatus = decryptWithSM4(this.$route.query.fileStatus)
|
||||
},
|
||||
methods: {
|
||||
handleClose() {
|
||||
|
|
@ -54,39 +111,76 @@ export default {
|
|||
handleNodeClick(data) {
|
||||
this.selectedNode = data;
|
||||
},
|
||||
// 档案抽取
|
||||
handleFileExtract() {
|
||||
// 显示档案同步中的提示
|
||||
const loadingInstance = this.$loading({
|
||||
lock: true,
|
||||
text: '档案同步中...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
|
||||
// 调用档案抽取接口
|
||||
fileExtractApi({ projectId: this.projectId })
|
||||
// 移交清单确认
|
||||
moveListConfirm() {
|
||||
this.integrityStatus = true;
|
||||
},
|
||||
// 完整性确认
|
||||
handleIntegrityStatus() {
|
||||
this.confirmDialogVisible = true;
|
||||
},
|
||||
// 确认完整性状态
|
||||
confirmIntegrityStatus() {
|
||||
this.closeConfirmDialog();
|
||||
// 调用完整性确认接口
|
||||
updateIntegrityStatusApi({ proId: this.projectId })
|
||||
.then(res => {
|
||||
// 关闭加载提示
|
||||
loadingInstance.close();
|
||||
|
||||
if (res.code === 200) {
|
||||
this.$message.success('同步档案已完成');
|
||||
this.$message.success('完整性确认成功');
|
||||
this.closeConfirmDialog();
|
||||
// 可以在这里添加其他逻辑,比如刷新页面或更新状态
|
||||
} else {
|
||||
this.$message.error(res.msg || '档案同步失败');
|
||||
this.$message.error(res.msg || '完整性确认失败');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// 关闭加载提示
|
||||
loadingInstance.close();
|
||||
this.$message.error('档案同步失败,请重试');
|
||||
console.error('档案抽取失败:', error);
|
||||
this.$message.error('完整性确认失败,请重试');
|
||||
console.error('完整性确认失败:', error);
|
||||
});
|
||||
},
|
||||
// 档案移交确认
|
||||
handleUpdateIntegrityStatus() {
|
||||
// 关闭确认弹框
|
||||
closeConfirmDialog() {
|
||||
this.confirmDialogVisible = false;
|
||||
setTimeout(() => {
|
||||
const obj = { path: "/archivesManagement/fileManager" }
|
||||
this.$tab.closeOpenPage(obj)
|
||||
}, 200);
|
||||
},
|
||||
// 档案抽取
|
||||
handleFileExtract() {
|
||||
// 显示同步弹框
|
||||
this.syncDialogVisible = true;
|
||||
this.isSyncing = true;
|
||||
this.syncSuccess = false;
|
||||
this.syncError = false;
|
||||
|
||||
// 调用档案抽取接口
|
||||
setTimeout(() => {
|
||||
fileExtractApi({ projectId: this.projectId })
|
||||
.then(res => {
|
||||
this.isSyncing = false;
|
||||
|
||||
if (res.code === 200) {
|
||||
this.syncSuccess = true;
|
||||
} else {
|
||||
this.syncError = true;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
this.isSyncing = false;
|
||||
this.syncError = true;
|
||||
console.error('档案抽取失败:', error);
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
// 关闭同步弹框
|
||||
closeSyncDialog() {
|
||||
this.syncDialogVisible = false;
|
||||
this.isSyncing = false;
|
||||
this.syncSuccess = false;
|
||||
this.syncError = false;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -133,4 +227,96 @@ export default {
|
|||
.pane-right {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 档案同步弹框样式 */
|
||||
.dialog-title {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
.dialog-footer .el-button+.el-button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.sync-content {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.sync-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.sync-icon .el-icon-loading {
|
||||
color: #409EFF;
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
.sync-icon .el-icon-success {
|
||||
color: #67C23A;
|
||||
}
|
||||
|
||||
.sync-icon .el-icon-error {
|
||||
color: #F56C6C;
|
||||
}
|
||||
|
||||
.sync-text p {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
color: #67C23A !important;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: #F56C6C !important;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* 确认弹框样式 */
|
||||
.confirm-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.confirm-icon {
|
||||
font-size: 48px;
|
||||
color: #E6A23C;
|
||||
margin-right: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.confirm-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.main-message {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 16px;
|
||||
color: #303133;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.sub-message {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
line-height: 1.4;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
<script>
|
||||
import TableModel from '@/components/TableModel'
|
||||
import { columnsList, formLabel } from './config'
|
||||
import { encryptWithSM4 } from '@/utils/sm'
|
||||
import {
|
||||
getProListAPI
|
||||
} from '@/api/archivesManagement/fileManager/fileManager.js'
|
||||
|
|
@ -81,6 +82,7 @@ export default {
|
|||
},
|
||||
/* 搜索操作 */
|
||||
handleQuery() {
|
||||
alert(1);
|
||||
this.$refs.proTableRef.getTableList()
|
||||
},
|
||||
/* 打开档案管理 */
|
||||
|
|
@ -88,7 +90,8 @@ export default {
|
|||
this.$router.push({
|
||||
name: 'FileData',
|
||||
query: {
|
||||
id: row.id
|
||||
id: encryptWithSM4(row.id),
|
||||
fileStatus: encryptWithSM4(row.fileStatus)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,7 @@
|
|||
<div style="text-align:center">
|
||||
<!-- 图片预览 -->
|
||||
<template v-if="isImage">
|
||||
<el-image
|
||||
:src="fileUrl"
|
||||
:preview-src-list="previewList"
|
||||
fit="contain"
|
||||
style="max-width:100%;max-height:70vh"
|
||||
>
|
||||
<el-image :src="processedFileUrl" :preview-src-list="previewList" fit="contain" style="max-width:100%;max-height:70vh">
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
|
|
@ -19,17 +14,18 @@
|
|||
|
||||
<!-- PDF 预览 -->
|
||||
<template v-else>
|
||||
<pdf :src="fileUrl" style="width:100%;height:70vh" />
|
||||
<pdf :src="processedFileUrl" style="width:100%;height:70vh" />
|
||||
</template>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
</template>
|
||||
<script>
|
||||
import pdf from 'vue-pdf'
|
||||
|
||||
import { getFileAsBase64Api } from '@/api/archivesManagement/fileManager/fileManager'
|
||||
export default {
|
||||
name: 'ViewFile',
|
||||
props: ['width','hight','dataForm','title','disabled','isAdd','rowData','projectId'],
|
||||
props: ['width', 'hight', 'dataForm', 'title', 'disabled', 'isAdd', 'rowData', 'projectId'],
|
||||
components: { pdf },
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: true,
|
||||
|
|
@ -42,40 +38,57 @@ export default {
|
|||
computed: {
|
||||
isImage() {
|
||||
// 允许的图片类型
|
||||
const exts = ['.jpg','.jpeg','.png','.gif','.bmp','.webp']
|
||||
const url = (this.fileUrl || '').toLowerCase()
|
||||
const exts = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
|
||||
const url = (this.fileUrl || '')
|
||||
const name = (this.fileName || '').toLowerCase()
|
||||
return exts.some(ext => url.endsWith(ext) || name.endsWith(ext))
|
||||
},
|
||||
isPdf() {
|
||||
// 判断是否为PDF文件
|
||||
const exts = ['.pdf']
|
||||
const url = (this.fileUrl || '')
|
||||
const name = (this.fileName || '').toLowerCase()
|
||||
return exts.some(ext => url.endsWith(ext) || name.endsWith(ext))
|
||||
},
|
||||
processedFileUrl() {
|
||||
// 处理文件URL,为PDF添加data前缀
|
||||
if (this.isPdf && this.fileUrl && !this.fileUrl.startsWith('data:')) {
|
||||
return `data:application/pdf;base64,${this.fileUrl}`
|
||||
}
|
||||
return this.fileUrl
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 从 rowData 或 dataForm 里取文件信息(根据你现有数据结构调整)
|
||||
// 例如:
|
||||
this.fileUrl = this.rowData?.fileUrl || this.dataForm?.fileUrl || ''
|
||||
this.fileName = this.rowData?.fileName || this.dataForm?.fileName || ''
|
||||
// 预览组(如果你有多张,可放数组;没有就放当前一张)
|
||||
if (this.isImage && this.fileUrl) {
|
||||
this.previewList = [this.fileUrl]
|
||||
}
|
||||
this.getFileAsBase64();
|
||||
|
||||
},
|
||||
methods: {
|
||||
handleClose() {
|
||||
this.dialogVisible = false
|
||||
this.$emit('closeDialog')
|
||||
},
|
||||
/* 获取文件的base64 */
|
||||
getFileAsBase64() {
|
||||
getFileAsBase64Api({ id: this.rowData.fileId }).then(res => {
|
||||
const obj =res.data;
|
||||
this.fileUrl = obj?.fileBase64 || ''
|
||||
this.fileName = obj?.fileName || ''
|
||||
// 预览组(如果你有多张,可放数组;没有就放当前一张)
|
||||
if (this.isImage && this.fileUrl) {
|
||||
this.previewList = [this.processedFileUrl]
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
components: { pdf }
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.w700 .el-dialog {
|
||||
width: 700px;
|
||||
height: 800px;
|
||||
}
|
||||
|
||||
.w500 .el-dialog {
|
||||
width: 500px;
|
||||
height: 800px;
|
||||
}
|
||||
|
||||
.w500 .el-dialog__header,
|
||||
|
|
@ -103,6 +116,7 @@ export default {
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.image-slot {
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
|
|
|
|||
Loading…
Reference in New Issue