import React, { PureComponent } from "react" import { CopyToClipboard } from "react-copy-to-clipboard" import classnames from "classnames" import { isEmpty } from "lodash" import { browser } from "src/utils" import { http, getParam } from "src/utils" import { Formik, Form, Field } from "formik" import { Toast } from "antd-mobile" import CaptchaAli from "src/common/Captcha-ali" import FollowQRcode from "./../followQRcode" import "./index.scss" import cookie from "js-cookie" import { Link } from "react-router-dom" class RedPacket extends PureComponent { constructor(props) { super(props) this.state = { // 弹窗类型:0: 无弹出,1:非微信,2:微信 type: 0, isCopy: false, validate: "", captchaInstance: null, seconds: 60, isFirst: true, timer: null, isTimer: false, // 是否开始倒计时 shareInfo: { url: "", share_code: "", command: "【七月在线送你一个红包】https://www.julyedu.com/", }, doneInfo: { //领取后的状态,1:领取成功,2:领取超时 status: 2, txt: "手机号绑定超时,红包已失效!", desc: "", }, money: "", // 红包金额, endTime: 10, // 手机绑定时限 countdownTimer: null, countdown: "00分00秒", // 绑定时间 accountInfo: {}, bindInfo: {}, country: { num: "86", }, validationData: null, } } componentDidMount() { // console.log(this.props); this.judgePopupTypeFromCountry() // 分享链接进入 this.judgePopupType() window.addEventListener("beforeunload", this.removeStatisticsCookie) // 微信进入 const isWechat = getParam("wechat") const { userInfo } = this.props if (!userInfo || !userInfo.uid) { this.setRelativeCookie() } if (isWechat === "1" && !browser.isWeixin) { if (userInfo && userInfo.uid) { const type = window.localStorage.getItem("redpacket-click") if (type === "split") { http .get(`${API.home}/sys/redPacket/shareUrl/${getParam("id")}`) .then((res) => { const { code, data } = res.data if (code === 200) { // 检查收否领取过 http .post(`${API.home}/sys/redPacket/split`, { action: "check", share_code: data.share_code, }) .then((res) => { const { code, data } = res.data if (code === 200) { window.localStorage.removeItem("redpacket-click") // is_receive 是否领取过 0-否 1-是 if (data.is_receive) { this.judgeReceiveStatus(data, 8) } else { this.setState({ type: 3, }) } } }) } }) } else { this.setState({ type: 1, }) window.localStorage.removeItem("redpacket-click") } } else { this.setRelativeCookie() this.setState({ type: 1, }) } } this.fetchShareInfo() } removeStatisticsCookie = () => { cookie.remove("share_code", { path: "/", domain: ".julyedu.com" }) } componentWillUnmount() { window.removeEventListener("beforeunload", this.removeStatisticsCookie) } // 获取分享信息 fetchShareInfo = () => { const share_code = getParam("share_code") http .get(`${API.home}/sys/redPacket/shareUrl/${getParam("id")}`) .then((res) => { const { code, data } = res.data if (code === 200) { this.setState({ shareInfo: share_code ? Object.assign({}, data, { share_code }) : data, }) } }) } // 分享后进入,链接中带 share_code 字段 judgePopupType = () => { const share_code = getParam("share_code") const { shareInfo } = this.state if (share_code && share_code !== "null") { this.setState({ shareInfo: Object.assign({}, shareInfo, { share_code, }), }) // 检查收否领取过 http .post(`${API.home}/sys/redPacket/split`, { action: "check", share_code, }) .then((res) => { const { code, data } = res.data if (code === 200) { // is_overdue 红包是否过期 0-否 1-是 if (data.is_overdue) { this.setState({ type: 7, }) } else { // is_receive 是否领取过 0-否 1-是 if (data.is_receive) { this.judgeReceiveStatus(data) } else { this.setState({ type: browser.isWeixin ? 2 : 3, }) } } } if (code === 4030 || code === 4040) { this.setState({ type: browser.isWeixin ? 2 : 3, }) } }) } } // 选择区号后进入 judgePopupTypeFromCountry = () => { const { country } = this.props const { shareInfo } = this.state if (country.code) { this.setState({ country, shareInfo: Object.assign({}, shareInfo, { share_code: country.code, }), }) // 检查收否领取过 http .post(`${API.home}/sys/redPacket/split`, { action: "check", share_code: country.code, }) .then((res) => { console.log(res) const { code, data } = res.data if (code === 200) { // is_receive 是否领取过 0-否 1-是 if (data.is_receive) { this.judgeReceiveStatus(data, 8) } else { this.setState({ type: 3, }) } // 清除 this.props.delCountryNum() } }) } } // 判断领取状态--领取后 judgeReceiveStatus = (data, bindType = 4) => { let txt = "" let desc = "" // receive_type 领取类型 1自己 2别人 if (data.receive_type === 1) { desc = "越多好友领取,你所得越多!" } if (data.receive_type === 2) { desc = "每天只能帮好友领取一次哦~" } // is_overdue 红包是否过期 0-否 1-是 if (data.is_overdue) { txt = data.red_packet_type === 1 ? `您已经领过该红包 ${data.amount}元现金!` : `您已经领过该红包 ${data.amount}元代金券碎片!` } else { txt = data.red_packet_type === 1 ? `今日已领取${data.amount}元现金!` : `今日已领取${data.amount}元代金券碎片!` } // receive_status 领取状态 1-已领取 2-已领取未绑定 3-已失效 if (data.receive_status === 1) { this.setState({ type: 9, doneInfo: { status: 1, txt, desc, }, }) } else if (data.receive_status === 2) { this.setState({ type: bindType, money: data.amount, endTime: data.end_time, }) this.startCountDown() } else if (data.receive_status === 3) { this.setState({ type: 9, doneInfo: { status: 2, txt: "手机号绑定超时,红包已失效!", desc, }, }) } } // 绑定时间 startCountDown = () => { if (this.countdownTimer) { window.clearInterval(this.countdownTimer) } const { endTime } = this.state let time = endTime let minutes = 0 let seconds = 0 this.countdownTimer = window.setInterval(() => { if (time <= 0) { window.clearInterval(this.countdownTimer) this.setState({ endTime: 0, }) } time -= 1 minutes = `${Math.floor(time / 60)}`.padStart(2, 0) seconds = `${time % 60}`.padStart(2, 0) this.setState({ countdown: `${minutes}分${seconds}秒`, }) }, 1000) } // 获取分享信息 handleToShare = () => { const { history, userInfo } = this.props if (browser.isWeixin) { this.setState({ type: 2, }) history.push(`/detail?id=${getParam("id")}&wechat=1`) } else { if (userInfo && userInfo.uid) { // 领取好友的后,再领取自己的 share_code 未更新 http .get(`${API.home}/sys/redPacket/shareUrl/${getParam("id")}`) .then((res) => { const { code, data } = res.data if (code === 200) { this.setState({ shareInfo: data, type: 1, }) } }) } else { history.push("/passport/login") } } } // 提示关注公众号 openTip = () => { const { shareInfo } = this.state // is_follow 是否关注公众号,0否,1是 if (!shareInfo.is_follow) { this.setState({ type: 11, }) } } // 拆红包 handleToOpen = () => { const { history } = this.props const { shareInfo: { share_code = "" }, } = this.state http .post(`${API.home}/sys/redPacket/split`, { action: "receive", share_code, }) .then((res) => { const { code, data } = res.data if (code === 200) { // is_receive 是否领取过 0-否 1-是 if (data.is_receive) { this.judgeReceiveStatus(data) } else { // red_packet_type 红包类型 1-现金 2-代金券 if (data.red_packet_type === 2) { this.setState({ type: 6, money: data.amount, }) } else if (data.red_packet_type === 1) { // receive_status 领取状态 1-已领取 2-已领取未绑定 3-已失效 if (data.receive_status === 1) { if (data.red_packet_type === 1) { this.setState({ type: 5, money: data.amount, }) } else if (data.red_packet_type === 2) { this.setState({ type: 6, money: data.amount, }) } } else if (data.receive_status === 2) { this.setState({ type: 4, money: data.amount, endTime: data.end_time, }) this.startCountDown() } else if (data.receive_status === 3) { this.setState({ type: 9, doneInfo: { status: 2, txt: "手机号绑定超时,红包已失效!", desc: data.receive_type === 1 ? "越多好友领取,你所得越多!" : data.receive_type === 2 ? "每天只能帮好友领取一次哦~" : "", }, }) } } } } else if (code === 4030 || code === 4040) { history.push("/passport/login") } }) } // 关闭弹出 handleToClose = (isOpen, isShare = false) => { if (isOpen) { const { shareInfo: { share_code = "" }, } = this.state // 检查收否领取过 http .post(`${API.home}/sys/redPacket/split`, { action: "check", share_code, }) .then((res) => { const { code, data } = res.data if (code === 200) { // is_receive 是否领取过 0-否 1-是 if (data.is_receive) { this.judgeReceiveStatus(data) } else { this.setState({ type: 3, }) } } }) } else { if (isShare) { const { history } = this.props history.push(`/detail?id=${getParam("id")}`) } this.setState({ type: 0, }) } } // 微信内点击蒙层 clickMask = () => { const { type } = this.state if (type === 2) { this.setState({ type: 0, }) } } getCaptchaInstance = (instance) => { this.setState({ captchaInstance: instance, }) } onVerify = (data) => { this.setState({ validate: true, validationData: data, }) } handleToSend = ({ tel, code }) => { let { validate, seconds, validationData, isFirst, isTimer, captchaInstance, country: { num = "86" }, } = this.state if (validate) { if (!isFirst) { Toast.info("请重新进行滑块验证", 2, null, false) captchaInstance.reset() this.setState({ isFirst: true, }) return } if (!isTimer) { if (!tel) { Toast.info("手机号码不能为空", 2, null, false) } else if (!/^\d+$/.test(tel)) { // }else if (!validateTel(tel)) { Toast.info("请输入正确格式的手机号码", 2, null, false) } else { // 获取验证码 http .post(`${API["passport-api"]}/m/personal/bindPhoneSendCode`, { area_code: `00${num}`, phone_num: tel, ...validationData, }) .then((res) => { const { errno, msg } = res.data if (errno === 200) { Toast.info("验证码发送成功", 2, null, false) // 倒计时 this.timer = window.setInterval(() => { if (seconds <= 0) { window.clearInterval(this.timer) this.setState({ isTimer: false, seconds: 60, }) } else { this.setState({ isTimer: true, seconds: --seconds, }) } }, 1000) // 滑块 this.setState({ isFirst: false, }) } else { Toast.info(msg, 2, null, false) } }) } } } return false } // 绑定后领取 receviceAfterBind = () => { http.get(`${API.home}/sys/red_packet/receive`).then((res) => { const { code, data, msg } = res.data if (code === 200) { // receive_status 领取状态 1-已领取 2-已领取未绑定 3-已失效 if (data.receive_status === 1) { if (data.red_packet_type === 1) { this.setState({ type: 5, money: data.amount, }) } else if (data.red_packet_type === 2) { this.setState({ type: 6, money: data.amount, }) } } else if (data.receive_status === 2) { this.setState({ type: 4, money: data.amount, endTime: data.end_time, }) this.startCountDown() } else if (data.receive_status === 3) { this.setState({ type: 9, doneInfo: { status: 2, txt: "手机号绑定超时,红包已失效!", desc: data.receive_type === 1 ? "越多好友领取,你所得越多!" : data.receive_type === 2 ? "每天只能帮好友领取一次哦~" : "", }, }) } } else { Toast.info(msg, 2, null, false) } }) } // 绑定手机 toContinueBind = (isValid = 1) => { const { accountInfo: { tel, code }, country: { num = "86" }, } = this.state // is_valid 是否验证 1:验证(默认),0不验证 http .post(`${API["passport-api"]}/m/personal/bindPhone`, { area_code: `00${num}`, phone_num: tel, code: code, type: 1, is_valid: isValid, }) .then((res) => { const { errno, data, msg } = res.data if (errno === 200) { if (isValid) { if (data.tip_info) { this.setState({ type: 10, bindInfo: data.tip_info, }) } else { this.receviceAfterBind() } } else { this.receviceAfterBind() } } else { Toast.info(msg, 2, null, false) } }) } //设置统计信息 setRelativeCookie = () => { const config = { path: "/", domain: ".julyedu.com" } cookie.set( "share_code", getParam("share_code") ? getParam("share_code") : "share_code", config ) } render() { // console.log(this.props); const { history, userInfo } = this.props const { type, isCopy, validate, isTimer, seconds, shareInfo: { command = "", share_code = "" }, money, doneInfo, countdown, endTime, bindInfo, country, } = this.state const cls = classnames("popup-mask", { "popup-mask--no": type !== 2, }) return ( <> <div className="red-packet"> <p className="red-packet__title"> 分享课程给好友,你和好友都可以领红包哦〜 </p> <button className="red-packet__button" onClick={this.handleToShare}> 分享领红包 </button> </div> {/* popup */} {type !== 0 && ( <div className={cls} onClick={this.clickMask}> {/* wechat */} {type === 2 && ( <div className="pupup-wechat"> <h4 className="popup-wechat__title"> 当前环境不支持领红包活动 </h4> <p className="popup-wechat__desc"> 请点击右上角“ ··· ”,选择在浏览器中打开 然后参与活动! </p> <i className="popup-wechat__icon"></i> </div> )} {/* wechat--no */} {type === 1 && ( <div className="popup-password"> <div className="popup-password__content"> <h4 className="popup-password__header">复制口令发送给好友</h4> <div className="popup-password__body"> <p id="password" className="popup-passowrd__info"> {command.length > 16 ? `${command.substr(0, 16)}...` : command} </p> {!isCopy ? ( userInfo && userInfo.uid ? ( <CopyToClipboard text={command} onCopy={() => this.setState({ isCopy: true, }) } > <button className="popup-password__button--copy"> 复制口令 </button> </CopyToClipboard> ) : ( <button className="popup-password__button--copy" onClick={() => { window.localStorage.setItem( "redpacket-click", "copy" ) history.push("/passport/login") }} > 复制口令 </button> ) ) : ( <p className="popup-password__success"> 复制成功,快发送给好友吧~ </p> )} </div> <p className="popup-password__footer"> 好友领取红包后,你将获得同样奖励。 <br /> 自己也可以领取哦~ </p> </div> <i className="popup-password__button--close iconfont iconiconfront-2" onClick={() => { if (getParam("wechat") === "1") { if (userInfo && userInfo.uid) { this.handleToClose(true) history.push(`/detail?id=${getParam("id")}`) } else { this.setState({ type: 3, }) window.localStorage.setItem("redpacket-click", "split") } } else { this.handleToClose(true) } this.setState({ isCopy: false, }) }} /> </div> )} {/* red-packet--close */} {type === 3 && ( <Packet type={3} packetInfo={{ title: "七月在线给你发了个红包~", }} handleToClose={() => this.handleToClose(false)} handleToOpen={this.handleToOpen} /> )} {/* red-packet--open */} {type === 4 && ( <Packet type={4} packetInfo={{ money, tip: [ "为了您的资金安全,请于5分钟之内绑定手机号,超时红包将失效", ], btn: { txt: `立即绑定(${countdown})`, onClick: () => { this.setState({ type: 8, }) }, }, }} handleToClose={() => this.handleToClose(false)} /> )} {/* red-packet--money success */} {type === 5 && ( <Packet type={5} packetInfo={{ money, tip: ["可前往【七月在线】APP", "- 账户资金中提现"], btn: { txt: "获取更多奖励", onClick: () => { history.push("/ShareCourse") }, }, }} handleToClose={() => { const isShare = getParam("share_code") ? true : false this.handleToClose(false, isShare) this.openTip() }} /> )} {/* red-packet--fragment success */} {type === 6 && ( <Packet type={6} packetInfo={{ money, tip: ["可前往【七月在线】APP", "- 我的优惠券中合成代金券"], btn: { txt: "获取更多奖励", onClick: () => { history.push("/ShareCourse") }, }, }} handleToClose={() => { const isShare = getParam("share_code") ? true : false this.handleToClose(false, isShare) this.openTip() }} /> )} {/* red-packet--late 来完了 */} {type === 7 && ( <Packet type={7} packetInfo={{ btn: { txt: "获取更多奖励", onClick: () => { history.push("/ShareCourse") }, }, }} handleToClose={() => { const isShare = getParam("share_code") ? true : false this.handleToClose(false, isShare) }} /> )} {/* form */} {type === 8 && ( <div className="popup-form"> <Formik initialValues={{ tel: "", code: "", }} validate={({ tel, code }) => { const errors = {} // if (!validateTel(tel)) { if (!/^\d+$/.test(tel)) { errors.tel = "请填写正确格式的手机号" } if (!/[0-9]{6}/.test(code)) { errors.code = "请输入验证码" } return errors }} onSubmit={(values, { setStatus, setSubmitting }) => { this.setState({ accountInfo: { ...values, }, }) this.toContinueBind() }} > {({ values: { tel, code }, errors }) => ( <Form className="popup-form__content"> <h4 className="popup-form__title">绑定手机号</h4> <div className="popup-form__item"> <Link className="popup-form__button--num" to={`/country?id=${getParam( "id" )}&share_code=${share_code}`} > +{country.num} <i className="iconfont iconiconfront-69" /> </Link> <Field name="tel"> {({ field }) => { return ( <input {...field} className="popup-form__ipt" data-bdrs="0 6px 6px 0" data-type="tel" type="text" placeholder="请填写手机号" /> ) }} </Field> </div> <CaptchaAli getInstance={this.getCaptchaInstance} onVerify={this.onVerify} /> {endTime === 0 ? ( <> <div className="popup-form__item"> <p className="popup-form__tip"> <i className="iconfont icondanseshixintubiao-8"></i> 绑定超时,红包已失效! </p> </div> <button className="popup-packet__button--bundle" data-status="do" type="button" onClick={() => { history.push("/ShareCourse") }} > 获取更多奖励 </button> </> ) : ( <> <div className="popup-form__item"> <Field name="code"> {({ field }) => { return ( <input {...field} className="popup-form__ipt popup-form__ipt--left" type="text" placeholder="输入验证码" /> ) }} </Field> <button className="popup-form__button--code" data-status={validate && !isTimer ? "do" : ""} type="button" onClick={() => this.handleToSend({ tel, code })} > {isTimer ? `重新发送${seconds}s` : "发送验证码"} </button> </div> <button className="popup-packet__button--bundle" data-status={ tel && code && isEmpty(errors) ? "do" : "done" } type="submit" > {`完成绑定(${countdown})`} </button> </> )} </Form> )} </Formik> <i className="popup-password__button--close iconfont iconiconfront-2" onClick={() => this.handleToClose(false)} /> </div> )} {/* 领取后的状态 */} {type === 9 && ( <div className="popup-done"> <div className="popup-done__content"> <h4 className={classnames("popup-done__title", { "popup-done__title--overtime": doneInfo.status === 2, })} > {doneInfo.status === 2 && ( <i className="iconfont icondanseshixintubiao-8"></i> )} {doneInfo.txt} </h4> <p className="popup-done__desc">{doneInfo.desc}</p> <button className="popup-packet__button--bundle" data-status="do" type="submit" onClick={() => { history.push("/ShareCourse") }} > 获取更多奖励 </button> </div> <i className="popup-password__button--close iconfont iconiconfront-2" onClick={() => { const isShare = getParam("share_code") ? true : false this.handleToClose(false, isShare) }} /> </div> )} {/* 手机号绑定提示 */} {type === 10 && ( <div className="popup-bind"> <div className="popup-bind__content"> <h4 className="popup-bind__title">绑定确认</h4> <p className="popup-bind__desc"> 该手机号已绑定到以下账号,继续绑定将解除以下绑定状态 </p> <ul className="popup-bind__list"> {bindInfo["email"] && ( <li className="popup-bind__account"> {/* 邮箱 */} <i className="iconfont iconduanxin"></i> <p className="popup-bind__account--name"> {bindInfo["email"]} </p> </li> )} {bindInfo["wechat_nickname"] && ( <li className="popup-bind__account"> {/* wechat */} <i className="icon-wachat"></i> <p className="popup-bind__account--name"> {bindInfo["wechat_nickname"]} </p> </li> )} {bindInfo["qq_nickname"] && ( <li className="popup-bind__account"> {/* qq */} <i className="icon-qq"></i> <p className="popup-bind__account--name"> {bindInfo["qq_nickname"]} </p> </li> )} {bindInfo["sina_nickname"] && ( <li className="popup-bind__account"> {/* 微博 */} <i className="icon-sina"></i> <p className="popup-bind__account--name"> {bindInfo["sina_nickname"]} </p> </li> )} </ul> <div className="popup-bind__button"> <button className="popup-bind__button--cancle" onClick={() => this.handleToClose(false)} > 取消 </button> <button className="popup-bind__button--confirm" onClick={() => this.toContinueBind(0)} > 继续绑定 </button> </div> </div> <i className="popup-password__button--close iconfont iconiconfront-2" onClick={() => this.handleToClose(false)} /> </div> )} {/* 关注公众号 */} {type === 11 && ( <FollowQRcode toClose={() => this.handleToClose(false)} /> )} </div> )} </> ) } } const Packet = ({ type, packetInfo, handleToClose, handleToOpen }) => { const cls_content = classnames("popup-packet__content", { "popup-packet__content--open": type === 4, "popup-packet__content--money": type === 5, "popup-packet__content--fragment": type === 6, "popup-packet__content--late": type === 7, }) const { money, tip = [], btn } = packetInfo return ( <div className={classnames("popup-packet")}> <div className={cls_content}> {type === 3 && ( <> <p className="popup-packet__title">七月在线给你发了个红包~</p> <button className="popup-packet__button--split" onClick={handleToOpen} /> </> )} {(type === 4 || type === 5 || type === 6) && ( <> <h4 className="popup-packet__label">恭喜您获得</h4> <p className="popup-packet__value"> {money} <span className="popup-packet__value--unit">元</span> </p> <p className="popup-packet__tip"> {tip.map((item, index) => { if (index !== tip.lenght - 1) { return ( <> {item} <br /> </> ) } return item })} </p> <button className="popup-packet__button--bundle" onClick={btn.onClick} > {btn.txt} </button> </> )} {type === 7 && ( <> <h4 className="popup-packet__label">您来晚了!</h4> <p className="popup-packet__value"> 红包仅能当日领取,下次 <br /> 早点来哦~ </p> <button className="popup-packet__button--bundle" onClick={btn.onClick} > {btn.txt} </button> </> )} </div> <i className="popup-password__button--close iconfont iconiconfront-2" onClick={handleToClose} /> </div> ) } export default RedPacket