diff --git a/api/app/lib/controllers/means/index.js b/api/app/lib/controllers/means/index.js index ec83b08..4447e4c 100644 --- a/api/app/lib/controllers/means/index.js +++ b/api/app/lib/controllers/means/index.js @@ -43,12 +43,15 @@ async function addEditFile (ctx, next) { async function fileList (ctx, next) { try { const models = ctx.fs.dc.models; - const { projectId, limit, page } = ctx.query; + const { projectId, type } = ctx.query; let options = { where: {}, } if (projectId) { options.where.projectId = projectId } + if (type) { + options.where.type = type + } let res = await models.ProjectFolder.findAll(options) diff --git a/web/client/src/sections/means/components/fileModal.jsx b/web/client/src/sections/means/components/fileModal.jsx index a94300f..3c6d896 100644 --- a/web/client/src/sections/means/components/fileModal.jsx +++ b/web/client/src/sections/means/components/fileModal.jsx @@ -5,7 +5,7 @@ import { IconAlertCircle } from '@douyinfe/semi-icons'; function FileModal (props) { - const { close, success, dispatch, actions, editData, pepProjectId, higherFile } = props; + const { close, success, dispatch, actions, editData, pepProjectId, higherFile ,type} = props; const { means } = actions; const form = useRef();//表单 @@ -24,7 +24,7 @@ function FileModal (props) { projectId: pepProjectId, fileName: v.fileName, higherFileId: editData?.higherFileId || v.higherFileId || null, - type: 1 + type })).then(v => { if (v.success) { close() diff --git a/web/client/src/sections/means/containers/devOpsStandard.jsx b/web/client/src/sections/means/containers/devOpsStandard.jsx index 8abf95c..5a55621 100644 --- a/web/client/src/sections/means/containers/devOpsStandard.jsx +++ b/web/client/src/sections/means/containers/devOpsStandard.jsx @@ -1,22 +1,525 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState, useMemo } from 'react'; import { connect } from 'react-redux'; +import { Input, Button, Tree, Modal, Table, Upload, Pagination, Popconfirm } from '@douyinfe/semi-ui'; +import { IconDeleteStroked, IconEditStroked, IconUpload, IconAlertCircle } from '@douyinfe/semi-icons'; +import SimpleBar from 'simplebar-react'; +import FileModal from '../components/fileModal'; +import moment from 'moment'; +import './style.less' -const Server = (props) => { - const { dispatch, actions, user, loading, socket } = props +const Rest = (props) => { + const { dispatch, actions, user, qiniu, loading, clientHeight, overallProjectId } = props + const { install, means } = actions + const [pomsList, setPomsList] = useState([]); //项目 + const [showPomsList, setShowPomsList] = useState([]); //项目 + const [pepProjectId, setPepProjectId] = useState() //项目id + const [projectSearch, setProjectSearch] = useState() //项目搜索 + const [isFileModal, setIsFileModal] = useState(false) //添加文件弹窗 + const [editData, setEditData] = useState({}) //编辑参数 + const [treeData, settreeData] = useState([]); //文件夹列表 + const [higherFile, setHigherFile] = useState([]); //上级文件夹 + const [fileId, setFileId] = useState(); //文件夹id + const [uploadModal, setUploadModal] = useState(false) //上传弹窗 + const [uploadData, setUploadData] = useState({}) + const [dataSource, setDataSource] = useState([]) //表格数据 + const [query, setQuery] = useState({ limit: 10, page: 0 }) + const [count, setCount] = useState(0) + const [videoModalV, setVideoModalV] = useState(false); + const [videoUrl, setvideoUrl] = useState(null); + const [hint, setHint] = useState(false); + + useEffect(() => { + dispatch(install.getProjectPoms({ global: 1 })).then((res => { + if (res.success) { + let data = res.payload.data?.rows?.filter(v => v.pepProjectIsDelete !== 1)?.map(v => ({ pepProjectId: v.id, pepProjectName: v.pepProjectName || v.name })) + setPomsList(data) + setShowPomsList(data) + setPepProjectId(data[0]?.pepProjectId) + fileList(data[0]?.pepProjectId) + } + })) }, []) + useEffect(() => { + let data + if (overallProjectId) { + data = pomsList?.filter(v => (v.pepProjectName?.indexOf(projectSearch) != -1 && v.pepProjectId == overallProjectId)) + } else { + data = pomsList?.filter(v => v.pepProjectName?.indexOf(projectSearch) != -1) + } + setShowPomsList(data) + setPepProjectId(data[0]?.pepProjectId) + fileList(data[0]?.pepProjectId) + }, [projectSearch]) + + useEffect(() => { + setProjectSearch('') + let data + if (overallProjectId) { + data = pomsList?.filter(v => v.pepProjectId == overallProjectId) + } else { + data = pomsList + } + setShowPomsList(data) + setPepProjectId(data[0]?.pepProjectId) + fileList(data[0]?.pepProjectId) + }, [overallProjectId]) + + useEffect(() => { + if (fileId) { + filfolderFileListe() + setQuery({ limit: 10, page: 0 }) + } + }, [fileId]) + + const fileList = (id) => { + dispatch(means.fileList({ projectId: id, type: 4 })).then((res => { + if (res.success) { + let data = res.payload.data + let oneLevel = res.payload.data?.filter(f => !f.higherFileId) || [] + settreeData(listErgodic(oneLevel, data)) + setHigherFile(data?.map(d => ({ name: d.fileName, value: d.id }))) + } + })) + } + + + + const filfolderFileListe = (params) => { + let fileIds = [] + const treeDataList = (data, value) => { + data?.map(c => { + if (c.key == fileId || value) { + fileIds.push(c.key) + if (c.children?.length) { + treeDataList(c.children, true) + } + } else if (c.children?.length) { + treeDataList(c.children) + } + }) + } + treeDataList(treeData) + let datas = params || query + dispatch(means.folderFileList({ fileId: JSON.stringify(fileIds), ...datas })).then((res => { + if (res.success) { + setDataSource(res.payload.data?.rows || []) + setCount(res.payload.data?.count) + } + })) + } + + const listErgodic = (level, datas) => { + let data = [] + level.map(v => { + let list = { + value: v.id, + key: v.id, + } + let childrenList = datas?.filter(c => c.higherFileId == list.value) + if (childrenList?.length) { + list.children = listErgodic(childrenList, datas) + } + let fileData + dispatch(means.folderFileList({ fileId: JSON.stringify([v.id]) })).then((res => { + if (res.success) { + fileData = res.payload.data?.rows?.length + } + })) + list.label =