Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_item_bank

yslnewtiku
杨树林 5 years ago
commit 6720ff9930

@ -5,9 +5,10 @@ class Admins::ShixunSettingsController < Admins::BaseController
shixun_settings = Admins::ShixunSettingsQuery.call(params) shixun_settings = Admins::ShixunSettingsQuery.call(params)
@editing_shixuns = shixun_settings.where(status:0).size @editing_shixuns = shixun_settings.where(status:0).size
@pending_shixuns = shixun_settings.where(status:1).size @processed_shixuns = shixun_settings.where(status:2, public: 0).size
@processed_shixuns = shixun_settings.where(status:2).size
@closed_shixuns = shixun_settings.where(status:3).size @closed_shixuns = shixun_settings.where(status:3).size
@pending_public_shixuns = shixun_settings.where(public:1).size
@processed_pubic_shixuns = shixun_settings.where(public:2).size
@sort_json = { @sort_json = {
can_copy: params[:can_copy].present? ? params[:can_copy] : false, can_copy: params[:can_copy].present? ? params[:can_copy] : false,

@ -5,10 +5,8 @@ class Admins::ShixunsController < Admins::BaseController
params[:sort_direction] = params[:sort_direction].presence || 'desc' params[:sort_direction] = params[:sort_direction].presence || 'desc'
shixuns = Admins::ShixunQuery.call(params) shixuns = Admins::ShixunQuery.call(params)
@editing_shixuns = shixuns.where(status:0).size @editing_shixuns = shixuns.where(status:0).size
@pending_shixuns = shixuns.where(status:1).size @processed_shixuns = shixuns.where(status:2, public: 0).size
@processed_shixuns = shixuns.where(status:2).size
@closed_shixuns = shixuns.where(status:3).size @closed_shixuns = shixuns.where(status:3).size
@none_public_shixuns = shixuns.where(public:0).size
@pending_public_shixuns = shixuns.where(public:1).size @pending_public_shixuns = shixuns.where(public:1).size
@processed_pubic_shixuns = shixuns.where(public:2).size @processed_pubic_shixuns = shixuns.where(public:2).size
@shixuns_type_check = MirrorRepository.pluck(:type_name,:id) @shixuns_type_check = MirrorRepository.pluck(:type_name,:id)

@ -172,7 +172,7 @@ class HackUserLastestCodesController < ApplicationController
# 编程题已经发布,且之前未通关奖励积分 # 编程题已经发布,且之前未通关奖励积分
@hack.increment!(:pass_num) @hack.increment!(:pass_num)
if @hack.status == 1 && !@my_hack.passed? if @hack.status == 1 && !@my_hack.passed?
reward_attrs = { container_id: game.id, container_type: 'Hack', score: @hack.score } reward_attrs = { container_id: @hack.id, container_type: 'Hack', score: @hack.score }
RewardGradeService.call(@my_hack.user, reward_attrs) RewardGradeService.call(@my_hack.user, reward_attrs)
RewardExperienceService.call(@my_hack.user, reward_attrs) RewardExperienceService.call(@my_hack.user, reward_attrs)
# 评测完成更新通过数 # 评测完成更新通过数

@ -13,25 +13,14 @@ class Admins::ShixunQuery < ApplicationQuery
all_shixuns = Shixun.all all_shixuns = Shixun.all
status = status =
case params[:status] case params[:status]
when "editing" then [0] when "editing" then {status: 0}
when "pending" then [1] when "processed" then {status: 2, public: 0}
when "processed" then [2] when "pending" then {public: 1}
when "closed" then [3] when "publiced" then {public: 2}
else when "closed" then {status: 3}
[0,1,2,3]
end end
public = all_shixuns = all_shixuns.where(status) if status.present?
case params[:public]
when "editing" then [0]
when "pending" then [1]
when "processed" then [2]
else
[0,1,2]
end
all_shixuns = all_shixuns.where(status: status) if status.present?
all_shixuns = all_shixuns.where(public: public) if public.present?
if params[:fork_status].present? if params[:fork_status].present?
all_shixuns = all_shixuns.where.not(fork_from: nil) all_shixuns = all_shixuns.where.not(fork_from: nil)

@ -15,16 +15,15 @@ class Admins::ShixunSettingsQuery < ApplicationQuery
all_shixuns = all_shixuns.where(id: params[:id]) if params[:id].present? all_shixuns = all_shixuns.where(id: params[:id]) if params[:id].present?
status = status =
case params[:status] case params[:status]
when "editing" then [0] when "editing" then {status: 0}
when "pending" then [1] when "processed" then {status: 2, public: 0}
when "processed" then [2] when "pending" then {public: 1}
when "closed" then [3] when "publiced" then {public: 2}
else when "closed" then {status: 3}
[0,1,2,3] end
end
all_shixuns = all_shixuns.where(status) if status.present?
all_shixuns = all_shixuns.where(status: status) if status.present?
if params[:tag].present? if params[:tag].present?
all_shixuns = all_shixuns.joins(:mirror_repositories).where("mirror_repositories.id = ?",params[:tag].to_i) all_shixuns = all_shixuns.joins(:mirror_repositories).where("mirror_repositories.id = ?",params[:tag].to_i)

@ -8,7 +8,7 @@
<div class="d-flex position-r"> <div class="d-flex position-r">
<div class="form-group mr-2"> <div class="form-group mr-2">
<label for="status">状态:</label> <label for="status">状态:</label>
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["待审核(#{@pending_shixuns})", 'pending'], ["已发布(#{@processed_shixuns})", 'processed'],["已关闭(#{@closed_shixuns})",'closed']] %> <% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["已发布未公开(#{@processed_shixuns})", 'processed'], ["待审核(#{@pending_public_shixuns})", 'pending'], ["已公开(#{@processed_pubic_shixuns})", 'publiced'], ["已关闭(#{@closed_shixuns})",'closed']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div> </div>
<div class="form-group mr-2"> <div class="form-group mr-2">

@ -8,16 +8,10 @@
<div class="d-flex position-r"> <div class="d-flex position-r">
<div class="form-group"> <div class="form-group">
<label for="status">状态:</label> <label for="status">状态:</label>
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["待审核(#{@pending_shixuns})", 'pending'], ["已发布(#{@processed_shixuns})", 'processed'],["已关闭(#{@closed_shixuns})",'closed']] %> <% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["已发布未公开(#{@processed_shixuns})", 'processed'], ["待审核(#{@pending_public_shixuns})", 'pending'], ["已公开(#{@processed_pubic_shixuns})", 'publiced'], ["已关闭(#{@closed_shixuns})",'closed']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div> </div>
<div class="form-group mr-2">
<label for="status">公开:</label>
<% public_options = [['全部', ''], ["未公开(#{@none_public_shixuns})", "editing"], ["待审核(#{@pending_public_shixuns})", 'pending'], ["已公开(#{@processed_pubic_shixuns})", 'processed']] %>
<%= select_tag(:public, options_for_select(public_options), class: 'form-control') %>
</div>
<div class="form-group mr-2"> <div class="form-group mr-2">
<label for="tag-choosed">技术平台:</label> <label for="tag-choosed">技术平台:</label>
<%= select_tag(:tag, options_for_select(@shixuns_type_check.unshift(["",nil])), class: 'form-control',id:"tag-choosed") %> <%= select_tag(:tag, options_for_select(@shixuns_type_check.unshift(["",nil])), class: 'form-control',id:"tag-choosed") %>

