diff --git a/src/forge/Server/Index.jsx b/src/forge/Server/Index.jsx
index cdcb8bbcd..4a6547d47 100644
--- a/src/forge/Server/Index.jsx
+++ b/src/forge/Server/Index.jsx
@@ -13,10 +13,20 @@ const Data = Loadable({
loader: () => import('./data'),
loading: Loading,
})
+// 跨平台代码同步服务
+const Reposyncer = Loadable({
+ loader: () => import('./reposyncer'),
+ loading: Loading,
+})
function ServerIndex(props){
return(
+ ()
+ }
+ >
()
diff --git a/src/forge/Server/List.jsx b/src/forge/Server/List.jsx
index 3e49e8158..ea89393ea 100644
--- a/src/forge/Server/List.jsx
+++ b/src/forge/Server/List.jsx
@@ -1,4 +1,5 @@
import React,{useState , useEffect} from 'react';
+import { Link } from 'react-router-dom';
import AgreementModal from './agreementModal';
function Main(props){
@@ -41,6 +42,16 @@ function Main(props){
查看详情
+
+
+
+ Reposyncer仓库同步系统
+
+ 支持不同开源托管平台自动同步推送/拉取相关代码,实现多平台项目同步开发功能
+
+ 查看详情
+
+
)
diff --git a/src/forge/Server/img/bg1.png b/src/forge/Server/img/bg1.png
new file mode 100644
index 000000000..229ff93d6
Binary files /dev/null and b/src/forge/Server/img/bg1.png differ
diff --git a/src/forge/Server/img/bg2.png b/src/forge/Server/img/bg2.png
new file mode 100644
index 000000000..47602e0ef
Binary files /dev/null and b/src/forge/Server/img/bg2.png differ
diff --git a/src/forge/Server/img/gitee.png b/src/forge/Server/img/gitee.png
new file mode 100644
index 000000000..221862be2
Binary files /dev/null and b/src/forge/Server/img/gitee.png differ
diff --git a/src/forge/Server/img/gitee1.svg b/src/forge/Server/img/gitee1.svg
new file mode 100644
index 000000000..3b1577126
--- /dev/null
+++ b/src/forge/Server/img/gitee1.svg
@@ -0,0 +1,8 @@
+
diff --git a/src/forge/Server/img/github.png b/src/forge/Server/img/github.png
new file mode 100644
index 000000000..213968a36
Binary files /dev/null and b/src/forge/Server/img/github.png differ
diff --git a/src/forge/Server/img/github2.svg b/src/forge/Server/img/github2.svg
new file mode 100644
index 000000000..6dde707a9
--- /dev/null
+++ b/src/forge/Server/img/github2.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/forge/Server/img/logo2.png b/src/forge/Server/img/logo2.png
new file mode 100644
index 000000000..be5d0257c
Binary files /dev/null and b/src/forge/Server/img/logo2.png differ
diff --git a/src/forge/Server/reposyncer/component/editStore.jsx b/src/forge/Server/reposyncer/component/editStore.jsx
new file mode 100644
index 000000000..0e6362d57
--- /dev/null
+++ b/src/forge/Server/reposyncer/component/editStore.jsx
@@ -0,0 +1,57 @@
+import React, {forwardRef, useState} from "react";
+import { Button, Form, Input } from "antd";
+import gitHub from '../../img/github.png';
+import gitee from '../../img/gitee.png';
+import '../index.scss';
+
+function EditStore(props){
+ const { form, history} = props;
+ const { getFieldDecorator, validateFields , setFieldsValue } = form;
+
+ return
+}
+export default Form.create()(forwardRef(EditStore));
\ No newline at end of file
diff --git a/src/forge/Server/reposyncer/component/recordList.jsx b/src/forge/Server/reposyncer/component/recordList.jsx
new file mode 100644
index 000000000..e29efeefd
--- /dev/null
+++ b/src/forge/Server/reposyncer/component/recordList.jsx
@@ -0,0 +1,84 @@
+import React, {useState} from "react";
+import { Table } from 'antd';
+import gitHub from '../../img/github.png';
+import gitee from '../../img/gitee.png';
+import '../index.scss';
+
+function RecordList(props){
+ const [loading, setLoading] = useState(false);
+ const [data, setData] = useState([{id: 1, name: 'gitHub', content: 'commit', time: '2022.5.12', status: '0', last: 'aaaaaa', info: 'hajahjah'}]);
+ // table
+ const [current, setCurrent] = useState(1);
+ const [total, setTotal] = useState(0);
+ const [pageSize, setPageSize] = useState(20);
+ const [expandedRowKeys, setExpandedRowKeys] = useState([]);
+
+ const columns = [
+ { title: '序号', dataIndex: 'index', className:"recordColumns", render: (text, item, index) => {(current-1)*pageSize+index + 1} },
+ { title: '同步平台', dataIndex: 'name', className:"recordColumns taskName", render: (text, item) => text === 'gitHub' ?
:
},
+ { title: '同步内容', dataIndex: 'content', className:"recordColumns"},
+ { title: '同步时间', dataIndex: 'time', className:"recordColumns"},
+ { title: '同步状态', dataIndex: 'status', className:"recordColumns", render: (text) => text === '0' ? 错误 : 完成 },
+ { title: '最后一次哈希值', dataIndex: 'last', className:"primaryColor recordColumns"},
+ { title: '同步日志', dataIndex: 'action', align: 'center', className:"primaryColor recordColumns"},
+ ]
+
+ const customExpandIcon = (props) => {
+ if (props.expanded) {
+ return {
+ props.onExpand(props.record, e);
+ }}>查看
+ } else {
+ return {
+ props.onExpand(props.record, e);
+ }}>查看
+ }
+ }
+
+ const expandRow = (record) => {
+ return
+ {record.info}
+
+ }
+
+ // 展开收起行回调
+ function onExpand(expanded, record){
+ const keys = new Set(expandedRowKeys);
+ if(expanded){
+ keys.add(record.id);
+ }else{
+ keys.delete(record.id);
+ }
+ setExpandedRowKeys(Array.from(keys));
+ }
+
+ // 改变pagesize
+ function onShowSizeChange(current, pageSize){
+ window.scrollTo(0, 0);
+ setCurrent(1);
+ setPageSize(pageSize);
+ }
+
+ // 切换页数
+ function changePage(page, pageSize){
+ window.scrollTo(0, 0);
+ setCurrent(page);
+ }
+
+ return
+}
+export default RecordList;
\ No newline at end of file
diff --git a/src/forge/Server/reposyncer/component/storeList.jsx b/src/forge/Server/reposyncer/component/storeList.jsx
new file mode 100644
index 000000000..a3211c3da
--- /dev/null
+++ b/src/forge/Server/reposyncer/component/storeList.jsx
@@ -0,0 +1,49 @@
+import React, { useState} from "react";
+import { Button, Modal } from "antd";
+import { Link } from "react-router-dom";
+import gitHub1 from '../../img/github2.svg';
+import gitee1 from '../../img/gitee1.svg';
+import '../index.scss';
+
+function StoreList(props){
+ const { owner , projectsId } = props.match.params;
+ const [info, setInfo] = useState({gitHub: 'aaaaaaaa', gitee: 'bbbbbbbbb'});
+ const [visible, setVisible] = useState(false);
+
+ function updateStore(){
+
+ }
+ return
+
+
已绑定仓库地址
+
+
+
Github仓库地址
+
{info.gitHub}
+
+
+
+
+
+
Gitee仓库地址
+
{info.gitee}
+
+
+
+
+
+
{setVisible(false)}}
+ footer={}
+ width={486}
+ className="cancelBound"
+ >
+ !您确定要取消此仓库地址的绑定吗?
+ 缺文案
+
+
+}
+export default StoreList;
\ No newline at end of file
diff --git a/src/forge/Server/reposyncer/index.jsx b/src/forge/Server/reposyncer/index.jsx
new file mode 100644
index 000000000..1c3730ff5
--- /dev/null
+++ b/src/forge/Server/reposyncer/index.jsx
@@ -0,0 +1,76 @@
+import React, {useState} from "react";
+import { Button, Tooltip } from "antd";
+import './index.scss';
+import logo from '../img/logo2.png';
+import Loadable from "react-loadable";
+import { Route, Switch } from "react-router";
+import Loading from "../../../Loading";
+import { Link } from "react-router-dom";
+
+// 编辑同步仓库页面
+const EditStore = Loadable({
+ loader: () => import("./component/editStore"),
+ loading: Loading,
+});
+// 同步仓库页面
+const StoreList = Loadable({
+ loader: () => import("./component/storeList"),
+ loading: Loading,
+});
+// 同步记录页面
+const RecordList = Loadable({
+ loader: () => import("./component/recordList"),
+ loading: Loading,
+});
+
+function Reposyncer(propsF){
+ const {pathname} = propsF.location;
+ const { owner , projectsId } = propsF.match.params;
+
+ const [storeList, setStoreList] = useState([]);
+
+ return
+
Reposyncer仓库同步系统
+ {(storeList.length !== 0) && ?}
+
+ {(storeList.length === 0 && pathname.endsWith('/reposyncer')) ?
+

+
欢迎使用跨平台代码同步系统
+
跨平台代码同步系统提供跨托管平台的项目协同开发同步功能。支持用户在任何一个托管平台上的代码提交、代码推送、合并请求等操作自动同步至其他托管平台。不仅增加每个开源项目与开发者的流量,也使不同平台的开源项目维护与更新变得方便与快捷
+
+
+
:
+
+ 仓库绑定
+ 同步记录
+
+
+ (
+
+ )}
+ >
+ (
+
+ )}
+ >
+ (
+
+ )}
+ >
+ (
+
+ )}
+ >
+
+
}
+
+}
+export default Reposyncer;
\ No newline at end of file
diff --git a/src/forge/Server/reposyncer/index.scss b/src/forge/Server/reposyncer/index.scss
new file mode 100644
index 000000000..86688e874
--- /dev/null
+++ b/src/forge/Server/reposyncer/index.scss
@@ -0,0 +1,217 @@
+.red_border_but, .red_border_but:focus{
+ color:#f60011;
+ background-color:rgba(196, 0, 14, 0.09);
+ border:1px solid #f60011;
+ border-radius:5px;
+ &:hover{
+ color:#f60011;
+ background-color:rgba(196, 0, 14, 0.18);
+ border-color:#ff727c;
+ }
+ &:active{
+ color:#f60011;
+ background-color:rgba(196, 0, 14, 0.22);
+ border-color:#f60011;
+ }
+}
+.reposyncerBox{
+ padding-bottom: 60px;
+ .headBox{
+ height:60px;
+ line-height: 60px;
+ background-color:#fafcff;
+ border:1px solid rgba(42, 97, 255, 0.23);
+ border-radius:3px 3px 0px 0px;
+ color:#333333;
+ }
+ .helpBox1{
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ color: white;
+ background-color: #466aff;
+ line-height: normal;
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ cursor: default;
+ }
+ .nullStoreBox{
+ background-color:#fafcff;
+ border-radius:4px 4px 0px 0px;
+ text-align: center;
+ color:#333333;
+ padding-bottom: 65px;
+ .loBox{width: 68px;}
+ .introBox{
+ color:#666666;
+ width: 57%;
+ margin: 15px auto;
+ }
+ .borBox{
+ width: 45%;
+ margin: 0 auto 20px;
+ border-bottom: 1px solid rgba(90, 117, 193, 0.23);
+ }
+ }
+ .rightContentBox{
+ display: flex;
+ .leftNav{
+ width: 185px;
+ margin-right: 36px;
+ background-size: 100% 100%;
+ background-image: url('../img/bg1.png');
+ .oneBox{
+ padding: 15px;
+ color:#4c5b76;
+ display: block;
+ &.active{
+ position: relative;
+ background-color:rgba(70, 106, 255, 0.06);
+ color: $primary-color;
+ &::before{
+ content: '';
+ position: absolute;
+ width: 4px;
+ height: 86%;
+ left: 0;
+ top: 4px;
+ background-color: $primary-color;
+ }
+ }
+ }
+ }
+ }
+}
+.storeListBox{
+ flex: 1;
+ .storeTitle{
+ font-weight:700;
+ color:#151d40;
+ border-bottom: 1px solid #e0e6f5;;
+ }
+ .registerBox{
+ .storeLogo{
+ width: 75px;
+ }
+ .storeFormItem{
+ width: 70%;
+ }
+ #gitHubToken, #giteeToken, .storeInput{
+ border-color: #9eaacb;
+ height: 36px;
+ &:hover{border-color: $primary-color;}
+ }
+ .storeInput .ant-input-group-addon{
+ border-color: #9eaacb;
+ }
+ .tipStoreBox{
+ color: #4c5b76;
+ line-height: 30px;
+ padding: 10px 0 30px;
+ }
+ }
+ .listStore{
+ .showStoreInfo{
+ padding: 20px 0 10px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ &.dashedBor{
+ border-bottom: 1px dashed #e0e6f5;
+ }
+ }
+ .infoBox{
+ color:#99a2af;
+ }
+ .sTil{
+ color:#202d40;
+ display: flex;
+ align-items: flex-start;
+ }
+ }
+ th.recordColumns{
+ background-color: rgba(90, 117, 193, 0);
+ .ant-table-column-title{
+ font-family:PingFang SC;
+ font-size: 16px;
+ font-weight: 700;
+ color:#202d40;
+ }
+ }
+ .ant-table-tbody > tr > td.recordColumns{
+ color: #333;
+ font-size: 15px;
+ border-bottom: 1px dashed #e0e6f5;
+ &.primaryColor{color: $primary-color;}
+ }
+ tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) td.recordColumns{
+ background-color:#f8f9ff !important;
+ }
+ .statusBox{
+ width:58px;
+ height:32px;
+ border-radius:4px;
+ display: inline-block;
+ text-align: center;
+ &.errorBox{
+ color:#ff0c0c;
+ background-color:rgba(230, 0, 6, 0.1);
+ border:1px solid #fcb6c2;;
+ }
+ &.accomplish{
+ color:#009c44;
+ background-color:rgba(83, 255, 163, 0.1);
+ border:1px solid #00b843;;
+ }
+ }
+ .primaryColor{color: $primary-color;}
+}
+.cancelBound{
+ .ant-modal-header{
+ padding: 10px 25px;
+ background-color: #f8f8f8;
+ .ant-modal-title{
+ font-size: 14px;
+ text-align: left;
+ font-weight: normal !important;
+ }
+ }
+ .ant-modal-close{
+ top: 0 !important;
+ .ant-modal-close-x{font-size: 26px;}
+ }
+ .bTilModal{
+ color:#333333;
+ .errorRedSpan{
+ display: inline-block;
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ color: white;
+ background-color:#ca0002;
+ line-height: 36px;
+ text-align: center;
+ }
+ }
+ .sTilModal{
+ color:#666666;
+ margin: 30px 0 40px 70px;
+ }
+ .ant-modal-footer{
+ border-top: none;
+ text-align: center;
+ padding-bottom: 50px;
+ .okBut, .okBut:focus{
+ color:#df0002;
+ border-color: #d9d9d9;
+ margin-left: 43px;
+ &:hover{
+ border-color:#ff727c;
+ }
+ &:active{
+ border-color:#f60011;
+ }
+ }
+ }
+}
\ No newline at end of file