commit
d3fcf01d0e
@ -0,0 +1,62 @@
|
||||
$(document).on('turbolinks:load', function() {
|
||||
var $modal = $('.modal.admin-upload-file-modal');
|
||||
if ($modal.length > 0) {
|
||||
var $form = $modal.find('form.admin-upload-file-form')
|
||||
var $sourceIdInput = $modal.find('input[name="source_id"]');
|
||||
var $sourceTypeInput = $modal.find('input[name="source_type"]');
|
||||
|
||||
$modal.on('show.bs.modal', function(event){
|
||||
var $link = $(event.relatedTarget);
|
||||
var sourceId = $link.data('sourceId');
|
||||
var sourceType = $link.data('sourceType');
|
||||
|
||||
$sourceIdInput.val(sourceId);
|
||||
$sourceTypeInput.val(sourceType);
|
||||
|
||||
$modal.find('.upload-file-input').trigger('click');
|
||||
});
|
||||
|
||||
$modal.find('.upload-file-input').on('change', function(e){
|
||||
var file = $(this)[0].files[0];
|
||||
|
||||
if(file){
|
||||
$modal.find('.file-names').html(file.name);
|
||||
$modal.find('.submit-btn').trigger('click');
|
||||
}
|
||||
})
|
||||
|
||||
var formValid = function(){
|
||||
if($form.find('input[name="file"]').val() == undefined || $form.find('input[name="file"]').val().length == 0){
|
||||
$form.find('.error').html('请选择文件');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
$modal.on('click', '.submit-btn', function(){
|
||||
$form.find('.error').html('');
|
||||
|
||||
if (formValid()) {
|
||||
var formDataString = $form.serialize();
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
url: '/admins/files?' + formDataString,
|
||||
data: new FormData($form[0]),
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(data){
|
||||
$.notify({ message: '上传成功' });
|
||||
$modal.trigger('upload:success', data);
|
||||
$modal.modal('hide');
|
||||
},
|
||||
error: function(res){
|
||||
var data = res.responseJSON;
|
||||
$form.find('.error').html(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
@ -1,14 +1,22 @@
|
||||
input[type="checkbox"]{
|
||||
font-size:18px;
|
||||
}
|
||||
.select2 input::-webkit-input-placeholder{
|
||||
color:#ccc;
|
||||
}
|
||||
.select2 .select2-selection__choice{
|
||||
border: 1px solid #eee !important;
|
||||
}
|
||||
.setting-chosen{
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
color:#333;
|
||||
.admins-shixun-settings-index-page {
|
||||
input[type="checkbox"]{
|
||||
font-size:18px;
|
||||
}
|
||||
.select2 input::-webkit-input-placeholder{
|
||||
color:#ccc;
|
||||
}
|
||||
.select2 .select2-selection__choice{
|
||||
border: 1px solid #eee !important;
|
||||
}
|
||||
.setting-chosen{
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
color:#333;
|
||||
}
|
||||
|
||||
.shixun-setting-image {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
class Admins::FilesController < Admins::BaseController
|
||||
before_action :convert_file!, only: [:create]
|
||||
|
||||
def create
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
|
||||
Util.write_file(@file, file_path)
|
||||
|
||||
render_ok(source_id: params[:source_id], source_type: params[:source_type].to_s, url: file_url)
|
||||
rescue StandardError => ex
|
||||
logger_error(ex)
|
||||
render_error('上传失败')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def convert_file!
|
||||
max_size = 10 * 1024 * 1024 # 10M
|
||||
if params[:file].class == ActionDispatch::Http::UploadedFile
|
||||
@file = params[:file]
|
||||
render_error('请上传文件') if @file.size.zero?
|
||||
render_error('文件大小超过限制') if @file.size > max_size
|
||||
else
|
||||
file = params[:file].to_s.strip
|
||||
return render_error('请上传正确的图片') if file.blank?
|
||||
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def file_path
|
||||
@_file_path ||= begin
|
||||
case params[:source_type].to_s
|
||||
when 'Shixun' then
|
||||
disk_filename('Shixun', params[:source_id])
|
||||
else
|
||||
disk_filename(params[:source_type].to_s, params[:source_id].to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def disk_filename(type, id)
|
||||
File.join(storage_path, type.to_s, id.to_s)
|
||||
end
|
||||
|
||||
def storage_path
|
||||
@_storage_path ||= File.join(Rails.root, 'public', 'images', 'avatars')
|
||||
end
|
||||
|
||||
def file_url
|
||||
File.join('/images/avatars/', params[:source_type].to_s, params[:source_id].to_s)
|
||||
end
|
||||
end
|
@ -0,0 +1,32 @@
|
||||
<div class="modal fade admin-upload-file-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"><%= title ||= '上传文件' %></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="admin-upload-file-form" enctype="multipart/form-data">
|
||||
<%= hidden_field_tag(:source_type, nil) %>
|
||||
<%= hidden_field_tag(:source_id, nil) %>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">文件</span>
|
||||
</div>
|
||||
<div class="custom-file">
|
||||
<input type="file" name="file" class="upload-file-input" id="upload-file-input">
|
||||
<label class="custom-file-label file-names" for="upload-file-input">选择文件</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="error text-danger"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
|
||||
<button type="button" class="btn btn-primary submit-btn" data-disable-with="上传中...">上传</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,18 +0,0 @@
|
||||
json.question do
|
||||
json.id question.id
|
||||
json.question_number question.question_number
|
||||
json.question_title question.question_title
|
||||
json.question_type question.question_type
|
||||
json.is_necessary question.is_necessary
|
||||
if question.question_type == 2
|
||||
json.max_choices question.max_choices
|
||||
json.min_choices question.min_choices
|
||||
end
|
||||
json.answers do
|
||||
json.array! answers do | a|
|
||||
json.answer_id a.id
|
||||
json.answer_position a.choice_position
|
||||
json.answer_text a.choice_text.nil? ? "other_choices" : a.choice_text ##
|
||||
end
|
||||
end
|
||||
end
|
@ -1,2 +1 @@
|
||||
json.content @content
|
||||
json.path @path
|
||||
json.url "/shixuns/#{@shixun.identifier}/repository/master/shixun_show/#{@path}"
|
@ -1,9 +1,14 @@
|
||||
|
||||
json.count @count
|
||||
json.course_list @course_lists, partial: 'users/question_banks/shared/course_list', as: :course_list
|
||||
json.question_banks do
|
||||
json.array! @question_banks do |question_bank|
|
||||
json.partial! 'users/question_banks/shared/question_bank', locals: { question_bank: question_bank }
|
||||
json.solve_count @solve_count_map.fetch(question_bank.id, 0)
|
||||
end
|
||||
|
||||
json.question_banks @question_banks do |question_bank|
|
||||
json.id question_bank.id
|
||||
json.name question_bank.name
|
||||
json.is_public question_bank.is_public
|
||||
json.quotes_count question_bank.quotes
|
||||
json.creator_name question_bank.user.name
|
||||
json.course_list_name question_bank.course_list.name
|
||||
json.updated_at question_bank.updated_at
|
||||
json.solve_count @solve_count_map.fetch(question_bank.id, 0)
|
||||
end
|
||||
|
@ -0,0 +1,10 @@
|
||||
class AddAnnouncementToCourseModules < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
Course.all.each do |course|
|
||||
unless course.course_modules.exists?(module_type: "announcement")
|
||||
course.course_modules.where.not(module_type: "activity").update_all("position = position + 1")
|
||||
course.course_modules << CourseModule.new(module_type: "announcement", hidden: 1, module_name: "公告栏", position: 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
class AddTagToLibraries < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
execute "insert into library_tags(name) values('企业案例')"
|
||||
end
|
||||
end
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
|
||||
|
||||
import Loading from '../../Loading'
|
||||
|
||||
import Loadable from 'react-loadable';
|
||||
import { TPMIndexHOC } from '../tpm/TPMIndexHOC'
|
||||
import { SnackbarHOC } from 'educoder'
|
||||
|
||||
|
||||
const PackageIndex = Loadable({
|
||||
loader: () => import('../user/usersInfo/InfosTopics'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
||||
class Topic_bank extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="newMain clearfix">
|
||||
|
||||
<Switch>
|
||||
{/*众包首页*/}
|
||||
|
||||
<Route path="/topicbank/:username/:topicstype"
|
||||
render={
|
||||
(props) => (<PackageIndex {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SnackbarHOC() (TPMIndexHOC (Topic_bank)) ;
|
@ -0,0 +1,52 @@
|
||||
import React, { Component } from 'react';
|
||||
import { ActionBtn } from 'educoder'
|
||||
|
||||
import { Form , Modal } from 'antd'
|
||||
|
||||
class RepositoryAddFile extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
visible:false
|
||||
}
|
||||
}
|
||||
|
||||
addFile = () =>{
|
||||
this.setState({
|
||||
visible:true
|
||||
})
|
||||
}
|
||||
cancelAdd = () =>{
|
||||
this.setState({
|
||||
visible:false
|
||||
})
|
||||
}
|
||||
render(){
|
||||
let { visible } = this.state
|
||||
return(
|
||||
<React.Fragment>
|
||||
<ActionBtn style="orangeLine" className="ml20" onClick={this.addFile}>+添加文件</ActionBtn>
|
||||
<Modal
|
||||
className={"RepositioryModal"}
|
||||
title={'添加文件'}
|
||||
visible={visible}
|
||||
closable={false}
|
||||
footer={null}
|
||||
destroyOnClose={true}
|
||||
width="550px"
|
||||
>
|
||||
<div className="task-popup-content">
|
||||
|
||||
</div>
|
||||
<div className="clearfix mt30 edu-txt-center mb10">
|
||||
<a className="task-btn color-white mr30" onClick={this.cancelAdd}>取消</a>
|
||||
<a className="task-btn task-btn-orange">提交</a>
|
||||
</div>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
const WrappedRepositoryAddFile = Form.create({name: 'taskRepositoryAddFile'})(RepositoryAddFile);
|
||||
// RouteHOC()
|
||||
export default (WrappedRepositoryAddFile);
|
@ -0,0 +1,99 @@
|
||||
import React, { Component } from 'react';
|
||||
import axios from 'axios'
|
||||
import NewGtaskForm from './NewGtaskForm';
|
||||
import NewWorkForm from "./HomeworkBanksEdit";
|
||||
|
||||
class GtaskBanksEdit extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
isPublic: undefined,
|
||||
isGroup: false
|
||||
}
|
||||
}
|
||||
componentDidMount = () =>{
|
||||
let workId = this.props.match.params.workId;
|
||||
this.initData(workId);
|
||||
}
|
||||
|
||||
initData = (workId) =>{
|
||||
|
||||
let url = `/task_banks/${workId}.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
const crumbData={
|
||||
title:'编辑',
|
||||
is_public:result && result.data && result.data.is_public,
|
||||
crumbArray:[
|
||||
{to:`/banks/gtask/${workId}/edit`,content:'详情'},
|
||||
{content:'编辑'}
|
||||
]
|
||||
}
|
||||
this.props.initPublic(crumbData);
|
||||
result.data.isEdit = true;
|
||||
this.setState({ data:result.data})
|
||||
this.newWorkFormRef.initValue(result.data);
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
doNew = () => {
|
||||
}
|
||||
doEdit = (params) => {
|
||||
const workId = this.props.match.params.workId
|
||||
const newUrl = `/homework_banks/${workId}.json`
|
||||
|
||||
// const isGroup = this.props.isGroup()
|
||||
axios.put(newUrl, params)
|
||||
.then((response) => {
|
||||
if (response.data.status == 0) {
|
||||
this.props.showNotification('保存成功')
|
||||
this.toWorkDetail()
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
toWorkDetail = () => {
|
||||
this.props.history.push(`/banks/gtask/${this.props.match.params.workId}`);
|
||||
this.props.initPublic(undefined);
|
||||
}
|
||||
onCancel = () => {
|
||||
this.toWorkDetail()
|
||||
}
|
||||
isGroup = () => {
|
||||
return this.state.isGroup;
|
||||
}
|
||||
render(){
|
||||
|
||||
const common = {
|
||||
onCancel:this.onCancel,
|
||||
isGroup: this.isGroup,
|
||||
doNew: this.doNew,
|
||||
doEdit: this.doEdit,
|
||||
}
|
||||
return(
|
||||
<div className="courseForm">
|
||||
<style>
|
||||
{`
|
||||
.courseForm .ant-col-sm-24{
|
||||
text-align:left;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<NewGtaskForm
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
{...common}
|
||||
wrappedComponentRef={(ref) => this.newWorkFormRef = ref}
|
||||
topicId={this.props.match.params.workId}
|
||||
></NewGtaskForm>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default GtaskBanksEdit;
|
Loading…
Reference in new issue