forked from Gitlink/forgeplus
Merge pull request 'FIX 优化项目流程' (#146) from develop into dev_trustie_server
This commit is contained in:
commit
26c0d36227
|
@ -1,529 +0,0 @@
|
||||||
import React, {Component} from 'react';
|
|
||||||
import logo from './logo.svg';
|
|
||||||
import './App.css';
|
|
||||||
import {LocaleProvider} from 'antd'
|
|
||||||
import zhCN from 'antd/lib/locale-provider/zh_CN';
|
|
||||||
import {
|
|
||||||
BrowserRouter as Router,
|
|
||||||
Route,
|
|
||||||
Switch
|
|
||||||
} from 'react-router-dom';
|
|
||||||
import axios from 'axios';
|
|
||||||
import '@icedesign/base/dist/ICEDesignBase.css';
|
|
||||||
|
|
||||||
import '@icedesign/base/index.scss';
|
|
||||||
|
|
||||||
import LoginDialog from './modules/login/LoginDialog';
|
|
||||||
import Notcompletedysl from './modules/user/Notcompletedysl';
|
|
||||||
import Trialapplicationysl from './modules/login/Trialapplicationysl';
|
|
||||||
import Trialapplicationreview from './modules/user/Trialapplicationreview';
|
|
||||||
import Addcourses from "./modules/courses/coursesPublic/Addcourses";
|
|
||||||
import AccountProfile from"./modules/user/AccountProfile";
|
|
||||||
|
|
||||||
|
|
||||||
import Trialapplication from './modules/login/Trialapplication'
|
|
||||||
|
|
||||||
import NotFoundPage from './NotFoundPage'
|
|
||||||
|
|
||||||
import Loading from './Loading'
|
|
||||||
|
|
||||||
import Loadable from 'react-loadable';
|
|
||||||
|
|
||||||
|
|
||||||
import moment from 'moment'
|
|
||||||
|
|
||||||
import {MuiThemeProvider, createMuiTheme} from 'material-ui/styles';
|
|
||||||
|
|
||||||
// import './AppConfig'
|
|
||||||
|
|
||||||
import history from './history';
|
|
||||||
|
|
||||||
import {SnackbarHOC} from 'educoder'
|
|
||||||
import {initAxiosInterceptors} from './AppConfig'
|
|
||||||
|
|
||||||
|
|
||||||
// !!!tpi需要这个来加载css
|
|
||||||
import {TPMIndexHOC} from './modules/tpm/TPMIndexHOC';
|
|
||||||
|
|
||||||
|
|
||||||
const theme = createMuiTheme({
|
|
||||||
palette: {
|
|
||||||
primary: {
|
|
||||||
main: '#4CACFF',
|
|
||||||
contrastText: 'rgba(255, 255, 255, 0.87)'
|
|
||||||
},
|
|
||||||
secondary: {main: '#4CACFF'}, // #11cb5f This is just green.A700 as hex.
|
|
||||||
},
|
|
||||||
});
|
|
||||||
//
|
|
||||||
// const Trialapplication= Loadable({
|
|
||||||
// loader: () =>import('./modules/login/Trialapplication'),
|
|
||||||
// loading:Loading,
|
|
||||||
// })
|
|
||||||
//登入
|
|
||||||
const EducoderLogin = Loadable({
|
|
||||||
loader: () => import('./modules/login/EducoderLogin'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const TestIndex = Loadable({
|
|
||||||
loader: () => import('./modules/test'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
const IndexWrapperComponent = Loadable({
|
|
||||||
loader: () => import('./modules/page/IndexWrapper'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
const CommentComponent = Loadable({
|
|
||||||
loader: () => import('./modules/comment/CommentContainer'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
const TestMaterialDesignComponent = Loadable({
|
|
||||||
loader: () => import('./modules/test/md/TestMaterialDesign'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const TestCodeMirrorComponent = Loadable({
|
|
||||||
loader: () => import('./modules/test/codemirror/TestCodeMirror'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
const TestComponent = Loadable({
|
|
||||||
loader: () => import('./modules/test/TestRC'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const TestUrlQueryComponent = Loadable({
|
|
||||||
loader: () => import('./modules/test/urlquery/TestUrlQuery'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
const TPMIndexComponent = Loadable({
|
|
||||||
loader: () => import('./modules/tpm/TPMIndex'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const TPMShixunsIndexComponent = Loadable({
|
|
||||||
loader: () => import('./modules/tpm/shixuns/ShixunsIndex'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
//实训课程(原实训路径)
|
|
||||||
const ShixunPaths = Loadable({
|
|
||||||
loader: () => import('./modules/paths/Index'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
//在线课堂
|
|
||||||
const CoursesIndex = Loadable({
|
|
||||||
loader: () => import('./modules/courses/Index'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const SearchPage = Loadable({
|
|
||||||
loader: () => import('./search/SearchPage'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
//教学案例
|
|
||||||
const MoopCases = Loadable({
|
|
||||||
loader: () => import('./modules/moop_cases/index'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 课堂讨论
|
|
||||||
// const BoardIndex = Loadable({
|
|
||||||
// loader: () => import('./modules/courses/boards/BoardIndex'),
|
|
||||||
// loading:Loading,
|
|
||||||
// })
|
|
||||||
|
|
||||||
// //课堂普通作业&分组作业
|
|
||||||
// const CoursesWorkIndex = Loadable({
|
|
||||||
// loader: () => import('./modules/courses/busyWork/Index'),
|
|
||||||
// loading:Loading,
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
|
|
||||||
// const TPMShixunchildIndexComponent = Loadable({
|
|
||||||
// loader: () => import('./modules/tpm/shixunchild/ShixunChildIndex'),
|
|
||||||
// loading: Loading,
|
|
||||||
// })
|
|
||||||
|
|
||||||
|
|
||||||
// const TPMshixunfork_listIndexComponent = Loadable({
|
|
||||||
// loader: () => import('./modules/tpm/shixunchild/Shixunfork_list'),
|
|
||||||
// loading: Loading,
|
|
||||||
// })
|
|
||||||
|
|
||||||
|
|
||||||
const ForumsIndexComponent = Loadable({
|
|
||||||
loader: () => import('./modules/forums/ForumsIndex'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
// trustie plus forum
|
|
||||||
// const TPForumsIndexComponent = Loadable({
|
|
||||||
// loader: () => import('./modules/tp-forums/TPForumsIndex'),
|
|
||||||
// loading: Loading,
|
|
||||||
// })
|
|
||||||
|
|
||||||
|
|
||||||
// const TestPageComponent = Loadable({
|
|
||||||
// loader: () => import('./modules/page/Index'),
|
|
||||||
// loading: Loading,
|
|
||||||
// })
|
|
||||||
|
|
||||||
|
|
||||||
//新建实训
|
|
||||||
const Newshixuns = Loadable({
|
|
||||||
loader: () => import('./modules/tpm/newshixuns/Newshixuns'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
//实训首页
|
|
||||||
const ShixunsHome = Loadable({
|
|
||||||
loader: () => import('./modules/home/shixunsHome'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const CompatibilityPageLoadable = Loadable({
|
|
||||||
loader: () => import('./modules/common/CompatibilityPage'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
//403页面
|
|
||||||
const Shixunauthority = Loadable({
|
|
||||||
loader: () => import('./modules/403/Shixunauthority'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
//404页面
|
|
||||||
const Shixunnopage = Loadable({
|
|
||||||
loader: () => import('./modules/404/Shixunnopage'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
//500页面
|
|
||||||
const http500 = Loadable({
|
|
||||||
loader: () => import('./modules/500/http500'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 登录注册
|
|
||||||
const LoginRegisterPage = Loadable({
|
|
||||||
loader: () => import('./modules/user/LoginRegisterPage'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const AccountPage = Loadable({
|
|
||||||
loader: () => import('./modules/user/AccountPage'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 个人主页
|
|
||||||
const UsersInfo = Loadable({
|
|
||||||
loader: () => import('./modules/user/usersInfo/Infos'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 兴趣页面
|
|
||||||
const Interestpage = Loadable({
|
|
||||||
loader: () => import('./modules/login/EducoderInteresse'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
//众包创新
|
|
||||||
const ProjectPackages=Loadable({
|
|
||||||
loader: () => import('./modules/projectPackages/ProjectPackageIndex'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
class App extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props)
|
|
||||||
// this.state = {
|
|
||||||
// isRenders:false,
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
// force an update if the URL changes
|
|
||||||
history.listen(() => {
|
|
||||||
this.forceUpdate()
|
|
||||||
const $ = window.$
|
|
||||||
// https://www.trustie.net/issues/21919 可能会有问题
|
|
||||||
$("html").animate({ scrollTop: $('html').scrollTop() - 0 })
|
|
||||||
});
|
|
||||||
|
|
||||||
initAxiosInterceptors(this.props)
|
|
||||||
|
|
||||||
//
|
|
||||||
// axios.interceptors.response.use((response) => {
|
|
||||||
// // console.log("response"+response);
|
|
||||||
// if(response!=undefined)
|
|
||||||
// // console.log("response"+response.data.statu);
|
|
||||||
// if (response&&response.data.status === 407) {
|
|
||||||
// this.setState({
|
|
||||||
// isRenders: true,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// return response;
|
|
||||||
// }, (error) => {
|
|
||||||
// //TODO 这里如果样式变了会出现css不加载的情况
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
//修改登录方法
|
|
||||||
Modifyloginvalue=()=>{
|
|
||||||
this.setState({
|
|
||||||
isRender:false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<LocaleProvider locale={zhCN}>
|
|
||||||
|
|
||||||
|
|
||||||
<MuiThemeProvider theme={theme}>
|
|
||||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={()=>this.Modifyloginvalue()}></LoginDialog>
|
|
||||||
<Notcompletedysl {...this.props} {...this.state}></Notcompletedysl>
|
|
||||||
<Trialapplicationysl {...this.props} {...this.state}></Trialapplicationysl>
|
|
||||||
<Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview>
|
|
||||||
<Addcourses {...this.props} {...this.state}/>
|
|
||||||
<AccountProfile {...this.props} {...this.state}/>
|
|
||||||
{/*{*/}
|
|
||||||
{/* isRender === true?*/}
|
|
||||||
{/* <LoginDialog></LoginDialog> : ""*/}
|
|
||||||
{/*}*/}
|
|
||||||
|
|
||||||
{/*{*/}
|
|
||||||
{/* isRenders === true?*/}
|
|
||||||
{/*<Trialapplication></Trialapplication>*/}
|
|
||||||
{/*:""*/}
|
|
||||||
{/*}*/}
|
|
||||||
|
|
||||||
<Router>
|
|
||||||
<Switch>
|
|
||||||
{/*<Route path="/login" component={LoginRegisterPage}/>*/}
|
|
||||||
|
|
||||||
{/*众包创新*/}
|
|
||||||
<Route path={"/crowdsourcings"} component={ProjectPackages}/>
|
|
||||||
{/*认证*/}
|
|
||||||
<Route path="/account" component={AccountPage}/>
|
|
||||||
|
|
||||||
{/*403*/}
|
|
||||||
<Route path="/403" component={Shixunauthority}/>
|
|
||||||
|
|
||||||
<Route path="/500" component={http500}/>
|
|
||||||
|
|
||||||
{/*404*/}
|
|
||||||
<Route path="/nopage" component={Shixunnopage}/>
|
|
||||||
|
|
||||||
<Route path="/compatibility" component={CompatibilityPageLoadable}/>
|
|
||||||
<Route
|
|
||||||
path="/login" component={EducoderLogin}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/register" component={EducoderLogin}
|
|
||||||
/>
|
|
||||||
<Route path="/users/:username"
|
|
||||||
render={
|
|
||||||
(props) => (<UsersInfo {...this.props} {...props} {...this.state} />)
|
|
||||||
}></Route>
|
|
||||||
{/*<Route*/}
|
|
||||||
{/* path="/trialapplication" component={Trialapplication}*/}
|
|
||||||
{/*/>*/}
|
|
||||||
<Route
|
|
||||||
path="/changepassword" component={EducoderLogin}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/interesse" component={Interestpage}
|
|
||||||
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route path="/shixuns/new" component={Newshixuns}>
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path="/tasks/:stageId" component={IndexWrapperComponent}/>
|
|
||||||
|
|
||||||
<Route path="/shixuns/:shixunId" component={TPMIndexComponent}>
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
{/*列表页*/}
|
|
||||||
<Route path="/shixuns" component={TPMShixunsIndexComponent}/>
|
|
||||||
|
|
||||||
{/* <Route path="/shixunchild" component={TPMShixunchildIndexComponent}>
|
|
||||||
</Route>
|
|
||||||
<Route path="/fork_list" component={TPMshixunfork_listIndexComponent}>
|
|
||||||
</Route> */}
|
|
||||||
|
|
||||||
{/*<Route path="/forums" component={ForumsIndexComponent}>*/}
|
|
||||||
{/*</Route>*/}
|
|
||||||
|
|
||||||
|
|
||||||
{/*实训课程(原实训路径)*/}
|
|
||||||
<Route path="/paths" component={ShixunPaths}></Route>
|
|
||||||
|
|
||||||
<Route path="/search"
|
|
||||||
render={
|
|
||||||
(props)=>(<SearchPage {...this.props} {...props} {...this.state}></SearchPage>)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
{/*课堂*/}
|
|
||||||
<Route path="/courses" component={CoursesIndex} {...this.props}></Route>
|
|
||||||
|
|
||||||
{/* 课堂讨论 */}
|
|
||||||
{/* <Route path="/board" component = {BoardIndex} {...this.props}></Route> */}
|
|
||||||
|
|
||||||
{/* <Route path="/tpforums" component={TPForumsIndexComponent}>
|
|
||||||
</Route> */}
|
|
||||||
|
|
||||||
{/* <Route path="/myshixuns/:shixunId/stages/:stageId" component={Index}/> */}
|
|
||||||
{/* 兴趣页面*/}
|
|
||||||
{/*<Route path="/interest" component={Interestpage}/>*/}
|
|
||||||
|
|
||||||
<Route path="/comment" component={CommentComponent}/>
|
|
||||||
<Route path="/testMaterial" component={TestMaterialDesignComponent}/>
|
|
||||||
<Route path="/test" component={TestIndex}/>
|
|
||||||
<Route path="/testCodeMirror" component={TestCodeMirrorComponent}/>
|
|
||||||
<Route path="/testRCComponent" component={TestComponent}/>
|
|
||||||
<Route path="/testUrlQuery" component={TestUrlQueryComponent}/>
|
|
||||||
|
|
||||||
{/* 教学案例 */}
|
|
||||||
<Route path="/moop_cases"render={
|
|
||||||
(props) => (<MoopCases {...this.props} {...props} {...this.state} />)
|
|
||||||
}/>
|
|
||||||
|
|
||||||
{/* <Route component={NotFoundPage}/> */}
|
|
||||||
{/*列表页*/}
|
|
||||||
{/*<Route component={TPMShixunsIndexComponent}/>*/}
|
|
||||||
{/*首页*/}
|
|
||||||
<Route exact path="/" component={ShixunsHome}/>
|
|
||||||
<Route component={Shixunnopage}/>
|
|
||||||
|
|
||||||
{/*<Route component={ShixunsHome}/>*/}
|
|
||||||
|
|
||||||
</Switch>
|
|
||||||
</Router>
|
|
||||||
</MuiThemeProvider>
|
|
||||||
</LocaleProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// moment国际化,设置为中文
|
|
||||||
moment.defineLocale('zh-cn', {
|
|
||||||
months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
|
|
||||||
monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
|
|
||||||
weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
|
|
||||||
weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
|
|
||||||
weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
|
|
||||||
longDateFormat: {
|
|
||||||
LT: 'Ah点mm分',
|
|
||||||
LTS: 'Ah点m分s秒',
|
|
||||||
L: 'YYYY-MM-DD',
|
|
||||||
LL: 'YYYY年MMMD日',
|
|
||||||
LLL: 'YYYY年MMMD日Ah点mm分',
|
|
||||||
LLLL: 'YYYY年MMMD日ddddAh点mm分',
|
|
||||||
l: 'YYYY-MM-DD',
|
|
||||||
ll: 'YYYY年MMMD日',
|
|
||||||
lll: 'YYYY年MMMD日Ah点mm分',
|
|
||||||
llll: 'YYYY年MMMD日ddddAh点mm分'
|
|
||||||
},
|
|
||||||
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
|
|
||||||
meridiemHour: function (hour, meridiem) {
|
|
||||||
if (hour === 12) {
|
|
||||||
hour = 0;
|
|
||||||
}
|
|
||||||
if (meridiem === '凌晨' || meridiem === '早上' ||
|
|
||||||
meridiem === '上午') {
|
|
||||||
return hour;
|
|
||||||
} else if (meridiem === '下午' || meridiem === '晚上') {
|
|
||||||
return hour + 12;
|
|
||||||
} else {
|
|
||||||
// '中午'
|
|
||||||
return hour >= 11 ? hour : hour + 12;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
meridiem: function (hour, minute, isLower) {
|
|
||||||
var hm = hour * 100 + minute;
|
|
||||||
if (hm < 600) {
|
|
||||||
return '凌晨';
|
|
||||||
} else if (hm < 900) {
|
|
||||||
return '早上';
|
|
||||||
} else if (hm < 1130) {
|
|
||||||
return '上午';
|
|
||||||
} else if (hm < 1230) {
|
|
||||||
return '中午';
|
|
||||||
} else if (hm < 1800) {
|
|
||||||
return '下午';
|
|
||||||
} else {
|
|
||||||
return '晚上';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
calendar: {
|
|
||||||
sameDay: function () {
|
|
||||||
return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';
|
|
||||||
},
|
|
||||||
nextDay: function () {
|
|
||||||
return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';
|
|
||||||
},
|
|
||||||
lastDay: function () {
|
|
||||||
return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';
|
|
||||||
},
|
|
||||||
nextWeek: function () {
|
|
||||||
var startOfWeek, prefix;
|
|
||||||
startOfWeek = moment().startOf('week');
|
|
||||||
prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';
|
|
||||||
return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
|
|
||||||
},
|
|
||||||
lastWeek: function () {
|
|
||||||
var startOfWeek, prefix;
|
|
||||||
startOfWeek = moment().startOf('week');
|
|
||||||
prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]';
|
|
||||||
return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
|
|
||||||
},
|
|
||||||
sameElse: 'LL'
|
|
||||||
},
|
|
||||||
ordinalParse: /\d{1,2}(日|月|周)/,
|
|
||||||
ordinal: function (number, period) {
|
|
||||||
switch (period) {
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
case 'DDD':
|
|
||||||
return number + '日';
|
|
||||||
case 'M':
|
|
||||||
return number + '月';
|
|
||||||
case 'w':
|
|
||||||
case 'W':
|
|
||||||
return number + '周';
|
|
||||||
default:
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
relativeTime: {
|
|
||||||
future: '%s内',
|
|
||||||
past: '%s前',
|
|
||||||
s: '几秒',
|
|
||||||
m: '1分钟',
|
|
||||||
mm: '%d分钟',
|
|
||||||
h: '1小时',
|
|
||||||
hh: '%d小时',
|
|
||||||
d: '1天',
|
|
||||||
dd: '%d天',
|
|
||||||
M: '1个月',
|
|
||||||
MM: '%d个月',
|
|
||||||
y: '1年',
|
|
||||||
yy: '%d年'
|
|
||||||
},
|
|
||||||
week: {
|
|
||||||
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
|
|
||||||
dow: 1, // Monday is the first day of the week.
|
|
||||||
doy: 4 // The week that contains Jan 4th is the first week of the year.
|
|
||||||
}
|
|
||||||
});
|
|
||||||
export default SnackbarHOC()(App);
|
|
|
@ -338,10 +338,10 @@ http://localhost:3000/api/projects/ | jq
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|user_id |是|int |用户id或者组织id |
|
|user_id |是|int |用户id或者组织id |
|
||||||
|name |是|string |项目名称 |
|
|name |是|string |项目名称 |
|
||||||
|description |是|string |项目描述 |
|
|description |否|string |项目描述 |
|
||||||
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||||
|project_category_id|是|int |项目类别id |
|
|project_category_id|否|int |项目类别id |
|
||||||
|project_language_id|是|int |项目语言id |
|
|project_language_id|否|int |项目语言id |
|
||||||
|ignore_id |否|int |gitignore相关id |
|
|ignore_id |否|int |gitignore相关id |
|
||||||
|license_id |否|int |开源许可证id |
|
|license_id |否|int |开源许可证id |
|
||||||
|private |否|boolean|项目是否私有, true:为私有,false: 公开,默认为公开 |
|
|private |否|boolean|项目是否私有, true:为私有,false: 公开,默认为公开 |
|
||||||
|
@ -374,9 +374,7 @@ curl -X POST \
|
||||||
-d "user_id=36408" \
|
-d "user_id=36408" \
|
||||||
-d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
|
-d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
|
||||||
-d "name=golden_mirror1" \
|
-d "name=golden_mirror1" \
|
||||||
-d "description=golden_mirror" \
|
-d "repository_name=golden_mirror1" \
|
||||||
-d "project_category_id=1" \
|
|
||||||
-d "project_language_id=2" \
|
|
||||||
http://localhost:3000/api/projects/migrate.json | jq
|
http://localhost:3000/api/projects/migrate.json | jq
|
||||||
```
|
```
|
||||||
*请求参数说明:*
|
*请求参数说明:*
|
||||||
|
@ -388,8 +386,8 @@ http://localhost:3000/api/projects/migrate.json | jq
|
||||||
|clone_addr |是|string |镜像项目clone地址 |
|
|clone_addr |是|string |镜像项目clone地址 |
|
||||||
|description |否|string |项目描述 |
|
|description |否|string |项目描述 |
|
||||||
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||||
|project_category_id|是|int |项目类别id |
|
|project_category_id|否|int |项目类别id |
|
||||||
|project_language_id|是|int |项目语言id |
|
|project_language_id|否|int |项目语言id |
|
||||||
|is_mirror |否|boolean|是否设置为镜像, true:是, false:否,默认为否 |
|
|is_mirror |否|boolean|是否设置为镜像, true:是, false:否,默认为否 |
|
||||||
|auth_username |否|string|镜像源仓库的登录用户名 |
|
|auth_username |否|string|镜像源仓库的登录用户名 |
|
||||||
|auth_password |否|string|镜像源仓库的登录秘密 |
|
|auth_password |否|string|镜像源仓库的登录秘密 |
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
class Admins::EduSettingsController < Admins::BaseController
|
||||||
|
before_action :find_setting, only: [:edit,:update, :destroy]
|
||||||
|
|
||||||
|
def index
|
||||||
|
default_sort('id', 'desc')
|
||||||
|
|
||||||
|
edu_settings = Admins::EduSettingQuery.call(params)
|
||||||
|
@edu_settings = paginate edu_settings
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@edu_setting = EduSetting.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@edu_setting = EduSetting.new(edu_setting_params)
|
||||||
|
if @edu_setting.save
|
||||||
|
redirect_to admins_edu_settings_path
|
||||||
|
flash[:success] = '创建成功'
|
||||||
|
else
|
||||||
|
redirect_to admins_edu_settings_path
|
||||||
|
flash[:danger] = @edu_setting.errors.full_messages.join(",")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @edu_setting.update!(edu_setting_params)
|
||||||
|
flash[:success] = '更新成功'
|
||||||
|
else
|
||||||
|
flash[:danger] = @edu_setting.errors.full_messages.join(",")
|
||||||
|
end
|
||||||
|
redirect_to admins_edu_settings_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @edu_setting.destroy!
|
||||||
|
flash[:success] = '删除成功'
|
||||||
|
else
|
||||||
|
lash[:danger] = '删除失败'
|
||||||
|
end
|
||||||
|
redirect_to admins_edu_settings_path
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_setting
|
||||||
|
@edu_setting ||= EduSetting.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def edu_setting_params
|
||||||
|
params.require(:edu_setting).permit(:name, :value, :description)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,56 @@
|
||||||
|
class Admins::SitesController < Admins::BaseController
|
||||||
|
before_action :find_site, only: [:edit,:update, :destroy]
|
||||||
|
|
||||||
|
def index
|
||||||
|
default_sort('id', 'desc')
|
||||||
|
|
||||||
|
sites = Admins::SiteQuery.call(params)
|
||||||
|
@sites = paginate sites
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@site = Site.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@site = Site.new(site_params)
|
||||||
|
if @site.save
|
||||||
|
redirect_to admins_sites_path
|
||||||
|
flash[:success] = '创建成功'
|
||||||
|
else
|
||||||
|
redirect_to admins_sites_path
|
||||||
|
flash[:danger] = @site.errors.full_messages.join(",")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @site.update!(site_params)
|
||||||
|
flash[:success] = '更新成功'
|
||||||
|
else
|
||||||
|
flash[:danger] = @site.errors.full_messages.join(",")
|
||||||
|
end
|
||||||
|
redirect_to admins_sites_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @site.destroy!
|
||||||
|
flash[:success] = '删除成功'
|
||||||
|
else
|
||||||
|
lash[:danger] = '删除失败'
|
||||||
|
end
|
||||||
|
redirect_to admins_sites_path
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_site
|
||||||
|
@site ||= Site.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def site_params
|
||||||
|
params.require(:site).permit(:name, :url, :key, :site_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -41,7 +41,7 @@ module LaboratoryHelper
|
||||||
my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
|
my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
|
||||||
my_projects: "/users/#{current_user.try(:login)}/projects",
|
my_projects: "/users/#{current_user.try(:login)}/projects",
|
||||||
my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
|
my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
|
||||||
default_url: "https://www.trustie.net/",
|
default_url: Rails.application.config_for(:configuration)['platform_url'],
|
||||||
tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
|
tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
|
||||||
register_url: "https://www.trustie.net/login?login=false"
|
register_url: "https://www.trustie.net/login?login=false"
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,8 @@ class EduSettingsController < ApplicationController
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @edu_setting.save
|
if @edu_setting.save
|
||||||
format.html { redirect_to @edu_setting, notice: 'Edu setting was successfully created.' }
|
|
||||||
format.json { render :show, status: :created, location: @edu_setting }
|
format.json { render :show, status: :created, location: @edu_setting }
|
||||||
else
|
else
|
||||||
format.html { render :new }
|
|
||||||
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
|
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -43,10 +41,8 @@ class EduSettingsController < ApplicationController
|
||||||
def update
|
def update
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @edu_setting.update(edu_setting_params)
|
if @edu_setting.update(edu_setting_params)
|
||||||
format.html { redirect_to @edu_setting, notice: 'Edu setting was successfully updated.' }
|
|
||||||
format.json { render :show, status: :ok, location: @edu_setting }
|
format.json { render :show, status: :ok, location: @edu_setting }
|
||||||
else
|
else
|
||||||
format.html { render :edit }
|
|
||||||
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
|
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -57,7 +53,6 @@ class EduSettingsController < ApplicationController
|
||||||
def destroy
|
def destroy
|
||||||
@edu_setting.destroy
|
@edu_setting.destroy
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to edu_settings_url, notice: 'Edu setting was successfully destroyed.' }
|
|
||||||
format.json { head :no_content }
|
format.json { head :no_content }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,7 +46,6 @@ class ProjectsController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
tip_exception("无法使用以下关键词:#{project_params[:repository_name]},请重新命名") if ReversedKeyword.is_reversed(project_params[:repository_name]).present?
|
|
||||||
Projects::CreateForm.new(project_params).validate!
|
Projects::CreateForm.new(project_params).validate!
|
||||||
@project = Projects::CreateService.new(current_user, project_params).call
|
@project = Projects::CreateService.new(current_user, project_params).call
|
||||||
|
|
||||||
|
@ -57,7 +56,6 @@ class ProjectsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def migrate
|
def migrate
|
||||||
tip_exception("无法使用以下关键词:#{mirror_params[:repository_name]},请重新命名") if ReversedKeyword.is_reversed(mirror_params[:repository_name]).present?
|
|
||||||
Projects::MigrateForm.new(mirror_params).validate!
|
Projects::MigrateForm.new(mirror_params).validate!
|
||||||
|
|
||||||
@project =
|
@project =
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class Users::HeadmapsController < Users::BaseController
|
class Users::HeadmapsController < Users::BaseController
|
||||||
def index
|
def index
|
||||||
result = Gitea::User::HeadmapService.call(observed_user.login, start_stamp, end_stamp)
|
result = Gitea::User::HeadmapService.call(observed_user.login, start_stamp, end_stamp)
|
||||||
@headmaps = result[2]
|
@headmaps = result[2].blank? ? [] : result[2]
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
uid_logger_error(e.message)
|
uid_logger_error(e.message)
|
||||||
tip_exception(e.message)
|
tip_exception(e.message)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Users::StatisticsController < Users::BaseController
|
||||||
@date_data << date.strftime("%Y.%m.%d")
|
@date_data << date.strftime("%Y.%m.%d")
|
||||||
@issue_data << observed_user.issues.where("DATE(created_on) = ?", date).size
|
@issue_data << observed_user.issues.where("DATE(created_on) = ?", date).size
|
||||||
@pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size
|
@pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size
|
||||||
date_commit_data = commit_data.select{|item| item["timestamp"] == date.to_time.to_i}
|
date_commit_data = commit_data.blank? ? nil : commit_data.select{|item| item["timestamp"] == date.to_time.to_i}
|
||||||
@commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)
|
@commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)
|
||||||
end
|
end
|
||||||
render :json => {dates: @date_data, issues_count: @issue_data, pull_requests_count: @pull_request_data, commits_count: @commit_data}
|
render :json => {dates: @date_data, issues_count: @issue_data, pull_requests_count: @pull_request_data, commits_count: @commit_data}
|
||||||
|
|
|
@ -2,18 +2,24 @@ class BaseForm
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
|
||||||
def check_project_category(project_category_id)
|
def check_project_category(project_category_id)
|
||||||
raise "project_category_id参数值无效." if (ProjectCategory.find_by_id project_category_id).blank?
|
raise "project_category_id参数值无效." if project_category_id && !ProjectCategory.exists?(project_category_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_project_language(project_language_id)
|
def check_project_language(project_language_id)
|
||||||
raise "project_language_id参数值无效." if (ProjectLanguage.find_by_id project_language_id).blank?
|
raise "project_language_id参数值无效." if project_language_id && !ProjectLanguage.exists?(project_language_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_repository_name(user_id, repository_name)
|
def check_repository_name(user_id, repository_name)
|
||||||
raise "仓库名称已被使用." if Repository.where(user_id: user_id, identifier: repository_name.strip).exists?
|
check_reversed_keyword(repository_name)
|
||||||
|
raise "项目标识已被使用." if Repository.where(user_id: user_id, identifier: repository_name.strip).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_project_name(user_id, project_name)
|
def check_project_name(user_id, project_name)
|
||||||
raise "项目名称已被使用." if Project.where(user_id: user_id, name: project_name.strip).exists?
|
raise "项目名称已被使用." if Project.where(user_id: user_id, name: project_name.strip).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_reversed_keyword(repository_name)
|
||||||
|
raise "项目标识已被占用." if ReversedKeyword.is_reversed(repository_name).exists?
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
class Projects::CreateForm < BaseForm
|
class Projects::CreateForm < BaseForm
|
||||||
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
|
||||||
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id,
|
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id,
|
||||||
:project_language_id, :ignore_id, :license_id, :private, :owner
|
:project_language_id, :ignore_id, :license_id, :private, :owner
|
||||||
|
|
||||||
validates :user_id, :name, :description,:repository_name,
|
validates :user_id, :name, :repository_name, presence: true
|
||||||
:project_category_id, :project_language_id, presence: true
|
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||||
validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
|
||||||
|
|
||||||
validates :name, length: { maximum: 50 }
|
validates :name, length: { maximum: 50 }
|
||||||
validates :repository_name, length: { maximum: 100 }
|
validates :repository_name, length: { maximum: 100 }
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
class Projects::MigrateForm < BaseForm
|
class Projects::MigrateForm < BaseForm
|
||||||
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
attr_accessor :user_id, :name, :repository_name, :project_category_id, :description,
|
||||||
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
|
:project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner
|
||||||
|
|
||||||
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id, :project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner
|
validates :user_id, :name, :repository_name, :clone_addr, presence: true
|
||||||
|
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||||
validates :user_id, :name, :description,:repository_name, :project_category_id, :project_language_id, presence: true
|
validates :clone_addr, format: { with: CustomRegexp::URL_REGEX, multiline: true, message: "地址格式不正确" }
|
||||||
validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
validates :name, length: { maximum: 50 }
|
||||||
validates :clone_addr, format: { with: URL_REGEX, multiline: true, message: "地址格式不正确" }
|
validates :repository_name, length: { maximum: 100 }
|
||||||
|
validates :description, length: { maximum: 200 }
|
||||||
validate do
|
validate do
|
||||||
check_project_name(user_id, name) unless name.blank?
|
check_project_name(user_id, name) unless name.blank?
|
||||||
check_repository_name(user_id, repository_name) unless repository_name.blank?
|
check_repository_name(user_id, repository_name) unless repository_name.blank?
|
||||||
|
|
|
@ -6,4 +6,8 @@ module CustomRegexp
|
||||||
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
||||||
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
||||||
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
||||||
|
|
||||||
|
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
|
||||||
|
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,4 +24,12 @@ class ApplicationRecord < ActiveRecord::Base
|
||||||
def reset_platform_cache_async_job
|
def reset_platform_cache_async_job
|
||||||
ResetPlatformCacheJob.perform_later
|
ResetPlatformCacheJob.perform_later
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.strip_param(key)
|
||||||
|
key.to_s.strip.presence
|
||||||
|
end
|
||||||
|
|
||||||
|
def strip_param(key)
|
||||||
|
key.to_s.strip.presence
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
#
|
#
|
||||||
# Table name: edu_settings
|
# Table name: edu_settings
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# name :string(255)
|
# name :string(255)
|
||||||
# value :string(255)
|
# value :string(255)
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# description :string(255)
|
# description :string(255)
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
# index_edu_settings_on_name (name) UNIQUE
|
# index_edu_settings_on_name (name) UNIQUE
|
||||||
#
|
#
|
||||||
|
|
||||||
class EduSetting < ApplicationRecord
|
class EduSetting < ApplicationRecord
|
||||||
after_commit :expire_value_cache
|
after_commit :expire_value_cache
|
||||||
|
|
||||||
|
scope :by_search, -> (keyword){ where("name LIKE :keyword OR value LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
|
||||||
|
|
||||||
def value_cache_key
|
def value_cache_key
|
||||||
self.class.value_cache_key(name)
|
self.class.value_cache_key(name)
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,6 +17,9 @@ class Site < ApplicationRecord
|
||||||
# common: 普通链接
|
# common: 普通链接
|
||||||
enum site_type: { add: 0, personal: 1, common: 2 }
|
enum site_type: { add: 0, personal: 1, common: 2 }
|
||||||
|
|
||||||
|
scope :by_search, -> (keyword){ where("name LIKE :keyword OR url LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
|
||||||
|
scope :by_site_type, -> (site_type){ where(site_type: strip_param(site_type)) unless strip_param(site_type).blank? }
|
||||||
|
|
||||||
def self.set_default_menu
|
def self.set_default_menu
|
||||||
set_add_menu!
|
set_add_menu!
|
||||||
set_personal_menu!
|
set_personal_menu!
|
||||||
|
@ -26,8 +29,8 @@ class Site < ApplicationRecord
|
||||||
private
|
private
|
||||||
def self.set_add_menu!
|
def self.set_add_menu!
|
||||||
adds= [
|
adds= [
|
||||||
{name: '新建镜像项目', key: 'add_mirror_project', url: '/projects/mirror/new'},
|
{name: '新建项目', key: 'add_mirror_project', url: '/projects/mirror/new'},
|
||||||
{name: '新建托管项目', key: 'add_common', url: '/projects/deposit/new'},
|
{name: '导入项目', key: 'add_common', url: '/projects/deposit/new'},
|
||||||
{name: '新建组织', key: 'add_r', url: '/organize/new'}]
|
{name: '新建组织', key: 'add_r', url: '/organize/new'}]
|
||||||
|
|
||||||
adds.each { |ele|
|
adds.each { |ele|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
class Admins::EduSettingQuery < ApplicationQuery
|
||||||
|
include CustomSortable
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
sort_columns :id, default_by: :id, default_direction: :desc
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
collection = EduSetting.all
|
||||||
|
collection = filter_settings(collection)
|
||||||
|
|
||||||
|
custom_sort collection, params[:sort_by], params[:sort_direction]
|
||||||
|
end
|
||||||
|
|
||||||
|
def filter_settings(collection)
|
||||||
|
by_search(collection)
|
||||||
|
end
|
||||||
|
|
||||||
|
def by_search(collection)
|
||||||
|
keyword = strip_param(:search)
|
||||||
|
collection.by_search(keyword)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,35 @@
|
||||||
|
class Admins::SiteQuery < ApplicationQuery
|
||||||
|
include CustomSortable
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
sort_columns :id, default_by: :id, default_direction: :desc
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
collection = Site.all
|
||||||
|
collection = filter_sites(collection)
|
||||||
|
|
||||||
|
custom_sort collection, params[:sort_by], params[:sort_direction]
|
||||||
|
end
|
||||||
|
|
||||||
|
def filter_sites(collection)
|
||||||
|
collection = by_search(collection)
|
||||||
|
collection = by_stie_type(collection)
|
||||||
|
collection
|
||||||
|
end
|
||||||
|
|
||||||
|
def by_search(collection)
|
||||||
|
keyword = strip_param(:search)
|
||||||
|
collection.by_search(keyword)
|
||||||
|
end
|
||||||
|
|
||||||
|
def by_stie_type(collection)
|
||||||
|
site_type = strip_param(:site_type)
|
||||||
|
collection.by_site_type(site_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -15,8 +15,8 @@ class Gitea::Organization::Repository::CreateService < Gitea::ClientService
|
||||||
private
|
private
|
||||||
|
|
||||||
def request_params
|
def request_params
|
||||||
create_params = params.merge(readme: "readme")
|
# create_params = params.merge(readme: "readme")
|
||||||
Hash.new.merge(token: token, data: create_params)
|
Hash.new.merge(token: token, data: params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
|
|
|
@ -25,8 +25,8 @@ class Gitea::Repository::CreateService < Gitea::ClientService
|
||||||
private
|
private
|
||||||
|
|
||||||
def request_params
|
def request_params
|
||||||
create_params = params.merge(readme: "readme")
|
# create_params = params.merge(readme: "readme")
|
||||||
Hash.new.merge(token: token, data: create_params)
|
Hash.new.merge(token: token, data: params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Projects::CreateService < ApplicationService
|
||||||
ignore_id: params[:ignore_id],
|
ignore_id: params[:ignore_id],
|
||||||
license_id: params[:license_id],
|
license_id: params[:license_id],
|
||||||
website: params[:website],
|
website: params[:website],
|
||||||
identifier: params[:repository_name] #新增,hs
|
identifier: params[:repository_name]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Repositories::MigrateService < ApplicationService
|
||||||
private: params[:hidden],
|
private: params[:hidden],
|
||||||
mirror: wrapper_mirror || false,
|
mirror: wrapper_mirror || false,
|
||||||
auth_username: params[:login],
|
auth_username: params[:login],
|
||||||
auth_password: Base64.decode64(params[:password])
|
auth_password: Base64.decode64(params[:password] || "")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<div class="modal fade edu_setting-change-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><%= type == "create" ? "新增" : "编辑" %></h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<%= form_for @edu_setting, url: {controller: "edu_settings", action: "#{type}"} do |p| %>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
变量名 <span class="ml10 color-orange mr20">*</span>
|
||||||
|
</label>
|
||||||
|
<%= p.text_field :name, class: "form-control input-lg",required: true%>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
变量值 <span class="ml10 color-orange mr20">*</span>
|
||||||
|
</label>
|
||||||
|
<%= p.text_field :value, class: "form-control input-lg",required: true%>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
备注说明
|
||||||
|
</label>
|
||||||
|
<%= p.text_area :description, class: "form-control", placeholder: ""%>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
|
||||||
|
<%= p.submit "确认", class: "btn btn-primary submit-btn" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<table class="table table-hover text-center subject-list-table">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th width="5%">序号</th>
|
||||||
|
<th width="15%">变量名</th>
|
||||||
|
<th width="35%">变量值</th>
|
||||||
|
<th width="20%">备注说明</th>
|
||||||
|
<th width="10%"><%= sort_tag('创建时间', name: 'created_at', path: admins_edu_settings_path) %></th>
|
||||||
|
<th width="10%">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% if edu_settings.present? %>
|
||||||
|
<% edu_settings.each_with_index do |edu_setting, index| %>
|
||||||
|
<tr class="edu_setting-item-<%= edu_setting.id %>">
|
||||||
|
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||||
|
<td>
|
||||||
|
<%= edu_setting.name %>
|
||||||
|
</td>
|
||||||
|
<td><%= edu_setting.value %></td>
|
||||||
|
|
||||||
|
<td><%= overflow_hidden_span display_text(edu_setting.description), width: 200 %></td>
|
||||||
|
<td><%= edu_setting.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
|
||||||
|
<td class="action-container">
|
||||||
|
<%= link_to "编辑", edit_admins_edu_setting_path(edu_setting), remote: true, class: "action" %>
|
||||||
|
<%= link_to "删除", admins_edu_setting_path(edu_setting), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% else %>
|
||||||
|
<%= render 'admins/shared/no_data_for_table' %>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= render partial: 'admins/shared/paginate', locals: { objects: edu_settings } %>
|
|
@ -0,0 +1,2 @@
|
||||||
|
$("#edu_setting-modals").html("<%= j render(partial: 'admins/edu_settings/form', locals: {type: 'update'}) %>")
|
||||||
|
$(".edu_setting-change-modal").modal('show');
|
|
@ -0,0 +1,22 @@
|
||||||
|
<% define_admin_breadcrumbs do %>
|
||||||
|
<% add_admin_breadcrumb('全局变量配置') %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="box search-form-container edu_settings-list-form">
|
||||||
|
<%= form_tag(admins_edu_settings_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
||||||
|
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '关键字检索') %>
|
||||||
|
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
||||||
|
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to "新增", new_admins_edu_setting_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box py-0 pt-4 pl-4 daily-school-statistic-title">
|
||||||
|
说明:该界面适用于存储全局变量.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box admin-list-container edu_settings-list-container">
|
||||||
|
<%= render partial: 'admins/edu_settings/list', locals: { edu_settings: @edu_settings } %>
|
||||||
|
</div>
|
||||||
|
<div id="edu_setting-modals">
|
||||||
|
</div>
|
|
@ -0,0 +1 @@
|
||||||
|
$('.edu_settings-list-container').html("<%= j( render partial: 'admins/edu_settings/list', locals: { edu_settings: @edu_settings } ) %>");
|
|
@ -0,0 +1,2 @@
|
||||||
|
$("#edu_setting-modals").html("<%= j render(partial: 'admins/edu_settings/form', locals: {type: 'create'}) %>")
|
||||||
|
$(".edu_setting-change-modal").modal('show');
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<div class="box search-form-container laboratory-list-form">
|
<div class="box search-form-container laboratory-list-form">
|
||||||
<%= form_tag(admins_laboratories_path(unsafe_params), method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
<%= form_tag(admins_laboratories_path(unsafe_params), method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
||||||
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-6 col-md-4 ml-3', placeholder: '学校名称/二级域名前缀检索') %>
|
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-6 col-md-4 ml-3', placeholder: '单位名称/二级域名前缀检索') %>
|
||||||
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<% school = laboratory&.school %>
|
<% school = laboratory&.school %>
|
||||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||||
<td class="text-left"><%= school&.name || 'Trustie主站' %></td>
|
<td class="text-left"><%= school&.name || '主站' %></td>
|
||||||
<td class="text-left">
|
<td class="text-left">
|
||||||
<% if laboratory.identifier %>
|
<% if laboratory.identifier %>
|
||||||
<%= link_to laboratory.site, "https://#{laboratory.site}", target: '_blank' %>
|
<%= link_to laboratory.site, "https://#{laboratory.site}", target: '_blank' %>
|
||||||
|
@ -29,40 +29,10 @@
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td><%= laboratory.created_at.strftime('%Y-%m-%d %H:%M') %></td>
|
<td><%= laboratory.created_at.strftime('%Y-%m-%d %H:%M') %></td>
|
||||||
<td>
|
|
||||||
<% if school.present? && laboratory.id != 1 %>
|
|
||||||
<%= check_box_tag :sync_course,!laboratory.sync_course,laboratory.sync_course,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<% if school.present? && laboratory.id != 1 %>
|
|
||||||
<%= check_box_tag :sync_subject,!laboratory.sync_subject,laboratory.sync_subject,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<% if school.present? && laboratory.id != 1 %>
|
|
||||||
<%= check_box_tag :sync_shixun,!laboratory.sync_shixun,laboratory.sync_shixun,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
<td class="action-container">
|
<td class="action-container">
|
||||||
<%= link_to '定制', admins_laboratory_laboratory_setting_path(laboratory), class: 'action' %>
|
<%= link_to '设置', admins_laboratory_laboratory_setting_path(laboratory), class: 'action' %>
|
||||||
|
|
||||||
<% if school.present? && laboratory.id != 1 %>
|
<% if school.present? && laboratory.id != 1 %>
|
||||||
<%= javascript_void_link '添加管理员', class: 'action', data: { laboratory_id: laboratory.id, toggle: 'modal', target: '.admin-add-laboratory-user-modal' } %>
|
<%= delete_link '删除', admins_laboratory_path(laboratory, element: ".laboratory-item-#{laboratory.id}"), class: 'action' %>
|
||||||
<%= link_to '同步用户', synchronize_user_admins_laboratory_path(laboratory), remote: true, data: { confirm: '确认同步该单位下的所有用户到云上实验室吗?' }, class: 'action' %>
|
<% end %>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div class="d-inline">
|
|
||||||
<%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %>
|
|
||||||
<div class="dropdown-menu more-action-dropdown">
|
|
||||||
<%= link_to '轮播图', admins_laboratory_carousels_path(laboratory), class: 'dropdown-item' %>
|
|
||||||
|
|
||||||
<%= link_to '查看实训项目', admins_laboratory_laboratory_shixuns_path(laboratory), class: 'dropdown-item' %>
|
|
||||||
<%= link_to '查看实践课程', admins_laboratory_laboratory_subjects_path(laboratory), class: 'dropdown-item' %>
|
|
||||||
|
|
||||||
<% if school.present? && laboratory.id != 1 %>
|
|
||||||
<%= delete_link '删除', admins_laboratory_path(laboratory, element: ".laboratory-item-#{laboratory.id}"), class: 'dropdown-item delete-laboratory-action' %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -7,9 +7,6 @@
|
||||||
<th width="6%">统计链接</th>
|
<th width="6%">统计链接</th>
|
||||||
<th width="22%">管理员</th>
|
<th width="22%">管理员</th>
|
||||||
<th width="10%"><%= sort_tag('创建时间', name: 'id', path: admins_laboratories_path) %></th>
|
<th width="10%"><%= sort_tag('创建时间', name: 'id', path: admins_laboratories_path) %></th>
|
||||||
<th width="4%" title="同步显示主站下该单位的课堂">同步课堂</th>
|
|
||||||
<th width="4%" title="同步显示主站下该单位用户创建的实践课程">同步实践课程</th>
|
|
||||||
<th width="4%" title="同步显示主站下该单位用户创建的实训">同步实训</th>
|
|
||||||
<th width="16%">操作</th>
|
<th width="16%">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
|
@ -86,7 +86,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group px-2 setting-item">
|
<%
|
||||||
|
=begin%>
|
||||||
|
<div class="form-group px-2 setting-item">
|
||||||
<div class="setting-item-head"><h6>Banner设置</h6></div>
|
<div class="setting-item-head"><h6>Banner设置</h6></div>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<div class="pl-0 py-3 row setting-item-body">
|
<div class="pl-0 py-3 row setting-item-body">
|
||||||
|
@ -140,7 +142,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<%
|
||||||
|
=end%>
|
||||||
|
|
||||||
<div class="form-group px-2 setting-item">
|
<div class="form-group px-2 setting-item">
|
||||||
<div class="setting-item-head">
|
<div class="setting-item-head">
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
<%= link_to "新增", new_admins_reversed_keyword_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
<%= link_to "新增", new_admins_reversed_keyword_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="box py-0 pt-4 pl-4 daily-school-statistic-title">
|
||||||
|
旨在为特殊用户群体、特殊场景、路由而保留的关键词,如:Gitlink、Trustie等;目前主要在用户注册、创建组织、创建项目等场景下做关键词的验证.
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="box admin-list-container reversed-keyword-list-container">
|
<div class="box admin-list-container reversed-keyword-list-container">
|
||||||
<%= render partial: 'admins/reversed_keywords/list', locals: { keywords: @keywords } %>
|
<%= render partial: 'admins/reversed_keywords/list', locals: { keywords: @keywords } %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -26,10 +26,11 @@
|
||||||
<li><%= sidebar_item(admins_project_categories_path, '分类列表', icon: 'sitemap', controller: 'admins-project_categories') %></li>
|
<li><%= sidebar_item(admins_project_categories_path, '分类列表', icon: 'sitemap', controller: 'admins-project_categories') %></li>
|
||||||
<li><%= sidebar_item(admins_project_licenses_path, '开源许可证', icon: 'file-text-o', controller: 'admins-project_licenses') %></li>
|
<li><%= sidebar_item(admins_project_licenses_path, '开源许可证', icon: 'file-text-o', controller: 'admins-project_licenses') %></li>
|
||||||
<li><%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores') %></li>
|
<li><%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores') %></li>
|
||||||
<li><%= sidebar_item(admins_reversed_keywords_path, '系统保留关键词', icon: 'key', controller: 'admins-reversed_keywords') %></li>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li><%= sidebar_item(admins_reversed_keywords_path, '系统保留关键词', icon: 'key', controller: 'admins-reversed_keywords') %></li>
|
||||||
|
|
||||||
<li><%= sidebar_item(admins_laboratories_path, '云上实验室', icon: 'cloud', controller: 'admins-laboratories') %></li>
|
<li><%= sidebar_item(admins_laboratories_path, '云上实验室', icon: 'cloud', controller: 'admins-laboratories') %></li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
|
@ -42,6 +43,12 @@
|
||||||
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li>
|
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= sidebar_item_group('#setting-system', '系统配置', icon: 'wrench') do %>
|
||||||
|
<li><%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites') %></li>
|
||||||
|
<li><%= sidebar_item(admins_edu_settings_path, '全局变量配置', icon: 'pencil-square', controller: 'admins-edu_settings') %></li>
|
||||||
|
<% end %>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<%= sidebar_item('/admins/sidekiq', '定时任务', icon: 'bell', controller: 'root') %>
|
<%= sidebar_item('/admins/sidekiq', '定时任务', icon: 'bell', controller: 'root') %>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<div class="modal fade site-change-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><%= type == "create" ? "新增" : "编辑" %></h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<%= form_for @site, url: {controller: "sites", action: "#{type}"} do |p| %>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
名称 <span class="ml10 color-orange mr20">*</span>
|
||||||
|
</label>
|
||||||
|
<%= p.text_field :name, class: "form-control input-lg",required: true%>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
路由 <span class="ml10 color-orange mr20">*</span>
|
||||||
|
</label>
|
||||||
|
<%= p.text_field :url, class: "form-control input-lg",required: true%>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
标识 <span class="ml10 color-orange mr20">*</span>
|
||||||
|
</label>
|
||||||
|
<%= p.text_field :key, class: "form-control input-lg",required: true%>
|
||||||
|
</div>
|
||||||
|
<div class="form-group ">
|
||||||
|
<label for="status">类型:</label>
|
||||||
|
<%= p.select :site_type, options_for_select(Site.site_types.map { |key, value| [key.humanize, key] }), {}, class: "form-control" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
|
||||||
|
<%= p.submit "确认", class: "btn btn-primary submit-btn" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<table class="table table-hover text-center subject-list-table">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th width="5%">序号</th>
|
||||||
|
<th width="15%">名称</th>
|
||||||
|
<th width="30%">路由</th>
|
||||||
|
<th width="20%">标识</th>
|
||||||
|
<th width="10%">类型</th>
|
||||||
|
<th width="20%"><%= sort_tag('创建时间', name: 'created_at', path: admins_sites_path) %></th>
|
||||||
|
<th width="25%">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% if sites.present? %>
|
||||||
|
<% sites.each_with_index do |site, index| %>
|
||||||
|
<tr class="site-item-<%= site.id %>">
|
||||||
|
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||||
|
<td>
|
||||||
|
<%= overflow_hidden_span display_text(site.name), width: 150 %>
|
||||||
|
</td>
|
||||||
|
<td><%= site.url %></td>
|
||||||
|
|
||||||
|
<td><%= overflow_hidden_span display_text(site.key), width: 150 %></td>
|
||||||
|
<td><%= site.site_type.humanize %></td>
|
||||||
|
<td><%= site.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
|
||||||
|
<td class="action-container">
|
||||||
|
<%= link_to "编辑", edit_admins_site_path(site), remote: true, class: "action" %>
|
||||||
|
<%= link_to "删除", admins_site_path(site), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% else %>
|
||||||
|
<%= render 'admins/shared/no_data_for_table' %>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= render partial: 'admins/shared/paginate', locals: { objects: sites } %>
|
|
@ -0,0 +1,2 @@
|
||||||
|
$("#site-modals").html("<%= j render(partial: 'admins/sites/form', locals: {type: 'update'}) %>")
|
||||||
|
$(".site-change-modal").modal('show');
|
|
@ -0,0 +1,24 @@
|
||||||
|
<% define_admin_breadcrumbs do %>
|
||||||
|
<% add_admin_breadcrumb('Setting接口配置') %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="box search-form-container sites-list-form">
|
||||||
|
<%= form_tag(admins_sites_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
||||||
|
<div class="form-group mr-2">
|
||||||
|
<label for="status">类型:</label>
|
||||||
|
<% type_options = [['全部', ''], ['Add', Site.site_types[:add]], ['Personal', Site.site_types[:personal]], ['Common', Site.site_types[:common]]] %>
|
||||||
|
<%= select_tag(:site_type, options_for_select(type_options), class: 'form-control') %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '关键字检索') %>
|
||||||
|
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
||||||
|
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to "新增", new_admins_site_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box admin-list-container sites-list-container">
|
||||||
|
<%= render partial: 'admins/sites/list', locals: { sites: @sites } %>
|
||||||
|
</div>
|
||||||
|
<div id="site-modals">
|
||||||
|
</div>
|
|
@ -0,0 +1 @@
|
||||||
|
$('.sites-list-container').html("<%= j( render partial: 'admins/sites/list', locals: { sites: @sites } ) %>");
|
|
@ -0,0 +1,2 @@
|
||||||
|
$("#site-modals").html("<%= j render(partial: 'admins/sites/form', locals: {type: 'create'}) %>")
|
||||||
|
$(".site-change-modal").modal('show');
|
|
@ -1,27 +0,0 @@
|
||||||
<%= form_with(model: edu_setting, local: true) do |form| %>
|
|
||||||
<% if edu_setting.errors.any? %>
|
|
||||||
<div id="error_explanation">
|
|
||||||
<h2><%= pluralize(edu_setting.errors.count, "error") %> prohibited this edu_setting from being saved:</h2>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<% edu_setting.errors.full_messages.each do |message| %>
|
|
||||||
<li><%= message %></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<%= form.label :name %>
|
|
||||||
<%= form.text_field :name %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<%= form.label :value %>
|
|
||||||
<%= form.text_field :value %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<%= form.submit %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<h1>Editing Edu Setting</h1>
|
|
||||||
|
|
||||||
<%= render 'form', edu_setting: @edu_setting %>
|
|
||||||
|
|
||||||
<%= link_to 'Show', @edu_setting %> |
|
|
||||||
<%= link_to 'Back', edu_settings_path %>
|
|
|
@ -1,30 +0,0 @@
|
||||||
<p id="notice"><%= notice %></p>
|
|
||||||
|
|
||||||
<h1>EduCoder公共配置</h1>
|
|
||||||
<p>说明:该界面适用于存储全局变量</p>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>变量名</th>
|
|
||||||
<th>变量值</th>
|
|
||||||
<th colspan="3"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
<% @edu_settings.each do |edu_setting| %>
|
|
||||||
<tr>
|
|
||||||
<td><%= edu_setting.name %></td>
|
|
||||||
<td><%= edu_setting.value %></td>
|
|
||||||
<td><%= link_to 'Show', edu_setting %></td>
|
|
||||||
<td><%= link_to 'Edit', edit_edu_setting_path(edu_setting) %></td>
|
|
||||||
<td><%= link_to 'Destroy', edu_setting, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<%= link_to 'New Edu Setting', new_edu_setting_path %>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<h1>New Edu Setting</h1>
|
|
||||||
|
|
||||||
<%= render 'form', edu_setting: @edu_setting %>
|
|
||||||
|
|
||||||
<%= link_to 'Back', edu_settings_path %>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<p id="notice"><%= notice %></p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>Name:</strong>
|
|
||||||
<%= @edu_setting.name %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>Value:</strong>
|
|
||||||
<%= @edu_setting.value %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<%= link_to 'Edit', edit_edu_setting_path(@edu_setting) %> |
|
|
||||||
<%= link_to 'Back', edu_settings_path %>
|
|
|
@ -3,18 +3,18 @@ json.login @user.login
|
||||||
json.name @user.full_name
|
json.name @user.full_name
|
||||||
json.location @user.location
|
json.location @user.location
|
||||||
json.image_url url_to_avatar(@user)
|
json.image_url url_to_avatar(@user)
|
||||||
json.url "#{request.base_url }/users/#{@user.login}"
|
json.url "#{request.base_url }/#{@user.login}"
|
||||||
json.followers_count @user.followers_count
|
json.followers_count @user.followers_count
|
||||||
json.followers_url "#{base_url}/users/#{@user.login}/fan_users"
|
json.followers_url "#{base_url}/#{@user.login}/fan_users"
|
||||||
json.following_count @user.following_count
|
json.following_count @user.following_count
|
||||||
json.following_url "#{base_url}/users/#{@user.login}/watchers"
|
json.following_url "#{base_url}/#{@user.login}/watchers"
|
||||||
json.projects_count @user.projects_count
|
json.projects_count @user.projects_count
|
||||||
json.projects_url "#{base_url}/users/#{@user.login}"
|
json.projects_url "#{base_url}/#{@user.login}"
|
||||||
json.projects_count @user.projects_count
|
json.projects_count @user.projects_count
|
||||||
json.is_watch current_user&.watched?(@user)
|
json.is_watch current_user&.watched?(@user)
|
||||||
json.organizations @user.organizations do |organization|
|
json.organizations @user.organizations do |organization|
|
||||||
json.login organization.login
|
json.login organization.login
|
||||||
json.name organization.real_name
|
json.name organization.real_name
|
||||||
json.image_url url_to_avatar(organization)
|
json.image_url url_to_avatar(organization)
|
||||||
json.url "#{base_url}/organize/#{organization.login}"
|
json.url "#{base_url}/#{organization.login}"
|
||||||
end
|
end
|
|
@ -651,6 +651,8 @@ Rails.application.routes.draw do
|
||||||
get :visits_static
|
get :visits_static
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
resources :sites
|
||||||
|
resources :edu_settings
|
||||||
resources :project_languages
|
resources :project_languages
|
||||||
resources :project_categories
|
resources :project_categories
|
||||||
resources :project_licenses
|
resources :project_licenses
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
# 新版Git测试说明
|
|
||||||
统一:
|
|
||||||
参考实训:http://47.96.87.25:48080/shixuns/ca9fvobr/repository
|
|
||||||
请求方式:POST
|
|
||||||
参数{repo_path: "educoder/ca9fvobr.git"}
|
|
||||||
公共方法:
|
|
||||||
['add_repository', 'fork_repository', 'delete_repository', 'file_tree', 'update_file',
|
|
||||||
'file_content', 'commits']
|
|
||||||
|
|
||||||
1、仓库目录接口
|
|
||||||
测试方法:模拟1000个用户同时去访问接口,访问方式
|
|
||||||
http://121.199.19.206:9000/api/file_tree
|
|
||||||
参数:
|
|
||||||
{repo_path: "educoder/ca9fvobr.git", path: ''} // 如:{path: 'step1'}
|
|
||||||
|
|
||||||
2、创建版本库
|
|
||||||
访问地址:http://121.199.19.206:9000/api/add_repository
|
|
||||||
参数:
|
|
||||||
{repo_path: 比如:"Hjqreturn/aaass1.git"}
|
|
||||||
|
|
||||||
3、fork版本库
|
|
||||||
http://121.199.19.206:9000/api/fork_repository
|
|
||||||
参数:
|
|
||||||
{repo_path: 'Hjqreturn/aaass1.git', fork_repository_path: 'educoder/ca9fvobr.git'}
|
|
||||||
说明:fork_repository_path是新项目的repo_path, repo_path是源项目的
|
|
||||||
|
|
||||||
|
|
||||||
4、更新文件
|
|
||||||
测试方法:
|
|
||||||
1、更新同一个文件,并发量可以不用很大,可以用同一个用户并发10-100
|
|
||||||
2、更新不同的文件:可以依据创建的版本库去更新
|
|
||||||
访问地址:http://121.199.19.206:9000/api/update_file
|
|
||||||
参数:
|
|
||||||
{repo_path: "educoder/ca9fvobr.git",
|
|
||||||
file_path: 'step1/main.py',
|
|
||||||
message: 'commit by test',
|
|
||||||
content: 'afdjadsjfj1111',
|
|
||||||
author_name: 'guange',
|
|
||||||
author_email: '8863824@gmil.com'}
|
|
||||||
|
|
||||||
5、获取文件内容
|
|
||||||
访问地址:http://121.199.19.206:9000/api/file_content
|
|
||||||
参数:
|
|
||||||
{repo_path: "educoder/ca9fvobr.git", path: 'step1/main.py',}
|
|
||||||
|
|
||||||
6、获取提交记录
|
|
||||||
访问地址:http://121.199.19.206:9000/api/commits
|
|
||||||
参数:
|
|
||||||
{repo_path: 比如:"educoder/ca9fvobr.git"}
|
|
||||||
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
mbtclufr
|
|
||||||
9op3hs4j
|
|
||||||
96ctv7yr
|
|
||||||
rtmzxfke
|
|
||||||
ofqxthrf
|
|
||||||
czu9w4gj
|
|
||||||
9fpzj6et
|
|
||||||
pwhc865b
|
|
||||||
maozpx4l
|
|
||||||
y5wh2ofx
|
|
||||||
b5rzhpf3
|
|
||||||
bs243nrl
|
|
||||||
47fn2yfb
|
|
||||||
kwotfxey
|
|
||||||
w5468sbp
|
|
||||||
fyekprio
|
|
||||||
q6ze5fih
|
|
||||||
b5hjq9zm
|
|
||||||
ky8pbqux
|
|
||||||
53phc7nq
|
|
||||||
b9j2yuix
|
|
||||||
9t3uphwk
|
|
||||||
iokm8ah2
|
|
||||||
qlsy6xb4
|
|
||||||
345bqhfi
|
|
||||||
v728fqia
|
|
||||||
4euftvf2
|
|
||||||
f23sef5m
|
|
||||||
nhqis8m9
|
|
||||||
qp72tb5x
|
|
||||||
gt3anszw
|
|
||||||
tng6heyf
|
|
||||||
nb9keawo
|
|
||||||
elgnbkp9
|
|
||||||
4neslomg
|
|
||||||
lh35s6ma
|
|
||||||
xmc4rpay
|
|
||||||
qrpaxi6b
|
|
||||||
9fla2zry
|
|
||||||
efuibzrm
|
|
||||||
fzp3iu4w
|
|
||||||
pligsyn8
|
|
||||||
glbksr29
|
|
||||||
kfm7ghyc
|
|
||||||
p6hk3svf
|
|
||||||
p539gjhm
|
|
||||||
am5o73er
|
|
||||||
4x3qwrbe
|
|
||||||
fqosyl8g
|
|
||||||
of5z3fci
|
|
||||||
tb7hw62n
|
|
||||||
ie6zxg7r
|
|
||||||
4q2bmy9h
|
|
||||||
fpm3u5yb
|
|
||||||
nikx3ojt
|
|
||||||
vt82s9bq
|
|
||||||
ma59fefo
|
|
||||||
lxa39tfq
|
|
||||||
4gnockxf
|
|
||||||
nxwg84ey
|
|
||||||
fmie8nzb
|
|
||||||
w5nsr24v
|
|
||||||
4hn3efwc
|
|
||||||
h9ljfbq7
|
|
||||||
nuv54t8b
|
|
||||||
2te9fmfq
|
|
||||||
vihnsayz
|
|
||||||
qhlyn82s
|
|
||||||
vw74kmfr
|
|
||||||
vcta36bz
|
|
||||||
henz425l
|
|
||||||
g529v38z
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Admins::EduSettingsController, type: :controller do
|
||||||
|
|
||||||
|
describe "GET #index" do
|
||||||
|
it "returns http success" do
|
||||||
|
get :index
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #new" do
|
||||||
|
it "returns http success" do
|
||||||
|
get :new
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #update" do
|
||||||
|
it "returns http success" do
|
||||||
|
get :update
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #edit" do
|
||||||
|
it "returns http success" do
|
||||||
|
get :edit
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #create" do
|
||||||
|
it "returns http success" do
|
||||||
|
get :create
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #destroy" do
|
||||||
|
it "returns http success" do
|
||||||
|
get :destroy
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Admins::SitesController, type: :controller do
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "edu_settings/create.html.erb", type: :view do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "edu_settings/destroy.html.erb", type: :view do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "edu_settings/edit.html.erb", type: :view do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "edu_settings/index.html.erb", type: :view do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "edu_settings/new.html.erb", type: :view do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "edu_settings/update.html.erb", type: :view do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
Loading…
Reference in New Issue