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
def create
@course_target = Ecs::CreateCourseAchievementMethodsService.call(current_course_target, create_params)
Ecs::CreateCourseAchievementMethodsService.call(current_course_target, create_params)
render_ok
end
private
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
def current_course_target

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

@ -5,7 +5,7 @@ class Wechats::JsSdkSignaturesController < ApplicationController
signature = Util::Wechat.js_sdk_signature(params[:url], noncestr, timestamp)
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)
end
end

@ -13,63 +13,15 @@ module Util::Wechat
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
wechat_store.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"
wechat_store.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
def wechat_store
@_wechat_store ||= ::Util::WechatStore.new(appid, secret)
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_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
# 课程等级

@ -16,4 +16,23 @@ class EcCourseEvaluation < ApplicationRecord
def imported?
import_status?
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

@ -131,7 +131,7 @@ class Exercise < ApplicationRecord
status = 4
else
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]
ed_time = ex_time[:end_time]
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?
item[:ec_achievement_evaluation_relates_attributes] =
Array(*item[:course_evaluation_subitem_ids]).uniq.map do |subitem_id|
{ ec_course_evaluation_subitem_id: subitem_id.to_i }
item[:course_evaluation_relates].map do |relate|
{ ec_course_evaluation_subitem_id: relate[:subitem_id].to_i, position: relate[:position] }
end
return
end
@ -41,22 +41,22 @@ class Ecs::CreateCourseAchievementMethodsService < ApplicationService
relates = achievement_method.ec_achievement_evaluation_relates
# 获取传入的 subitem id数组和已存在的 subitem id数组
old_subitem_ids = relates.map(&:ec_course_evaluation_subitem_id).uniq
new_subitem_ids = Array(*item[:course_evaluation_subitem_ids]).map(&:to_i).uniq
old_data = relates.map { |e| [e.ec_course_evaluation_subitem_id, e.position] }
new_data = item[:course_evaluation_relates].map { |e| [e[:subitem_id, e[:position]]] }
# 分别得到需要移除的 subitem ID数组和需要创建的 subitem ID数组
destroy_subitem_ids = old_subitem_ids - new_subitem_ids
create_subitem_ids = new_subitem_ids - old_subitem_ids
destroy_data = old_data - new_data
create_data = new_data - old_data
# 生成需要创建关系的 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|
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 }
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

@ -24,5 +24,4 @@ json.course_identity @user_course_identity
json.excellent @course.excellent
if @course.is_end == 0
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,
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", () => {
notification.destroy()
notification.success({
duration: null,
duration: 2,
message: '网络恢复正常',
description:
'网络恢复正常,感谢使用。',

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

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

@ -55,7 +55,6 @@ class CoursesBanner extends Component {
}
}
componentDidMount() {
this.onloadupdatabanner()
on('updatabanner', this.updatabanner)
axios.interceptors.response.use((response) => {
@ -69,9 +68,17 @@ class CoursesBanner extends Component {
}
return response;
}, (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() {
off('updatabanner', this.updatabanner)
}

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

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

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

@ -302,7 +302,8 @@ class studentsList extends Component{
}
componentDidUpdate(prevProps) {
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)
}
// 加载了2次

@ -518,7 +518,10 @@ class PollDetailTabForth extends Component{
</span>
{
!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>

@ -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>
{
!flagPageEdit && this.props.isAdmin() === true ?
<a className="fr" onClick={this.editSetting}><Tooltip title="编辑"><i
className="iconfont icon-bianjidaibeijing font-20 color-green pr20 "></i></Tooltip></a>
<a className="fr white-btn edu-blueline-btn mr10 mr20 lineh-24" onClick={this.editSetting}>
编辑设置
{/*<Tooltip title="编辑"><i*/}
{/*className="iconfont icon-bianjidaibeijing font-20 color-green pr20 "></i></Tooltip>*/}
</a>
: ""
}
</p>

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

Loading…
Cancel
Save