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

dev_hjm_a
杨树林 5 years ago
commit ed40d0a977

@ -5,13 +5,17 @@ class Ecs::CourseAchievementMethodsController < Ecs::CourseBaseController
end end
def create def create
@course_target = Ecs::CreateCourseAchievementMethodsService.call(current_course_target, create_params) Ecs::CreateCourseAchievementMethodsService.call(current_course_target, create_params)
render_ok
end end
private private
def create_params def create_params
params.permit(course_achievement_methods: %i[id course_evaluation_id course_evaluation_subitem_ids score percentage]) params.permit(course_achievement_methods: [
:id, :course_evaluation_id, :score, :percentage,
course_evaluation_relates: %i[:subitem_id position]
])
end end
def current_course_target def current_course_target

@ -46,8 +46,8 @@ class ExercisesController < ApplicationController
@exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : []
else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷
# 已发布 当前用户班级分组的 试卷id # 已发布 当前用户班级分组的 试卷id
not_exercise_ids = @course.exercise_group_settings.exercise_group_not_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) publish_exercise_ids = @course.exercise_group_settings.exercise_group_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id)
@exercises = member_show_exercises.where.not(id: not_exercise_ids) @exercises = member_show_exercises.unified_setting.or(member_show_exercises.where(id: publish_exercise_ids))
end end
else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁
@is_teacher_or = 0 @is_teacher_or = 0

@ -5,7 +5,7 @@ class Wechats::JsSdkSignaturesController < ApplicationController
signature = Util::Wechat.js_sdk_signature(params[:url], noncestr, timestamp) signature = Util::Wechat.js_sdk_signature(params[:url], noncestr, timestamp)
render_ok(appid: Util::Wechat.appid, timestamp: timestamp, noncestr: noncestr, signature: signature) render_ok(appid: Util::Wechat.appid, timestamp: timestamp, noncestr: noncestr, signature: signature)
rescue Util::Wechat::Error => ex rescue Util::WechatStore::Error => ex
render_error(ex.message) render_error(ex.message)
end end
end end

@ -13,63 +13,15 @@ module Util::Wechat
end end
def access_token def access_token
# 7200s 有效时间 wechat_store.access_token
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 end
def jsapi_ticket def jsapi_ticket
# 7200s 有效时间 wechat_store.jsapi_ticket
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 end
result def wechat_store
@_wechat_store ||= ::Util::WechatStore.new(appid, secret)
end end
end end
end end

@ -0,0 +1,72 @@
class Util::WechatStore
BASE_SITE = 'https://api.weixin.qq.com'.freeze
Error = Class.new(StandardError)
attr_reader :appid, :secret
def initialize(appid, secret)
@appid = appid
@secret = secret
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

@ -6,7 +6,7 @@ class EcCourse < ApplicationRecord
has_many :ec_graduation_subitem_course_targets, through: :ec_course_targets has_many :ec_graduation_subitem_course_targets, through: :ec_course_targets
# 课程负责教师 # 课程负责教师
has_many :ec_course_users has_many :ec_course_users
has_many :course_managers, through: :ec_course_users, class_name: 'User' has_many :course_managers, through: :ec_course_users, source: :user
# 课程考核标准 # 课程考核标准
has_many :ec_course_evaluations, dependent: :destroy has_many :ec_course_evaluations, dependent: :destroy
# 课程等级 # 课程等级

@ -16,4 +16,23 @@ class EcCourseEvaluation < ApplicationRecord
def imported? def imported?
import_status? import_status?
end end
def evaluation_relates
# 总成绩支撑只有课程考核标准的名称, 分项成绩支撑是课程考核标准名称与考核分项的笛卡尔积
if status == 1
return evaluation_count.times.map { |index| { id: -1, name: "#{name}#{index + 1}", position: index + 1 } }
end
if is_course_type?
ec_course_evaluation_subitems.map.with_index { |item, index| { id: item.id, name: item.name, position: index + 1 } }
else
data = []
ec_course_evaluation_subitems.each do |item|
evaluation_count.times do |i|
data << { id: item.id, name: "#{name}#{i + 1}#{item.name}", position: i + 1 }
end
end
data
end
end
end end

@ -131,7 +131,7 @@ class Exercise < ApplicationRecord
status = 4 status = 4
else else
if user.present? && user.student_of_course?(course) #当为学生的时候,需根据分班来判断试卷状态 if user.present? && user.student_of_course?(course) #当为学生的时候,需根据分班来判断试卷状态
ex_time = get_exercise_times(user_id,false) ex_time = get_exercise_times(user.id,false)
pb_time = ex_time[:publish_time] pb_time = ex_time[:publish_time]
ed_time = ex_time[:end_time] ed_time = ex_time[:end_time]
if pb_time.present? && ed_time.present? && pb_time <= Time.now && ed_time > Time.now if pb_time.present? && ed_time.present? && pb_time <= Time.now && ed_time > Time.now

