react-app-shell
Version:
react打包脚本和example, 这里的版本请忽略
316 lines (293 loc) • 10.6 kB
JavaScript
import React, { Component } from 'react';
import { observer, inject } from 'mobx-react';
import moment from 'moment';
import classNames from 'classnames';
import _ from 'lodash';
import { JOIN_STATUS, GROUP_STATUS, MEMBERTYPE } from '../../../constants';
import EndCountDown from './end-count-down';
import styles from './styles.less';
import headerImg from '../../../public/images/group/header.png';
const DEFAULT_SHOW_MUMBER = 5; // 团购成员默认展示的人数
/**
* 开团进度
*/
(({ groupStore }) => {
const groupInfo = groupStore.groupInfo;
const teamData = groupStore.teamData || {};
return {
// 数据
/**
* 参团/开团 状态
* NOT_JOIN: 'NOT_JOIN', // 未参加过团购, 未登录时无法获取用户身份 所以也判定是未参加团购
* MY_TEAM: 'MY_TEAM', // 自己参加的team
* OTHER_TEAM: 'OTHER_TEAM', // 别人开的team
* SINGLE_BUY: 'SINGLE_BUY', // 单独购买
*/
teamData,
joinStatus: groupStore.joinStatus,
groupStatus: groupStore.state.groupStatus, // 团购活动状态: 未知, 未开始, 活动中, 已结束
userId: groupStore.state.userId, // 当前登录用户的Id
serverTime: groupStore.state.serverTime, // 服务器时间
isFull: groupStore.isFull, // 是否满团
memberType: teamData.memberType, // 参团角色
// nowTeamNum: groupStore.state.nowTeamNum, // 当前参团人数
steppedRewardBonusNum: groupStore.state.steppedRewardBonusNum, // 团长显示魔力币
steppedRewardPersonNum: groupStore.state.steppedRewardPersonNum, // 团长显示超出人数
steps: groupInfo.courseStep || {}, // 档位信息
members: teamData.members || [], // 参团人员
isAllowFullJoin: !!groupInfo.isAllowFullJoin || false, // 超出参团人数上限时 是否还允许参团 (0有满团限制 1 没有满团限制)
startTime: groupInfo.startTime || 0, // 活动开始时间, 时间戳
endTime: groupInfo.endTime || 0 // 活动结束时间, 时间戳
};
})
export default class Progress extends Component {
state = {
collapse: true // 默认收起
};
/**
* 修改 Collapse状态
*/
handleUpCollapse = () => {
this.setState({
collapse: !this.state.collapse
});
};
/**
* 对象转数组 key value 并且排序
* @param {*} obj
*/
objectToArray(obj) {
const arrs = [];
_.mapKeys(obj, (value, key) => {
arrs.push({
key: parseInt(key, 10),
value: value
});
});
_.sortBy(arrs, (o) => {
return o.key;
});
return arrs;
}
/**
* 展示活动进度步骤
*/
renderStep = () => {
const {
steps,
joinStatus,
members,
groupStatus,
isAllowFullJoin,
memberType,
steppedRewardPersonNum,
teamData,
userId
} = this.props;
const stepData = this.objectToArray(steps);
let isShowStage = false; // 是否显示团购的进度
let step = 0;
const lastStep = _.last(stepData); // 最后一个step
// 1.根据当前参团人数 展示进度
// 2.活动状态 已结束/未开始/单独购买 不展示当前进度
// 3.step第一个展示为:团长开团
// 3.超出参团人数上限时 是否还允许参团 允许的情况:最后一个step 文案:xx人及以上
// 不是单独购买 and 团购的状态是进行中 and 已经开团
if (
joinStatus !== JOIN_STATUS.SINGLE_BUY &&
groupStatus === GROUP_STATUS.ACTIVE &&
!!members.length
) {
isShowStage = true;
// 如果当前角色是团长并且参团人数比阶段人数多 会展示魔力币并且阶段在魔力币上
if (
memberType === MEMBERTYPE.LEADER &&
(steppedRewardPersonNum && members.length >= steppedRewardPersonNum) &&
(members.length && members[0].userId === userId)
) {
step = 0;
} else {
if (members.length >= lastStep.key) {
step = lastStep.key;
} else {
for (let index = 0; index < stepData.length; index++) {
const item = stepData[index];
if (members.length < item.key) {
step = stepData[index - 1].key;
break;
}
}
}
}
}
// 团购进度图标
let finishClass = '';
const className = stepData.length === 3 ? 'progress-item-33p' : 'progress-item';
let stepText = '';
return stepData.map((item, index) => {
stepText = `${item.key}人成团`;
if (isShowStage) {
finishClass = item.key === step ? 'progress-icon-finish' : ''; // 这里判断当前是第几步
stepText = index === 0 ? `团长开团` : stepText;
}
// 超出参团人数上限时 是否还允许参团
if (isAllowFullJoin && item.key === lastStep.key) {
stepText = `${item.key}人及以上`;
}
// 参团人数展示文字过滤
const num = item.key - members.length <= 0 ? stepText : `还差${item.key - members.length}人`;
// 判断teamInfo接口是否返回值
const status = !Object.keys(teamData).length;
let alone = false;
if (members.length && members[0].productType === 1) alone = true;
return (
<div key={item.key} className={styles[className]}>
<div className={classNames(styles['progress-icon'], styles[finishClass])}></div>
<p>
<span>{alone ? stepText : status ? stepText : item.key <= step ? stepText : num}</span>
<span> 每人{item.value}课时 </span>
</p>
</div>
);
});
};
/**
* 团长多余显示魔力币
*/
renderLeader = () => {
const {
memberType,
steppedRewardBonusNum,
steppedRewardPersonNum,
members,
userId
} = this.props;
let person = '';
let bonus = '';
// 参团人数 及 魔力币 展示文字过滤
if (steppedRewardPersonNum - members.length <= 0) {
person = `${steppedRewardPersonNum}人及以上`;
bonus = `成功获得${steppedRewardBonusNum}魔力币`;
} else {
person = `还差${steppedRewardPersonNum - members.length}人`;
bonus = `额外获得${steppedRewardBonusNum}魔力币`;
}
const finishClass = members.length >= steppedRewardPersonNum ? 'progress-icon-finish' : ''; // 这里判断当前是第几步
const Purchase = members.length && members[0].productType; // 单独购买 1: 团购 2: 单独购买
// 团长才显示此逻辑: memberType是团长 && 单独购买 && 有魔力币 && 团长属于当前团
if (
memberType === MEMBERTYPE.LEADER &&
Purchase === 2 &&
steppedRewardPersonNum &&
(members.length && members[0].userId === userId)
) {
return (
<div className={styles['progress-item-33p']}>
<div className={classNames(styles['progress-icon'], styles[finishClass])}></div>
<p>
<span> {person}</span>
<span> {bonus} </span>
</p>
</div>
);
}
return null;
};
/**
* 展示团购状态
*/
renderGroupState = () => {
const { joinStatus, groupStatus, endTime, serverTime } = this.props;
let element = null;
// 已经单独购买课程
if (joinStatus === JOIN_STATUS.SINGLE_BUY) {
element = (
<div className={styles['bought-course']}> 你已单独购买过课程, 赶紧去约课吧! </div>
);
} else {
switch (groupStatus) {
case GROUP_STATUS.UNKNOWN:
case GROUP_STATUS.NOT_BEGIN:
// 未开始 and 未开始
element = <div className={styles['button-normal']}> 活动未开始, 敬请期待 </div>;
break;
case GROUP_STATUS.ACTIVE:
// 活动中
element = (
<EndCountDown endTime={endTime} serverTime={serverTime}>
{' '}
</EndCountDown>
);
break;
case GROUP_STATUS.END:
// 已结束
element = <div className={styles['button-normal']}> 活动已结束 </div>;
break;
default:
break;
}
}
return element;
};
/**
* 展示参团列表
*/
renderMembers = () => {
const { members, isAllowFullJoin, isFull, joinStatus } = this.props;
const { collapse } = this.state;
// 单独购买或没有参团人员 不展示列表
if (members.length < 1 || joinStatus === JOIN_STATUS.SINGLE_BUY) return null;
const showMembers = collapse ? _.take(members, DEFAULT_SHOW_MUMBER) : members;
const teams = showMembers.map((item, index) => {
return (
<div className={styles['team-item']} key={item.userId}>
<div className={styles['team-item-image']}>
<img src={item.headImageUrl || headerImg} alt="成员" />
{item.memberType === 1 ? <span className={styles['commander']}>团长</span> : null}
</div>
<div className={styles['team-item-info']}>
<p className={styles['name']}>{item.nickName.replace(/CAPATER_AND_00100100/g, '&')}</p>
</div>
<div className={styles['team-item-time']}>
<span>{moment(item.createTime).format('YYYY-MM-DD HH:mm')}</span>
</div>
</div>
);
});
return (
<div className={styles['team-wrapper']}>
<div className={styles['team-member-count']}>{`已有${members.length}人成团`}</div>
{/* 团员是否已满并且不允许满团参团 */}
{!isAllowFullJoin && isFull ? <div className={styles['team-full']}></div> : null}
<div className={styles['team-list']}>
{teams}
{members.length > DEFAULT_SHOW_MUMBER ? (
<div className={styles['expand']}>
<div className={styles['expand-btn']} onClick={this.handleUpCollapse}>
{!collapse ? '点击关闭全部' : '点击展开全部'}
</div>
</div>
) : null}
</div>
</div>
);
};
render() {
return (
<div className={styles['group-progress']}>
<div className={styles['innercon']}>
<div className={styles['progress-title']}> 活动进度</div>
<div className={styles['progress-desc']}>
<div className={styles['progress-list']}>
{this.renderStep()}
{this.renderLeader()}
</div>
</div>
{this.renderGroupState()}
</div>
{this.renderMembers()}
</div>
);
}
}