Commit 4c81867f by xuzhenghua

碎片

parent 5aedbc91
......@@ -4,12 +4,14 @@ $bg_type2: #E0B97B;
position: relative;
margin-bottom: 15px;
box-shadow: 0px 2px 12px -8px;
border-radius: 3px;
.coupon-info {
position: relative;
height: 95px;
padding: 10px 15px;
color: $white;
border-radius: 3px;
.type {
font-size: $font_14;
......@@ -47,7 +49,7 @@ $bg_type2: #E0B97B;
&.coupon-type2 {
background: $E0B97B;
}
&.invalid{
background: $color_999;
}
......@@ -93,6 +95,7 @@ $bg_type2: #E0B97B;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 0 0 3px 3px;
.limit {
width: 63.81%;
......
......@@ -2,8 +2,8 @@
position: relative;
.custom-input {
width: 255px;
height: 36px;
width: 277px;
height: 33px;
padding-left: 10px;
......
......@@ -5,21 +5,22 @@
padding: 10px 12px;
border-bottom: 1px solid $border_e7eaf1;
position: absolute;
top: 44px;
top: 96px;
left: 0;
z-index: 10;
background: $white;
button {
display: inline-block;
width: 84px;
height: 36px;
line-height: 36px;
font-size: $font_16;
width: 64px;
height: 33px;
line-height: 33px;
font-size: $font_14;
color: $white;
background-color: $bg_ccc;
border: none;
-webkit-appearance: none;
border-radius: 3px;
&.active {
background-color: $active;
......
.use-coupon {
display: flex;
flex-flow: column;
.coupons-box{
height: 100%;
#coupons {
height: 100%;
.tab {
width: 100%;
height: 44px;
line-height: 44px;
background-color: #fff;
display: flex;
justify-content: space-around;
font-size: 14px;
color: #555;
.coupons-area {
padding: 72px 12px 0px;
//background: $bg_f5f5f5;
flex: 1 1 auto;
a {
display: inline-block;
height: 100%;
}
.empty {
min-height: 211px;
line-height: 211px;
font-size: $font_12;
color: $color_666;
text-align: center;
}
}
.btm-border {
background-color: #f5f5f5;
width: 100%;
height: 8px;
}
.invalid-title{
text-align: center;
font-size: $font_12;
line-height: 52px;
color: $color_999;
}
.tab-active {
color: #09f;
border-bottom: 1px solid #09f;
}
.coupons-container {
height: 100%;
}
}
\ No newline at end of file
}
}
import React, { PureComponent } from 'react';
import './index.scss'
import RedeemBar from "../RedeemBar";
import Coupon from '../Coupon'
import { http, getParam } from '@/utils'
import { WithFullSize } from '@/HOCs'
import { Toast } from 'antd-mobile'
import { isEmpty } from 'lodash'
import {connect} from 'react-redux';
@connect()
class UseCoupon extends PureComponent {
state = {
selectedCouponId: 0,
redeemCode: '',
couponList: [],
valid_coupons: [],
invalid_coupons: [],
courseId: getParam('id'),
showUseButton: false
}
componentDidMount() {
const {history, location} = this.props
const {state} = this.props.location
if (state && state.from) {
if (state.from === '/my') {
this.getMyCoupons();
this.setState({
showUseButton: true
})
} else {
if (!this.state.courseId) {
location.state && location.state.from ? history.replace(location.state.from) : history.goBack()
}
this.getAllCoupons();
}
}
}
handleChange = e => {
let value = e ? e.target.value : ''
this.setState({redeemCode: value})
}
exchange = () => {
const { location: { state = {}} } = this.props;
if (this.state.redeemCode !== '') {
http.post(`${API.home}/m/coupon/exchange`, {
code: this.state.redeemCode
})
.then(res => {
const data = res.data
if (data.code === 200) {
const coupon = data.data
if (this.state.showUseButton) {
this.setState({
couponList: [...this.state.couponList, coupon],
redeemCode: ''
})
} else {
const coupon = data.data
if (coupon['ctype'] == 2
&& coupon['limit_course'] != this.state.courseId) {
this.setState({
invalid_coupons: [...this.state.invalid_coupons, coupon],
showUseButton: null
});
} else {
this.setState({
valid_coupons: [...this.state.valid_coupons, coupon],
redeemCode: ''
})
}
}
Toast.info('兑换成功')
if (state.from === '/my') {
this.getMyCoupons()
}
if(state.from === '/order') {
this.getAllCoupons()
}
} else {
Toast.info(data.msg)
}
})
} else {
Toast.info('请输入兑换码')
}
}
getMyCoupons = () => {
http.get(`${API.home}/m/coupon/all`)
.then(res => {
const data = res.data
if (data.code === 200) {
this.setState({
couponList: isEmpty(data.data) ? [] : data.data
})
} else {
Toast.info(data.msg)
}
})
}
getAllCoupons = () => {
http.post(`${API.home}/m/coupon/select`, {course_id: this.state.courseId})
.then(res => {
const data = res.data
if (data.code === 200) {
const inuse_coupon = data.data['inuse_coupon'];
this.setState({
valid_coupons: inuse_coupon
? [...inuse_coupon, ...data.data.valid_coupons]
: data.data.valid_coupons,
invalid_coupons: data.data.invalid_coupons,
selectedCouponId: inuse_coupon.length ? inuse_coupon[0].id : 0
})
} else {
Toast.info(data.msg)
}
})
}
useCoupon = val => {
const {history, dispatch} = this.props
const coupon = this.state.couponList.find(item => item.id === val)
if (val) {
if (this.state.showUseButton) {
if (coupon['ctype'] === 1) {
history.push(`/classify`)
} else {
// dispatch(getCourses(coupon['limit_course'], () => {
history.push(`/detail?id=${coupon['limit_course']}`);
return false;
// }));
}
} else {
const {courseId, selectedCouponId} = this.state
if (selectedCouponId === val) {
http.post(`${API.home}/m/coupon/cancel`, {
course_id: courseId
}).then(res => {
const data = res.data
if (data.code === 200) {
this.setState({
selectedCouponId: 0
})
} else {
Toast.info(data.msg)
}
})
} else {
http.post(`${API.home}/m/coupon/use`, {
course_id: this.state.courseId,
coupon_id: val
})
.then(res => {
const data = res && res.data
if (data.code === 200) {
this.setState({selectedCouponId: val})
this.props.history.goBack()
} else {
Toast.info(data.msg)
}
})
}
}
} else {
Toast.info('未知错误')
location.reload()
}
}
render() {
const {state} = this.props.location
const {showUseButton, selectedCouponId} = this.state
return (
<div className='use-coupon'>
<RedeemBar onChange={this.handleChange}
exchange={this.exchange}
redeemCode={this.state.redeemCode}/>
<div className="coupons-area">
<Content
coupons={
state
&& state.from
&& state.from === '/my'
? this.state.couponList
: this.state.valid_coupons
}
showUseButton={showUseButton}
selectedCouponId={selectedCouponId}
select={this.select}
useCoupon={this.useCoupon}
/>
{
this.state.invalid_coupons.length > 0 &&
(
<>
<div className='invalid-title'>- 不可使用的优惠券 -</div>
<Content
coupons={this.state.invalid_coupons}
selectedCouponId={selectedCouponId}
select={this.select}
purpose={'use'}
invalid={'invalid'}
/>
</>
)
}
</div>
</div>
);
}
}
function Content({coupons, ...rest}) {
if (coupons.length === 0) {
return (
<div className='empty'>
<p>暂无可使用的优惠券</p>
</div>
)
}
return (
<ul>
{
coupons.map(item => {
return (
<Coupon
key={item.id}
{...item}
id={item.id}
{...rest}
/>
)
})
}
</ul>
)
}
export default WithFullSize(UseCoupon);
\ No newline at end of file
.use-coupon {
display: flex;
flex-flow: column;
height: 100%;
background-color: #f5f5f5;
.coupons-area {
padding: 72px 12px 0px;
background: $bg_f5f5f5;
flex: 1 1 auto;
.empty {
min-height: 211px;
line-height: 211px;
font-size: $font_12;
color: $color_666;
text-align: center;
}
.invalid-title{
text-align: center;
font-size: $font_12;
line-height: 52px;
color: $color_999;
}
}
}
\ No newline at end of file
import React, {PureComponent} from 'react';
import './index.scss'
import {http, getParam} from '@/utils'
import {WithFullSize} from '@/HOCs'
import {Toast} from 'antd-mobile'
import {HeaderBar} from "@/common";
class UsePatch extends PureComponent {
constructor(props) {
super(props);
this.state = {
success: false,
checkedIndex: 0,
list: [
{
amount: 10,
desc: '兑换后7日内有效',
type: '代金券'
},
{
amount: 20,
desc: '兑换后7日内有效',
type: '代金券'
},
{
amount: 50,
desc: '兑换后7日内有效',
type: '代金券'
},
{
amount: 100,
desc: '兑换后7日内有效',
type: '代金券'
}
],
couponAmount: '', // 碎片额度
};
}
componentDidMount() {
this.getPatchList()
}
// 选中
select = (index, item) => {
if (this.state.couponAmount >= item.amount) {
this.setState({
checkedIndex: index
})
}
}
// 合成
compound = () => {
const _this = this
if (this.state.couponAmount >= 10) {
http.post(`${API.home}/sys/red_packet/compose`, {type: _this.state.checkedIndex + 1}).then((res) => {
if (res.data.code === 200) {
_this.setState({
success: true
})
setTimeout(() => {
_this.getPatchList()
}, 2000)
} else {
Toast.info(res.data.msg, 2)
}
})
}
}
getPatchList() {
http.get(`${API.home}/sys/red_packet/balance`).then((res) => {
if (res.data.code === 200) {
this.setState({
couponAmount: res.data.data.coupon_amount,
success: false
})
} else {
Toast.info(res.data.msg, 2)
}
})
}
render() {
return (
<div className='my-patch'>
<div className={'couponAmount'}>
代金券碎片余额:<span>{this.state.couponAmount}</span>
</div>
<Coupon data={this.state.list}
myAmount={this.state.couponAmount}
select={this.select}
checkedIndex={this.state.checkedIndex}/>
<div className="patch-desc">
<p className={'title'}><i></i><span>代金券碎片说明</span><i></i></p>
<p className={'desc-item'}>1. 碎片可通过“分享课程领取红包”获得,也可通过线上活动获得,具体请关注官网信息;</p>
<p className={'desc-item'}>2. 碎片在购课时不能单独使用,可合成完整代金券后用代金券抵扣现金;</p>
<p className={'desc-item'}>3. 碎片合成代金券后7日内有效。</p>
</div>
<button
className={`compound ${this.state.couponAmount >= 10 ? 'disable-active' : 'disable'}`}
onClick={this.compound}>合成
</button>
{
this.state.success &&
<div className="success">
兑换成功
</div>
}
</div>
);
}
}
function Coupon(props) {
const {data, myAmount, select, checkedIndex} = props
return (
<div className={'coupons'}>
{
data && data.length > 0 && data.map((item, index) => {
return (
<div className='items-box' key={index} onClick={() => select(index, item)}>
<div className={`coupon-info ${myAmount >= item.amount ? 'active' : null}`}>
<div className="type">{item.type}</div>
<div className={'amount'}><span>{item.amount}</span>元</div>
{
myAmount >= item.amount &&
<i className={`checkout ${index === checkedIndex ? 'iconfont icondanseshixintubiao-5' : 'nochecked'}`}
/>
}
<ul>
{
new Array(19).fill('a').map((item, index) => {
return <li key={index}/>
})
}
</ul>
</div>
<div className={'coupon-des'}>
{item.desc}
</div>
</div>
)
})
}
</div>
)
}
export default WithFullSize(UsePatch);
\ No newline at end of file
.my-patch {
background-color: #f5f5f5;
.couponAmount {
padding: 5px 12px 0 12px;
font-size: 14px;
color: #555;
margin-bottom: 15px;
span {
color: #FF4000;
}
}
.coupons {
padding: 0 12px;
.items-box {
margin-bottom: 10px;
.coupon-info {
position: relative;
background-color: #999;
height: 95px;
color: #fff;
border-radius: 3px;
padding: 10px 15px 0 15px;
.type {
font-size: 14px;
}
.amount {
width: 100%;
text-align: center;
font-size: 12px;
span {
font-size: 26px;
margin-right: 5px;
}
}
ul {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
justify-content: space-around;
li {
width: 10px;
height: 10px;
border-radius: 50%;
background: #fff;
transform: translateY(50%);
}
}
}
.coupon-des {
border-radius: 3px;
background-color: #fff;
height: 33px;
line-height: 33px;
color: #999;
font-size: 12px;
padding-left: 15px;
}
}
.active {
background-color: #FE6161 !important;
}
.checkout {
width: 22px;
height: 22px;
position: absolute;
right: 15px;
top: 37px;
font-size: 28px;
line-height: 22px;
}
.icondanseshixintubiao-5 {
right: 18px;
}
.nochecked {
background: rgba(255, 255, 255, .2);
border: 1px solid #fff;
border-radius: 50%;
}
}
.patch-desc {
padding: 0 12px;
margin-top: 30px;
.title {
height: 15px;
line-height: 15px;
font-size: 14px;
margin-bottom: 10px;
color: #555;
text-align: center;
span {
display: inline-block;
margin-left: 15px;
margin-right: 15px;
}
i {
display: inline-block;
width: 30px;
height: 1px;
background-color: #CCC;
position: relative;
top: -5px;
}
}
.desc-item {
font-size: 12px;
color: #777;
line-height: 18px;
}
}
.compound {
margin-top: 44px;
width: 100%;
height: 40px;
border: none;
outline: none;
font-size: 16px;
color: #fff;
}
.disable-active {
background-color: #09f;
}
.disable {
background-color: #999;
}
.success {
width: 100px;
height: 30px;
background: rgba(0, 0, 0, .7);
font-size: 14px;
border-radius: 15px;
text-align: center;
line-height: 30px;
color: #fff;
position: fixed;
top: 50%;
left: 50%;
margin-top: -15px;
margin-left: -50px;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment