Commit 86605974 by FE

split success popup

parent 11675ee6
import React, { Component } from 'react';
import { http } from '@/utils';
import { Formik, Form, Field } from 'formik';
import { Toast } from "antd-mobile";
import './index.scss';
class AddressPopup extends Component {
constructor(props) {
super(props)
this.state = {
isLoading: false,
addressInfo: {
name: '',
phone: '',
address: '',
},
}
}
componentDidMount() {
this.fetchUserAddress();
}
// 获取收货信息
fetchUserAddress = () => {
const { addressInfo } = this.state;
http.get(`${API.home}/sys/user_address_info`).then(res => {
const {code, data, msg} = res.data;
if (code === 200) {
this.setState({
addressInfo: Object.assign({}, addressInfo, {
name: data.name,
phone: data.phone,
address: data.address,
}),
isLoading: true,
});
}
});
}
handleToSubmit = (params = {}) => {
const { handleToHide } = this.props;
http.post(`${API.home}/sys/collect_info`, params).then(res => {
const {code, msg} = res.data;
if (code === 200) {
handleToHide();
} else {
Toast.info(msg, 2, null, false);
}
});
}
render() {
const { isLoading, addressInfo } = this.state;
const {tip, prize, skip = 'default'} = this.props;
return (
<>
{
isLoading &&
<Formik
initialValues={{
...addressInfo
}}
validate={({name, phone, address}) => {
const errors = {};
if (!name) {
errors.name = '请输入收件人';
}
if(!/^1[3-9]\d{9}$/.test(phone)) {
errors.phone = '请填写正确格式的手机号';
}
if (!address) {
errors.address = '请输入收货地址';
}
return errors;
}}
validateOnBlur={false}
validateOnChange={false}
onSubmit={(values) => {
this.handleToSubmit(values);
}}
render={({errors}) => (
<Form className="address-form" data-skip={skip}>
{
prize ? (
<p className='address__prize'>您抽中了{prize}<span style={{'color': '#FF4000'}}>实物奖品</span></p>
) : (null)
}
{
tip ? (<div className="address-form__subtitle">{tip}</div>) : (<p className="address-form__desc">请及时填写收货信息,获得实物奖品后将第一时间为您邮寄</p>)
}
<Field
name="name"
render={({ field }) => (
<div className="address-form__item">
<input
{...field}
className="address-form__ipt"
type="text"
placeholder="收件人"
/>
{
errors.name &&
<p className="address-form__tip">{errors.name}</p>
}
</div>
)}
/>
<Field
name="phone"
render={({ field }) => (
<div className="address-form__item">
<input
{...field}
className="address-form__ipt"
type="text"
placeholder="联系方式"
/>
{
errors.phone &&
<p className="address-form__tip">{errors.phone}</p>
}
</div>
)}
/>
<Field
name="address"
render={({ field }) => (
<div className="address-form__item">
<input
{...field}
className="address-form__ipt"
type="text"
placeholder="收货地址"
/>
{
errors.address &&
<p className="address-form__tip">{errors.address}</p>
}
</div>
)}
/>
<button
className="address-form__submit"
data-status="do"
type="submit"
>提交</button>
</Form>
)}
/>
}
</>
);
}
}
export default AddressPopup;
\ No newline at end of file
// 地址弹窗
[data-skip="default"] {
.address-form__item {
width: 250px;
}
.address-form__submit {
width: 120px;
height: 34px;
margin: 8px auto 0;
border-style: none;
border-radius: 17px;
color: rgba(255, 255, 255, 1);
background-color: rgba(82, 92, 101, 0.3);
&[data-status="do"] {
background-color: #0099FF;
}
}
}
[data-skip="year"] {
.address-form__subtitle {
margin: 0 15px;
}
.address-form__item {
width: 270px;
margin: 0 15px 10px;
}
.address-form__ipt {
border-radius: 3px;
}
.address-form__submit {
width: 270px;
height: 44px;
margin: 15px auto 0;
border: 1px solid #090909;
border-radius: 5px;
color: #090909;
background-color: #FFE319;
}
}
.address-form__desc {
// width: 238px;
margin: 16px auto 15px;
font-size: 12px;
color: #999;
}
.address-form__item {
position: relative;
width: 250px;
margin: 0 auto 16px;
}
.address-form__ipt {
display: block;
width: 100%;
height: 40px;
border: 1px solid rgba(221, 221, 221, 1);
font-size: 14px;
font-weight: 400;
color: rgba(153, 153, 153, 1);
text-indent: 10px;
}
.address-form__tip {
position: absolute;
bottom: -14px;
width: 100%;
font-size: 12px;
color: #ff0000;
line-height: 14px;
}
.address-form__submit {
display: block;
font-size: 15px;
font-weight: 500;
cursor: pointer;
outline: none;
}
\ No newline at end of file
...@@ -6,15 +6,15 @@ import classnames from 'classnames' ...@@ -6,15 +6,15 @@ import classnames from 'classnames'
const re = /(https?|ftp):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/ const re = /(https?|ftp):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/
function ClosablePopup({ function ClosablePopup({
title, title,
content, content,
className, className,
closable = true, closable = true,
close = function () { close = function () {},
}, clickMaskClose = true,
clickMaskClose = true, skip='default',
closeIcon = 'iconiconfront-2' closeIcon = 'iconiconfront-2'
} = {}) { } = {}) {
function unmountComponent() { function unmountComponent() {
...@@ -36,29 +36,30 @@ function ClosablePopup({ ...@@ -36,29 +36,30 @@ function ClosablePopup({
} }
function clickMask() { function clickMask() {
if(closable){ if (closable) {
return return
} }
if(!clickMaskClose){ if (!clickMaskClose) {
return return
} }
_close() _close()
} }
const closablePopup = ( const closablePopup = (
<div className={'closable-popup-mask'} onClick={clickMask}> <div className={'closable-popup-mask'} data-skip={skip} onClick={clickMask}>
<div className={classnames(['popup-container', className])}> <div className={classnames(['popup-container', className])}>
<div className="title">{title}</div> <div className="title">{title}</div>
<div className="content"> <div className="content">
{content} {content}
</div> </div>
{
closable &&
(re.test(closeIcon)
? <img src={closeIcon} alt="" className={'close-icon'} onClick={_close}/>
: <i className={`close iconfont ${closeIcon}`} onClick={_close}/>)
}
</div> </div>
{
closable &&
(re.test(closeIcon)
? <img src={closeIcon} alt="" className={'close-icon'} onClick={_close} />
: <i className={`close iconfont ${closeIcon}`} onClick={_close} />
)
}
</div> </div>
) )
const div = document.createElement('div') const div = document.createElement('div')
......
.closable-popup-mask { .closable-popup-mask {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
...@@ -7,40 +11,40 @@ ...@@ -7,40 +11,40 @@
background: rgba(0, 0, 0, 0.6); background: rgba(0, 0, 0, 0.6);
z-index: 999; z-index: 999;
&[data-skip="default"] {
.popup-container {
border-radius: 10px;
}
}
&[data-skip="year"] {
.popup-container {
border-radius: 5px;
}
}
.popup-container { .popup-container {
position: absolute;
top: 165px;
left: 50%;
transform: translateX(-50%);
width: 300px;
padding: 20px 10px; padding: 20px 10px;
border-radius: 10px; background-color: #fff;
background: #fff;
.title { .title {
font-size: 16px; font-size: 16px;
color: #525C65; color: #525C65;
text-align: center; text-align: center;
} }
}
.close { .close {
position: absolute; font-size: 36px;
bottom: -74px; color: #fff;
left: 50%; }
transform: translateX(-50%);
font-size: 36px;
color: #fff;
}
.close-icon { .close-icon {
position: absolute; width: 33px;
bottom: -66px; height: 33px;
left: 50%; font-size: 36px;
width: 33px; color: #fff;
height: 33px;
transform: translateX(-50%);
font-size: 36px;
color: #fff;
}
} }
} }
import React, { Component } from 'react';
import './index.scss';
class SplitSuccess extends Component {
render() {
const { handleToInvite } = this.props;
return (
<div data-skip="split">
<div className="split-success__image">
<img src="" alt=""/>
</div>
<p className="split-success__prize">AI100题纸质书</p>
<a href="" className="split-success__link">
<span>查看/修改收货信息</span>
</a>
<div className="split-success__member">
<div className="member-item">
<span className="member-item__avatar">
<i className="member-item__captain">队长</i>
</span>
<span className="member-item__prize">AI100题纸质书</span>
</div>
<div className="member-item">
<span className="member-item__avatar">
<i className="member-item__captain">队长</i>
</span>
<span className="member-item__prize">AI100题纸质书</span>
</div>
<div className="member-item">
<span className="member-item__avatar">
<i className="member-item__captain">队长</i>
</span>
<span className="member-item__prize">AI100题纸质书</span>
</div>
<div className="member-item">
<span className="member-item__avatar">
<i className="member-item__captain">队长</i>
</span>
<span className="member-item__prize">AI100题纸质书</span>
</div>
</div>
<button className="split-success__jump" onClick={handleToInvite}>继续组队开宝箱</button>
</div>
);
}
}
export default SplitSuccess;
\ No newline at end of file
[data-skip="split"] {
text-align: center;
.split-success__image {
width: 130px;
height: 103px;
margin: 10px auto 0;
border: 2px solid #CDCDCD;
box-sizing: border-box;
img {
display: block;
width: 100%;
}
}
.split-success__prize {
margin: 8px 0 0;
font-size: 15px;
font-weight: 500;
color: #FF232D;
text-align: center;
line-height: 1;
}
.split-success__link {
display: inline-block;
margin: 8px 0 0;
font-size: 12px;
color: #666;
text-align: center;
line-height: 1;
span {
text-decoration: underline;
}
}
.split-success__member {
margin: 18px 0 0;
padding: 4px 12px;
border-radius: 6px;
background-color: #EFEFEF;
}
.member-item {
display: flex;
align-items: center;
margin: 8px 0;
}
.member-item__avatar {
display: inline-block;
position: relative;
width: 25px;
height: 25px;
border-radius: 50%;
background-color: #fff;
}
.member-item__captain {
position: absolute;
top: -14px;
right: -18px;
width: 30px;
height: 18px;
border: 1px solid #fff;
border-radius: 9px 9px 9px 0;
font-size: 12px;
font-style: normal;
color: #0B7B45;
text-align: center;
background-color: #FFE319;
}
.member-item__prize {
padding-left: 8px;
font-size: 12px;
color: #090909;
}
.split-success__jump {
width: 270px;
height: 44px;
margin: 18px 0 0;
border: 1px solid #090909;
border-radius: 5px;
box-sizing: border-box;
font-size: 16px;
color: #090909;
text-align: center;
line-height: 44px;
background-color: #FFE319;
}
}
\ No newline at end of file
import React, { Component } from 'react'; import React, { Component } from 'react';
import { HeaderBar } from '@common'; import { HeaderBar, Popup } from '@common';
import AddressPopup from '@common/addressPopup/index';
import TreasureTeam from './team'; import TreasureTeam from './team';
import { http } from '@/utils'; import { http } from '@/utils';
import './index.scss'; import './index.scss';
...@@ -23,6 +24,29 @@ class MyTreasure extends Component { ...@@ -23,6 +24,29 @@ class MyTreasure extends Component {
} }
this.fetchMyTreasure(); this.fetchMyTreasure();
this.fetchActivityStatus(); this.fetchActivityStatus();
// 绑定地址--宝箱
}
handleToBindPhone = () => {
}
handleToBindAddress = () => {
this.addressInstance = Popup({
title: '收货信息',
skip: 'year',
content: <AddressPopup
skip="year"
tip={
<>
<p className="address-treasure__desc">恭喜您获得 奖品名称奖品名称奖品名称</p>
<p className="address-treasure__notice">请及时填写/确认收货信息,活动结束后统一邮寄</p>
</>
}
handleToHide={() => this.addressInstance.close()}
/>
});
} }
fetchMyTreasure = () => { fetchMyTreasure = () => {
...@@ -32,15 +56,10 @@ class MyTreasure extends Component { ...@@ -32,15 +56,10 @@ class MyTreasure extends Component {
this.rule = data.rule; this.rule = data.rule;
if(Array.isArray(data.team) && data.team.length > 0) { if(Array.isArray(data.team) && data.team.length > 0) {
const teams = data.team.map(item => { const teams = data.team.map(item => {
console.log(item); return Object.assign({}, item, {
if(item) { members: item.member
return Object.assign({}, item, { });
members: item.member
});
}
return {};
}); });
console.log(teams);
this.setState({ this.setState({
isEmpty: false, isEmpty: false,
teams, teams,
...@@ -110,13 +129,17 @@ class MyTreasure extends Component { ...@@ -110,13 +129,17 @@ class MyTreasure extends Component {
{ {
(!isEnd && !isEmpty) && (!isEnd && !isEmpty) &&
<div className="treasure-content"> <div className="treasure-content">
{JSON.stringify(teams)}
{ {
teams.map((item, index) => ( teams.map((item, index) => (
<TreasureTeam data={item} key={index} /> <TreasureTeam
data={item}
key={index}
handleToBindPhone={this.handleToBindPhone}
handleToBindAddress={this.handleToBindAddress}
/>
)) ))
} }
<TreasureTeam data={{ {/* <TreasureTeam data={{
is_captain: 0, is_captain: 0,
status: 1, status: 1,
is_open: 1, is_open: 1,
...@@ -136,7 +159,7 @@ class MyTreasure extends Component { ...@@ -136,7 +159,7 @@ class MyTreasure extends Component {
prize_name:"带份饭问" prize_name:"带份饭问"
} }
] ]
}}></TreasureTeam> }}></TreasureTeam> */}
</div> </div>
} }
</div> </div>
......
...@@ -47,4 +47,19 @@ ...@@ -47,4 +47,19 @@
color: #090909; color: #090909;
background-color: #FFE319; background-color: #FFE319;
} }
}
// 地址弹窗--宝箱
.address-treasure__desc {
margin: 10px 0 0;
font-size: 14px;
color: #666;
line-height: 1;
}
.address-treasure__notice {
margin: 10px 0 16px;
font-size: 12px;
color: #FF2121;
line-height: 1;
} }
\ No newline at end of file
import React, { Component } from 'react'; import React, { Component } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import { withRouter, Link } from 'react-router-dom';
import { http } from '@/utils';
import { Popup } from '@common';
import SplitSuccess from './../common/splitSuccess/index';
import './team.scss'; import './team.scss';
class TreasureTeam extends Component { class TreasureTeam extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
team: [], team: {},
currentMember: {} currentMember: {}
}; };
} }
...@@ -15,6 +19,14 @@ class TreasureTeam extends Component { ...@@ -15,6 +19,14 @@ class TreasureTeam extends Component {
this.initMemberInfo(); this.initMemberInfo();
} }
handleToInvite = () => {
const { history } = this.props;
history.push('/activity/newyear-2019/landing');
if(this.splitInstance) {
this.splitInstance.close();
}
}
initMemberInfo = () => { initMemberInfo = () => {
const { data } = this.props; const { data } = this.props;
let members = data.members; let members = data.members;
...@@ -36,7 +48,7 @@ class TreasureTeam extends Component { ...@@ -36,7 +48,7 @@ class TreasureTeam extends Component {
return classnames( return classnames(
'team-member__item', 'team-member__item',
{ {
'active': id === currentMember.uid && is_open === 1, 'active': id === currentMember.uid && is_open,
} }
); );
} }
...@@ -59,7 +71,28 @@ class TreasureTeam extends Component { ...@@ -59,7 +71,28 @@ class TreasureTeam extends Component {
} }
toSplitTreasure = () => { toSplitTreasure = () => {
const { handleToBindPhone, handleToBindAddress } = this.props;
const { team: {captain_uid, team_num} } = this.state;
http.post(`${API.home}/sys/split_treasure`, {
team_num: team_num,
owner_uid: captain_uid
}).then(res => {
const { code, data } = res.data;
if(code === 200) {
// 拆宝箱弹窗--成功
this.splitInstance = Popup({
title: '恭喜你获得',
skip: 'year',
content: <SplitSuccess handleToInvite={this.handleToInvite} />
});
}else if(code === 12000) {
// 绑定手机号
handleToBindPhone();
}else if(code === 12001) {
// 绑定地址
handleToBindAddress();
}
});
} }
render() { render() {
...@@ -83,7 +116,7 @@ class TreasureTeam extends Component { ...@@ -83,7 +116,7 @@ class TreasureTeam extends Component {
return ( return (
<div className="team-container" data-skip="team"> <div className="team-container" data-skip="team">
{ {
is_captain === 0 && !is_captain &&
<i className="team-friend"></i> <i className="team-friend"></i>
} }
...@@ -93,7 +126,14 @@ class TreasureTeam extends Component { ...@@ -93,7 +126,14 @@ class TreasureTeam extends Component {
? <i className="team-status">组队中..</i> ? <i className="team-status">组队中..</i>
: <i className="team-decorate"></i> : <i className="team-decorate"></i>
} }
<h2 className="team-title">{team_num}号队伍</h2>
{/* 队伍类型 */}
{
is_captain
? <h2 className="team-title">{team_num}号队伍</h2>
: <h2 className="team-title">好友队伍</h2>
}
{/* 队员情况 */} {/* 队员情况 */}
{ {
...@@ -111,39 +151,39 @@ class TreasureTeam extends Component { ...@@ -111,39 +151,39 @@ class TreasureTeam extends Component {
style={this.computedBg(item.head_img)} style={this.computedBg(item.head_img)}
> >
{ {
item.is_captain === 1 && item.is_captain &&
<span className="team-member__captain">队长</span> <span className="team-member__captain">队长</span>
} }
</div> </div>
)) ))
} }
</div> </div>
<div className="team-footer" data-layout={is_open === 1? 'column': 'row'}> <div className="team-footer" data-layout={is_open? 'column': 'row'}>
{/* 队伍未满 */} {/* 队伍未满 */}
{ {
status === 0 && status === 1 &&
<> <>
{ {
is_captain === 1 is_captain
? <button className="team-button" onClick="$emit('to-invite-team')">继续邀请队友</button> ? <Link className="team-button" to="/activity/newyear-2019/landing">继续邀请队友</Link>
: <button className="team-button" onClick="$emit('to-help-team')">帮好友完成组队</button> : <Link className="team-button" to="/activity/newyear-2019/landing">帮好友完成组队</Link>
} }
</> </>
} }
{/* 可拆状态 */} {/* 可拆状态 */}
{ {
(status === 1 && is_open === 0) && (status === 2 && !is_open) &&
<> <>
<span className="team-icon" data-direction="left"></span> <span className="team-icon" data-direction="left"></span>
<span className="team-button--split" onClick={() => this.toSplitTreasure(id)}></span> <span className="team-button--split" onClick={this.toSplitTreasure}></span>
<span className="team-icon" data-direction="right"></span> <span className="team-icon" data-direction="right"></span>
</> </>
} }
{/* 已拆状态 */} {/* 已拆状态 */}
{ {
(status === 1 && is_open === 1) && (status === 2 && is_open) &&
<> <>
<p className="team-prize">{prize_name}</p> <p className="team-prize">{prize_name}</p>
...@@ -232,4 +272,4 @@ class TreasureTeam extends Component { ...@@ -232,4 +272,4 @@ class TreasureTeam extends Component {
} }
} }
export default TreasureTeam; export default withRouter(TreasureTeam);
\ No newline at end of file \ No newline at end of file
...@@ -144,6 +144,8 @@ ...@@ -144,6 +144,8 @@
box-sizing: border-box; box-sizing: border-box;
font-size: 16px; font-size: 16px;
color: #090909; color: #090909;
text-align: center;
line-height: 44px;
background-color: #FFE319; background-color: #FFE319;
} }
......
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