Authored by 李奇

Merge branch 'feature/group-buy-part' into 'feature/group-buy'

Feature/group buy part

merge

See merge request !1683
Showing 33 changed files with 1378 additions and 43 deletions
const {GroupService} = require('../models/group-service');
const {
GroupService
} = require('../models/group-service');
function index(req, res, next) {
req.ctx(GroupService).index()
Promise.all([req.ctx(GroupService).index(),
req.ctx(GroupService).tabData(),
req.ctx(GroupService).filterGroupList()
]).then(result => {
return res.render('group/index', {
title: '有货福利团',
page: 'group',
localCss: true,
nodownload: true,
width750: true,
wechatShare: true,
floors: result[0],
tabs: result[1],
filterList: result[2]
});
}).catch(next);
}
function groupListIndex(req, res, next) {
req.ctx(GroupService).groupList()
.then(result => {
return res.render('group/index', {
title: '有货福利团',
page: 'group',
return res.render('group/group-list', {
title: '拼团列表',
page: 'group-list',
localCss: true,
nodownload: true,
width750: true,
wechatShare: true,
floors: result
activityData: result
});
}).catch(next);
}
function groupList(req, res, next) {
let params = Object.assign({}, req.query);
req.ctx(GroupService).groupList(params)
.then(result => {
return res.render('group/group-list-ajax', {
page: 'group-list',
layout: false,
localCss: true,
nodownload: true,
width750: true,
wechatShare: true,
activityData: result
});
}).catch(next);
}
function progress(req, res, next) {
... ... @@ -29,7 +69,6 @@ function progress(req, res, next) {
floors: result
});
}).catch(next);
}
function goodsDetail(req, res, next) {
... ... @@ -46,6 +85,7 @@ function goodsDetail(req, res, next) {
});
}).catch(next);
}
function order(req, res, next) {
const uid = req.user.uid.toString();
const param = {
... ... @@ -71,6 +111,8 @@ function order(req, res, next) {
module.exports = {
index,
groupListIndex,
groupList,
progress,
goodsDetail,
order
... ...
... ... @@ -23,6 +23,61 @@ class GroupApi extends global.yoho.BaseModel {
return result;
});
}
_getGroupList(params) {
let option = {
data: {
method: 'app.collage.productList.page',
page: params.page || 1,
limit: params.limit || 20,
...params
},
param: {
code: 200
}
};
return this.get(option).then((result => {
let activityData = result.data;
return activityData;
}));
}
_getPromoteCount() {
let option = {
data: {
method: 'app.collage.promoteCount'
},
param: {
code: 200
}
};
return this.get(option).then((result => {
let promoteCount = result.data;
return promoteCount;
}));
}
_getPromoteList(params) {
let option = {
data: {
method: 'app.collage.promoteList',
page: params.page || 1,
limit: params.limit || 20,
...params
},
param: {
code: 200
}
};
return this.get(option).then((result => {
let promoteList = result.data;
return promoteList;
}));
}
/**
* 拼团详情
... ...
const GroupApi = require('./group-api');
const _ = require('lodash');
class GroupService extends global.yoho.BaseModel {
constructor(ctx) {
... ... @@ -18,12 +19,92 @@ class GroupService extends global.yoho.BaseModel {
}
}
async tabData() {
const result = await this.api._getPromoteCount();
let tabsData = {};
let {
newGroup = 0, normalGroup = 0
} = result;
if (+newGroup && +normalGroup) {
tabsData.showTab = true;
}
return tabsData;
}
async filterGroupList(params) {
const initParams = {
page: 1,
limit: 20,
joinLimit: 1
};
let newParams = {
...initParams,
...params
};
const result = await this.api._getPromoteList(newParams);
let finalResult = {};
if (_.get(result, 'list')) {
finalResult = result.list;
_.forEach(finalResult, (val) => {
val.sales_price = val.sales_price ? val.sales_price.toFixed(2) : '';
val.market_price = val.market_price ? val.market_price.toFixed(2) : '';
val.collagePrice = val.collagePrice ? val.collagePrice.toFixed(2) : '';
});
}
return finalResult;
}
async groupList(params) {
const initParams = {
page: 1,
limit: 20
};
let newParams = {
...initParams,
...params
};
console.log(newParams);
try {
const result = await this.api._getGroupList(newParams);
let finalResult = {};
if (result.banner && result.banner.length > 0) {
let imagePath = result.banner;
let imageUrl = result.jumpUrl;
finalResult.banner = {
imageUrl,
imagePath
};
}
if (_.get(result, 'collageProductVoList')) {
finalResult.activityList = result.collageProductVoList;
_.forEach(finalResult.activityList, (val) => {
val.salesPrice = val.salesPrice ? val.salesPrice.toFixed(2) : '';
val.marketPrice = val.marketPrice ? val.marketPrice.toFixed(2) : '';
val.collagePrice = val.collagePrice ? val.collagePrice.toFixed(2) : '';
});
}
return finalResult;
} catch (e) {
throw new Error('Group list fail to load resources.');
}
}
async goodsDetail() {
// const goodsDetail = await this.api._getGoodsInfo({})
return {};
}
async order({ type, page, limit }) {
async order({
type,
page,
limit
}) {
try {
const result = await this.api.getOrderList({
limit,
... ...
... ... @@ -159,10 +159,10 @@ router.post('/vip-day/msg/save.json', vipDay.beforeIn, vipDay.saveMsg);
router.get('/vip-day/msg/fetch.json', vipDay.fetchMsg);
router.get('/coin/sendCoin', coin.sendCoin);
router.get('/shopCollect', shopCollect.shopIndex);// 店铺收藏
router.get('/shopList', shopCollect.shopList);// 店铺收藏列表
router.get('/shopNav', shopCollect.shopNav);// 店铺收藏导航
router.get('/shopfavStatus', shopCollect.shopFav);// 店铺收藏状态
router.get('/shopCollect', shopCollect.shopIndex); // 店铺收藏
router.get('/shopList', shopCollect.shopList); // 店铺收藏列表
router.get('/shopNav', shopCollect.shopNav); // 店铺收藏导航
router.get('/shopfavStatus', shopCollect.shopFav); // 店铺收藏状态
router.get('/single-day', singleDay.singleDay);
router.get('/single-day/getSingleData', singleDay.getSingleData);
... ... @@ -367,6 +367,8 @@ router.post('/yoluck/detail/mylist.html', yoluck.getActivityCodeList);
// 拼团
router.get('/group', group.index); // 拼团首页
router.get('/group/list', group.groupListIndex); // 拼团列表页
router.get('/group/goods-list', group.groupList); // 拼团列表
router.get('/group/progress', auth, group.progress); // 拼团状态详情页
router.get('/group/goodsDetail/:id', group.goodsDetail);
router.get('/group/order', auth, group.order); // 我的拼团
... ...
{{#each activityData.activityList}}
{{> group/group-list-item}}
{{/each}}
\ No newline at end of file
... ...
<div class="container">
{{#if activityData.banner}}
<a href="{{activityData.banner.imageUrl}}" class="img-wrapper">
<img class="img" src="{{activityData.banner.imagePath}}" alt="" style="display:block">
</a>
{{/if}}
<div id="goodsContainer">
<div class="goods-list">
{{#each activityData.activityList}}
{{> group/group-list-item}}
{{/each}}
</div>
</div>
</div>
<a class="my-group my-group-handler" href="/activity/group/progress">我的拼团</a>
<div class='my-share'></div>
\ No newline at end of file
... ...
<div class="group">
<div class="resources">
{{#each floors}}
{{#ifcond template_name "==" 'focus'}}
{{> group/resources/focus}}
{{/ifcond}}
{{#ifcond template_name "==" 'newSingleImage'}}
{{> group/resources/new-single-image}}
{{/ifcond}}
{{#ifcond template_name "==" 'focus'}}
{{> group/resources/focus}}
{{/ifcond}}
{{#ifcond template_name "==" 'newSingleImage'}}
{{> group/resources/new-single-image}}
{{/ifcond}}
{{#ifcond template_name "==" 'twoPicture'}}
{{> group/resources/two-image}}
{{/ifcond}}
{{#ifcond template_name "==" 'image_list'}}
{{> group/resources/four-image}}
{{/ifcond}}
{{#ifcond template_name "==" 'splitJointImg'}}
{{> group/resources/split-image}}
{{/ifcond}}
{{#ifcond template_name "==" 'collageBuyPrdList'}}
{{> group/resources/collage-buy-prd-list}}
{{/ifcond}}
{{/each}}
<div id='fixedTab' class="tab-filter">
{{!-- {{#if floatTab}} float{{/if}}{{#if !tabs.showTab}} only-filter{{/if}} --}}
{{#if tabs.showTab}}
<div class="tab">
<div class="tab-item">
<div class="tiptext active" data-channel="newGroup">邀新团</div>
{{!-- {{#if isNewGroup}} --}}
<div class="tab-line"></div>
{{!-- {{/if}} --}}
</div>
<div class="tab-item">
<div class="tiptext" data-channel="normalGroup">普通团</div>
{{!-- {{#if !isNewGroup}} --}}
{{!-- <div class="tab-line"></div> --}}
{{!-- {{/if}} --}}
</div>
</div>
{{/if}}
{{> group/resources/filter-tab}}
</div>
{{#if filterList.length}}
<div class="group-list">
{{#each filterList}}
{{> group/resources/filter-list-item}}
{{/each}}
</div>
{{/if}}
</div>
<a class="bottom" href="/activity/group/progress">我的拼团</a>
</div>
</div>
\ No newline at end of file
... ...
<div class='cell groupListCellTapped' data-product-skn="{{productSkn}}" data-activity-id="{{activityId}}">
<div class='left'>
<img class="activity-image" src="{{image2 defaultImages w=324 h=432 q=60 mode=3}}"></img>
</div>
<div class='right'>
{{#ifcond joinLimit "==" '1'}}
<div class='new-name-tag'>
</div>
{{/ifcond}}
<div class='title-view'>
<p class="title">{{productName}}</p>
</div>
<div class='price-view'>
<div class="tip hide">
<p class='tip-text'>{{peopleNum}}人团</p>
</div>
<p class="price1">¥{{collagePrice}}</p>
<p class="price2">¥{{marketPrice}}</p>
</div>
{{#ifcond showType "==" '2'}}
<div class='group-start-time'>{{beginTimeText}} 开始</div>
<div class='button-view'>
<p class="btn1">{{peopleNum}}人成团</p>
<p class="btn2">即将开始</p>
</div>
{{/ifcond}}
{{#ifcond showType "!==" '2'}}
{{#if joinPeopleNum}}
<div class='group-num'>{{joinPeopleNum}} 人已參加</div>
{{/if}}
<div class='button-view'>
<p class="button1">{{peopleNum}}人成团</p>
<p class="button2">立即购买</p>
</div>
{{/ifcond}}
</div>
</div>
\ No newline at end of file
... ...
{{#data.data}}
{{#if prdList}}
<div class="resource-collage-buy-prd-list">
{{#each prdList}}
<div id="{{../../template_id}}" name="{{../../template_intro}}" class="product-item" data-product-skn="{{productSkn}}"
data-activity-id="{{activityId}}">
<img src="{{image2 defaultImages w=188 h=250 q=60 mode=3}}"></img>
<div class="product-name">{{brandName}}</div>
<div class='product-price-wrap'>
<span class='product-price'>{{formatCollagePrice}}</span>
<span class='product-market-price'>{{marketPrice}}</span>
</div>
<div class='product-joinnum'>{{collagedPersonNum}} 人已拼</div>
</div>
{{/each}}
</div>
{{/if}}
{{/data.data}}
\ No newline at end of file
... ...
<div class="group-product-cell-bg" data-group-product="{{group_product}}" data-item-idx="{{itemIdx}}">
<div class="group-product-header">
<div class="group-product-left-icon">
<span class="group-product-left-icon-number">{{people_num}}人团</span>
</div>
<img class="group-product-image" src="{{image2 default_images w=400 h=390 q=60 mode=3}}"></img>
</div>
<div class="group-product-name">{{product_name}}</div>
<div class="group-price">
<div class="group-prict-bg">
<span class="group-price-market">{{market_price_str}}</span>
<span class="group-price-collage">{{collage_price_str}}</span>
</div>
<div class="group-free-post"></div>
</div>
</div>
\ No newline at end of file
... ...
<ul id="list-nav" class="list-nav filter-nav clearfix">
{{!-- <li class="default active first-li-more">
<a href="javascript:void(0);">
<span class="span-test">默认</span>
<span class="iconfont drop">&#xe613;</span>
</a>
</li> --}}
<li class="new active" data-order="s_t_desc">
<a href="javascript:void(0);">
<span class="span-test">新品</span>
</a>
</li>
<li class="popularity" data-order="h_v_desc">
<a href="javascript:void(0);">
<span class="span-test">人气</span>
</a>
</li>
<li class="price">
<a href="javascript:void(0);">
<span class="span-test">价格</span>
<span class="icon">
<i class="iconfont up cur" data-order="s_p_asc">&#xe615;</i>
<i class="iconfont down" data-order="s_p_desc">&#xe616;</i>
</span>
</a>
</li>
<li class="filter">
<a href="javascript:void(0);">
<span class="span-test">筛选</span>
<span class="iconfont cur">&#xe613;</span>
</a>
</li>
</ul>
\ No newline at end of file
... ...
{{#data}}
<div class="resource-four-image">
{{#each list}}
<div class="img-item">
<a href="{{url}}" id="{{../template_id}}" name="{{../template_intro}}">
<img src="{{image2 src w=400 h=400 q=60 mode=3}}"></img>
</a>
</div>
{{/each}}
</div>
{{/data}}
\ No newline at end of file
... ...
{{#if singleOne}}
{{#data}}
<div class="banner-list">
<a href="{{url}}" id="{{../template_id}}" name="{{../template_intro}}" rel="nofollow">
<img src="{{image2 src w=imageWidth h=imageHeight q=60 mode=3}}" alt="活动图片">
</a>
</div>
{{/data}}
{{else}}
{{#data}}
<div class="banner-center banner-center-swiper">
<ul class="banner-list swiper-wrapper clearfix">
{{#list}}
<li class="swiper-slide">
<a href="{{url}}" id="{{../../template_id}}" name="{{../../template_intro}}" rel="nofollow">
<img src="{{image2 src w=../imageWidth h=../imageWidth q=60 mode=3}}" alt="活动图片">
</a>
</li>
{{/list}}
</ul>
<div class="swiper-pagination" {{#unless singleOne}}style="display:block"{{/unless}}>
<div class="pagination-inner">
<div class="resource-single">
{{#if title}}
<div class="title">
<div class='line'></div>
<div class='text'>{{title}}</div>
</div>
{{/if}}
{{#list}}
{{#if @first}}
<a href="{{url}}" id="{{../../template_id}}" name="{{../../template_intro}}">
<img src="{{image2 src w=../imageWidth h=../imageHeight q=60 mode=3}}"></img>
</a>
{{/if}}
{{/list}}
</div>
</div>
{{/data}}
{{/if}}
{{/data}}
\ No newline at end of file
... ...
{{#data}}
<div class="split-image" {{#ifcond ../is_extend '!==' '1'}}style="margin: 0 15px"{{/ifcond}}>
<img src="{{image2 src w=../image_width h=../image_height q=60 mode=3}}"></img>
<div class='url-content'>
{{#each urls}}
<div class="split-item">
<a href="{{this}}" id="{{../../template_id}}" name="{{../../template_intro}}">
<div class='placeholder'></div>
</a>
</div>
{{/each}}
</div>
</div>
{{/data}}
\ No newline at end of file
... ...
{{#data}}
<div class="resource-two-image">
{{#each list}}
<div class="img-item">
<a href="{{url}}" id="{{../template_id}}" name="{{../template_intro}}">
<img src="{{image2 src w=../imageWidth h=../imageHeight q=60 mode=3}}"></img>
</a>
</div>
{{/each}}
</div>
{{/data}}
\ No newline at end of file
... ...
import 'scss/activity/group/group-list.page.scss';
import $ from 'yoho-jquery';
import Page from 'js/yoho-page';
import qs from 'yoho-qs';
import ProductListLoader from './group/group-list';
class ProductList extends Page {
constructor() {
super();
this.selector = {
$goodsContainer: $('.goods-list'),
$detailTarget: $('.groupListCellTapped')
};
this.firstScreen = this.selector.$goodsContainer.children().size() > 0;
if (!this.firstScreen) {
this.selector.$goodsContainer.html('<div>暂未查询到数据!</div>');
}
let initParams = {
page: 2
};
if (qs) {
$.extend(initParams, qs);
}
new ProductListLoader(initParams, '/activity/group/goods-list', {
scrollActived: this.firstScreen
});
this.bindEvents();
}
bindEvents() {
this.selector.$detailTarget.on('click', this.detail.bind(this));
}
detail(e) {
let $this = $(e.currentTarget);
let productSkn = $this.data('product-skn');
let activityId = $this.data('activity-id');
console.log(productSkn, activityId);
this.ajax({
url: '/activity/group/progress',
data: {
productSkn,
activityId
},
}).then((result) => {
if (result && result.code) {
console.log(result);
}
}).catch(error => {
console.error(error);
});
}
}
$(() => {
new ProductList();
});
... ...
import 'scss/activity/group/group.page.scss';
import Swiper from 'yoho-swiper';
import $ from 'yoho-jquery';
import Page from 'js/yoho-page';
class Group extends Page {
constructor() {
super();
this.selector = {};
this.swiperTop();
}
bindEvents() {}
// 顶部swiper
swiperTop() {
if ($('.banner-swiper').find('li').size() > 1) {
new Swiper('.banner-swiper', {
lazyLoading: true,
lazyLoadingInPrevNext: true,
loop: true,
autoplay: 3000,
autoplayDisableOnInteraction: false,
paginationClickable: true,
slideElement: 'li',
pagination: '.banner-top .pagination-inner'
});
}
}
}
$(() => {
new Group();
});
... ...
const engine = require('store/src/store-engine');
const storages = [
require('store/storages/sessionStorage')
];
const plugins = [
require('store/plugins/defaults'),
require('store/plugins/expire')
];
const store = engine.createStore(storages, plugins);
module.exports = {
get: (...params) => {
return store.enabled ? store.get(...params) : false;
},
set: (...params) => {
return store.enabled ? store.set(...params, new Date().getTime() + 180000) : false;
}
};
... ...
const cacheStore = require('./cache-store');
class ProductListLoader {
constructor(params, url, extra) {
this.scrollActived = extra && typeof extra.scrollActived !== 'undefined' ?
extra.scrollActived : true; // 是否激活滚动加载,默认激活
this.params = params;
this.view = {
goodsContainer: $('#goodsContainer'),
container: $('#goodsContainer').children('.goods-list')
};
// this.url = location.protocol + '//m.yohobuy.com/' + url;
this.url = url;
this.beforeScroll = document.body.scrollTop; // 滚动前位置记录
this.defaultOpt = Object.assign({}, this.params); // 默认参数
this.isScrollLoad = false; // 是否是滚动加载
this.page = params.page || 1;
this.isLoadMore = true; // 是否继续请求数据
let self = this;
/**
* 滚动加载
*/
window.onscroll = function() {
if (self.scrollActived) {
setTimeout(function() {
let afterScroll = window.scrollY;
if (afterScroll - self.beforeScroll > 0) {
window.requestAnimationFrame(() => {
self.scrollHandler();
});
self.beforeScroll = afterScroll;
} else {
self.beforeScroll = afterScroll;
return false;
}
}, 5);
}
};
}
/**
* 当scroll到1/2$goodsContainer高度后继续请求下一页数据
*/
scrollHandler() {
let goodsContainerHeight = this.view.container.height();
if ($(window).scrollTop() > goodsContainerHeight * 0.6) {
this.isScrollLoad = true;
this.getGoodsList();
}
}
dataRender(result) {
// 去掉正在加载
$('.search-divide').remove();
let noResult = !result || !result.length ||
result.length < 1 ||
(result.list && result.list.length < 1);
// 没有结果输出没有结果页面
if (noResult) {
if (this.isScrollLoad) {
this.view.container.after(() => {
return '<div class="search-divide">没有更多内容了...</div>';
});
} else {
this.view.container.html('<div>未查询到数据!</div>');
}
this.isLoadMore = false;
return false;
}
if (this.isScrollLoad) {
this.view.container.append(result);
} else {
this.view.container.html(result);
}
}
/**
* 获取商品列表
*/
getGoodsList(params) {
Object.assign(this.defaultOpt, {
page: this.page++
});
// 有参数,参数优先,滚动加载相关参数重置
if (params) {
Object.assign(this.defaultOpt, params);
if (params.page) {
this.page = params.page + 1;
}
this.isScrollLoad = false;
this.beforeScroll = document.body.scrollTop;
}
let catchKey = this.url + '?' + $.param(this.defaultOpt);
if (!this.isLoadMore) {
return false;
}
$.ajax({
type: 'GET',
url: this.url,
data: this.defaultOpt,
xhrFields: {
withCredentials: true
},
beforeSend: () => {
let cacheData = cacheStore.get(catchKey);
if (cacheData) {
this.dataRender(cacheData);
return false;
}
if ($('.search-divide').length > 0) {
$('.search-divide').remove();
}
this.view.container.after(() => {
return '<div class="search-divide">正在加载...</div>';
});
},
success: (result) => {
this.dataRender(result);
if (result && result.length) {
cacheStore.set(catchKey, result);
}
},
error: () => {
let $divide = $('.search-divide');
$divide.text('加载失败,点击重试');
$divide.one('click', () => {
$divide.text('正在加载...');
this.getGoodsList();
});
}
});
}
}
module.exports = ProductListLoader;
... ...
.group-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
margin-left: 20px;
margin-right: 20px;
margin-bottom: 100px;
}
.group-product-image {
width: 322px;
height: 430px;
}
.group-product-cell-bg {
margin-top: 20px;
}
.group-product-header {
position: relative;
}
.group-product-left-icon {
position: absolute;
top: 10px;
width: 88px;
height: 40px;
left: -12px;
font-size: 22px;
background: url("img/activity/group/group/tab@3x.png") no-repeat;
background-size: contain;
}
.group-product-left-icon-number {
display: inline-block;
color: #fff;
font-size: 22px;
margin-left: 12px;
margin-top: 10px;
}
.group-product-name {
width: 322px;
height: 56px;
line-height: 28px;
font-size: 20px;
color: #444;
margin-top: 24px;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
white-space: normal !important;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.group-price {
display: flex;
flex-direction: row;
align-items: center;
}
.group-price-market {
text-decoration: line-through;
padding-right: 15px;
}
.group-price-collage {
font-size: 32px;
color: #d0021b;
font-weight: bold;
}
.group-prict-bg {
font-size: 22px;
color: #444;
}
.group-free-post {
width: 60px;
height: 40px;
margin-left: 20px;
background: url("img/activity/group/group/free-post@3x.png") no-repeat;
background-size: contain;
}
... ...
.banner-top {
position: relative;
margin-bottom: -2PX;
.swiper-pagination {
position: absolute;
left: 0;
right: 0;
bottom: 20px;
text-align: center;
z-index: 1;
.pagination-inner {
display: inline-block;
padding: 0 8px 4px;
background: rgba(0, 0, 0, 0.2);
border-radius: 50px;
line-height: 1.2;
span {
display: inline-block;
width: 14px;
height: 14px;
background: #fff;
opacity: 0.5;
margin: 0 9px;
border-radius: 50%;
&.swiper-pagination-bullet-active {
background: #fff;
opacity: 1;
}
}
}
}
}
.banner-swiper {
position: static;
max-height: 312px;
ul {
position: relative;
max-height: 312px;
li {
float: left;
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
}
}
}
}
... ...
.resource-collage-buy-prd-list {
width: 100%;
height: 440px;
padding-top: 20px;
white-space: nowrap;
box-sizing: border-box;
overflow-x: auto;
.product-item {
display: inline-block;
margin-left: 30px;
font-size: 0;
width: 188px;
&:last-child {
margin-right: 30px;
}
}
.product-name {
text-align: center;
font-size: 24px;
padding-bottom: 20px;
padding-top: 20px;
overflow: hidden;
text-overflow: ellipsis;
}
.product-price-wrap {
text-align: center;
}
.product-price {
font-size: 24px;
color: #d0021b;
letter-spacing: 0;
font-weight: 500;
}
.product-market-price {
font-size: 18px;
color: #b0b0b0;
letter-spacing: 0;
margin-left: 10px;
text-decoration: line-through;
}
.product-joinnum {
font-size: 18px;
color: #b0b0b0;
letter-spacing: 0;
margin-top: 16px;
text-align: center;
}
}
... ...
.resource-four-image {
display: flex;
width: 750px;
padding: 20px 30px !important;
box-sizing: border-box;
font-size: 0;
.img-item {
flex: 1;
}
}
... ...
.resource-single {
width: 100%;
font-size: 0;
.title {
height: 80px;
line-height: 80px;
}
.line {
display: inline-block;
width: 4px;
height: 30px;
background-color: #444;
margin-left: 20px;
margin-top: 25px;
}
.text {
display: inline-block;
text-align: left;
color: #444;
font-size: 30px;
margin-left: 16px;
font-weight: 600;
vertical-align: top;
}
}
... ...
.split-image {
font-size: 0;
box-sizing: border-box;
position: relative;
overflow: hidden;
.url-content {
position: absolute;
display: flex;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 111;
.split-item {
position: relative;
flex: 1;
.placeholder {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
}
}
... ...
.resource-two-image {
display: flex;
width: 100%;
padding: 0 30px !important;
font-size: 0;
box-sizing: border-box;
.img-item {
flex: 1;
}
}
... ...
@import "tabs";
.container {
margin-bottom: 90px;
}
.hide {
display: none;
}
.tip-text {
font-size: 18px;
color: #fff;
text-align: center;
flex: 1;
}
.search-divide {
height: 50px;
width: 100%;
padding: 10px 0;
color: #ccc;
text-align: center;
}
.img-wrapper {
width: 100%;
height: 380px;
border: 1px solid yellowgreen;
}
.my-share {
position: fixed;
bottom: 200px;
right: 4%;
width: 88px;
height: 88px;
background-image: url("img/activity/group/group/share-copy@3x.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.cell {
width: 100%;
height: 300px;
display: flex;
flex-direction: row;
align-items: center;
}
.left {
width: 230px;
height: 300px;
display: flex;
justify-content: flex-end;
}
.activity-image {
width: 200px;
height: 260px;
margin-top: 20px;
margin-right: 0;
}
.right {
position: relative;
width: 490px;
height: 260px;
}
.new-name-tag {
float: left;
margin-top: 18px;
margin-left: 20px;
height: 30px;
width: 80px;
display: flex;
align-items: center;
justify-content: center;
background-image: url("img/activity/group/group/ptj_yxk.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.name-tag {
height: 28px;
width: 80px;
}
.title-view {
float: left;
margin-top: 10px;
margin-left: 20px;
height: wrap;
}
.title {
font-size: 28px;
line-height: 38px;
color: #444;
word-break: break-all;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.price-view {
position: absolute;
bottom: 44%;
width: 470px;
height: 40px;
margin-left: 20px;
display: flex;
flex-direction: row;
align-items: flex-end;
}
.icon {
width: 80px;
height: 28px;
margin-bottom: 3px;
}
.tip {
width: 80px;
height: 28px;
margin-bottom: 3px;
background-color: #d00218;
}
.price1 {
font-size: 36px;
color: #d0021b;
line-height: 35px;
text-align: end;
font-weight: bold;
}
.price2 {
font-size: 24px;
margin-left: 16px;
line-height: 28px;
color: #b0b0b0;
text-align: end;
text-decoration: line-through;
}
.button-view {
position: absolute;
bottom: 0;
width: 470px;
height: 60px;
margin-left: 20px;
display: flex;
justify-content: flex-end;
align-items: center;
}
.group-num {
position: absolute;
bottom: 10px;
margin-left: 20px;
color: #444;
font-size: 24px;
text-align: center;
}
.group-start-time {
position: absolute;
bottom: 10px;
margin-left: 20px;
color: #d0021b;
font-size: 24px;
text-align: center;
}
.button1 {
width: 120px;
height: 60px;
font-size: 24px;
color: #d0021b;
border: 1px solid;
border-color: #d0021b;
border-bottom-left-radius: 50px;
border-top-left-radius: 50px;
line-height: 60px;
text-align: center;
background: white;
}
.button2 {
width: 120px;
height: 60px;
font-size: 24px;
color: white;
border: 1px solid;
border-color: #d0021b;
border-bottom-right-radius: 50px;
border-top-right-radius: 50px;
text-align: center;
line-height: 60px;
background: #d0021b;
}
.btn1 {
width: 120px;
height: 60px;
font-size: 24px;
color: #444;
border: 1px solid;
border-color: #444;
border-bottom-left-radius: 50px;
border-top-left-radius: 50px;
line-height: 60px;
text-align: center;
background: white;
}
.btn2 {
width: 120px;
height: 60px;
font-size: 24px;
color: white;
border: 1px solid;
border-color: #444;
border-bottom-right-radius: 50px;
border-top-right-radius: 50px;
text-align: center;
line-height: 60px;
background: #444;
}
.my-group {
position: fixed;
right: 0;
bottom: 0;
left: 0;
height: 90px;
padding: 0;
margin: 0;
background-color: #fff;
font-size: 28px;
color: #444;
letter-spacing: 0;
font-weight: 500;
text-align: center;
line-height: 90px;
border-top: 1px solid #e0e0e0;
z-index: 999;
border-radius: 0 !important;
&:after {
border-radius: 0;
border: none;
}
}
.button-hover {
opacity: 1;
}
... ...
@import "~scss/layout/swiper";
@import "floor/single-image";
@import "floor/banner-top";
@import "floor/four-image";
@import "floor/two-image";
@import "floor/split-image";
@import "floor/collage-buy-list";
@import "tabs";
@import "filter-list";
.group {
.resources {
margin-bottom: 90px;
}
.bottom {
position: fixed;
right: 0;
... ... @@ -9,6 +23,72 @@
line-height: 90px;
font-size: 28px;
color: #444;
background-color: #fff;
border-top: 1px solid #e0e0e0;
}
.tab {
width: 100%;
height: wrap;
display: flex;
flex-direction: row;
align-items: center;
background-color: white;
z-index: 1000;
border-bottom: 1px solid #e0e0e0;
border-top: 10px solid #f0f0f0;
.tab-item {
position: relative;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
height: 80px;
justify-content: center;
}
}
.tiptext {
font-size: 32px;
color: #b0b0b0;
flex: 1;
width: wrap;
text-align: center;
height: 100%;
display: flex;
flex-wrap: wrap;
align-content: center;
flex-direction: row;
align-items: center;
font-weight: 500;
}
.tiptext.active {
color: #444;
}
.tab-line {
position: absolute;
bottom: -2px;
left: 50%;
background-color: black;
width: 180px;
height: 4px;
transform: translateX(-50%);
}
.tab-filter.float {
position: fixed;
top: -22px;
left: 0;
right: 0;
border-top: none;
z-index: 998;
background-color: #fff;
}
.tab-filter.float.only-filter {
top: -1px;
}
}
... ...
.list-nav {
border-top: 2px solid #fff;
border-bottom: 1px solid #e6e6e6;
> li {
float: left;
width: 25%;
height: 33PX;
line-height: 33PX;
text-align: center;
font-size: 14PX;
}
a {
display: block;
box-sizing: border-box;
width: 100%;
height: 100%;
color: #999;
}
.nav-txt {
display: inline-block;
height: 100%;
box-sizing: border-box;
}
.active > a {
color: #000;
.iconfont {
color: #999;
&.cur {
color: #000;
}
}
}
.new .iconfont {
transform: scale(0.8);
font-weight: bold;
font-size: 12PX;
}
.filter .iconfont {
font-size: 12PX;
transition: transform 0.1 ease-in;
}
.filter.active .iconfont {
transform: rotate(-180deg);
}
.icon {
position: relative;
i {
position: absolute;
transform: scale(0.8);
font-weight: bold;
}
.up {
top: -11PX;
}
.down {
top: -4PX;
}
}
}
... ...