From 602d4a748a5444c591cd0237ef6f4fbcd53411b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E6=80=9D?= <2897217417@qq.com> Date: Tue, 22 Aug 2023 09:55:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E5=BB=BA=E7=AB=99+=E8=BA=AB?= =?UTF-8?q?=E4=BB=BD=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/forge/SecuritySetting/Index.jsx | 20 +- .../SecuritySetting/website/createSite.jsx | 177 +++++++++++++++++ src/forge/SecuritySetting/website/index.scss | 26 ++- .../SecuritySetting/website/mySiteList.jsx | 64 +++++- src/forge/Server/Index.jsx | 11 ++ src/forge/Server/List.jsx | 10 + src/forge/Server/pages/index.jsx | 187 ++++++++++++++++++ src/forge/Server/pages/index.scss | 8 + src/forge/users/Material/verification.jsx | 8 +- 9 files changed, 495 insertions(+), 16 deletions(-) create mode 100644 src/forge/SecuritySetting/website/createSite.jsx create mode 100644 src/forge/Server/pages/index.jsx create mode 100644 src/forge/Server/pages/index.scss diff --git a/src/forge/SecuritySetting/Index.jsx b/src/forge/SecuritySetting/Index.jsx index cdabd86d3..82e2155c0 100644 --- a/src/forge/SecuritySetting/Index.jsx +++ b/src/forge/SecuritySetting/Index.jsx @@ -70,6 +70,10 @@ const Mysite = Loadable({ loader: () => import("./website/mySiteList"), loading: Loading, }); +const CreateSite = Loadable({ + loader: () => import("./website/createSite"), + loading: Loading, +}); function Index(props){ const { current_user,mygetHelmetapi , checkIfLogin } = props; @@ -78,7 +82,6 @@ function Index(props){ const [ avatarVisible , setAvatarVisible ] = useState(false); const [active, setActive] = useState(1); - console.log('active', active); useEffect(()=>{ if(checkIfLogin() === false){ @@ -87,7 +90,7 @@ function Index(props){ },[]) useEffect(()=>{ - console.log('pathname', pathname, ["/settings/profile"].indexOf(pathname)); + const pattern = /^\/settings\/installbot\/\d+$/; if(["/settings/profile"].indexOf(pathname) !== -1){ setActive(1); }else if(["/settings/emails", "/settings/phone", "/settings/password", "/settings/cancel"].indexOf(pathname) !== -1){ @@ -100,11 +103,11 @@ function Index(props){ setActive(5); }else if(["/settings/CLA"].indexOf(pathname) !== -1){ setActive(6); - }else if(["/settings/mybot"].indexOf(pathname) !== -1){ + }else if(["/settings/mybot", "/settings/mybot/new"].indexOf(pathname) !== -1){ setActive(7); - }else if(["/settings/installbot"].indexOf(pathname) !== -1){ + }else if(["/settings/installbot"].indexOf(pathname) !== -1 || pattern.test(pathname)){ setActive(8); - }else if(["/settings/mysite"].indexOf(pathname) !== -1){ + }else if(["/settings/mysite", "/settings/mysite/create"].indexOf(pathname) !== -1){ setActive(9); } }, [pathname]) @@ -262,6 +265,13 @@ function Index(props){ )} > + {/* 创建站点 */} + ( + + )} + > {/* 个人建站 */} { + document.title = "创建站点"; + }, []); + + useEffect(()=>{ + axios.get(`/site_pages/themes.json`, {params: {language_frame: language === 1 ? "jekyll" : language === 2 ? "hexo" : "hugo"}}).then(res=>{ + if(res && res.status === 200){ + setThemes(res.data.themes); + setTheme(res.data.themes[0]) + } + }) + }, [language]) + + useEffect(()=>{ + if(theme && theme.clone_url && theme && theme.clone_url.indexOf("/") > -1){ + let arr = theme && theme.clone_url.split("/"); + let first = arr[arr.length-1]; + if(first.indexOf(".") > -1){ + let second = first.split('.')[0]; + if(!second)return; + setFieldsValue({ + repository_name:second, + name:second + }) + }else{ + setFieldsValue({ + repository_name:first + }) + } + } + }, [theme]) + + function submit(e) { + e.preventDefault(); + validateFieldsAndScroll((err, values) => { + if (!err) { + axios.post(`/projects/page_migrate.json`,{ + ...values, + clone_addr: theme && theme.clone_url, + theme: theme && theme.name, + user_id: current_user.user_id + }).then(res=>{ + if(res && res.status === 200){ + message.success("新建成功"); + history.push(`/settings/mysite`); + } + }) + } + }); + } + + return ( + + 我的站点 / 新建站点 + + + {getFieldDecorator("site_name", { + rules: [{ required: true, message: "请输入站点名称" }], + })()} + + + {getFieldDecorator("identifier", { + rules: [{ required: true, message: "请输入站点标识" }], + })( + { + setTag(e.target.value); + }} + placeholder="请输入站点标识" + /> + )} + + http://{current_user.login}.kingchan.cn/{tag} + + + + {getFieldDecorator("language_frame", {initialValue: 0})( + {setLanguage(value)}}> + hugo + jekyll + hexo + + )} + + + + {themes && themes.map(item=>{ + const {imgage_url, name, clone_url} = item; + return {setTheme(item)}}> + + + {name} + + })} + + + + + + + {/* / */} + + {getFieldDecorator("name", { + rules: [{ required: true, message: "请输入项目名称" }], + })( + + )} + + + + {getFieldDecorator("repository_name", { + rules: [{ required: true, message: "请输入项目标识" }], + })( + + )} + + + {getFieldDecorator("description", {})( + + )} + + + + 创建站点 + + { + history.push("/settings/mysite"); + }} + > + 取消 + + + + + ); +} +export default Form.create()(CreateSite); diff --git a/src/forge/SecuritySetting/website/index.scss b/src/forge/SecuritySetting/website/index.scss index 89b9d18c0..a8d921d4a 100644 --- a/src/forge/SecuritySetting/website/index.scss +++ b/src/forge/SecuritySetting/website/index.scss @@ -1,8 +1,30 @@ -.default_head{ +.mySites_head{ height: 65px; line-height: 64px; border-bottom: 1px solid rgba(224, 230, 245, 1); color:#151d40; font-size:17px; - padding-bottom:20px; +} +.createSiteForm{ + .themeBox{ + text-align: center; + position: relative; + cursor: pointer; + } + .icon-wancheng{ + position: absolute; + right: 4px; + top: -7px; + color: #e5e3e0; + &.active{ + color: #ffa13a; + } + } +} +.siteBox{ + padding: 15px 0; + border-bottom: 1px dashed #e0e6f5; + .siteName{ + color: $primary-color; + } } \ No newline at end of file diff --git a/src/forge/SecuritySetting/website/mySiteList.jsx b/src/forge/SecuritySetting/website/mySiteList.jsx index 4c2417778..5efe6cc3c 100644 --- a/src/forge/SecuritySetting/website/mySiteList.jsx +++ b/src/forge/SecuritySetting/website/mySiteList.jsx @@ -1,16 +1,70 @@ import React, { useState, useEffect, Fragment } from "react"; -import { Button, Icon, message, Modal } from "antd"; +import { Button, Spin } from "antd"; import './index.scss'; +import '../../users/Material/Index.scss'; +import '../bot/exploit/index.scss' +import axios from "axios"; +import Nodata from "../../Nodata"; +import { FlexAJ } from "../../Component/layout"; function MySiteList(props){ - const {current_user} = props; + const {current_user, history} = props; + const {id_card_verify} = current_user; + const [total, setTotal] = useState(0); + const [pages, setPages] = useState([]); + const [loading, setLoading] = useState(false); useEffect(()=>{ document.title='我的站点'; }, []) - return - 我的站点 - + useEffect(()=>{ + if(id_card_verify){ + setLoading(true); + // 获取站点列表 + axios.get(`/site_pages.json`).then(res=>{ + if(res && res.status === 200){ + const {total_count, pages} = res.data; + setPages(pages); + setTotal(total_count); + } + setLoading(false); + }) + } + }, [id_card_verify]) + + return + + 我的站点 + {id_card_verify && {history.push(`/settings/mysite/create`)}}>新建站点} + + {/* 未通过实名认证 */} + {!id_card_verify && + 您尚未通过实名认证,无法使用此服务,如需使用,请先进行实名认证。 + {history.push(`/settings/verification`)}}>前往验证 + } + + {/* 通过实名认证 */} + {id_card_verify && + {!loading && total === 0 ? : + {pages && pages.map(item=>{ + const {owner, repo, url, last_build_at} = item + return + + + {last_build_at && window.open(url)}}>{item.site_name} + {last_build_at ? "已部署" : "未部署"} + + 主题: {item.theme} + | + 建站工具:{item.language_frame} + + + {history.push(`/${owner}/${repo}/service/pages`)}}>去仓库 + + })} + } + } + } export default MySiteList; \ No newline at end of file diff --git a/src/forge/Server/Index.jsx b/src/forge/Server/Index.jsx index ef62dc12f..d50d49adb 100644 --- a/src/forge/Server/Index.jsx +++ b/src/forge/Server/Index.jsx @@ -18,6 +18,11 @@ const Reposyncer = Loadable({ loader: () => import('./reposyncer'), loading: Loading, }) +// 个人建站服务 +const Pages = Loadable({ + loader: () => import('./pages'), + loading: Loading, +}) function ServerIndex(props){ return( @@ -32,6 +37,12 @@ function ServerIndex(props){ () => () } > + {/* 个人建站服务 */} + () + } + > () diff --git a/src/forge/Server/List.jsx b/src/forge/Server/List.jsx index e1c59ff10..bbee0d608 100644 --- a/src/forge/Server/List.jsx +++ b/src/forge/Server/List.jsx @@ -64,6 +64,16 @@ function Main(props){ 查看详情 */} + + + + 个人建站服务 + + 支持Hugo、Jekyll、Hexo静态网站服务 + + 查看详情 + + ) diff --git a/src/forge/Server/pages/index.jsx b/src/forge/Server/pages/index.jsx new file mode 100644 index 000000000..e7f9ac05c --- /dev/null +++ b/src/forge/Server/pages/index.jsx @@ -0,0 +1,187 @@ +import React, { Fragment, useEffect, useState } from 'react'; +import { Spin, message, Button, Form, Input, Select, Descriptions } from 'antd'; +import axios from 'axios'; +import SelectBranch from '../../../forge/Branch/Select'; +import './index.scss'; +import { Link } from 'react-router-dom'; + +function Pages(props) { + const {current_user, history, form, projectDetail, defaultBranch} = props; + const { owner , projectsId } = props.match.params; + const {id_card_verify} = current_user; + const { getFieldDecorator, validateFieldsAndScroll } = form; + const [reload, setReload] = useState(undefined); + const [loading, setLoading] = useState(false); + const [pageInfo, setPageInfo] = useState(undefined); + const [tag, setTag] = useState(undefined); + const [branch, setBranch ] = useState(null); + const [building, setBuilding] = useState(false); + const [isBuild, setIsBuild] = useState(false); + const [result, setResult] = useState(undefined); + + useEffect(()=>{ + // 更新网页标题 + if(projectDetail){ + const { author, name} = projectDetail; + document.title = `个人建站-${author.name}/${name}`; + } + }, [projectDetail]) + + useEffect(()=>{ + if(id_card_verify){ + setLoading(true); + // 获取站点列表 + axios.get(`/site_pages/x.json`, {params:{owner, repo: projectsId}}).then(res=>{ + if(res && res.status === 200){ + setPageInfo(res.data.data) + } + setLoading(false); + }) + } + }, [id_card_verify, reload]) + + // 基于仓库创建站点 + function submit(e) { + e.preventDefault(); + validateFieldsAndScroll((err, values) => { + if (!err) { + axios.post(`/site_pages.json`,{ + ...values, + owner, + repo: projectsId + }).then(res=>{ + if(res && res.status === 200){ + setReload(Math.random()); + message.success("创建成功"); + } + }) + } + }); + } + + // 部署 + function startBuild(){ + setBuilding(true); + axios.post(`/site_pages/${pageInfo.id}/build.json`,{ + owner, + repo: projectsId, + branch: branch || defaultBranch + }).then(res=>{ + if(res && res.data && res.data.status === 0){ + setResult(res.data.data); + }else{ + message.error((res && res.data && res.data.message) || "部署失败,请稍后重试"); + } + setBuilding(false); + }) + } + + return ( + + + 个人建站服务{!pageInfo && !loading && id_card_verify && ' - 新建站点'} + + {/* 未通过实名认证 */} + {!id_card_verify && + 您尚未通过实名认证,无法使用此服务,如需使用,请先进行实名认证。 + {history.push(`/settings/verification`)}}>前往验证 + } + {id_card_verify && + {/* 未开通 */} + {!pageInfo && + + {getFieldDecorator("site_name", { + rules: [{ required: true, message: "请输入站点名称" }], + })()} + + + {getFieldDecorator("identifier", { + rules: [{ required: true, message: "请输入站点标识" }], + })( + { + setTag(e.target.value); + }} + placeholder="请输入站点标识" + /> + )} + + http://{current_user.login}.kingchan.cn/{tag} + + + + {getFieldDecorator("language_frame", {initialValue: 0})( + + hugo + jekyll + hexo + + )} + + + + 创建站点 + + { + history.push(`/${owner}/${projectsId}/service`); + }} + > + 取消 + + + } + {/* 已开通 */} + {pageInfo && + + {window.open(pageInfo.url)}} className='theme-btn'>{pageInfo.site_name} + {pageInfo.url} + {pageInfo.language_frame} + {pageInfo.created_at} + {pageInfo.last_build_at && {pageInfo.last_build_at}} + + {!isBuild && {setIsBuild(true)}}>去部署} + {isBuild && + 部署 + + 部署分支: + {setBranch(params)}} + owner={owner} + history={props.history} + tagflag={false} + branchList={projectDetail && projectDetail.branches && projectDetail.branches.list} + > + 选择您要部署的分支 + + + 确定 + {setIsBuild(false)}} className='ml30'>取消 + + } + } + {result && + 部署结果 + {result.map(item=> {item})} + } + } + + ) +} +export default Form.create()(Pages); \ No newline at end of file diff --git a/src/forge/Server/pages/index.scss b/src/forge/Server/pages/index.scss new file mode 100644 index 000000000..24c4d753a --- /dev/null +++ b/src/forge/Server/pages/index.scss @@ -0,0 +1,8 @@ +.buildResult{ + padding: 10px 20px; + background-color: rgb(20, 20, 20); + color: white; +} +.theme-btn{ + color: $primary-color; +} \ No newline at end of file diff --git a/src/forge/users/Material/verification.jsx b/src/forge/users/Material/verification.jsx index 2fb684145..5b2014a85 100644 --- a/src/forge/users/Material/verification.jsx +++ b/src/forge/users/Material/verification.jsx @@ -9,7 +9,7 @@ import { getImageUrl } from '../../../common/UrlTool'; export default Form.create()( forwardRef((props)=>{ const { getFieldDecorator, validateFields , setFieldsValue } = props && props.form; - const { resetUserInfo , current_user } = props; + const { current_user } = props; const [loading, setLoading] = useState(false); const [data, setData] = useState(undefined); const [reload, setReload] = useState(undefined); @@ -18,7 +18,7 @@ export default Form.create()( if(current_user && current_user.login){ setLoading(true); // 获取用户身份认证信息 - axios.get(`http://ng.learnerhub.net/api/identity_verifications.json`).then(res=>{ + axios.get(`/identity_verifications.json`).then(res=>{ setLoading(false); if(res && res.status === 200){ if(res.data && res.data.status === 0){ @@ -38,7 +38,7 @@ export default Form.create()( validateFields((error, values) => { if (!error) { if(data){ - axios.put(`http://ng.learnerhub.net/api/identity_verifications/${data.id}.json`, values).then(res => { + axios.put(`/identity_verifications/${data.id}.json`, values).then(res => { if(res && res.status === 200){ message.success("提交成功"); setReload(Math.random()); @@ -46,7 +46,7 @@ export default Form.create()( }).catch((error) => {}); }else{ // 新增 - axios.post(`http://ng.learnerhub.net/api/identity_verifications.json`, values).then(res=>{ + axios.post(`/identity_verifications.json`, values).then(res=>{ if(res && res.status === 200){ message.success("提交成功"); setReload(Math.random());
{name}
支持Hugo、Jekyll、Hexo静态网站服务
{item}