@ -31,8 +31,8 @@ class Ecs::CreateCourseAchievementMethodsService < ApplicationService
# 创建新的评价方法时,全部为新建 # 创建新的评价方法时,全部为新建
if item[:id].blank? || course_target.ec_course_achievement_methods.find_by(id: item[:id]).blank? if item[:id].blank? || course_target.ec_course_achievement_methods.find_by(id: item[:id]).blank?
item[:ec_achievement_evaluation_relates_attributes] = item[:ec_achievement_evaluation_relates_attributes] =
Array(*item[:course_evaluation_subitem_ids]).uniq.map do |subitem_id| item[:course_evaluation_relates].map do |relate|
{ ec_course_evaluation_subitem_id: subitem_id.to_i } { ec_course_evaluation_subitem_id: relate[:subitem_id].to_i, position: relate[:position] }
end end
return return
end end
@ -41,22 +41,22 @@ class Ecs::CreateCourseAchievementMethodsService < ApplicationService
relates = achievement_method.ec_achievement_evaluation_relates relates = achievement_method.ec_achievement_evaluation_relates
# 获取传入的 subitem id数组和已存在的 subitem id数组 # 获取传入的 subitem id数组和已存在的 subitem id数组
old_subitem_ids = relates.map(&:ec_course_evaluation_subitem_id).uniq old_data = relates.map { |e| [e.ec_course_evaluation_subitem_id, e.position] }
new_subitem_ids = Array(*item[:course_evaluation_subitem_ids]).map(&:to_i).uniq new_data = item[:course_evaluation_relates].map { |e| [e[:subitem_id, e[:position]]] }
# 分别得到需要移除的 subitem ID数组和需要创建的 subitem ID数组 # 分别得到需要移除的 subitem ID数组和需要创建的 subitem ID数组
destroy_subitem_ids = old_subitem_ids - new_subitem_ids destroy_data = old_data - new_data
create_subitem_ids = new_subitem_ids - old_subitem_ids create_data = new_data - old_data
# 生成需要创建关系的 subitem id 数据 # 生成需要创建关系的 subitem id 数据
create_attributes = create_subitem_ids.map { |item_id| { ec_course_evaluation_subitem_id: item_id } } create_attributes = create_data.map { |arr| { ec_course_evaluation_subitem_id: arr[0], position: arr[1] } }
# 处理需要更新或者删除的记录 # 处理需要更新或者删除的记录
exists_attributes = relates.map do |relate| exists_attributes = relates.map do |relate|
if destroy_subitem_ids.include?(relate.ec_course_evaluation_subitem_id) if destroy_data.include?([relate.ec_course_evaluation_subitem_id, relate.position])
{ id: relate.id, _destroy: true } { id: relate.id, _destroy: true }
else else
relate.as_json(only: %i[id ec_course_evaluation_subitem_id ec_course_achievement_method_id]) relate.as_json(only: %i[id ec_course_evaluation_subitem_id ec_course_achievement_method_id position])
end end
end end

@ -25,4 +25,3 @@ json.excellent @course.excellent
if @course.is_end == 0 if @course.is_end == 0
json.days_remaining (@course.end_date.to_date - Time.now.to_date).to_i json.days_remaining (@course.end_date.to_date - Time.now.to_date).to_i
end end

@ -7,3 +7,5 @@ end
json.course_evaluation_subitems ec_course_achievement_method.ec_course_evaluation_subitems, json.course_evaluation_subitems ec_course_achievement_method.ec_course_evaluation_subitems,
partial: 'ecs/shared/ec_course_evaluation_subitem', as: :ec_course_evaluation_subitem partial: 'ecs/shared/ec_course_evaluation_subitem', as: :ec_course_evaluation_subitem
json.course_evaluation_relates ec_course_achievement_method.ec_course_evaluation.evaluation_relates

@ -1 +1,7 @@
json.course_evaluations @course_evaluations, partial: 'ecs/course_evaluations/shared/ec_course_evaluation_slim', as: :ec_course_evaluation json.course_evaluations do
json.array! @course_evaluations do |course_evaluation|
json.partial! 'ecs/course_evaluations/shared/ec_course_evaluation_slim', ec_course_evaluation: course_evaluation
json.evaluation_relates course_evaluation.evaluation_relates
end
end

