From f5df464d90d68077bcf56ef3d8e69316f131ceb3 Mon Sep 17 00:00:00 2001
From: caishi <1149225589@qq.com>
Date: Mon, 12 Apr 2021 17:58:46 +0800
Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E6=BA=90=E5=BA=93=E6=A8=A1=E5=9D=97+?=
=?UTF-8?q?=E5=90=88=E5=B9=B6=E8=AF=B7=E6=B1=82=E5=88=86=E9=A1=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/forge/Main/Detail.js | 19 ++
src/forge/Merge/merge.js | 6 +-
src/forge/Source/AddTag.jsx | 47 +++++
src/forge/Source/Index.jsx | 288 ++++++++++++++++++++++++++++++
src/forge/Source/Index.scss | 109 +++++++++++
src/forge/Source/Upload.jsx | 82 +++++++++
src/forge/Source/UploadSource.jsx | 150 ++++++++++++++++
7 files changed, 698 insertions(+), 3 deletions(-)
create mode 100644 src/forge/Source/AddTag.jsx
create mode 100644 src/forge/Source/Index.jsx
create mode 100644 src/forge/Source/Index.scss
create mode 100644 src/forge/Source/Upload.jsx
create mode 100644 src/forge/Source/UploadSource.jsx
diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js
index 9886b7e2..1df5784d 100644
--- a/src/forge/Main/Detail.js
+++ b/src/forge/Main/Detail.js
@@ -104,6 +104,10 @@ const TrendsIndex = Loadable({
loading: Loading,
})
+const Source = Loadable({
+ loader: () => import('../Source/Index'),
+ loading: Loading,
+})
const DevAbout = Loadable({
loader: () => import('../About/Index'),
loading: Loading,
@@ -133,6 +137,8 @@ function checkPathname(projectsId,owner,pathname){
name="setting"
}else if(url.indexOf(`/devops`)>-1){
name="devops"
+ }else if(url.indexOf(`/source`)>-1){
+ name="source"
}
}
return name;
@@ -544,6 +550,13 @@ class Detail extends Component {
}
+
+
+
+ 资源库
+ {projectDetail && projectDetail.source_count ? {projectDetail.source_count} :""}
+
+
{/* {
platform &&
@@ -590,6 +603,12 @@ class Detail extends Component {
:
+ {/* 资源 */}
+ ()
+ }
+ >
{/* 主页 */}
- {search_count > limit ? (
+ {search_count > select_params.limit ? (
diff --git a/src/forge/Source/AddTag.jsx b/src/forge/Source/AddTag.jsx
new file mode 100644
index 00000000..8b94b5a6
--- /dev/null
+++ b/src/forge/Source/AddTag.jsx
@@ -0,0 +1,47 @@
+import React , { forwardRef, useEffect } from 'react';
+import { Modal , Form , Input } from 'antd';
+
+function AddTag({form , visible , onCancel ,onOk}){
+ const { getFieldDecorator, validateFields , setFieldsValue } = form;
+
+ useEffect(()=>{
+ setFieldsValue({tagName:undefined})
+ },[visible])
+
+ function submit(){
+ validateFields((error,values)=>{
+ if(!error){
+ onOk(values);
+ }
+ })
+ }
+ const layout = {
+ labelCol: { span: 5 },
+ wrapperCol: { span: 18 },
+ };
+ return(
+
+
+ {getFieldDecorator("tagName",{
+ rules:[{required:true,message:"请输入标签名"}]
+ })(
+
+ )}
+
+
+
+ )
+
+}
+export default Form.create()(forwardRef(AddTag));
\ No newline at end of file
diff --git a/src/forge/Source/Index.jsx b/src/forge/Source/Index.jsx
new file mode 100644
index 00000000..f3c68217
--- /dev/null
+++ b/src/forge/Source/Index.jsx
@@ -0,0 +1,288 @@
+import React, { useEffect, useState } from 'react';
+import './Index.scss';
+import { AlignCenter, Blueback , FlexAJ } from '../Component/layout';
+import { Dropdown, Input , Menu , Pagination, Spin , Popconfirm, Button } from 'antd';
+import { Link } from 'react-router-dom';
+import UploadSource from './UploadSource';
+import AddTag from './AddTag';
+import { getImageUrl } from 'educoder';
+import Nodata from '../Nodata';
+import axios from 'axios';
+
+const { Search } = Input;
+const sort = [
+ "按上传时间排序",
+ "按下载次数排序",
+ "按引用排序"
+]
+const limit = 15;
+const https = 'https://testfiles.trustie.net';
+function Index(props){
+ const [ sortValue , setSortValue ] = useState(0);
+ const [ page , setPage ] = useState(1);
+ const [ total , setTotal ] = useState(0);
+ const [ search , setSearch ] = useState(undefined);
+ const [ data , setData ] = useState(undefined);
+ const [ isSpin , setIsSpin ] = useState(true);
+ const [ error , setError ] = useState(false);
+ const [ attachments , setAttachments ] = useState(undefined);
+
+ const [ id , setId ] = useState(undefined);
+
+ const [ visible , setVisible ] = useState(false);
+ const [ addVisible , setAddVisible ] = useState(false);
+
+ const repo_id = props.projectDetail && props.projectDetail.repo_id;
+ const owner = props.match.params.owner;
+ const current_user = props.current_user;
+
+ useEffect(()=>{
+ if(owner && repo_id){
+ setIsSpin(true);
+ getData();
+ }
+ },[repo_id,owner,search,sortValue,page])
+
+ function getData(){
+ const url = https +`/api/project/achievement/`;
+ axios.get(url,{
+ params:{
+ projectId:repo_id,
+ curPage:page,
+ pageSize:limit,
+ name:search,
+ sort:sortValue+1,
+ }
+ }).then(result=>{
+ if(result && result.data){
+ setData(result.data.data.rows);
+ setTotal(result.data.data.total);
+ setIsSpin(false);
+ setError(false);
+ }
+ }).catch(error=>{setIsSpin(false);setError(true);})
+ }
+
+ // 搜索
+ function onSearch(value){
+ setSearch(value);
+ }
+
+ // 切换排序方式
+ function changeSort(e,index){
+ setSortValue(index);
+ }
+
+
+ const menu=(
+
+ )
+
+ function listmenu(id,attachments,isPublic){
+ return(
+
+ )
+ }
+ // 更细私有状态
+ function changeStatus(id,isPublic){
+ const url = https+`/api/project/achievement/updateStatus`;
+ axios.put(url,{
+ id,status:isPublic
+ }).then(result=>{
+ if(result && result.data){
+ props.showNotification(`资源${isPublic === 1 ? "设为公开":"设为私有"}成功!`);
+ setIsSpin(true);
+ getData();
+ }
+ }).catch({})
+ }
+
+ // 删除资源方法
+ function deleteSourceFunc(id){
+ props.confirm({
+ content: "是否确认删除所选资源文件?",
+ onOk: () => {
+ const url = https + `/api/project/achievement/${id}`;
+ axios.delete(url).then(result=>{
+ if(result && result.data && result.data.code === "1"){
+ props.showNotification("资源删除成功");
+ setIsSpin(true);
+ getData();
+ }
+ })
+ }
+ })
+
+ }
+
+
+ // 上传资源成功
+ function onOk(){
+ setVisible(false);
+ setIsSpin(true);
+ getData();
+ }
+
+ // 确认删除标签
+ function removeTagFunc(id,tag){
+ const url = https + `/api/project/achievement/deleteTag`;
+ axios.delete(url,{
+ params:{id,tagName:tag}
+ }).then(result=>{
+ if(result && result.data){
+ props.showNotification("标签删除成功");
+ setIsSpin(true);
+ getData();
+ }
+ }).then(error=>{})
+ }
+
+ function addPanel(id){
+ setAddVisible(true);
+ setId(id);
+ }
+
+ function onCancelAdd(){
+ setId(undefined);
+ setAddVisible(false);
+ }
+
+ // 添加标签
+ function sureAddTag(values){
+ const url = https+`/api/project/achievement/addTag?id=`+id+`&tagName=`+values.tagName;
+ axios.put(url).then(result=>{
+ if(result){
+ setId(undefined);
+ setAddVisible(false);
+ setIsSpin(true);
+ getData();
+ }
+ })
+ }
+
+ return(
+
+
+
setVisible(false)}
+ onOk={onOk}
+ showNotification={props.showNotification}
+ owner={owner}
+ projectsId={repo_id}
+ id={id}
+ attachments={attachments}
+ />
+
+
+ 资源库(18)
+ { current_user && current_user.login && (props.projectDetail && props.projectDetail.permission) ?
+ {setId(undefined);setVisible(true);}}>上传资源:""
+ }
+
+
+
+
+
+ {sort[sortValue]}
+
+
+
+
+ {
+ data && data.length> 0 &&
+
+ {
+ data.map((item,key)=>{
+ return(
+ -
+
+
+
+
+ {item.fileName}
+
+ {item.isPublic === 0 && 私有}
+
+ { current_user && current_user.login &&
+ listmenu(item.id,item.attachments,item.isPublic)} placement={'bottomRight'}>
+
+
+ }
+
+
+ 上传时间:{item.uploadTime}
+ 文件大小:{item.fileSize}
+ 下载:{item.download}
+
+
{item.remark}
+
+ {
+ item.tags && item.tags.length>0 && item.tags.map((i,k)=>{
+ return(
+
{i}
+ {
+ current_user && (current_user.login === item.login) ?
+ removeTagFunc(item.id,i)} okText="是" cancelText="否">
+
+ :""
+ }
+
+ )
+ })
+ }
+ {
+ current_user && (current_user.login === item.login) &&
+
addPanel(item.id)} style={{height:"20px",lineHeight:"20px"}}>+新增标签
+ }
+
+
+
+ )
+ })
+ }
+
+ }
+ {
+ ((data && data.length === 0) || error) &&
+ }
+ {
+ total > limit &&
+
+ }
+
+
+
+ )
+}
+export default Index;
\ No newline at end of file
diff --git a/src/forge/Source/Index.scss b/src/forge/Source/Index.scss
new file mode 100644
index 00000000..57b122ae
--- /dev/null
+++ b/src/forge/Source/Index.scss
@@ -0,0 +1,109 @@
+.sourcePanel{
+ width: 1200px;
+ margin: 20px auto;
+ background: #fff;
+ border-radius: 2px;
+ box-shadow: 0px 0px 4px rgba(0,0,0,0.1);
+ .headtitle{
+ padding:15px 20px;
+ border-bottom: 1px solid #eee;
+ }
+ .subHeadtitle{
+ padding:15px 20px;
+ border-bottom: 1px solid #eee;
+ .ant-input-group-wrapper{
+ width:320px;
+ .ant-btn.ant-input-search-button{
+ margin: 0px;
+ margin-top: -1px;
+ }
+ }
+ }
+ .bodycontent{
+ padding:0px 20px;
+ min-height: 500px;
+ & > ul.bodycontentul > li{
+ display: flex;
+ border-bottom: 1px solid #eee;
+ padding:20px 0px;
+ align-items: flex-start;
+ &:last-child{
+ border-bottom: none;
+ }
+ .infoImg{
+ img{
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ }
+ margin-right: 15px;
+ }
+ .infoname{
+ font-size: 16px;
+ }
+ .privateTip{
+ display: block;
+ font-size: 12px;
+ margin-left: 10px;
+ background-color: orange;
+ height: 18px;
+ line-height: 18px;
+ padding:0px 3px;
+ color: #fff;
+ }
+ .infos{
+ & > span{
+ margin-right: 20px;
+ color: #999;
+ & >span{
+ color: #666;
+ }
+ }
+ }
+ .infodesc{
+ color: #666;
+ line-height: 20px;
+ margin:5px 0px!important;
+ }
+ .infotag{
+ display: flex;
+ flex-wrap: wrap;
+ span{
+ display: block;
+ padding:0px 4px;
+ height: 20px;
+ line-height: 20px;
+ font-size: 12px;
+ margin-right: 10px;
+ border: 1px solid #f8df8c;
+ background: #fffce6;
+ color: #0d90c3;
+ border-radius: 2px;
+ cursor: pointer;
+ }
+ }
+ }
+ }
+}
+.versionTable{
+ .currentTip{
+ display: block;
+ padding:0px 3px;
+ border-radius: 2px;
+ border:1px solid #68c7ec;
+ font-size: 12px;
+ color: #68c7ec;
+ height: 18px;
+ line-height: 18px;
+ margin-left: 5px;
+ }
+ .ant-table-body{
+ margin:0px!important;
+ thead{
+ background-color: #eee;
+ }
+ thead >tr >th,tbody > tr > td{
+ padding:4px 5px!important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/forge/Source/Upload.jsx b/src/forge/Source/Upload.jsx
new file mode 100644
index 00000000..de2c8ecb
--- /dev/null
+++ b/src/forge/Source/Upload.jsx
@@ -0,0 +1,82 @@
+import React, { useEffect, useState } from "react";
+import { Upload, Button } from 'antd';
+import { appendFileSizeToUploadFileAll } from 'educoder';
+
+import axios from 'axios';
+function Uploads({ className , size , actionUrl,fileList,showNotification , load}) {
+ const [ files , setFiles ] = useState(undefined);
+
+ useEffect(()=>{
+ if(fileList){
+ init();
+ }
+ },[fileList]);
+
+ function init(){
+ let f = appendFileSizeToUploadFileAll(fileList);
+ setFiles(f);
+ }
+ function onAttachmentRemove(file){
+ if (!file.percent || file.percent === 100) {
+ deleteAttachment(file);
+ return false;
+ }
+ }
+ function deleteAttachment(file){
+ let id = file.response && file.response.data && file.response.data.id;
+ const url = actionUrl + `/busiAttachments/${id}`;
+ axios.delete(url).then((response) => {
+ if (response.data) {
+ if (response.data.code === "1") {
+ let nf = files.filter(item=>item.response.data.id !== id);
+ setFiles(nf);
+ fileIdList(nf);
+ } else {
+ showNotification(response.data.message)
+ }
+ }
+ }).catch(function (error) {
+ console.log(error);
+ });
+ }
+
+
+ function handleChange (info) {
+ if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
+ let fileList = info.fileList;
+ let len = info.fileList && info.fileList.length;
+ setFiles(appendFileSizeToUploadFileAll([fileList[len-1]]));
+ fileIdList(fileList[len-1]);
+ }
+ }
+
+ function fileIdList (fileList) {
+ let data = fileList.response && fileList.response.data;
+ fileList && load && load(data && data.id,data && data.fileName);
+ }
+
+ function beforeUpload(file){
+ const isLt100M = file.size / 1024 / 1024 < size;
+ if (!isLt100M) {
+ showNotification(`文件大小必须小于${size}MB!`);
+ }
+ return isLt100M;
+ }
+
+ const upload = {
+ name: 'file',
+ fileList: files,
+ action: actionUrl+`/busiAttachments/upload`,
+ onChange:handleChange,
+ onRemove:onAttachmentRemove,
+ beforeUpload:beforeUpload,
+ maxCount:1
+ };
+ return (
+
+
+ (你可以上传小于{size}MB的文件)
+
+ )
+}
+export default Uploads;
\ No newline at end of file
diff --git a/src/forge/Source/UploadSource.jsx b/src/forge/Source/UploadSource.jsx
new file mode 100644
index 00000000..64bd5b7c
--- /dev/null
+++ b/src/forge/Source/UploadSource.jsx
@@ -0,0 +1,150 @@
+import React , { forwardRef, useEffect, useState } from 'react';
+import { Modal , Form , Checkbox , Input , Table } from 'antd';
+import Upload from './Upload';
+import { AlignCenter } from '../Component/layout';
+import axios from 'axios';
+const { TextArea } = Input;
+
+const https = 'https://testfiles.trustie.net';
+function UploadSource({ form , visible , onCancel , onOk , showNotification , attachments , id ,owner,projectsId}){
+ const [ tableData , setTableData ] = useState(undefined);
+ const [ fileId , setFilesId ] = useState(undefined);
+ const [ fileName , setFileName ] = useState(undefined);
+ const { getFieldDecorator, validateFields , setFieldsValue } = form;
+
+ useEffect(()=>{
+ if(id && attachments){
+ setTableData(attachments);
+ }
+ },[id,attachments])
+ // 上传附件后得到的文件id数组
+ function UploadFunc(id,name){
+ setFilesId(id);
+ setFileName(name);
+ }
+
+ const columns = [
+ {
+ dataIndex:"fileName",
+ key:"fileName",
+ title:"资源名称",
+ width:"42%",
+ ellipsis:true,
+ render:(value,item,key)=>{
+ return
+ {value}
+ { key === 0 && 当前版本 }
+
+ }
+ },
+ {
+ dataIndex:"downloads",
+ key:"downloads",
+ title:"下载数",
+ width:"14%",
+ className:"edu-txt-center"
+ },
+ {
+ dataIndex:"fileSizeString",
+ key:"fileSizeString",
+ title:"文件大小",
+ width:"16%",
+ className:"edu-txt-center"
+ },
+ {
+ dataIndex:"createdAt",
+ key:"createdAt",
+ title:"上传时间",
+ }
+ ]
+
+ // 确定
+ function submit(){
+ if(fileId){
+ validateFields((error,values)=>{
+ if(!error){
+ postInfo(values);
+ }
+ })
+ }else{
+ showNotification("请先上传文件!");
+ }
+ }
+
+ function postInfo(values){
+ const url = https+`/api/project/achievement/`;
+ if(id){
+ // 修改
+ axios.put(url,{
+ id,fileName,fileId:`${fileId}`,
+ remark:values.remark
+ }).then(result=>{
+ if(result && result.data){
+ onOk();
+ }
+ }).catch(error=>{})
+ }else{
+ // 上传
+ axios.post(url,{
+ fileId:`${fileId}`,
+ fileName,
+ login:owner,
+ projectId:projectsId,
+ ...values
+ }).then(result=>{
+ if(result && result.data){
+ onOk();
+ }
+ }).catch(error=>{})
+ }
+
+ }
+ return(
+
+