Binary file not shown.

@ -1,6 +1,52 @@
@import '../split_pane_resizer.scss'; @import '../split_pane_resizer.scss';
.split-pane-area{ .split-pane-area{
height: calc(100vh - 65px); height: calc(100vh - 65px);
.right_pane_code_wrap{
position: relative;
.editor_nodte_area,
.student_notes{
position: absolute;
z-index: 100;
}
.student_notes{
right: 0px;
top: 50%;
width: 36px;
height: 36px;
margin-top: -18px;
border-radius: 50%;
background: #5091FF;
color: #fff;
font-size: 18px;
text-align: center;
transform: translateX(18px);
cursor: pointer;
opacity: 0.5;
transition: all .3s;
&:hover{
opacity: 1;
transform: translateX(-10px);
}
}
.editor_nodte_area{
right: 10px;
top: 50%;
width: 450px;
height: 200px;
margin-top: -100px;
background: #fff;
border-radius: 5px;
padding: 14px 10px 0;
// opacity: ;
transform: translateX(500px);
transition: all .3s;
&.active{
transform: translateX(0px);
}
}
}
} }
.right_pane_code_wrap{ .right_pane_code_wrap{

@ -3,15 +3,20 @@
* @Author: tangjiang * @Author: tangjiang
* @Github: * @Github:
* @Date: 2019-11-27 14:59:51 * @Date: 2019-11-27 14:59:51
* @LastEditors: tangjiang * @LastEditors : tangjiang
* @LastEditTime: 2019-12-20 14:01:57 * @LastEditTime : 2019-12-26 17:56:51
*/ */
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import MyMonacoEditor from '../../components/myMonacoEditor'; import MyMonacoEditor from '../../components/myMonacoEditor';
import ControlSetting from '../../components/controlSetting'; import ControlSetting from '../../components/controlSetting';
import actions from '../../../../redux/actions'; import actions from '../../../../redux/actions';
// import QuillForEditor from '../../../../common/quillForEditor';
// import TextArea from 'antd/lib/input/TextArea';
import { Input, Form, Button } from 'antd';
// import FormItem from 'antd/lib/form/FormItem';
const { TextArea } = Input;
const FormItem = Form.Item;
const RightPane = (props) => { const RightPane = (props) => {
const { const {
@ -20,6 +25,7 @@ const RightPane = (props) => {
submitUserCode, submitUserCode,
input, input,
hack, hack,
loading,
notice, notice,
updateCode, updateCode,
hadCodeUpdate, hadCodeUpdate,
@ -27,12 +33,15 @@ const RightPane = (props) => {
updateNotice, updateNotice,
saveUserInputCode, saveUserInputCode,
restoreInitialCode, restoreInitialCode,
saveOpacityType, // saveOpacityType,
saveUserCodeForInterval saveUserCodeForInterval,
addNotes,
changeLoadingState
} = props; } = props;
const [editorCode, setEditorCode] = useState(''); const [editorCode, setEditorCode] = useState('');
const [noteClazz, setNoteClazz] = useState('editor_nodte_area');
const [noteCount] = useState(5000);
let initFlag = true; let initFlag = true;
useEffect(() => { useEffect(() => {
if (editor_code) { if (editor_code) {
@ -86,6 +95,28 @@ const RightPane = (props) => {
updateNotice && updateNotice(); updateNotice && updateNotice();
}; };
const handleClickNote = () => {
setNoteClazz('editor_nodte_area active');
}
const handleCancelNote = () => {
props.form.resetFields();
setNoteClazz('editor_nodte_area');
}
const handleSubmitNote = () => {
props.form.validateFields((err, values) => {
if (!err) {
changeLoadingState(true);
addNotes(identifier, values, function () {
setNoteClazz('editor_nodte_area');
props.form.resetFields();
});
}
});
}
const { getFieldDecorator } = props.form;
return ( return (
<div className={'right_pane_code_wrap'}> <div className={'right_pane_code_wrap'}>
<MyMonacoEditor <MyMonacoEditor
@ -98,6 +129,40 @@ const RightPane = (props) => {
onUpdateNotice={handleUpdateNotice} onUpdateNotice={handleUpdateNotice}
onRestoreInitialCode={handleRestoreInitialCode} onRestoreInitialCode={handleRestoreInitialCode}
/> />
<span
className="iconfont icon-biji student_notes"
onClick={handleClickNote}
></span>
{/* <div className="student_notes">
<TextArea rows={5} />
</div> */}
<div className={noteClazz}>
<Form>
<FormItem>
{
getFieldDecorator('notes',{
rules: [
{ required: true, message: '笔记不能为空' },
{ max: noteCount, message: `笔记最大字数为${noteCount}` }
],
initialValue: (hack && hack.notes) || ''
})(<TextArea
max={noteCount}
placeholder="请输入笔记内容"
rows="5"
/>)
}
</FormItem>
<FormItem style={{ textAlign: 'right' }}>
<Button loading={loading} style={{ marginRight: '10px' }} onClick={handleCancelNote}>取消</Button>
<Button type="primary" onClick={handleSubmitNote}>提交</Button>
</FormItem>
</Form>
</div>
<ControlSetting <ControlSetting
identifier={identifier} identifier={identifier}
inputValue={input} inputValue={input}
@ -117,10 +182,14 @@ const mapStateToProps = (state) => {
notice, notice,
hadCodeUpdate hadCodeUpdate
} = state.ojForUserReducer; } = state.ojForUserReducer;
const {
loading
} = state.commonReducer;
// const { language, code } = hack; // const { language, code } = hack;
return { return {
hack, hack,
notice, notice,
loading,
hadCodeUpdate, hadCodeUpdate,
editor_code, editor_code,
input: userTestInput, input: userTestInput,
@ -141,9 +210,12 @@ const mapDispatchToProps = (dispatch) => ({
// 恢复初始代码 // 恢复初始代码
restoreInitialCode: (identifier, msg) => dispatch(actions.restoreInitialCode(identifier, msg)), restoreInitialCode: (identifier, msg) => dispatch(actions.restoreInitialCode(identifier, msg)),
// saveOpacityType: (type) => dispatch(actions.saveOpacityType(type)) // saveOpacityType: (type) => dispatch(actions.saveOpacityType(type))
// 添加笔记
addNotes: (identifier, params, cb) => dispatch(actions.addNotes(identifier, params, cb)),
changeLoadingState: (flag) => dispatch(actions.changeLoadingState(flag))
}); });
export default connect( export default connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps
)(RightPane); )(Form.create()(RightPane));

@ -56,7 +56,8 @@ const types = {
CLEAR_OJ_FOR_USER_REDUCER: 'CLEAR_OJ_FOR_USER_REDUCER', // 退出时清空 ojForUserReducer保存内容 CLEAR_OJ_FOR_USER_REDUCER: 'CLEAR_OJ_FOR_USER_REDUCER', // 退出时清空 ojForUserReducer保存内容
ADD_OJ_LIKE_COUNT: 'ADD_OJ_LIKE_COUNT', // 增加点赞数 ADD_OJ_LIKE_COUNT: 'ADD_OJ_LIKE_COUNT', // 增加点赞数
CHANGE_RECORD_PAGINATION_PAGE: 'CHANGE_RECORD_PAGINATION_PAGE', // 改变提交分页 CHANGE_RECORD_PAGINATION_PAGE: 'CHANGE_RECORD_PAGINATION_PAGE', // 改变提交分页
UPDATE_OJ_FOR_USER_COMMENT_COUNT: 'UPDATE_OJ_FOR_USER_COMMENT_COUNT', // 更新 hack 中的评论数 UPDATE_OJ_FOR_USER_COMMENT_COUNT: 'UPDATE_OJ_FOR_USER_COMMENT_COUNT', // 更新 hack 中的评论数,
UPDATE_NOTE_CONTENT: 'UPDATE_NOTE_CONTENT', // 更新笔记内容
/*** jupyter */ /*** jupyter */
GET_JUPYTER_DATA_SETS: 'GET_JUPYTER_DATA_SETS', // jupyter 数据集 GET_JUPYTER_DATA_SETS: 'GET_JUPYTER_DATA_SETS', // jupyter 数据集
GET_JUPYTER_TPI_URL: 'GET_JUPYTER_TPI_URL', // 获取 jupyter url GET_JUPYTER_TPI_URL: 'GET_JUPYTER_TPI_URL', // 获取 jupyter url

@ -50,7 +50,8 @@ import {
saveEditorCodeForDetail, saveEditorCodeForDetail,
saveOpacityType, saveOpacityType,
clearOjForUserReducer, clearOjForUserReducer,
changeRecordPagination changeRecordPagination,
addNotes
// isUpdateCodeCtx // isUpdateCodeCtx
} from './ojForUser'; } from './ojForUser';
@ -137,6 +138,7 @@ export default {
saveOpacityType, saveOpacityType,
clearOjForUserReducer, clearOjForUserReducer,
changeRecordPagination, changeRecordPagination,
addNotes,
// jupyter // jupyter
getJupyterTpiDataSet, getJupyterTpiDataSet,
getJupyterTpiUrl, getJupyterTpiUrl,

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-11-27 13:42:11 * @Date: 2019-11-27 13:42:11
* @LastEditors : tangjiang * @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 14:27:58 * @LastEditTime : 2019-12-26 18:32:08
*/ */
import types from "./actionTypes"; import types from "./actionTypes";
import { Base64 } from 'js-base64'; import { Base64 } from 'js-base64';
@ -17,7 +17,8 @@ import {
fetchUserCommitRecordDetail, fetchUserCommitRecordDetail,
fetchUpdateCode, fetchUpdateCode,
fetchUserCodeSubmit, fetchUserCodeSubmit,
fetchRestoreInitialCode fetchRestoreInitialCode,
fetchAddNotes
} from "../../services/ojService"; } from "../../services/ojService";
import { notification } from "antd"; import { notification } from "antd";
@ -488,3 +489,33 @@ export const changeRecordPagination = (page) => {
} }
} }
// 更新通知状态 // 更新通知状态
// 添加笔记
export const addNotes = (identifier, params, cb) => {
return (dispatch) => {
fetchAddNotes(identifier, params).then(res => {
// console.log('添加笔记成功===>>', res);
dispatch({
type: types.LOADING_STATUS,
payload: false
});
const { data } = res;
if (data.status === 0) {
cb && cb();
notification.success({
message: '提示',
description: '添加笔记成功'
});
dispatch({
type: types.UPDATE_NOTE_CONTENT,
payload: params.notes
})
}
}).catch(() => {
dispatch({
type: types.LOADING_STATUS,
payload: false
});
})
}
}

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-11-27 13:41:48 * @Date: 2019-11-27 13:41:48
* @LastEditors : tangjiang * @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 13:39:41 * @LastEditTime : 2019-12-26 18:34:56
*/ */
import types from "../actions/actionTypes"; import types from "../actions/actionTypes";
import { Base64 } from 'js-base64'; import { Base64 } from 'js-base64';
@ -218,6 +218,13 @@ const ojForUserReducer = (state = initialState, action) => {
...state, ...state,
hack: Object.assign({}, state.hack, { comments_count: _comments_count }) hack: Object.assign({}, state.hack, { comments_count: _comments_count })
} }
// 修改笔记内容
case types.UPDATE_NOTE_CONTENT:
const _hack1 = Object.assign({}, state.hack, {notes: action.payload });
return {
...state,
hack: _hack1
}
default: default:
return state; return state;
} }

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-11-20 10:55:38 * @Date: 2019-11-20 10:55:38
* @LastEditors : tangjiang * @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 14:27:30 * @LastEditTime : 2019-12-26 17:37:38
*/ */
import axios from 'axios'; import axios from 'axios';
@ -137,3 +137,9 @@ export async function fetchUploadImageUrl (id) {
const url = `/attachments/${id}`; const url = `/attachments/${id}`;
return axios.get(url); return axios.get(url);
} }
// 添加笔记
export async function fetchAddNotes (identifier, params) {
const url = `/myproblems/${identifier}/add_notes.json`;
return axios.post(url, params);
}
Loading…
Cancel
Save