@ -212,7 +212,7 @@ function initOnlineOfflineListener() {
$(window).bind("online", () => { $(window).bind("online", () => {
notification.destroy() notification.destroy()
notification.success({ notification.success({
duration: null, duration: 2,
message: '网络恢复正常', message: '网络恢复正常',
description: description:
'网络恢复正常,感谢使用。', '网络恢复正常,感谢使用。',

@ -1029,8 +1029,9 @@ class CommonWorkSetting extends Component{
<span className="font-16 fl color-dark">发布设置</span> <span className="font-16 fl color-dark">发布设置</span>
{ {
!startEditFlag && isAdmin ? !startEditFlag && isAdmin ?
<a className="fr mr6" onClick={() => { this.setState({startEditFlag: true}) }}> <a className="fr white-btn edu-blueline-btn mr10 mr6 lineh-24" onClick={() => { this.setState({startEditFlag: true}) }}>
<Tooltip title="编辑"><i className="iconfont icon-bianjidaibeijing font-20 color-green"></i></Tooltip> 编辑设置
{/*<Tooltip title="编辑"><i className="iconfont icon-bianjidaibeijing font-20 color-green"></i></Tooltip>*/}
</a> </a>
:"" :""
} }

@ -33,6 +33,7 @@ class commonWork extends Component{
modalsBottomval:"", modalsBottomval:"",
modalCancel:"", modalCancel:"",
mainList:undefined, mainList:undefined,
selectedKeys: 'all',
order:"", order:"",
page:1, page:1,
search:"", search:"",
@ -77,7 +78,9 @@ class commonWork extends Component{
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (prevProps.match.path != this.props.match.path) { if (prevProps.match.path != this.props.match.path) {
this.clearSelection() this.clearSelection()
this.setState({ selectedKeys: 'all', order: '' }, () => {
this._getList() this._getList()
})
} }
} }
@ -143,6 +146,7 @@ class commonWork extends Component{
this.clearSelection() this.clearSelection()
this.setState({ this.setState({
order:e.key==="all"?"":e.key, order:e.key==="all"?"":e.key,
selectedKeys: e.key,
page:1, page:1,
isSpin:true, isSpin:true,
checkBoxValues:[], checkBoxValues:[],
@ -403,7 +407,7 @@ class commonWork extends Component{
} }
secondRowBotton={ secondRowBotton={
<div className="fl mt6 task_menu_ul"> <div className="fl mt6 task_menu_ul">
<Menu mode="horizontal" defaultSelectedKeys="all" onClick={this.selectedStatus}> <Menu mode="horizontal" selectedKeys={this.state.selectedKeys} onClick={this.selectedStatus}>
<Menu.Item key="all">全部</Menu.Item> <Menu.Item key="all">全部</Menu.Item>
{isAdmin && <Menu.Item key="0">未发布</Menu.Item>} {isAdmin && <Menu.Item key="0">未发布</Menu.Item>}
<Menu.Item key="1">提交中</Menu.Item> <Menu.Item key="1">提交中</Menu.Item>

@ -55,7 +55,6 @@ class CoursesBanner extends Component {
} }
} }
componentDidMount() { componentDidMount() {
this.onloadupdatabanner() this.onloadupdatabanner()
on('updatabanner', this.updatabanner) on('updatabanner', this.updatabanner)
axios.interceptors.response.use((response) => { axios.interceptors.response.use((response) => {
@ -69,9 +68,17 @@ class CoursesBanner extends Component {
} }
return response; return response;
}, (error) => { }, (error) => {
}); });
} }
componentDidUpdate(prevProps) {
if(prevProps.user!=this.props.user){
if(this.props.match.path==="/courses/:coursesId"){
if(this.props.user!=undefined){
this.props.history.push(this.props.user.first_category_url)
}
}
}
}
componentWillUnmount() { componentWillUnmount() {
off('updatabanner', this.updatabanner) off('updatabanner', this.updatabanner)
} }

@ -101,6 +101,7 @@ class ShixunChooseModal extends Component{
return( return(
shixunmodal===true?<NewShixunModel shixunmodal===true?<NewShixunModel
statustype={'published'} statustype={'published'}
type={'shixuns'}
datas={datas} datas={datas}
category_id={this.props.match.params.category_id} category_id={this.props.match.params.category_id}
NewShixunModelType={shixunmodal} NewShixunModelType={shixunmodal}

@ -618,10 +618,11 @@ class Exercisesetting extends Component{
<span className="font-16 fl">发布设置<span className="color-grey-c font-14"></span></span> <span className="font-16 fl">发布设置<span className="color-grey-c font-14"></span></span>
{ {
!flagPageEdit&&this.props.isAdmin()===true ? !flagPageEdit&&this.props.isAdmin()===true ?
<a className="fr mr6" onClick={this.editSetting}> <a className="fr mr6 white-btn edu-blueline-btn lineh-24" onClick={this.editSetting}>
<Tooltip title="编辑"> 编辑设置
<i className="iconfont icon-bianjidaibeijing font-20 color-green"></i> {/*<Tooltip title="编辑">*/}
</Tooltip> {/*<i className="iconfont icon-bianjidaibeijing font-20 color-green"></i>*/}
{/*</Tooltip>*/}
</a> </a>
:"" :""
} }

@ -1001,8 +1001,11 @@ debugger
<Form id={"starttime"}> <Form id={"starttime"}>
{ {
!flagPageEdit && this.props.isAdmin() === true ? !flagPageEdit && this.props.isAdmin() === true ?
<a className="fr mt20 mr40" onClick={this.editSetting}><Tooltip title="编辑"><i <a className="mt20 mr40 fr white-btn edu-blueline-btn lineh-24" onClick={this.editSetting}>
className="iconfont icon-bianjidaibeijing font-20 color-green "></i></Tooltip></a> 编辑设置
{/*<Tooltip title="编辑"><i*/}
{/*className="iconfont icon-bianjidaibeijing font-20 color-green "></i></Tooltip>*/}
</a>
: "" : ""
} }
{/*内容*/} {/*内容*/}

@ -302,7 +302,8 @@ class studentsList extends Component{
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if (prevProps.match.params.course_group_id != this.props.match.params.course_group_id) { if (prevProps.match.params.course_group_id != this.props.match.params.course_group_id) {
this.setState({checkBoxValues: []}) this.setState({checkBoxValues: [], checkAllValue: false })
this.fetchAll(1) this.fetchAll(1)
} }
// 加载了2次 // 加载了2次

@ -518,7 +518,10 @@ class PollDetailTabForth extends Component{
</span> </span>
{ {
!flagPageEdit && isAdmin ? !flagPageEdit && isAdmin ?
<a className="fr" onClick={this.editSetting}><Tooltip title="编辑"><i className="iconfont icon-bianjidaibeijing font-20 color-green"></i></Tooltip></a> <a className="fr white-btn edu-blueline-btn lineh-24" onClick={this.editSetting}>
编辑设置
{/*<Tooltip title="编辑"><i className="iconfont icon-bianjidaibeijing font-20 color-green"></i></Tooltip>*/}
</a>
:"" :""
} }
</p> </p>

@ -2150,8 +2150,11 @@ class Trainingjobsetting extends Component {
<span className="font-16 fl "style={{"color":"#05101A"}}>发布设置 <span className="ml15 color-grey-9" style={{"font-size":"14px","text-align":"left"}}></span></span> <span className="font-16 fl "style={{"color":"#05101A"}}>发布设置 <span className="ml15 color-grey-9" style={{"font-size":"14px","text-align":"left"}}></span></span>
{ {
!flagPageEdit && this.props.isAdmin() === true ? !flagPageEdit && this.props.isAdmin() === true ?
<a className="fr" onClick={this.editSetting}><Tooltip title="编辑"><i <a className="fr white-btn edu-blueline-btn mr10 mr20 lineh-24" onClick={this.editSetting}>
className="iconfont icon-bianjidaibeijing font-20 color-green pr20 "></i></Tooltip></a> 编辑设置
{/*<Tooltip title="编辑"><i*/}
{/*className="iconfont icon-bianjidaibeijing font-20 color-green pr20 "></i></Tooltip>*/}
</a>
: "" : ""
} }
</p> </p>

@ -146,14 +146,15 @@ a.decoration{text-decoration: underline}
.margin20{margin:20px;} .margin20{margin:20px;}
/*行高*/ /*行高*/
.lineh-12{line-height: 12px} .lineh-12{line-height: 12px !important;}
.lineh-15{line-height: 15px} .lineh-15{line-height: 15px !important;}
.lineh-17{line-height: 17px} .lineh-17{line-height: 17px !important;}
.lineh-20{line-height: 20px} .lineh-20{line-height: 20px !important;}
.lineh-25{line-height: 25px} .lineh-24{line-height: 24px !important;}
.lineh-30{line-height: 30px} .lineh-25{line-height: 25px !important;}
.lineh-35{line-height: 35px} .lineh-30{line-height: 30px !important;}
.lineh-40{line-height: 40px} .lineh-35{line-height: 35px !important;}
.lineh-40{line-height: 40px !important;}
/*pre标签换行*/ /*pre标签换行*/
.break_word{word-break: break-all;word-wrap: break-word;} .break_word{word-break: break-all;word-wrap: break-word;}

Loading…
Cancel
Save