/* eslint-disable eqeqeq, jsx-a11y/alt-text */ import React, { Component } from "react" import "./index.scss" import Bargain from "./bargain" import Group from "./group" import OutLine from "./outline" import { HeaderBar, CallApp } from "../../common" import ShareRank from "./shareRank" import Audition from "./audition" import Single from "./single" import SingleSuccess from "./single/singleSuccess" import BtnStatus from "./btnstatus" import Barrage from "./barrage" import Deposit from "./deposit" import { connect } from "react-redux" import { getCourses, addCourseToCart } from "./actions" import { getParam, http, browser, wxShare } from "src/utils" import { Toast } from "antd-mobile" import { bindActionCreators } from "redux" import { delCountryNum } from "./../country/countryRedux" import { Popup } from "src/common/index" import RedPacket from "./redPacket" import ExpandActiveToast from "../Index/expandActiveToast" // import { UserGift } from "src/common" class Detail extends Component { courseId constructor(props) { super(props) this.state = { isbuy: 0, isvip: 0, auditionBox: false, singleBox: false, singleType: 1, shareRank: false, singMess: "", barInfo: "", share: false, countdown: "00:00:00", outList: [], list: [], course: {}, nowPrice: 0, laterPrice: 0, isPdd: 0, // 是否是拼团课程 控制首次单集购买后的 全集购买 接口: 拼团课程走拼团接口,否则直接走购买接口 isRedPacket: true, countDownTime: "20s", isShowChannel: window.sessionStorage.getItem("isShowSiteWindowByChannel"), isShowUserGift: false, } } componentDidMount() { this.fetchCourseInfo() const { location: { state = {} }, } = this.props if (state.oid) { this.check(state.oid) } if (getParam("is_class") === 1 || getParam("weixinpay")) { this.payCallback() } if (browser.isWeixin) { this.isweixinPay() } this.judgeIsRedPacket() // 红包链接进入详情也 if (getParam("share_code")) { this.setState({ isRedPacket: true, }) } if (getParam("ac") && Number(getParam("ac")) === 11) { this.getBorwerCourse() } this.userStatus() } componentWillMount() { // this.showUserGiftFun() } userStatus = () => { http.get(`${API["base-api"]}/sys/user/new_user_status`).then((res) => { const { errno, data } = res.data if (errno === 0) { if (Number(data.status) === 1) { // 新用户登录之后判断是否是新用户 this.setState({ isShowUserGift: false, }) // Toast.info("新人大礼包已领取成功!", 2) } else { this.setState({ isShowUserGift: false, }) } } }) } // showUserGiftFun = () => { // let newer_last_time = localStorage.getItem("newer_last_time") // 获取用户关闭大礼包的时间 // let now_time = new Date().valueOf() // if (!newer_last_time || now_time - newer_last_time > 86400000) { // this.setState({ // isShowUserGift: true, // }) // } else { // this.setState({ // isShowUserGift: false, // }) // } // } // close = () => { // this.setState({ // isShowUserGift: false, // }) // let now_time = new Date().valueOf() // 获取当前时间 // localStorage.setItem("newer_last_time", now_time) // 存储关闭时间 // } // get_newerModal = () => { // this.close() // this.props.history.push("/passport/login") // } getBorwerCourse = () => { http .get(`${API.home}/sys/user/blessing`, { type: 4, course_id: getParam("id"), }) .then((res) => { let { code, data: { today_browsed_courses }, } = res.data if (code === 200) { let currentCourseId = getParam("id") if (today_browsed_courses.includes(Number(currentCourseId))) { this.setState({ countDownTime: "任务完成", }) } else { this.startActivity() } } }) } startActivity = () => { let _this = this let countDownInterval = setInterval(function () { let countDown = parseInt(_this.state.countDownTime) countDown-- if (countDown > 0) { _this.setState({ countDownTime: countDown + "s", }) } else if (countDown === 0) { clearInterval(countDownInterval) countDownInterval = null http .post(`${API.home}/sys/add/blessing`, { type: 4, course_id: getParam("id"), }) .then((res) => { let { code } = res.data if (code === 200) { _this.setState({ countDownTime: "任务完成", }) } }) } }, 1000) } // 判断时候未红包课程 judgeIsRedPacket = () => { http .get(`${API.home}/sys/redPacket/showShareActive/${getParam("id")}`) .then((res) => { const { code, data } = res.data if (code === 200) { this.setState({ isRedPacket: data.is_show, }) } }) } componentDidUpdate(prevProps) { if (prevProps.user.hasError !== this.props.user.hasError) { this.fetchCourseInfo() } } payCallback = () => { const _this = this if (!getParam("oid")) { return } else { this.setState({ singMess: JSON.parse(window.localStorage.getItem("singMess")), }) _this.intervalPayStatus = setInterval(function () { http .get(`${API["base-api"]}/m/orderState/oid/${getParam("oid")}`) .then((res) => { if (res.data.errno === 401) { clearInterval(_this.intervalPayStatus) _this.intervalPayStatus = null // 获取课程类型 http .get(`${API["base-api"]}/class_order_status/${getParam("oid")}`) .then((res) => { if (Number(res.data.data.errno) === 200) { // 正常购买单集成功 _this.setState({ singleType: 6, }) } else if (Number(res.data.data.errno) === 201) { // 0元参团 _this.setState({ singleType: 4, }) } else if (Number(res.data.data.errno) === 202) { // 0元购 _this.setState({ singleType: 3, }) } else if (Number(res.data.data.errno) === 203) { // 三天内特价 _this.setState({ nowPrice: res.data.data.data.now_price, laterPrice: res.data.data.data.three_day_later_price, singleType: 2, isPdd: res.data.data.data.is_pdd, }) } else { Toast.info(res.data.data.msg, 2) } }) } }) }, 1000) } } isweixinPay = () => { let _this = this let weixin_code = getParam("code") if (weixin_code) { if (!getParam("oid")) { return } else { // this.props.weixinPay(weixin_code) this.setState({ singMess: JSON.parse(window.localStorage.getItem("singMess")), }) http .get( `${API["base-api"]}/pay/wxpay/pub_charge/oid/${getParam( "oid" )}/code/${weixin_code}` ) .then((res) => { if (res.data.errno === 0) { const data = res.data.data function onBridgeReady() { WeixinJSBridge.invoke( "getBrandWCPayRequest", { appId: data.appId, //公众号名称,由商户传入 timeStamp: data.timeStamp, //时间戳,自1970年以来的秒数 nonceStr: data.nonceStr, //随机串 package: data.package, signType: data.signType, //微信签名方式: paySign: data.paySign, //微信签名 }, function (res) { if (res.err_msg === "get_brand_wcpay_request:ok") { Toast.info("支付成功", 2) _this.intervalPayStatus = setInterval(function () { http .get( `${API["base-api"]}/m/orderState/oid/${getParam( "oid" )}` ) .then((res) => { if (res.data.errno === 401) { clearInterval(_this.intervalPayStatus) _this.intervalPayStatus = null // 获取课程类型 http .get( `${ API["base-api"] }/class_order_status/${getParam("oid")}` ) .then((res) => { if (Number(res.data.data.errno) === 200) { // 正常购买单集成功 _this.setState({ singleType: 6, }) } else if ( Number(res.data.data.errno) === 201 ) { // 0元参团 _this.setState({ singleType: 4, }) } else if ( Number(res.data.data.errno) === 202 ) { // 0元购 _this.setState({ singleType: 3, }) } else if ( Number(res.data.data.errno) === 203 ) { // 三天内特价 _this.setState({ nowPrice: res.data.data.data.now_price, laterPrice: res.data.data.data .three_day_later_price, singleType: 2, isPdd: res.data.data.data.is_pdd, }) } else { Toast.info(res.data.data.msg, 2) } }) } }) }, 1000) } else { alert("支付失败") } } ) } if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener( "WeixinJSBridgeReady", onBridgeReady, false ) } else if (document.attachEvent) { document.attachEvent("WeixinJSBridgeReady", onBridgeReady) document.attachEvent("onWeixinJSBridgeReady", onBridgeReady) } } else { onBridgeReady() } } else { Toast.info(res.data.msg, 2) } }) } } } // 判断支付是否成功 check = (oid) => { this.setState({ singMess: JSON.parse(window.localStorage.getItem("singMess")), }) http.get(`${API["base-api"]}/class_order_status/${oid}`).then((res) => { if (Number(res.data.data.errno) === 200) { // 正常购买单集成功 this.setState({ singleType: 6, }) } else if (Number(res.data.data.errno) === 201) { // 0元参团 this.setState({ singleType: 4, }) } else if (Number(res.data.data.errno) === 202) { // 0元购 this.setState({ singleType: 3, }) } else if (Number(res.data.data.errno) === 203) { // 三天内特价 this.setState({ nowPrice: res.data.data.data.now_price, laterPrice: res.data.data.data.three_day_later_price, singleType: 2, isPdd: res.data.data.data.is_pdd, }) } else { Toast.info(res.data.data.msg, 2) } }) } payCallBack = (singleType, nowPrice, laterPrice) => { const _this = this if (singleType === 2) { _this.setState({ singleType, nowPrice, laterPrice, }) } else { _this.setState({ singleType, }) } } fetchCourseInfo = () => { const id = getParam("id") http.get(`${API.home}/m/course/detail/${id}`).then((res) => { const { data, code } = res.data if (code === 200) { if (data["redirect_url"] !== "") { window.location.href = data["redirect_url"] } this.setState({ course: data, }) if (data.course_info) { const mode = data.course_info.mode if (mode) { const { history } = this.props /* * mode: 课程模式 1集训营2普通小课3就业班4VIP 5AI特训营 6图文小课-python 7图文小课-ML * */ const route = { 6: "python", 7: "ml", } if (Object.keys(route).includes(mode)) { history.push(`${route[mode]}?id=${id}`) } } let course_info = data.course_info document.title = `${course_info.course_title} - 七月在线` if ( course_info.group_status === 3 || course_info.group_status === 4 ) { let endTime = course_info.pdd_group_info.groupon_member.end_time if (endTime && endTime > 0) { let date = endTime * 1000, day = 0, hours = 0, minutes = 0, seconds = 0 setInterval(() => { date -= 1000 if (endTime > 86400) { day = `${parseInt(date / (3600000 * 24))}`.padStart(2, 0) hours = `${parseInt( (date - day * 3600000 * 24) / 3600000 )}`.padStart(2, 0) minutes = `${parseInt( (date - day * 3600000 * 24 - hours * 3600000) / 60000 )}`.padStart(2, 0) // seconds = `${parseInt((date - day * 3600000 * 24 - hours * 3600000 - minutes * 60000) / 1000)}`.padStart(2, 0); this.setState({ countdown: `${day}天${hours}时${minutes}分`, }) } else { hours = `${parseInt(date / (60 * 60 * 1000))}`.padStart(2, 0) minutes = `${parseInt( (date - hours * 3600000) / 60000 )}`.padStart(2, 0) seconds = `${parseInt( (date - hours * 3600000 - minutes * 60000) / 1000 )}`.padStart(2, 0) this.setState({ countdown: `${hours}:${minutes}:${seconds}`, }) } }, 1000) } } wxShare({ title: course_info.course_title, desc: course_info.index_description, link: encodeURI( window.location.origin + "/detail?id=" + getParam("id") ), imgUrl: course_info.image_name, }) } } }) } // 点击子组件试听按钮 toAudition = (vCourseId, videoId) => { const { user } = this.props const uid = user && user.data && user.data.uid if (!uid) { this.props.history.push("/passport/login") } else { /* eslint-disable-next-line */ if (videoId == "" || videoId == 0 || videoId == undefined) { return false } http .post(`${API["base-api"]}/sys/get_class_audition?video_id=${videoId}`) .then((res) => { if (res.data.errno == 200) { this.props.history.push( `/play/video?id=${vCourseId + "&video_id=" + videoId}` ) } else { Toast.info(res.data.msg, 2) } }) // this.setState({ // auditionBox: true, // }) } } // 点击子组件单集购买按钮 toSingleset = (item) => { const { user } = this.props const uid = user && user.data && user.data.uid if (!uid) { this.props.history.push("/passport/login") } else { this.setState({ singleBox: true, singleType: 1, singMess: item, }) window.localStorage.setItem("singMess", JSON.stringify(item)) } } // 加入购物车 type:1 加入购物车,2加入购物车并跳转到购物车页面去支付 toCart = (type) => { const { history, addCourseToCart } = this.props let data = { course_id: getParam("id"), } http.post(`${API.home}/m/cart/add`, data).then((res) => { if (res.data.code === 200) { if (type === 1) { Toast.info("已加入购物车", 2) // this.props.getCourses() // document.location.reload() addCourseToCart() this.fetchCourseInfo() } else { history.replace("/shopcart") } } else if (res.data.code === 15001) { history.replace("/shopcart") } else if (res.data.code === 4030) { history.replace("/passport") } else { Toast.info(res.data.msg, 2) } }) } invitedFriends = () => { // const {course_title, image_name, course_id, pdd_group_info, pdd_group_info: {groupon_member, groupon_member: {number}, price}} = this.state.course.course_info; // if (browser.isWeixin) { // wxShare({ // title: `【仅剩${number}个名额】我${price}元拼了《${course_title}》`, // desc: course_title, // link: location.href, // imgUrl: image_name, // }); // } else { // Toast.info('请在微信中使用分享功能!', 2); // } const { history } = this.props const { course = {} } = this.state if (course.course_info && course.course_info.self_oid) { history.push(`/togroup?id=${course.course_info.self_oid}`) } } // 自组件传给父组件的boxHide boxHide = (val) => { this.setState({ auditionBox: val, singleBox: val, singleType: 1, }) this.props.history.push(`/detail?id=${getParam("id")}`) } formatTime = (seconds) => ({ d: Math.floor(seconds / 60 / 60 / 24) .toString() .padStart(2, "0"), h: Math.floor((seconds / 60 / 60) % 24) .toString() .padStart(2, "0"), m: Math.floor((seconds / 60) % 60) .toString() .padStart(2, "0"), }) getCourse = (courseId, vCourseId) => { const { history } = this.props http .post(`${API.home}/sys/limitFree/receive`, { course_id: courseId, }) .then((res) => { const { code, msg } = res.data if (code === 200) { const instance = Popup({ className: "get-course-popup", closable: false, clickMaskClose: false, title: ( <div> <img src="https://cdn.julyedu.com/time_limited_free/M/check.png" alt="" /> <div>课程有效期7天,快去学习吧~</div> </div> ), content: ( <div className={"btns"}> <button onClick={() => { instance.close() this.fetchCourseInfo() }} > 知道了 </button> <button onClick={() => { history.push(`/play/video?id=${vCourseId}`) instance.close() }} > 立即学习 </button> </div> ), }) } else { Toast.info(msg, 2, null, false) } }) } render() { const { course: { course_info = {} }, singleBox, singleType, isRedPacket, countDownTime, } = this.state const { d, h, m } = this.formatTime(course_info.limit_free_time) let number = 0 if (course_info.group_status === 3 || course_info.group_status === 4) { number = course_info.pdd_group_info.groupon_member.number } // } const { share, countdown } = this.state let href = "" const { location: { state = {} }, } = this.props if (state.to && state.to === "classify") { href = "/classify" } if (state.oid) { href = "/classify" } if (getParam("dist_code")) { href = "/" } let isCent = course_info.pdd_group_info && course_info.pdd_group_info.price != "0.01" return ( <div> {Number(getParam("ac")) === 11 ? ( <div className="activity__blessing"> <img src="https://cdn.julyedu.com/active19_1111/m/count_donw.png" /> <span className="count__down__time">{`${countDownTime}`}</span> </div> ) : null} <div className="detail-box"> <HeaderBar title="课程详情" arrow={true} cart={true} toHref={href} /> <ExpandActiveToast /> {this.state.isShowChannel == 1 && ( <CallApp className="toapp" path={`/detail/id=${getParam("id")}`} /> )} {/*弹幕*/} <Barrage isShow={course_info.is_show} /> {/*课程*/} <div className="course-content"> <div className="cover"> <img src={course_info.image_name} alt="" /> {course_info.is_aist && <span className="return_cash" />} </div> <div className="info"> <p className="title">{course_info.course_title}</p> <p className="contact text-overflow-2"> {course_info.simpledescription} </p> <div className="des"> {course_info.is_baoming === 0 && !course_info.is_limit_free && ( <p className="course-price"> <span className="new">¥{course_info.price1}</span> <span className="old">¥{course_info.price0}</span> </p> )} {!!course_info.is_deposit && course_info.is_deposit != 0 && ( <div className="openExpand"> 支付定金¥{course_info.deposit_info.deposit_amount} ,可抵扣¥{course_info.deposit_info.deduction_amount} </div> )} {course_info.is_limit_free ? ( course_info.limit_free_status == 0 ? ( <div className="limit-free"> <span>限时免费</span> <span className={"origin-price"}> ¥{course_info.price0} </span> </div> ) : course_info.limit_free_status == 1 ? ( <div className={"time-limit"}> <span> 有效期7天,{d}天{h}时{m}分后过期 </span> </div> ) : null ) : null} </div> </div> </div> {/*正常课程已购买时显示*/} {/* 没有权限:不显示 vip及赠课:显示黄的 不在vip范围内,单独购买:显示蓝的 单独买了课然后买了vip:显示蓝的 vip_range是vip里买的课,而且买了vip才会返回时间 is_pay 1是单独购买 0是买vip赠的 is_vip 1是属于vip赠的 0是不在vip范围内的 */} {!(course_info.is_limit_free && course_info.limit_free_status == 1) && course_info.is_baoming === 1 && course_info.is_pay == 1 && course_info.contact_type == 1 && course_info.course_qq && ( <div className="group"> 上课QQ群:{course_info.course_qq},加群请备注您的学号: {course_info.uid} </div> )} {!(course_info.is_limit_free && course_info.limit_free_status == 1) && course_info.is_baoming === 1 && course_info.is_pay == 1 && course_info.contact_type == 2 && course_info.course_qq && ( <div className="group"> 请添加班主任微信:{course_info.course_qq},添加时备注学号: {course_info.uid} </div> )} {/*vip课程显示*/} {course_info.vip_range && course_info.is_vip == 1 && course_info.is_pay == 0 && course_info.contact_type == 1 && course_info.course_qq && ( <div className="vip"> <p>已开通年会员:{course_info.vip_range}</p> <p> 上课QQ群:{course_info.course_qq},加群请备注您的学号: {course_info.uid} </p> </div> )} {course_info.vip_range && course_info.is_vip == 1 && course_info.is_pay == 0 && course_info.contact_type == 2 && course_info.course_qq && ( <div className="vip"> <p>已开通年会员:{course_info.vip_range}</p> <p> 请添加班主任微信:{course_info.course_qq},添加时备注学号: {course_info.uid} </p> </div> )} {/*定金相关信息*/} {!!course_info.is_deposit && course_info.is_deposit != 0 && ( <Deposit courseInfo={course_info} /> )} {/*服务承诺*/} <div className="promise"> <label>服务承诺</label> <p> {course_info.service && course_info.service.length > 0 && course_info.service.map((item, index) => { return <span key={index}> {item} </span> })} </p> </div> {/*试听弹窗*/} <Audition auditionBox={this.state.auditionBox} boxHide={this.boxHide} /> {/*单集购买弹窗*/} {singleBox && ( <Single singleType={this.state.singleType} singleBox={this.state.singleBox} boxHide={this.boxHide} data={this.state.singMess} vcourseId={course_info.v_course_id} videoId={this.state.singMess.video_id} title={course_info.course_title} check={this.check} courseId={course_info.course_id} /> )} {/* 单集购买成功弹窗 */} {singleType !== 1 && ( <SingleSuccess boxHide={this.boxHide} data={this.state.singMess} singleType={singleType} vcourseId={course_info.v_course_id} videoId={this.state.singMess.video_id} nowPrice={this.state.nowPrice} isPdd={this.state.isPdd} laterPrice={this.state.laterPrice} courseId={course_info.course_id} /> )} {/*payCallback={this.payCallback}*/} {/*weixinPay = {this.weixinPay}*/} {/* 红包 */} {isRedPacket && ( <RedPacket history={this.props.history} country={this.props.country} delCountryNum={this.props.delCountryNum} userInfo={this.props.user.data} /> )} {/*分享赚钱*/} {course_info.is_dist && <ShareRank courseInfo={course_info} />} {/** * 拼团 * is_aist: 是否AI特训营 * group_status: 团状态,3:课程有小团 用户没参加小团;4:用户参加了小团 * 拼团价格为1分钱时,不允许参团 */} {/*双十一期间不需要显示 不要删除*/} {isCent && !course_info.is_aist && (course_info.group_status === 3 || course_info.group_status === 4) && ( <Group courseInfo={course_info} history={this.props.history} countdown={countdown} invitedFriends={this.invitedFriends} /> )} {/* * 砍价 * is_baoming 否报名 0-未购买弹出报名 1-已购买弹出开始学习 * is_dist 是否分销课程 * is_bargain 是否砍价课程 */} {course_info.is_baoming === 0 && !course_info.is_aist && course_info.is_bargain && ( <Bargain country={this.props.country} delCountryNum={this.props.delCountryNum} /> )} {/*课程介绍、大纲*/} <OutLine data={course_info} toAudition={this.toAudition} toSingleset={this.toSingleset} /> {/*课程按钮*/} {course_info && ( <BtnStatus country={this.props.country} countdown={countdown} data={course_info} user={this.props.user} invitedFriends={this.invitedFriends} getCourse={this.getCourse} // addCourseToCart={this.props.addCourseToCart} toCart={this.toCart} history={this.props.history} /> )} {share ? ( <div className="groupSuccessMbc" onClick={() => { this.setState({ share: false }) }} > <div className="tipContent"> {`还差${number}人,分享到3个群,成团率高达98%`} </div> <div className="tipArrow"> <i className="iconfont iconyindao" /> </div> </div> ) : null} </div> {/* {this.state.isShowUserGift && ( <UserGift close={this.close} get_newerModal={this.get_newerModal} /> )} */} </div> ) } } const mapStateToProps = (state) => { return { // courseInfo: state.courseInfo, user: { ...state.user, }, country: state.country, } } // const mapDispatchToProps = { // fetchCoursesListIfNeeded // } const mapDispatchToProps = (dispatch) => { return bindActionCreators( { getCourses, addCourseToCart, delCountryNum, }, dispatch ) } export default connect(mapStateToProps, mapDispatchToProps)(Detail)