diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js index 3e9601bf8..e7a4d28ff 100644 --- a/app/assets/javascripts/admin.js +++ b/app/assets/javascripts/admin.js @@ -83,4 +83,4 @@ $(document).on("turbolinks:before-cache", function () { // }); $(function () { -}); \ No newline at end of file +}); diff --git a/app/controllers/wechats/js_sdk_signatures_controller.rb b/app/controllers/wechats/js_sdk_signatures_controller.rb new file mode 100644 index 000000000..e4ee0da27 --- /dev/null +++ b/app/controllers/wechats/js_sdk_signatures_controller.rb @@ -0,0 +1,8 @@ +class Wechats::JsSdkSignaturesController < ApplicationController + def create + signature = Util::Wechat.js_sdk_signature(params[:url], params[:noncestr], params[:timestamp]) + render_ok(signature: signature) + rescue Util::Wechat::Error => ex + render_error(ex.message) + end +end \ No newline at end of file diff --git a/app/libs/util/wechat.rb b/app/libs/util/wechat.rb new file mode 100644 index 000000000..069322f18 --- /dev/null +++ b/app/libs/util/wechat.rb @@ -0,0 +1,74 @@ +module Util::Wechat + BASE_SITE = 'https://api.weixin.qq.com'.freeze + + Error = Class.new(StandardError) + + class << self + attr_accessor :appid, :secret + + def js_sdk_signature(url, noncestr, timestamp) + str = { jsapi_ticket: jsapi_ticket, noncestr: noncestr, timestamp: timestamp, url: url }.to_query + Digest::SHA1.hexdigest(str) + end + + def access_token + # 7200s 有效时间 + Rails.cache.fetch(access_token_cache_key, expires_in: 100.minutes) do + result = request(:get, '/cgi-bin/token', appid: appid, secret: secret, grant_type: 'client_credential') + result['access_token'] + end + end + + def refresh_access_token + Rails.cache.delete(access_token_cache_key) + access_token + end + + def jsapi_ticket + # 7200s 有效时间 + Rails.cache.fetch(jsapi_ticket_cache_key, expires_in: 100.minutes) do + result = request(:get, '/cgi-bin/ticket/getticket', access_token: access_token, type: 'jsapi') + result['ticket'] + end + end + + def refresh_jsapi_ticket + Rails.cache.delete(jsapi_ticket_cache_key) + jsapi_ticket + end + + def access_token_cache_key + "#{base_cache_key}/access_token" + end + + def jsapi_ticket_cache_key + "#{base_cache_key}/jsapi_ticket" + end + + def base_cache_key + "wechat/#{appid}" + end + + private + + def request(method, url, **params) + Rails.logger.error("[wechat] request: #{method} #{url} #{params.inspect}") + + client = Faraday.new(url: BASE_SITE) + response = client.public_send(method, url, params) + result = JSON.parse(response.body) + + Rails.logger.error("[wechat] response:#{response.status} #{result.inspect}") + + if response.status != 200 + raise Error, result.inspect + end + + if result['errcode'].present? && result['errcode'].to_i.nonzero? + raise Error, result.inspect + end + + result + end + end +end \ No newline at end of file diff --git a/config/configuration.yml.example b/config/configuration.yml.example index 2a4f4f017..6feee28d9 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -6,6 +6,9 @@ defaults: &defaults cate_id: '-1' callback_url: 'http://47.96.87.25:48080/api/callbacks/aliyun_vod.json' signature_key: 'test12345678' + wechat: + appid: 'test' + secret: 'test' development: <<: *defaults diff --git a/config/initializers/aliyun_vod_init.rb b/config/initializers/aliyun_vod_init.rb index 47b1dc6a3..9185eac20 100644 --- a/config/initializers/aliyun_vod_init.rb +++ b/config/initializers/aliyun_vod_init.rb @@ -4,7 +4,7 @@ aliyun_vod_config = {} begin config = Rails.application.config_for(:configuration) aliyun_vod_config = config['aliyun_vod'] - raise 'oauth wechat config missing' if aliyun_vod_config.blank? + raise 'aliyun vod config missing' if aliyun_vod_config.blank? rescue => ex raise ex if Rails.env.production? diff --git a/config/initializers/util_wechat_init.rb b/config/initializers/util_wechat_init.rb new file mode 100644 index 000000000..cb39afcaf --- /dev/null +++ b/config/initializers/util_wechat_init.rb @@ -0,0 +1,16 @@ +wechat_config = {} + +begin + config = Rails.application.config_for(:configuration) + wechat_config = config['wechat'] + raise 'wechat config missing' if wechat_config.blank? +rescue => ex + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] wechat config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} + wechat_config = {} +end + +Util::Wechat.appid = wechat_config['appid'] +Util::Wechat.secret = wechat_config['secret'] diff --git a/config/routes.rb b/config/routes.rb index e53f3a57a..27d5c4488 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -880,6 +880,10 @@ Rails.application.routes.draw do end end + namespace :wechats do + resource :js_sdk_signature, only: [:create] + end + #git 认证回调 match 'gitauth/*url', to: 'gits#auth', via: :all diff --git a/public/react/src/modules/courses/boards/BoardsNew.js b/public/react/src/modules/courses/boards/BoardsNew.js index 58cd0c02b..8411e8c49 100644 --- a/public/react/src/modules/courses/boards/BoardsNew.js +++ b/public/react/src/modules/courses/boards/BoardsNew.js @@ -186,7 +186,7 @@ class BoardsNew extends Component{ }); } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ confirm({ // title: '确定要删除这个附件吗?', title: '是否确认删除?', diff --git a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js index d1e271981..698fbd398 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js @@ -218,7 +218,8 @@ class CommonWorkAppraise extends Component{ {item.filesize} {/*{item.delete===true?:""}*/} - {item.delete===true?:""} + {item.delete===true?:""} + {/* style={{display: 'none'}} */} ) })} diff --git a/public/react/src/modules/courses/busyWork/CommonWorkPost.js b/public/react/src/modules/courses/busyWork/CommonWorkPost.js index fec3f02a1..98fe5401c 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkPost.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkPost.js @@ -320,11 +320,19 @@ class CommonWorkPost extends Component{ // ModalSave: ()=>this.deleteAttachment(file), // ModalCancel:this.cancelAttachment // }) - if(file.response!=undefined){ - this.deleteAttachment(file) + + if(!file.percent || file.percent == 100){ + this.props.confirm({ + content: '是否确认删除?', + onOk: () => { + this.deleteAttachment(file) + }, + onCancel() { + console.log('Cancel'); + }, + }); return false; } - } cancelAttachment=()=>{ diff --git a/public/react/src/modules/courses/busyWork/NewWork.js b/public/react/src/modules/courses/busyWork/NewWork.js index fb2d18de0..4b2224fd1 100644 --- a/public/react/src/modules/courses/busyWork/NewWork.js +++ b/public/react/src/modules/courses/busyWork/NewWork.js @@ -3,7 +3,8 @@ import { Input, InputNumber, Form, Button, Checkbox, Upload, Icon, message, Moda import axios from 'axios' import '../css/busyWork.css' import '../css/Courses.css' -import { WordsBtn, getUrl, ConditionToolTip, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder' +import { WordsBtn, getUrl, ConditionToolTip, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll + , getUploadActionUrl } from 'educoder' import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor'; import CBreadcrumb from '../common/CBreadcrumb' @@ -243,7 +244,7 @@ class NewWork extends Component{ } onAttachmentRemove = (file, stateName) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.props.confirm({ content: '是否确认删除?', @@ -331,7 +332,7 @@ class NewWork extends Component{ // https://github.com/ant-design/ant-design/issues/15505 // showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。 // showUploadList: false, - action: `${getUrl()}/api/attachments.json`, + action: `${getUploadActionUrl()}`, onChange: this.handleContentUploadChange, onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'), beforeUpload: (file) => { diff --git a/public/react/src/modules/courses/coursesPublic/AccessoryModal.js b/public/react/src/modules/courses/coursesPublic/AccessoryModal.js index 3b25ceb6d..750679111 100644 --- a/public/react/src/modules/courses/coursesPublic/AccessoryModal.js +++ b/public/react/src/modules/courses/coursesPublic/AccessoryModal.js @@ -73,7 +73,7 @@ class AccessoryModal extends Component{ // ModalCancel:this.cancelAttachment // }) // return false; - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.deleteAttachment(file); } } diff --git a/public/react/src/modules/courses/coursesPublic/AccessoryModal2.js b/public/react/src/modules/courses/coursesPublic/AccessoryModal2.js index a9a627387..a15cb0617 100644 --- a/public/react/src/modules/courses/coursesPublic/AccessoryModal2.js +++ b/public/react/src/modules/courses/coursesPublic/AccessoryModal2.js @@ -64,7 +64,7 @@ class AccessoryModal2 extends Component{ // ModalCancel:this.cancelAttachment // }) // return false; - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.deleteAttachment(file); } diff --git a/public/react/src/modules/courses/coursesPublic/SelectSetting.js b/public/react/src/modules/courses/coursesPublic/SelectSetting.js index d52b328e2..1a18513e7 100644 --- a/public/react/src/modules/courses/coursesPublic/SelectSetting.js +++ b/public/react/src/modules/courses/coursesPublic/SelectSetting.js @@ -296,7 +296,7 @@ class Selectsetting extends Component{ onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ const url = `/attachments/${file.response ? file.response.id : file.uid}.json` axios.delete(url, { }) diff --git a/public/react/src/modules/courses/coursesPublic/sendResource.js b/public/react/src/modules/courses/coursesPublic/sendResource.js index 56c85439c..a9ceb6405 100644 --- a/public/react/src/modules/courses/coursesPublic/sendResource.js +++ b/public/react/src/modules/courses/coursesPublic/sendResource.js @@ -132,7 +132,7 @@ class Sendresource extends Component{ onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ const url = `/attachments/${file.response ? file.response.id : file.uid}.json` axios.delete(url, { }) diff --git a/public/react/src/modules/courses/exercise/ExerciseDisplay.js b/public/react/src/modules/courses/exercise/ExerciseDisplay.js index a0296476f..cbaf38c80 100644 --- a/public/react/src/modules/courses/exercise/ExerciseDisplay.js +++ b/public/react/src/modules/courses/exercise/ExerciseDisplay.js @@ -53,11 +53,15 @@ class ExerciseDisplay extends Component{ componentDidMount = () => { const Id = this.props.match.params.Id if (Id) { - const url = `/exercises/${Id}.json` + const url = `/${this.props.urlPath || 'exercises'}/${Id}.json` axios.get(url) .then((response) => { - if (response.data.status == 0) { - this.setState({...response.data}) + if (response.data.exercise) { + response.data.exercise.exercise_description = response.data.exercise.exercise_description || response.data.exercise.description + response.data.exercise.exercise_name = response.data.exercise.exercise_name || response.data.exercise.name + response.data.exercise.exercise_status = response.data.exercise.exercise_status == undefined ? 1 : response.data.exercise.exercise_status + this.setState({...response.data}) + this.props.detailFetchCallback && this.props.detailFetchCallback(response); } }) .catch(function (error) { diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js index b603e375d..2d9280ec1 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js @@ -157,7 +157,7 @@ class GraduationTasksSubmitedit extends Component{ } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ let {attachments,fileList}=this.state; const url = `/attachments/${file}.json` axios.delete(url, { diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js index ed2731c61..57eb6502f 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js @@ -146,7 +146,7 @@ class GraduationTasksSubmitnew extends Component{ // }, // }); // return false; - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.setState({ Modalstype:true, Modalstopval:'确定要删除这个附件吗?', diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js index 6b741f413..6a481c61c 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js @@ -88,7 +88,7 @@ class GraduationTasksappraiseMainEditor extends Component{ this.setState({ fileList }); } onAttachmentRemove = (file, stateName) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.props.confirm({ content: '确定要删除这个附件吗?', okText: '确定', diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js index e6139bad6..256dba7d4 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js @@ -150,7 +150,7 @@ class GraduationTasksedit extends Component{ } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ // debugger this.cancelAttachment(); const url = `/attachments/${file.response ? file.response.id : file.uid}.json` diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js index 3b6b60ac8..da83e8d7e 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js @@ -173,7 +173,7 @@ class GraduationTasksnew extends Component { } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ const url = `/attachments/${file.response ? file.response.id : file.uid}.json` // const url = `/attachments/${file}.json` axios.delete(url, {}) diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js index 511deb511..28d6fcf77 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js @@ -216,7 +216,7 @@ class GraduateTopicNew extends Component{ } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ confirm({ title: '确定要删除这个附件吗?', okText: '确定', diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicPostWorksNew.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicPostWorksNew.js index 3998669d7..60fa071a9 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicPostWorksNew.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicPostWorksNew.js @@ -163,7 +163,7 @@ class GraduateTopicPostWorksNew extends Component{ this.setState({ fileList }); } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ confirm({ title: '确定要删除这个附件吗?', okText: '确定', diff --git a/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js b/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js index 77a41e47d..afbe8de58 100644 --- a/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js +++ b/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js @@ -73,7 +73,7 @@ class CreateGroupByImportModal extends Component{ } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.props.confirm({ content: '是否确认删除?', diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index 64e2e6a99..0755b9df5 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -2499,6 +2499,8 @@ class Listofworksstudentone extends Component { // console.log(data); // console.log(datas); // console.log(this.props.isAdmin()); + console.log("学生老师列表"); + return ( this.props.isAdmin() === true ? ( diff --git a/public/react/src/modules/forums/MemoNew.js b/public/react/src/modules/forums/MemoNew.js index 476d41a8a..88425ab53 100644 --- a/public/react/src/modules/forums/MemoNew.js +++ b/public/react/src/modules/forums/MemoNew.js @@ -561,7 +561,7 @@ class MemoNew extends Component { } } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.props.confirm({ // title: '确定要删除这个附件吗?', content: '是否确认删除?', diff --git a/public/react/src/modules/moop_cases/CaseNew.js b/public/react/src/modules/moop_cases/CaseNew.js index 6d9e5b251..bb684de22 100644 --- a/public/react/src/modules/moop_cases/CaseNew.js +++ b/public/react/src/modules/moop_cases/CaseNew.js @@ -47,7 +47,7 @@ class CaseNew extends Component{ // 上传附件-删除确认框 onAttachmentRemove = (file, stateName) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ this.props.confirm({ content: '是否确认删除?', onOk: () => { diff --git a/public/react/src/modules/tpm/TPMsettings/TPMsettings.js b/public/react/src/modules/tpm/TPMsettings/TPMsettings.js index e7e8a1d75..ca6c6a342 100644 --- a/public/react/src/modules/tpm/TPMsettings/TPMsettings.js +++ b/public/react/src/modules/tpm/TPMsettings/TPMsettings.js @@ -1384,7 +1384,7 @@ export default class TPMsettings extends Component { } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ confirm({ title: '确定要删除这个附件吗?', okText: '确定', diff --git a/public/react/src/modules/tpm/newshixuns/Newshixuns.js b/public/react/src/modules/tpm/newshixuns/Newshixuns.js index 9a22269f6..2313426a2 100644 --- a/public/react/src/modules/tpm/newshixuns/Newshixuns.js +++ b/public/react/src/modules/tpm/newshixuns/Newshixuns.js @@ -772,7 +772,7 @@ class Newshixuns extends Component { } onAttachmentRemove = (file) => { - if(file.response!=undefined){ + if(!file.percent || file.percent == 100){ confirm({ title: '确定要删除这个附件吗?', okText: '确定', diff --git a/public/react/src/modules/user/usersInfo/banks/BanksIndex.js b/public/react/src/modules/user/usersInfo/banks/BanksIndex.js index 916601420..6a303f62b 100644 --- a/public/react/src/modules/user/usersInfo/banks/BanksIndex.js +++ b/public/react/src/modules/user/usersInfo/banks/BanksIndex.js @@ -149,6 +149,13 @@ class BanksIndex extends Component{ />) } }> + { + return () + } + }> import('./PollBanksContent'), loading: Loading, }) +// 试卷详情 +const ExerciseBanksDetail = Loadable({ + loader: () => import('./ExerciseBanksDetail'), + loading: Loading, +}); class BanksTabIndex extends Component{ constructor(props){ @@ -53,7 +58,13 @@ class BanksTabIndex extends Component{ > } - + { + return () + } + }> { + + } + detailFetchCallback = (result) => { + let Id=this.props.match.params.Id; + + const crumbData={ + title: result.data.exercise && result.data.exercise.name, + is_public: result.data.exercise && result.data.exercise.is_public, + crumbArray:[ + {content:'详情'}, + ] + } + const menuData={ + tab:'0',//tab选中的index + menuArray:[//tab以及tab路由 + {to:`/banks/exercise/${Id}`,content:'内容详情'} + ], + category:'exercise',// + tos: `/banks/exercise/${Id}/edit`, + id: Id, + + } + this.props.initPublic(crumbData,menuData); + } + + render(){ + let { pollDetail } = this.state + + return( +
+ + +
+ ) + } +} +export default ExerciseBanksDetail diff --git a/public/react/src/modules/user/usersInfo/banks/banksMenu.js b/public/react/src/modules/user/usersInfo/banks/banksMenu.js index 0d7d1a24a..7680dc748 100644 --- a/public/react/src/modules/user/usersInfo/banks/banksMenu.js +++ b/public/react/src/modules/user/usersInfo/banks/banksMenu.js @@ -126,7 +126,7 @@ class BanksMenu extends Component{ this.deletecheckBoxValues(banksMenu&&banksMenu.id,banksMenu&&banksMenu.category)}style="blue" className="ml20 font-16">删除 - 编辑 + 编辑 this.sendTopics()} style="blue" className="ml20 font-16">发送