' + text + ''
+ return '' + text + ''
}
marked.setOptions({
silent: true,
diff --git a/src/components/render-html.jsx b/src/components/render-html.jsx
index 3b7e4b520..9eafa5c74 100644
--- a/src/components/render-html.jsx
+++ b/src/components/render-html.jsx
@@ -31,6 +31,7 @@ export default ({
rs = rs.replace("[TOC]
", getTocContent())
cleanToc()
}
+ // 循环匹配所有emoji
let matchStr = str.match(strRegexSub);
if(matchStr && matchStr.length>0){
for(var i=0;i < matchStr.length;i++){
diff --git a/src/forge/Account/Index.jsx b/src/forge/Account/Index.jsx
new file mode 100644
index 000000000..18087d324
--- /dev/null
+++ b/src/forge/Account/Index.jsx
@@ -0,0 +1,38 @@
+import React , { useState } from 'react';
+import './index.scss';
+import logo from './image/logo.png';
+import { Menu } from 'antd';
+import Bind from './bind';
+import UnBind from './unbind';
+
+function Index(props){
+ const [ key , setKey ] = useState("0");
+
+ // 选择menu
+ function chooseMenuFunc(e){
+ setKey(e.key)
+ }
+ return(
+
+
+

+
+
+
关联账号
+
+
+ {
+ key === "0" ?
+
+ :
+
+ }
+
+
+
+ )
+}
+export default Index;
\ No newline at end of file
diff --git a/src/forge/Account/bind.jsx b/src/forge/Account/bind.jsx
new file mode 100644
index 000000000..33453191b
--- /dev/null
+++ b/src/forge/Account/bind.jsx
@@ -0,0 +1,99 @@
+import React ,{ useState } from 'react';
+import { Form , Input , Button } from 'antd';
+import phone from './image/phone.svg';
+import lock from "./image/lock.png";
+import axios from 'axios';
+
+
+const phonereg = /^([1][3456789])\d{9}$/
+const emailreg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
+function Bind(props){
+ const { form } = props;
+
+ const { getFieldDecorator , getFieldsValue } = form;
+ const [ bindFlag , setBindFlag] = useState(true);
+ const type = props.match.params.type;
+
+ // 绑定登录
+ function bindloginFunc(){
+ const {username, password } = getFieldsValue();
+ if(username && password){
+ var url = '/bind_user.json';
+ axios.post(url,{
+ username,password,type
+ }).then(result=>{
+ if(result){
+ window.location.href = "/"+result.data.login;
+ }
+ })
+ }
+ }
+
+ function accountConfirm(r,v,c){
+ if(v){
+ const {password } = getFieldsValue();
+ if(!(phonereg.test(v) || emailreg.test(v))){
+ setBindFlag(true);
+ c(`请输入正确的手机号或邮箱地址`);
+ }else if(password){
+ setBindFlag(false);
+ }
+ }else{
+ c();
+ setBindFlag(true);
+ }
+ }
+ function psdConfirm(r,v,c){
+ if(v){
+ const { username } = getFieldsValue();
+ if(phonereg.test(username) || emailreg.test(username)){
+ setBindFlag(false);
+ }else{
+ setBindFlag(true);
+ }
+ }else{
+ c();
+ setBindFlag(true);
+ }
+ }
+ return(
+
+
+ {getFieldDecorator('username',{
+ rules:[
+ {
+ required:true,
+ message:"请输入手机号或邮箱地址"
+ },
+ {
+ validator: (rule, value, callback) => { accountConfirm(rule, value, callback) }
+ }
+ ],
+ validateTrigger:"onInput",
+ })(} size="large" placeholder="请输入手机号或邮箱地址"/>)}
+
+
+ {getFieldDecorator('password', {
+ rules: [
+ {
+ required:true,
+ message:"请输入登录密码"
+ },
+ {
+ validator: (rule, value, callback) => { psdConfirm(rule, value, callback) }
+ }
+ ],
+ validateTrigger:"onInput",
+ })(
+ } className="psd" size="large" placeholder="请输入登录密码" />,
+ )}
+
+
+
+
+ )
+}
+export default Form.create({ name: 'Bind' })(Bind);
\ No newline at end of file
diff --git a/src/forge/Account/image/lock.png b/src/forge/Account/image/lock.png
new file mode 100644
index 000000000..4d5d27c2f
Binary files /dev/null and b/src/forge/Account/image/lock.png differ
diff --git a/src/forge/Account/image/logo.png b/src/forge/Account/image/logo.png
new file mode 100644
index 000000000..d474b79d2
Binary files /dev/null and b/src/forge/Account/image/logo.png differ
diff --git a/src/forge/Account/image/phone.svg b/src/forge/Account/image/phone.svg
new file mode 100644
index 000000000..a33d110a9
--- /dev/null
+++ b/src/forge/Account/image/phone.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/forge/Account/image/shield.png b/src/forge/Account/image/shield.png
new file mode 100644
index 000000000..475867bf3
Binary files /dev/null and b/src/forge/Account/image/shield.png differ
diff --git a/src/forge/Account/image/user.png b/src/forge/Account/image/user.png
new file mode 100644
index 000000000..4f03d6c71
Binary files /dev/null and b/src/forge/Account/image/user.png differ
diff --git a/src/forge/Account/index.scss b/src/forge/Account/index.scss
new file mode 100644
index 000000000..1c9de9ccd
--- /dev/null
+++ b/src/forge/Account/index.scss
@@ -0,0 +1,85 @@
+.bodies{
+ height: 100vh;
+ width: 100%;
+ background-color: rgba(245, 248, 255, 1);
+ .logo{
+ width: 100%;
+ background-color: #fff;
+ padding:7px 26px;
+ }
+ .content{
+ padding-top: 50px;
+ margin:0px auto;
+ width: 570px;
+ &>p{
+ height:42px;
+ line-height:42px;
+ font-weight:400;
+ color:#000000;
+ font-size:30px;
+ margin-bottom: 32px!important;
+ text-align: center;
+ }
+ .panels{
+ background-color: #fff;
+ border-radius:6.6px;
+ padding:32px 42px;
+ .panelsMenu{
+ border-bottom: none!important;
+ margin-bottom: 36px!important;
+ .ant-menu-item{
+ padding: 0px;
+ margin-right: 60px!important;
+ }
+ }
+ .bind_form{
+ padding-bottom: 48px;
+ .has-error .ant-input:focus,.has-error .ant-input, .has-error .ant-input:hover{
+ border-color: #ff4d4f!important;
+ }
+ .ant-btn-primary[disabled]{
+ background-color:rgba(70, 106, 255,0.55);
+ color: #fff;
+ border:none
+ }
+ .ant-input-group-addon{
+ background-color: transparent;
+ }
+ .ant-input{
+ border-left: none;
+ background-color: #fff!important;
+ }
+ .ant-input:focus,.ant-input:hover{
+ border-right: 1px solid #ddd!important;
+ border-color: #ddd!important;
+ border-left: none!important;
+ }
+ .codeBut{
+ border:1px solid rgba(70, 106, 255, 1)!important;
+ span{
+ color: rgba(70, 106, 255, 1);
+ }
+ }
+ .codeBut.disable{
+ border:1px solid #ddd!important;
+ span{
+ color: #ddd;
+ }
+ }
+ .login_register_head{
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ &>span:first-child{
+ font-size: 1.5em;
+ font-weight: 600;
+ color: #000000;
+ line-height: 1.5;
+ }
+ //注册页面的获取验证码输入框
+ .ant-btn{margin-left: 15px; }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/forge/Account/unbind.jsx b/src/forge/Account/unbind.jsx
new file mode 100644
index 000000000..57db4d8e3
--- /dev/null
+++ b/src/forge/Account/unbind.jsx
@@ -0,0 +1,271 @@
+import React ,{ useState , useRef } from 'react';
+import { Form , Input , Button , message } from 'antd';
+import user from "./image/user.png";
+import lock from "./image/lock.png";
+import shield from './image/shield.png';
+import phone from './image/phone.svg';
+import axios from 'axios';
+import { setmiyah } from 'educoder';
+
+const phonereg = /^([1][3456789])\d{9}$/
+const emailreg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
+function Bind(props){
+ const { form } = props;
+ const seconds = useRef();
+ let interval = undefined;
+ const { getFieldDecorator , getFieldsValue } = form;
+ const [ bindFlag , setBindFlag] = useState(true);
+ const [ captchaFlag , setCaptchaFlag ] = useState(true);
+ const [secondsStr, setSecondsStr] = useState(60);
+ const [ getCaptchaBut , setGetCaptchaBut ] = useState(true);
+
+
+ //判断用户名(username)是否注册
+ function usernameConfirm(rule, value, callback){
+ value ? axios.post(`/accounts/check.json`, {
+ value: value,
+ type: 1
+ }).then(response => {
+ if(response){
+ if (response.data.status === -1) {
+ callback('该名称已经被使用');
+ } else {
+ const { captcha , password , confirm_password,username} = getFieldsValue();
+ if( captcha && password && confirm_password && (password === confirm_password) &&(phonereg.test(username) || emailreg.test(username)) ){
+ setBindFlag(false);
+ }
+ }
+ }
+ callback();
+ }):callback();
+ }
+
+ function accountConfirm(rule, value, callback){
+ if(value){
+ const { captcha , password , confirm_password,register_username} = getFieldsValue();
+ if(!(phonereg.test(value) || emailreg.test(value))){
+ setCaptchaFlag(true);
+ callback(`请输入正确的手机号或邮箱地址`);
+ }else{
+ setCaptchaFlag(false);
+ if(captcha && password && confirm_password && (password === confirm_password) && register_username){
+ setBindFlag(false);
+ }
+ }
+ callback();
+ }else{
+ setBindFlag(true);
+ callback();
+ }
+ }
+ function psdConfirm(r,v,c){
+ if(v){
+ const { username , captcha , confirm_password , register_username } = getFieldsValue();
+ if(register_username && (phonereg.test(username) || emailreg.test(username)) && captcha && confirm_password && (v=== confirm_password) ){
+ setBindFlag(false);
+ }else{
+ setBindFlag(true);
+ }
+ c();
+ }else{
+ c();
+ setBindFlag(true);
+ }
+ }
+ function captchaConfirm(r,v,c){
+ if(v){
+ const { username , password , confirm_password , register_username } = getFieldsValue();
+ if(register_username && (phonereg.test(username) || emailreg.test(username)) && password && confirm_password && (password ===confirm_password) ){
+ setBindFlag(false);
+ }else{
+ setBindFlag(true);
+ }
+ c();
+ }else{
+ c();
+ setBindFlag(true);
+ }
+ }
+ function repsdConfirm(r,v,c){
+ if(v){
+ const { username , password , register_username , captcha} = getFieldsValue();
+ if(v !== password){
+ c("两次输入的密码不一样");
+ }else{
+ c();
+ }
+ if((phonereg.test(username) || emailreg.test(username)) && password && register_username && captcha){
+ setBindFlag(false);
+ }else{
+ setBindFlag(true);
+ }
+ c();
+ }else{
+ c();
+ }
+ }
+
+ //获取验证码
+ function getCaptcha() {
+ const { username }= getFieldsValue();
+ if (username) {
+ // 倒计时开始
+ setCaptchaFlag(true);
+ setGetCaptchaBut(false);
+ seconds.current = 60;
+ setSecondsStr(60);
+ !interval && clearInterval(interval);
+ interval = setInterval(() => {
+ if (seconds.current > 1) {
+ let oldSeconds = seconds.current;
+ seconds.current = oldSeconds - 1;
+ setSecondsStr(oldSeconds - 1);
+ } else {
+ clearInterval(interval);
+ //倒计时结束->可以获取验证码
+ setCaptchaFlag(false);
+ setGetCaptchaBut(true);
+ }
+ }, 1000)
+
+ //请求获取验证码接口
+ axios.get(`/accounts/get_verification_code.json`, {
+ params: {
+ login: username,
+ type: 1,
+ smscode: setmiyah(username),
+ }
+ }).then(response => {
+ if (response.data && response.data.status === 0) {
+ //验证码发送成功
+ setGetCaptchaBut(false);
+ }
+ })
+ }
+ }
+ // 绑定登录
+ function bindRegFunc(){
+ form.validateFields((err, values) => {
+ if (!err) {
+ var url = '/accounts/register.json';
+ axios.post(url,{
+ namespace: values.register_username,
+ login: values.username,
+ password: values.password,
+ password_confirmation: values.confirm_password,
+ code: values.captcha
+ }).then(response=>{
+ if(response.data && response.data.status === -6){
+ //验证码不正确
+ form.setFields({captcha: {value:values.captcha,errors:[new Error('验证码错误,请重新输入')]}});
+
+ }else if(response.data && response.data.status === 0){
+ //注册成功,页面跳转即可,注册后登录流程forge处理了
+ window.location.href = "/"+values.register_username;
+ }
+ })
+ }
+ })
+ }
+ return(
+
+
+ {getFieldDecorator('register_username',{
+ rules:[
+ {
+ required:true,
+ message:"请输入用户名"
+ },
+ {
+ pattern: /^[a-zA-Z]/,
+ message: "用户名必须以字母开头"
+ },
+ {
+ pattern: /[a-zA-Z0-9]$/,
+ message: "用户名只能使用英文字母和数字"
+ },
+ {
+ min: 4,
+ max: 15,
+ message: "用户名长度为4到15个字符"
+ },
+ {
+ validator: (rule, value, callback) => { usernameConfirm(rule, value, callback) }
+ }
+ ],
+ validateTrigger:"onBlur",
+ validateFirst: true,
+ })(} size="large" autoComplete="off"/>)}
+
+
+ {getFieldDecorator('username',{
+ rules:[
+ {
+ required:true,
+ message:"请输入手机号或邮箱地址"
+ },
+ {
+ validator: (rule, value, callback) => { accountConfirm(rule, value, callback) }
+ }
+ ],
+ validateTrigger:"onInput",
+ })(} size="large" placeholder="请输入手机号或邮箱地址"/>)}
+
+
+
+ {getFieldDecorator('captcha', {
+ rules: [{
+ required: true,
+ message: "请输入验证码"
+ },
+ {
+ validator: (rule, value, callback) => { captchaConfirm(rule, value, callback) }
+ }],
+ validateTrigger: "onInput",
+ })(
+ } placeholder="请输入验证码" autoComplete="off"/>
+ )}
+
+
+
+
+ {getFieldDecorator('password', {
+ rules: [
+ {
+ required:true,
+ message:"请输入登录密码"
+ },
+ {
+ validator: (rule, value, callback) => { psdConfirm(rule, value, callback) }
+ }
+ ],
+ validateTrigger:"onInput",
+ })(
+ } className="psd" size="large" placeholder="请输入登录密码" />,
+ )}
+
+
+ {getFieldDecorator('confirm_password', {
+ rules: [
+ {
+ required:true,
+ message:"请再次输入登录密码"
+ },
+ {
+ validator: (rule, value, callback) => { repsdConfirm(rule, value, callback) }
+ }
+ ],
+ validateTrigger:"onBlur",
+ })(
+ } className="psd" size="large" placeholder="请确认登录密码" />,
+ )}
+
+
+
+
+ )
+}
+export default Form.create({ name: 'Bind' })(Bind);
\ No newline at end of file
diff --git a/src/forge/Main/CoderDepotReadme.jsx b/src/forge/Main/CoderDepotReadme.jsx
index 93d8b04c2..5e8bc3532 100644
--- a/src/forge/Main/CoderDepotReadme.jsx
+++ b/src/forge/Main/CoderDepotReadme.jsx
@@ -19,7 +19,6 @@ function CoderDepotReadme({ operate , history , readme , ChangeFile }){
},[readme])
useEffect(()=>{
- let path = history.location.pathname;
const items = $.map($("#readme").find("h1,h2,h3,h4,h5,h6"), function (el, _) {
const anchor = el.id;
const level = el.tagName.replace("H", "");
diff --git a/src/forge/Main/Index.scss b/src/forge/Main/Index.scss
index f17bc4805..a2ff111c4 100644
--- a/src/forge/Main/Index.scss
+++ b/src/forge/Main/Index.scss
@@ -521,7 +521,9 @@
}
}
}
-
+.readmeFile{
+ overflow: inherit;
+}
.readmeFile p{
white-space: normal;
}
\ No newline at end of file