Toggle navigation
Toggle navigation
This project
Loading...
Sign in
fe
/
yohobuy-node
·
Commits
Go to a project
GitLab
Go to group
Project
Activity
Files
Commits
Pipelines
0
Builds
0
Graphs
Milestones
Issues
1
Merge Requests
0
Members
Labels
Wiki
Forks
Network
Create a new issue
Download as
Plain Diff
Browse Files
Authored by
htoooth
8 years ago
Commit
e232f769c68c3d94e5daebde7600f1950eef989a
2 parents
0fa85408
11dc4280
master
...
baidu_ocpcapi
develop
feature/canbuy
feature/channelDataMap
feature/company-profile
feature/contact
feature/detail-link
feature/home-optimize
feature/overseas-edition
feature/payment
feature/pcurl
feature/reduce
feature/refactor_alert
feature/shoppingPay
feature/virtualOrder
hotfix/11
hotfix/cart
hotfix/changeappversion
hotfix/gift
hotfix/im
hotfix/link
hotfix/ocpc
hotfix/shop
hotfix/upload
hotfix/yohobi
release/6.9.0
release/6.9.2
2019-12-5
all
Merge branch 'release/5.3' into feature/new-product-detail
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
632 additions
and
392 deletions
app.js
apps/brands/models/brands-model.js
apps/cart/models/easypay-api.js
apps/cart/models/easypay.js
apps/cart/views/action/order-ensure.hbs
apps/cart/views/partial/order-tpl.hbs
apps/channel/controllers/index.js
apps/channel/models/index.js
apps/channel/router.js
apps/passport/controllers/login.js
apps/passport/views/action/login/index.hbs
apps/product/controllers/favorite.js
apps/product/models/coupon-service.js
apps/product/models/detail-service.js
apps/product/models/favorite-brand-api.js
apps/product/models/favorite-brand-service.js
apps/product/models/list.js
apps/product/models/search-api.js
apps/product/models/search-handler.js
apps/product/models/shop-handler.js
apps/product/views/action/product/detail.hbs
config/common.js
doraemon/views/layout.hbs
package.json
public/img/cart/row.png
public/img/sprite.cart.png
public/js/cart/easypay.page.js
public/js/cart/order/invoice.js
public/js/channel/channel.page.js
public/js/common/data-yas.js
public/js/passport/login/index.js
public/js/product/detail.page.js
public/js/product/index/brand.js
public/js/product/index/top-coupon.js
public/scss/cart/_order-ensure.css
public/scss/passport/_login.css
public/scss/product/_detail.css
public/scss/product/_top-coupon.css
app.js
View file @
e232f76
...
...
@@ -5,6 +5,10 @@
*/
'use strict'
;
if
(
process
.
env
.
USE_APM
===
'1'
&&
process
.
env
.
NODE_ENV
===
'production'
)
{
require
(
'oneapm'
);
}
const
config
=
require
(
'./config/common'
);
global
.
Promise
=
require
(
'bluebird'
);
...
...
apps/brands/models/brands-model.js
View file @
e232f76
...
...
@@ -160,7 +160,7 @@ const getBrandViewList = (channel, start, length) => {
let
res
=
yield
brandApi
.
getBrandListData
(
switchParams
.
channelType
);
let
result
=
[],
n
avigation
=
[]
;
n
umResult
=
{}
;
if
(
!
res
||
res
.
code
!==
200
)
{
return
result
;
...
...
@@ -195,12 +195,18 @@ const getBrandViewList = (channel, start, length) => {
listTmp
.
push
(
brandItem
);
});
navigation
.
push
(
key
);
result
.
push
({
key
:
key
,
val
:
_
.
sortBy
(
listTmp
,
'name'
)
// 对name排序
});
if
(
key
.
match
(
/
\d
+/g
))
{
numResult
=
{
// 把0-9提出来
key
:
key
,
val
:
_
.
sortBy
(
listTmp
,
'name'
)
// 对name排序
};
}
else
{
result
.
push
({
key
:
key
,
val
:
_
.
sortBy
(
listTmp
,
'name'
)
// 对name排序
});
}
});
}
...
...
@@ -208,15 +214,15 @@ const getBrandViewList = (channel, start, length) => {
// 只取部分数据
let
begin
;
if
(
start
)
{
begin
=
(
start
-
1
)
?
(
start
-
1
)
:
0
;
begin
=
(
begin
>
0
)
?
begin
:
0
;
result
=
length
?
result
.
slice
(
begin
,
length
+
begin
)
:
result
.
slice
(
begin
);
}
result
.
navigation
=
navigation
;
result
=
_
.
sortBy
(
result
,
'key'
);
// A-Z排序
result
.
push
(
numResult
);
// 0-9放到最后
result
.
navigation
=
_
.
map
(
result
,
'key'
);
return
result
;
})();
};
...
...
apps/cart/models/easypay-api.js
View file @
e232f76
...
...
@@ -113,9 +113,9 @@ const easypayOrderSubmitAsync = (uid, cartType, addressId, deliveryTime, deliver
if
(
other
.
invoicesType
)
{
Object
.
assign
(
param
,
{
invoices_type
:
other
.
invoicesType
,
invoices_itle
:
other
.
invoicesTitle
,
invoices_
t
itle
:
other
.
invoicesTitle
,
invoice_content
:
other
.
invoicesContent
,
receiverMobile
:
other
.
receiver
Mobile
receiverMobile
:
other
.
receiver
});
}
...
...
apps/cart/models/easypay.js
View file @
e232f76
...
...
@@ -12,7 +12,7 @@ const crypto = global.yoho.crypto;
const
easypayApi
=
require
(
'./easypay-api'
);
const
handelViewPrice
=
list
=>
{
const
_
handelViewPrice
=
list
=>
{
if
(
list
)
{
_
.
forEach
(
list
,
val
=>
{
if
(
val
.
promotion
===
'商品金额'
)
{
...
...
@@ -26,6 +26,36 @@ const handelViewPrice = list => {
}
};
const
_handelUseYohoCoin
=
(
info
)
=>
{
let
resData
=
{};
let
limitCoin
=
_
.
get
(
info
,
'yoho_coin_pay_rule.num_limit'
,
0
);
if
(
info
)
{
Object
.
assign
(
resData
,
{
yoho_coin
:
info
.
yoho_coin
.
toFixed
(
2
),
use_yoho_coin
:
info
.
use_yoho_coin
,
total_yoho_coin_num
:
info
.
total_yoho_coin_num
,
yoho_coin_pay_rule
:
info
.
yoho_coin_pay_rule
,
canUseCoinNum
:
_
.
round
(
info
.
yoho_coin
*
100
),
usedCoinNum
:
_
.
round
(
info
.
use_yoho_coin
*
100
)
});
if
(
!
resData
.
canUseCoinNum
)
{
let
coinErrorTip
=
''
;
if
(
info
.
total_yoho_coin_num
>
limitCoin
)
{
coinErrorTip
=
'抱歉,您的订单实付款不满足有货币使用条件'
;
}
else
{
coinErrorTip
=
`抱歉,您的有货币不足,有货币满
$
{
limitCoin
}
个方可使用`
;
}
resData
.
coinErrorTip
=
coinErrorTip
;
}
}
return
resData
;
};
const
_handelPaymentInfo
=
(
d
)
=>
{
let
resData
=
{};
...
...
@@ -81,14 +111,14 @@ const _handelPaymentInfo = (d) => {
};
if
(
d
.
shopping_cart_data
&&
d
.
shopping_cart_data
.
promotion_formula_list
)
{
handelViewPrice
(
d
.
shopping_cart_data
.
promotion_formula_list
);
_
handelViewPrice
(
d
.
shopping_cart_data
.
promotion_formula_list
);
}
Object
.
assign
(
resData
,
{
paymentWay
:
d
.
payment_way
,
deliveryTime
:
d
.
delivery_time
,
deliveryWay
:
d
.
delivery_way
,
shoppingCartData
:
d
.
shopping_cart_data
,
shoppingCartData
:
Object
.
assign
(
d
.
shopping_cart_data
,
_handelUseYohoCoin
(
d
))
,
invoices
:
d
.
invoices
});
...
...
@@ -97,16 +127,15 @@ const _handelPaymentInfo = (d) => {
const
_getLimitProductData
=
(
params
)
=>
{
let
info
=
{
type
:
'limitcode'
,
buy_number
:
1
},
limitCode
=
crypto
.
decrypt
(
''
,
decodeURIComponent
(
params
.
limitcode
));
type
:
'limitcode'
,
buy_number
:
1
};
if
(
params
.
sku
&&
params
.
skn
&&
params
.
limitcode
)
{
Object
.
assign
(
info
,
{
sku
:
params
.
sku
,
skn
:
params
.
skn
,
limitproductcode
:
par
seInt
(
limitCode
,
10
)
limitproductcode
:
par
ams
.
limitcode
});
return
JSON
.
stringify
([
info
]);
...
...
@@ -132,18 +161,21 @@ const getEasypayOrderData = (params, uid) => {
});
};
const
getOrderComputeData
=
(
uid
,
cartType
,
params
)
=>
{
params
.
productSkuList
=
_getLimitProductData
(
params
);
return
easypayApi
.
getEasypayComputeAsync
(
uid
,
cartType
,
params
.
paymentType
,
params
.
deliveryWay
,
params
).
then
(
result
=>
{
// eslint-disable-line
if
(
result
.
code
===
200
)
{
if
(
_
.
has
(
result
,
'data.last_order_amount'
))
{
result
.
data
.
last_order_amount
=
_
.
round
(
result
.
data
.
last_order_amount
,
2
);
result
.
data
.
last_order_amount
=
(
result
.
data
.
last_order_amount
).
toFixed
(
2
);
}
if
(
_
.
has
(
result
,
'data.promotion_formula_list'
))
{
handelViewPrice
(
result
.
data
.
promotion_formula_list
);
_
handelViewPrice
(
result
.
data
.
promotion_formula_list
);
}
result
.
data
=
Object
.
assign
(
result
.
data
,
_handelUseYohoCoin
(
result
.
data
));
}
return
result
;
});
...
...
apps/cart/views/action/order-ensure.hbs
View file @
e232f76
...
...
@@ -268,23 +268,37 @@
<span
id=
"use-coin"
class=
"use-coin coin-trigger"
>
使用有货币支付
</span>
<div
class=
"using-coin coin-trigger hide"
>
<ul>
<ul
id=
"using-coin-cont"
>
{{#if
coinErrorTip
}}
<li><span
class=
"red"
>
{{
coinErrorTip
}}
</span></li>
{{/if}}
<li>
使用有货币:
<input
id=
"coin-used"
class=
"coin-used"
type=
"text"
data-max=
"
{{
hasCoin
}}
"
>
个
</li>
<li
class=
"coin-sum-row"
>
您目前有有货币
<em>
{{
hasCoin
}}
</em>
个
有货币满
<span
class=
"red"
>
{{
yoho_coin_pay_rule
.
num_limit
}}
</span>
个即可使用,每次使用有货币为
<span
class=
"red"
>
{{
yoho_coin_pay_rule
.
num_limit
}}
</span>
的整数倍
<i
class=
"iconfont help-icon"
>

</i>
<div
class=
"coin-tip-help"
>
<p>
有货币使用条件:
</p>
<p>
1.订单金额大于20元(含20元)
<br>
2.有货币数量大于
{{
yoho_coin_pay_rule
.
num_limit
}}
个(含
{{
yoho_coin_pay_rule
.
num_limit
}}
个)
<br>
3.有货币支付不得超过每笔订单应付金额的
{{
yoho_coin_pay_rule
.
max_pay_rate_desc
}}
</p>
<p
class=
"rs-text"
>
备注:使用有货币数量为
{{
yoho_coin_pay_rule
.
num_limit
}}
的整数倍,100有货币抵1元
</p>
</div>
</li>
<li
class=
"coin-tip-row"
>
<span
id=
"coin-tip"
class=
"coin-tip vhide"
></span>
<li>
您当前共有有货币
<span
class=
"red"
>
{{
total_yoho_coin_num
}}
</span>
个,可用
<span
class=
"red"
>
{{
canUseCoinNum
}}
</span>
个
</li>
<li>
<p
{{#if
coinErrorTip
}}
class=
"coin-use-hide"
{{/if}}
>
本次使用有货币
<span
class=
"red"
>
{{
canUseCoinNum
}}
</span>
个,抵扣
<span
class=
"red"
>
¥
{{
yoho_coin
}}
</span></p>
</li>
</ul>
<p
class=
"btns"
>
<span
id=
"coin-sure"
class=
"coin-sure sure-btn"
>
确定
</span>
<span
id=
"coin-cancel"
class=
"coin-cancel cancel-btn"
>
取消
</span>
<a
href=
"/help/?category_id=87"
class=
"coin-help"
target=
"_blank"
>
有货币使用规则?
</a>
</p>
</div>
<input
id=
"coin-used"
type=
"hidden"
data-coin=
"
{{
usedCoinNum
}}
"
data-max=
{{
canUseCoinNum
}}
>
</li
>
</ul>
</div>
...
...
apps/cart/views/partial/order-tpl.hbs
View file @
e232f76
...
...
@@ -101,6 +101,30 @@
\{{
/
each
}}
</script>
<script
id=
"yoho-coin-tpl"
type=
"text/html"
>
\{{#if coinErrorTip}}
<li><span class="red">\{{coinErrorTip}}</span></li>
\{{/if}}
<li>
有货币满<span class="red">\{{yoho_coin_pay_rule.num_limit}}</span>个即可使用,每次使用有货币为<span class="red">\{{yoho_coin_pay_rule.num_limit}}</span>的整数倍
<i class="iconfont help-icon"></i>
<div class="coin-tip-help">
<p>有货币使用条件:</p>
<p>
1.订单金额大于20元(含20元)<br>
2.有货币数量大于\{{yoho_coin_pay_rule.num_limit}}个(含\{{yoho_coin_pay_rule.num_limit}}个) <br>
3.有货币支付不得超过每笔订单应付金额的\{{yoho_coin_pay_rule.max_pay_rate_desc}}
</p>
<p class="rs-text">备注:使用有货币数量为\{{yoho_coin_pay_rule.num_limit}}的整数倍,100有货币抵1元</p>
</div>
</li>
<li>您当前共有有货币 <span class="red">\{{total_yoho_coin_num}}</span> 个,可用 <span class="red">\{{canUseCoinNum}}</span> 个</li>
<li>
<p\{{#if coinErrorTip}} class="coin-use-hide"\{{/if}}>本次使用有货币<span class="red">\{{canUseCoinNum}}</span>个,抵扣 <span class="red">¥\{{
yoho_coin
}}
<
/span></
p
>
<
/li
>
</script>
<script
id=
"promotion-list-tpl"
type=
"text/html"
>
\{{#each promotion_formula_list}}
<li class="promotion-item\{{#isEqual promotion '运费'}} fregit-promotion\{{/isEqual}}">
...
...
apps/channel/controllers/index.js
View file @
e232f76
...
...
@@ -15,7 +15,7 @@ exports.index = (req, res, next) => {
// 将woman转换为girls,以便model层进行处理
channelType
===
'woman'
?
channelType
=
'girls'
:
null
;
channelModel
.
getContent
(
channelType
,
req
).
then
(
data
=>
{
channelModel
.
getContent
(
channelType
).
then
(
data
=>
{
// channel为空不缓存
if
(
_
.
isEmpty
(
data
.
channel
))
{
...
...
@@ -28,7 +28,7 @@ exports.index = (req, res, next) => {
exports
.
getbrandFloorDataAjax
=
(
req
,
res
,
next
)
=>
{
const
channelType
=
req
.
query
.
channelType
||
'boys'
;
channelModel
.
getbrandFloorDataAjax
(
channelType
,
req
).
then
(
data
=>
{
channelModel
.
getbrandFloorDataAjax
(
channelType
).
then
(
data
=>
{
res
.
json
(
data
);
}).
catch
(
next
);
};
...
...
@@ -77,3 +77,10 @@ exports.getIndexGuide = (req, res, next) => {
res
.
render
(
'guide'
,
result
);
}).
catch
(
next
);
};
exports
.
hasNewUserFloor
=
(
req
,
res
,
next
)
=>
{
channelModel
.
hasNewUserFloor
(
req
.
yoho
.
channel
,
req
.
user
.
uid
).
then
(
data
=>
{
res
.
send
(
data
);
}).
catch
(
next
);
};
...
...
apps/channel/models/index.js
View file @
e232f76
...
...
@@ -576,7 +576,6 @@ const _requestContent = (type, params) => {
};
Object
.
assign
(
data
,
params
);
return
serviceApi
.
get
(
'operations/api/v5/resource/home'
,
data
,
{
cache
:
true
,
code
:
200
...
...
@@ -894,14 +893,9 @@ const getNewArrival = channel => {
* @param {String} type 传入频道页类型,值可以是: boys, girls, kids, lifestyle
* @return {Object}
*/
const
getContent
=
(
type
,
req
)
=>
{
let
params
=
{};
const
getContent
=
(
type
)
=>
{
let
params
=
{
new_device
:
'Y'
};
if
(
!
req
.
user
.
uid
)
{
params
.
new_device
=
'Y'
;
}
else
{
params
.
uid
=
req
.
user
.
uid
;
}
return
Promise
.
all
([
headerModel
.
requestHeaderData
(
type
),
_requestContent
(
type
,
params
)]).
then
(
res
=>
{
let
headerData
=
res
[
0
].
data
||
res
[
0
],
...
...
@@ -956,14 +950,9 @@ const getContent = (type, req) => {
// 优选品牌楼层floorData-ajax
const
getbrandFloorDataAjax
=
(
type
,
req
)
=>
{
let
params
=
{};
const
getbrandFloorDataAjax
=
(
type
)
=>
{
let
params
=
{
new_device
:
'Y'
};
if
(
!
req
.
user
.
uid
)
{
params
.
new_device
=
'Y'
;
}
else
{
params
.
uid
=
req
.
user
.
uid
;
}
return
_requestContent
(
type
,
params
).
then
(
res
=>
{
let
contentData
=
res
.
data
?
res
.
data
.
list
:
[];
...
...
@@ -1026,12 +1015,34 @@ const getIndexGuideData = () => {
return
serviceApi
.
get
(
'operations/api/v6/category/getCategory'
,
params
,
config
.
apiCache
);
};
const
hasNewUserFloor
=
(
channelType
,
uid
)
=>
{
let
params
=
{
uid
:
uid
};
return
_requestContent
(
channelType
,
params
).
then
(
res
=>
{
let
isNewUser
=
false
,
contentData
=
res
.
data
?
res
.
data
.
list
:
res
;
_
.
forEach
(
contentData
,
(
data
)
=>
{
if
(
data
.
template_name
===
'new_user_floor'
||
data
.
template_intro
===
'新人专享'
)
{
isNewUser
=
true
;
return
false
;
}
});
return
{
isNewUser
:
isNewUser
};
});
};
module
.
exports
=
{
getNewArrival
:
getNewArrival
,
getContent
:
getContent
,
getbrandFloorDataAjax
:
getbrandFloorDataAjax
,
getIndexGuideData
:
getIndexGuideData
,
formatIndexGuideData
:
formatIndexGuideData
,
getResourceData
:
getResourceData
getResourceData
:
getResourceData
,
hasNewUserFloor
:
hasNewUserFloor
};
...
...
apps/channel/router.js
View file @
e232f76
...
...
@@ -6,7 +6,7 @@
'use strict'
;
const
router
=
require
(
'express'
).
Router
();
// eslint-disable-line
const
router
=
require
(
'express'
).
Router
();
// eslint-disable-line
const
cRoot
=
'./controllers'
;
// Your controller here
...
...
@@ -17,6 +17,7 @@ router.get('/', channelController.index);
router
.
get
(
'/woman'
,
channelController
.
index
);
router
.
get
(
'/kids'
,
channelController
.
index
);
router
.
get
(
'/lifestyle'
,
channelController
.
index
);
router
.
get
(
'/channel/isNewUserAjax'
,
channelController
.
hasNewUserFloor
);
// ajax
router
.
get
(
'/getbrandFloorDataAjax'
,
channelController
.
getbrandFloorDataAjax
);
...
...
apps/passport/controllers/login.js
View file @
e232f76
...
...
@@ -235,7 +235,7 @@ const local = {
loginService
.
verifyPasswordBySMS
(
area
,
mobile
,
code
).
then
((
result
)
=>
{
if
(
_
.
get
(
result
,
'code'
,
200
)
!==
200
)
{
return
Promise
.
reject
(
'error'
);
return
res
.
json
(
result
);
}
let
pass
=
_
.
get
(
result
,
'data.is_pass'
,
'N'
);
...
...
apps/passport/views/action/login/index.hbs
View file @
e232f76
...
...
@@ -6,10 +6,10 @@
<ul
class=
"login-ul"
>
<div
class=
"switch-login-type"
data-type=
"DesktopLogin"
>
<div
id=
"device-bg"
class=
"type-mobile-bg"
></div>
<div
class=
"type-tip tip-title"
>
<div
id=
"device-tip"
style=
"margin-left: 15px;margin-top: 8px"
>
扫码登录更安全
</div>
</div>
<div
id=
"device-bg"
class=
"type-mobile-bg"
></div>
<div
class=
"type-tip tip-title"
>
<div
id=
"device-tip"
style=
"margin-left: 15px;margin-top: 8px"
>
扫码登录更安全
</div>
</div>
</div>
<div
class=
"desktop-login"
>
...
...
@@ -30,7 +30,7 @@
<li
class=
"relative"
>
<div
class=
"switch"
>
<div
class=
"left selected"
data-type=
"PasswordLogin"
>
普通登录
</div>
<div
class=
"right"
data-type=
"SMSLogin"
>
手机验证码登录
</div>
<div
class=
"right"
data-type=
"SMSLogin"
>
手机验证码登录
</div>
</div>
</li>
...
...
@@ -55,20 +55,10 @@
</span>
</li>
<li
class=
"relative clearfix sms-login hide"
>
<input
id=
"account2"
class=
"account input va"
name=
"account2"
value=
"
{{
bindMobile
}}
"
type=
"text"
placeholder=
"手机号码"
autocomplete=
"off"
>
<span
class=
"err-tip hide"
>
<i></i>
<em></em>
</span>
</li>
<li
class=
"clearfix sms-captcha-img-wrap captcha-wrap sms-login hide"
>
<input
id=
"sms-captcha-input"
class=
"input va captcha"
type=
"text"
name=
"captcha"
placeholder=
"图形验证码"
<li
class=
"clearfix captcha-wrap hide"
>
<input
id=
"captcha"
class=
"input va captcha"
type=
"text"
name=
"captcha"
placeholder=
"图形验证码"
autocomplete=
"off"
maxlength=
"4"
>
<img
id=
"
sms-
captcha-img"
class=
"captcha-img"
alt=
""
>
<img
id=
"captcha-img"
class=
"captcha-img"
alt=
""
>
<a
class=
"link change-captcha"
>
换一张
</a>
<span
class=
"err-tip hide"
>
<i></i>
...
...
@@ -76,21 +66,21 @@
</span>
</li>
<li
class=
"relative clearfix sms-login hide"
>
<input
id=
"captcha-sms"
class=
"input va captcha-sms-input"
type=
"text"
name=
"captcha"
placeholder=
"短信验证码"
autocomplete=
"off"
maxlength=
"4"
>
<div
class=
"change-captcha-sms btn"
>
获取短信验证码
</div>
<span
class=
"err-tip hide"
>
<i></i>
<em></em>
</span>
</li>
<li
class=
"relative clearfix sms-login hide"
>
<input
id=
"account2"
class=
"account input va"
name=
"account2"
value=
"
{{
bindMobile
}}
"
type=
"text"
placeholder=
"手机号码"
autocomplete=
"off"
>
<span
class=
"err-tip hide"
>
<i></i>
<em></em>
</span>
</li>
<li
class=
"clearfix captcha-wrap hide"
>
<input
id=
"captcha"
class=
"input va captcha"
type=
"text"
name=
"captcha"
placeholder=
"图形验证码"
<li
class=
"clearfix sms-captcha-img-wrap sms-login hide"
>
<input
id=
"sms-captcha-input"
class=
"input va captcha"
type=
"text"
name=
"captcha"
placeholder=
"图形验证码"
autocomplete=
"off"
maxlength=
"4"
>
<img
id=
"captcha-img"
class=
"captcha-img"
alt=
""
>
<img
id=
"
sms-
captcha-img"
class=
"captcha-img"
alt=
""
>
<a
class=
"link change-captcha"
>
换一张
</a>
<span
class=
"err-tip hide"
>
<i></i>
...
...
@@ -98,6 +88,17 @@
</span>
</li>
<li
class=
"relative clearfix sms-login hide"
>
<input
id=
"captcha-sms"
class=
"input va captcha-sms-input"
type=
"text"
name=
"captcha"
placeholder=
"短信验证码"
autocomplete=
"off"
maxlength=
"4"
>
<div
class=
"change-captcha-sms btn"
>
获取短信验证码
</div>
<span
class=
"err-tip hide"
>
<i></i>
<em></em>
</span>
</li>
<li
class=
"desktop-login"
>
<span
id=
"login-btn"
class=
"login-btn btn"
>
登录
</span>
</li>
...
...
apps/product/controllers/favorite.js
View file @
e232f76
...
...
@@ -14,9 +14,10 @@ const fav = require('../models/favorite');
const
changeFavoriteBrand
=
(
req
,
res
,
next
)
=>
{
let
uid
=
req
.
user
.
uid
||
''
;
let
brandId
=
req
.
body
.
brandId
;
let
type
=
req
.
body
.
type
||
''
;
if
(
uid
&&
brandId
)
{
brandService
.
changeAsync
(
uid
,
brandId
).
then
(
result
=>
{
brandService
.
changeAsync
(
type
,
uid
,
brandId
).
then
(
result
=>
{
return
res
.
json
(
result
);
}).
catch
(
next
);
}
else
if
(
!
uid
)
{
...
...
apps/product/models/coupon-service.js
View file @
e232f76
...
...
@@ -8,39 +8,7 @@ const api = require('./coupon-api');
const
_
=
require
(
'lodash'
);
const
decrypt
=
_
.
partial
(
global
.
yoho
.
crypto
.
decrypt
,
null
);
const
_acquireAsync
=
_
.
overArgs
(
api
.
acquireAsync
,
[
decrypt
,
_
=>
_
]);
const
acquireAsync
=
(
cid
,
uid
)
=>
{
return
_acquireAsync
(
cid
,
uid
).
then
(
result
=>
{
switch
(
result
.
code
)
{
case
200
:
return
{
code
:
200
,
message
:
'恭喜您,成功领取优惠券'
};
case
401
:
return
{
code
:
401
,
message
:
'您已领取过优惠券'
};
case
315
:
return
{
code
:
315
,
message
:
'优惠券已过期'
};
case
300
:
return
{
code
:
300
,
message
:
'请求参数错误'
};
default
:
return
{
code
:
500
,
message
:
'领券失败!'
};
}
});
};
const
acquireAsync
=
_
.
overArgs
(
api
.
acquireAsync
,
[
decrypt
,
_1
=>
_1
]);
module
.
exports
=
{
acquireAsync
,
...
...
apps/product/models/detail-service.js
View file @
e232f76
...
...
@@ -1121,7 +1121,7 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
};
if
(
propOrigin
(
'isLimitBuy'
,
false
)
&&
propOrigin
(
'limitProductCode'
,
''
))
{
result
.
limitProductCode
=
crypto
.
encryption
(
null
,
propOrigin
(
'limitProductCode'
)
+
'
'
);
result
.
limitProductCode
=
propOrigin
(
'limitProductCode
'
);
requestApi
.
limited
=
productAPI
.
getLimitedProductStatusAsync
(
propOrigin
(
'limitProductCode'
),
...
...
@@ -1203,6 +1203,9 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
delete
result
.
salePrice
;
result
.
hasOtherPrice
=
false
;
// 普通预售
result
.
presale
=
'Y'
;
}
// sku商品信息
...
...
@@ -1238,8 +1241,18 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
result
.
buyNow
=
fashTopGoods
.
buyNow
;
// 是否立即购买
result
.
buyNowBase
=
helpers
.
urlFormat
(
'/cart/easypay'
);
// 购买链接
}
// 限购商品
result
.
limitedsale
=
'Y'
;
}
// 非普通商品没有优惠券
const
isSpecialProduct
=
(
pro
)
=>
{
return
pro
.
limitedsale
===
'Y'
||
pro
.
secKill
===
'Y'
||
pro
.
deposit
===
'Y'
||
pro
.
presale
===
'Y'
;
};
result
.
coupon
=
!
isSpecialProduct
(
result
)
?
result
.
coupon
:
[];
// 商品购买状态
let
soldOut
=
!!
(
propOrigin
(
'status'
)
===
0
||
totalStorageNum
===
0
);
let
notForSale
=
propOrigin
(
'attribute'
)
===
2
;
// 非卖品
...
...
@@ -1353,6 +1366,7 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
if
(
!
_
.
has
(
result
,
'fashionTopGoods'
))
{
cookies
&&
cookies
(
_
.
get
(
result
,
'skn'
,
''
));
}
return
{
goodsInfo
:
result
,
banner
:
_
.
isEmpty
(
bandInfo
)
?
null
:
bandInfo
,
...
...
@@ -1479,7 +1493,9 @@ const recommendAsync = (skn, page, limit) => {
if
(
_
.
get
(
recommendData
,
'code'
,
400
)
!==
200
)
{
return
{
code
:
200
,
products
:
[]
data
:
{
products
:
[]
}
};
}
...
...
apps/product/models/favorite-brand-api.js
View file @
e232f76
...
...
@@ -4,23 +4,17 @@
'use strict'
;
const
serviceAPI
=
global
.
yoho
.
ServiceAPI
;
const
api
=
require
(
'./favorite-api'
);
const
_
=
require
(
'lodash'
);
const
isFavoriteAsync
=
(
uid
,
bid
)
=>
{
return
serviceAPI
.
get
(
'shops/service/v1/favorite/getUidBrandFav'
,
{
uid
:
uid
,
brandId
:
bid
});
};
const
isFavoriteAsync
=
_
.
partial
(
api
.
isFavAsync
,
_
,
_
,
'brand'
);
const
changeAsync
=
(
uid
,
brandId
)
=>
{
return
serviceAPI
.
get
(
'guang/service/v2/favorite/toggleBrand'
,
{
uid
:
uid
,
brand_id
:
brandId
});
};
const
addFavAsync
=
_
.
partial
(
api
.
addFavAsync
,
_
,
_
,
'brand'
);
const
cancelFavAsync
=
_
.
partial
(
api
.
cancelFavAsync
,
_
,
_
,
'brand'
);
module
.
exports
=
{
isFavoriteAsync
,
changeAsync
addFavAsync
,
cancelFavAsync
};
...
...
apps/product/models/favorite-brand-service.js
View file @
e232f76
...
...
@@ -6,5 +6,21 @@
const
api
=
require
(
'./favorite-brand-api'
);
module
.
exports
=
api
;
const
changeAsync
=
(
type
,
uid
,
brandId
)
=>
{
switch
(
type
)
{
case
'add'
:
return
api
.
addFavAsync
(
uid
,
brandId
);
case
'cancel'
:
return
api
.
cancelFavAsync
(
uid
,
brandId
);
default
:
return
Promise
.
reject
(
'favorite brand error'
);
}
};
const
isFavoriteAsync
=
api
.
isFavoriteAsync
;
module
.
exports
=
{
changeAsync
,
isFavoriteAsync
};
...
...
apps/product/models/list.js
View file @
e232f76
...
...
@@ -312,6 +312,10 @@ const getBrandData = (params, extra, channel) => {
}
});
if
(
queryBase
.
shop_id
)
{
dps
.
shopId
=
queryBase
.
shop_id
;
}
Object
.
assign
(
finalResult
.
brand
,
{
leftContent
:
searchHandler
.
handleSortData
(
result
[
1
].
data
.
sort
,
dps
,
params
)
},
searchHandler
.
handlePathNavData
(
extra
,
params
,
'brand'
,
channel
));
...
...
@@ -349,7 +353,7 @@ const getBrandData = (params, extra, channel) => {
finalResult
.
criteo
=
{
skn
:
searchHandler
.
getCriteo
(
_
.
get
(
finalResult
.
brand
,
'goods'
))};
let
seo
=
searchHandler
.
getBrandS
eo
(
channel
,
extra
);
let
seo
=
searchHandler
.
getBrandS
hopSeo
(
channel
,
extra
,
params
);
return
Object
.
assign
({},
seo
,
finalResult
);
});
...
...
@@ -563,7 +567,7 @@ const getShopData = (shopId, channel, params, shopInfo) => {
Object
.
assign
(
finalResult
,
result
[
0
],
// 头部数据
searchHandler
.
handlePathNavData
(
shopInfo
,
params
,
'shop'
,
channel
),
// 面包屑导航
s
hopHandler
.
setShopSeo
(
shopInfo
.
shopName
||
shopInfo
.
brandName
)
// 店铺SEO
s
earchHandler
.
getBrandShopSeo
(
channel
,
{
shopName
:
shopInfo
.
shopName
||
shopInfo
.
brandName
},
params
)
// 店铺SEO
);
_
.
set
(
finalResult
,
'headerData.header'
,
true
);
...
...
@@ -806,7 +810,9 @@ const getShopListData = (channel, params, uid) => {
});
// 店铺SEO
Object
.
assign
(
finalResult
,
shopHandler
.
setShopSeo
(
data
.
shop_name
));
Object
.
assign
(
finalResult
,
searchHandler
.
getBrandShopSeo
(
channel
,
{
shopName
:
data
.
shop_name
},
params
));
}
}
else
{
return
Promise
.
reject
(
'No ShopDecorator data'
);
...
...
@@ -872,12 +878,13 @@ const getShopListData = (channel, params, uid) => {
return
searchApi
.
getSortList
({
brand
:
shopBrandIds
}).
then
(
subRes
=>
{
if
(
subRes
.
code
===
200
)
{
let
groupSort
=
_
.
get
(
subRes
,
'data.sort'
,
[]);
let
groupSort
=
_
.
get
(
subRes
,
'data.sort'
,
[]),
noPageQs
=
Object
.
assign
({},
params
,
{
page
:
1
});
finalResult
.
leftContent
=
searchHandler
.
handleSortData
(
groupSort
,
param
s
);
finalResult
.
leftContent
=
searchHandler
.
handleSortData
(
groupSort
,
noPageQ
s
);
if
(
finalResult
.
allGoods
)
{
Object
.
assign
(
finalResult
.
allGoods
,
searchHandler
.
setShopSort
(
groupSort
,
param
s
));
Object
.
assign
(
finalResult
.
allGoods
,
searchHandler
.
setShopSort
(
groupSort
,
noPageQ
s
));
}
}
...
...
@@ -939,7 +946,9 @@ const getBaseShopData = (params, extra, channel, shopId) => {
});
// 店铺SEO
Object
.
assign
(
resData
,
shopHandler
.
setShopSeo
(
shopName
));
Object
.
assign
(
resData
,
searchHandler
.
getBrandShopSeo
(
channel
,
{
shopName
:
shopName
},
params
));
}
_
.
unset
(
resData
,
'brand.coupon'
);
...
...
apps/product/models/search-api.js
View file @
e232f76
...
...
@@ -425,7 +425,7 @@ const getShopList = params => {
for
(
let
s
of
shops
)
{
promises
.
push
(
getSortList
({
brand
:
s
.
brand_id
brand
:
s
.
brand_id
||
brandShop
.
id
}));
}
...
...
apps/product/models/search-handler.js
View file @
e232f76
...
...
@@ -1427,34 +1427,65 @@ exports.getNewSeo = (channel, dlist) => {
};
/**
* 品牌页 seo
* 品牌
店铺
页 seo
* @param channel
* @param brandInfo
* @param info
* @param qs
* @returns {{title: (string|*|string), keywords: string, description: string}}
*/
exports
.
getBrandSeo
=
(
channel
,
brandInfo
)
=>
{
let
c
=
getChannelName
(
channel
),
bcn
=
brandInfo
&&
brandInfo
.
brandNameCn
,
b
=
brandInfo
&&
brandInfo
.
brandNameEn
,
bb
=
b
+
' '
+
bcn
,
bc
=
b
+
c
,
bbc
=
b
+
bcn
+
c
,
keywords
=
[
b
?
b
+
','
:
''
,
((
b
&&
bcn
)
?
(
bb
+
','
)
:
''
),
bc
||
''
,
'品牌'
].
join
(
''
),
desc
=
[
b
+
'正品网购。'
,
bbc
||
''
,
'品牌官方授权!YOHO! 有货中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。'
].
join
(
''
);
let
title
=
(
b
?
(
b
+
'|'
)
:
''
)
+
(
bb
?
(
bb
+
'|'
)
:
''
)
+
c
+
'品牌|YOHO!BUY 有货 100%正品保证'
;
return
{
title
:
title
,
keywords
:
keywords
,
description
:
desc
exports
.
getBrandShopSeo
=
(
channel
,
info
,
qs
)
=>
{
let
resData
=
{},
ctype
=
{
boys
:
{
fashionType
:
'男装'
,
brandType
:
'男生品牌'
},
girls
:
{
fashionType
:
'女装'
,
brandType
:
'女生品牌'
},
kids
:
{
fashionType
:
'童装'
,
brandType
:
'潮童品牌'
},
lifestyle
:
{
fashionType
:
'创意生活'
,
brandType
:
'创意生活品牌'
}
};
let
params
=
{
nameEn
:
''
,
name
:
''
};
if
(
info
)
{
Object
.
assign
(
params
,
{
nameEn
:
_
.
get
(
info
,
'brandNameEn'
,
''
),
nameCn
:
_
.
get
(
info
,
'brandNameCn'
,
''
)
});
params
.
name
=
`
$
{
params
.
nameEn
}
$
{
params
.
nameCn
}
`
;
if
(
info
.
shopName
)
{
Object
.
assign
(
params
,
{
nameEn
:
info
.
shopName
,
name
:
info
.
shopName
});
}
}
if
(
qs
&&
qs
.
gender
)
{
if
(
qs
.
gender
===
'1,3'
)
{
channel
=
'boys'
;
}
else
if
(
qs
.
gender
===
'2,3'
)
{
channel
=
'girls'
;
}
Object
.
assign
(
params
,
ctype
[
channel
]
||
ctype
.
boys
);
Object
.
assign
(
resData
,
{
title
:
`
$
{
params
.
nameEn
}
|
$
{
params
.
name
}
$
{
params
.
brandType
}
`
,
keywords
:
`
$
{
params
.
nameEn
},
$
{
params
.
name
}
$
{
params
.
fashionType
},
$
{
params
.
nameEn
}
$
{
params
.
brandType
}
`
,
description
:
`
$
{
params
.
nameEn
}
正品网购。
$
{
params
.
name
}
官方授权!`
});
}
else
{
Object
.
assign
(
resData
,
{
title
:
`
$
{
params
.
nameEn
}
|
$
{
params
.
name
}
官网`
,
keywords
:
`
$
{
params
.
nameEn
},
$
{
params
.
name
}
官网`
,
description
:
`
$
{
params
.
nameEn
}
正品网购。
$
{
params
.
name
}
官方授权!`
});
}
resData
.
title
+=
resData
.
title
?
' | YOHO!BUY 有货 100%正品保证'
:
''
;
resData
.
description
+=
resData
.
description
?
' YOHO!BUY 有货中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。'
:
''
;
// eslint-disable-line
return
resData
;
};
/**
...
...
apps/product/models/shop-handler.js
View file @
e232f76
...
...
@@ -16,14 +16,6 @@ const newProductsName = '新品上架 NEW';
const
hotProductsName
=
'人气单品 HOT'
;
const
shopListUrl
=
'/product/shoplist'
;
exports
.
setShopSeo
=
(
shopName
)
=>
{
return
{
title
:
`
$
{
shopName
}
|
$
{
shopName
}
潮流服装服饰
-
Yoho
!
Buy
有货`
,
keywords
:
`
$
{
shopName
},
$
{
shopName
}
服装服饰
,
$
{
shopName
}
潮流服装服饰`
,
description
:
`
$
{
shopName
}
|
Yoho
!
Buy
有货
$
{
shopName
}
潮流服饰官方授权店!
100
%
品牌正品保证
,
支持货到付款。`
};
};
/**
* 新品上架
*/
...
...
@@ -361,20 +353,17 @@ exports.getShopDecorator = (data, params, shopId, base) => {
if
(
base
)
{
_
.
forEach
(
data
.
list
,
(
value
)
=>
{
if
(
!
_
.
isEmpty
(
value
.
resource_data
))
{
let
info
=
Fn
.
pipe
(
JSON
.
parse
,
_
.
partial
(
_handleSaleCategory
,
shopId
))(
value
.
resource_data
);
switch
(
value
.
resource_name
)
{
case
'signboard'
:
dest
.
signboard
=
signboard
(
info
);
break
;
case
'shopTopBanner_base'
:
Object
.
assign
(
dest
,
shopTopBannerBase
(
info
));
break
;
default
:
break
;
}
let
info
=
Fn
.
pipe
(
JSON
.
parse
,
_
.
partial
(
_handleSaleCategory
,
shopId
))(
value
.
resource_data
||
'[]'
);
switch
(
value
.
resource_name
)
{
case
'signboard'
:
dest
.
signboard
=
signboard
(
info
);
break
;
case
'shopTopBanner_base'
:
Object
.
assign
(
dest
,
shopTopBannerBase
(
info
));
break
;
default
:
break
;
}
});
}
else
{
...
...
@@ -384,46 +373,44 @@ exports.getShopDecorator = (data, params, shopId, base) => {
});
_
.
forEach
(
data
.
list
,
(
value
)
=>
{
if
(
!
_
.
isEmpty
(
value
.
resource_data
))
{
let
info
=
Fn
.
pipe
(
JSON
.
parse
,
_
.
partial
(
_handleSaleCategory
,
shopId
))(
value
.
resource_data
);
let
tabBar
;
switch
(
value
.
resource_name
)
{
case
'newProducts'
:
Object
.
assign
(
dest
.
newArrivel
,
newProducts
(
info
));
break
;
case
'hotProducts'
:
Object
.
assign
(
dest
.
hotSingle
,
hotProducts
(
info
));
break
;
case
'goodsTabBar'
:
tabBar
=
goodsTabBar
(
info
,
shopId
);
Object
.
assign
(
dest
.
newArrivel
,
{
navs
:
tabBar
.
new
});
Object
.
assign
(
dest
.
hotSingle
,
{
navs
:
tabBar
.
hot
});
break
;
case
'shopTopBanner'
:
Object
.
assign
(
dest
,
shopTopBanner
(
info
));
break
;
case
'navigationBar'
:
Object
.
assign
(
dest
,
navigationBar
(
info
,
shopId
));
break
;
case
'largeSlideImg'
:
Object
.
assign
(
dest
,
largeSlideImg
(
info
,
shopId
));
break
;
case
'oneRowTwoColImages'
:
Object
.
assign
(
dest
,
oneRowTwoColImages
(
info
,
shopId
));
break
;
case
'recommend'
:
Object
.
assign
(
dest
,
recommend
(
info
,
shopId
));
break
;
case
'brandBrowse'
:
Object
.
assign
(
dest
,
brandBrowse
(
info
,
params
));
break
;
case
'hotRecommend'
:
Object
.
assign
(
dest
,
hotRecommend
(
info
));
break
;
default
:
break
;
}
let
info
=
Fn
.
pipe
(
JSON
.
parse
,
_
.
partial
(
_handleSaleCategory
,
shopId
))(
value
.
resource_data
||
'[]'
);
let
tabBar
;
switch
(
value
.
resource_name
)
{
case
'newProducts'
:
Object
.
assign
(
dest
.
newArrivel
,
newProducts
(
info
));
break
;
case
'hotProducts'
:
Object
.
assign
(
dest
.
hotSingle
,
hotProducts
(
info
));
break
;
case
'goodsTabBar'
:
tabBar
=
goodsTabBar
(
info
,
shopId
);
Object
.
assign
(
dest
.
newArrivel
,
{
navs
:
tabBar
.
new
});
Object
.
assign
(
dest
.
hotSingle
,
{
navs
:
tabBar
.
hot
});
break
;
case
'shopTopBanner'
:
Object
.
assign
(
dest
,
shopTopBanner
(
info
));
break
;
case
'navigationBar'
:
Object
.
assign
(
dest
,
navigationBar
(
info
,
shopId
));
break
;
case
'largeSlideImg'
:
Object
.
assign
(
dest
,
largeSlideImg
(
info
,
shopId
));
break
;
case
'oneRowTwoColImages'
:
Object
.
assign
(
dest
,
oneRowTwoColImages
(
info
,
shopId
));
break
;
case
'recommend'
:
Object
.
assign
(
dest
,
recommend
(
info
,
shopId
));
break
;
case
'brandBrowse'
:
Object
.
assign
(
dest
,
brandBrowse
(
info
,
params
));
break
;
case
'hotRecommend'
:
Object
.
assign
(
dest
,
hotRecommend
(
info
));
break
;
default
:
break
;
}
});
}
...
...
apps/product/views/action/product/detail.hbs
View file @
e232f76
...
...
@@ -358,9 +358,9 @@
{{#
unless
@root
.
pc
.
product
.
removeRecentView
}}
<div
class=
"individual-comment info-block"
>
<p
class=
"block-title"
>
<span
class=
"title cur"
>
店铺推荐 SHOP RECOMMENDED
</span>
<span
class=
"sep"
>
|
</span>
<span
class=
"title"
>
最近浏览 RECENT REVIEW
</span>
<span
class=
"title hide"
>
店铺推荐 SHOP RECOMMENDED
</span>
<span
class=
"sep hide"
>
|
</span>
<span
class=
"title cur"
>
最近浏览 RECENT REVIEW
</span>
</p>
{{#if
latestWalk
}}
<div
class=
"latest-walk"
>
...
...
config/common.js
View file @
e232f76
...
...
@@ -17,13 +17,13 @@ module.exports = {
cookieDomain
:
'.yohobuy.com'
,
domains
:
{
favApi
:
'http://192.168.102.31:8092/brower'
,
api
:
'http://api-test3.yohops.com:9999/'
,
service
:
'http://service-test3.yohops.com:9999/'
,
//api: 'http://api-test3.yohops.com:9999/',
//service: 'http://service-test3.yohops.com:9999/',
//
api
:
'http://api.yoho.cn/'
,
service
:
'http://service.yoho.cn/'
,
//api: 'http://api.yoho.cn/',
//service: 'http://service.yoho.cn/',
// api: 'http://dev-api.yohops.com:9999/',
//api: 'http://dev-api.yohops.com:9999/',
// service: 'http://dev-service.yohops.com:9999/',
search
:
'http://192.168.102.216:8080/yohosearch/'
...
...
doraemon/views/layout.hbs
View file @
e232f76
...
...
@@ -10,6 +10,11 @@
<meta
name=
"apple-mobile-web-app-status-bar-style"
content=
"black"
/>
<meta
content=
"telephone=no"
name=
"format-detection"
/>
<meta
content=
"email=no"
name=
"format-detection"
/>
<!-- oneapm js agent -->
<script
type=
'text/javascript'
>
window
.
BWEUM
||
(
BWEUM
=
{});
BWEUM
.
info
=
{
"stand"
:
true
,
"agentType"
:
"browser"
,
"agent"
:
"bi-collector.oneapm.com/static/js/bw-send-411.4.9.js"
,
"beaconUrl"
:
"bi-collector.oneapm.com/beacon"
,
"licenseKey"
:
"NQVuf~6yrQbvJnqr"
,
"applicationID"
:
2283338
};
</script><script
type=
"text/javascript"
>
/*!OneAPM-v411.4.9 */
!
function
(){
window
.
NREUM
||
(
window
.
NREUM
=
{}),
window
.
BWEUM
||
(
window
.
BWEUM
=
window
.
NREUM
);
var
a
;
window
.
BWEUM
.
require
=
a
,
window
.
apmFirstbyte
=
window
.
apmUserFirstbyte
||
(
new
Date
).
getTime
(),
a
=
function
b
(
c
,
d
,
e
){
function
f
(
h
,
i
){
if
(
!
d
[
h
]){
if
(
!
c
[
h
]){
var
j
=
"function"
==
typeof
a
&&
a
;
if
(
!
i
&&
j
)
return
j
(
h
,
!
0
);
if
(
g
)
return
g
(
h
,
!
0
);
var
k
=
new
Error
(
"Cannot find module '"
+
h
+
"'"
);
throw
k
.
code
=
"MODULE_NOT_FOUND"
,
k
}
var
l
=
d
[
h
]
=
{
exports
:{}};
c
[
h
][
0
].
call
(
l
.
exports
,
function
(
a
){
var
b
=
c
[
h
][
1
][
a
];
return
f
(
b
?
b
:
a
)},
l
,
l
.
exports
,
b
,
c
,
d
,
e
)}
return
d
[
h
].
exports
}
for
(
var
g
=
"function"
==
typeof
a
&&
a
,
h
=
0
;
h
<
e
.
length
;
h
++
)
f
(
e
[
h
]);
return
f
}({
38
:[
function
(
a
,
b
){
b
.
exports
=
function
(
a
){
var
b
=
document
.
createElement
(
"a"
),
c
=
window
.
location
,
d
=
{};
b
.
href
=
a
,
d
.
port
=
b
.
port
;
var
e
=
b
.
href
.
split
(
"://"
);
return
!
d
.
port
&&
e
[
1
]
&&
(
d
.
port
=
e
[
1
].
split
(
"/"
)[
0
].
split
(
":"
)[
1
]),
d
.
port
&&
"0"
!==
d
.
port
||
(
d
.
port
=
"https"
===
e
[
0
]?
"443"
:
"80"
),
d
.
hostname
=
b
.
hostname
||
c
.
hostname
,
d
.
pathname
=
b
.
pathname
,
"/"
!==
d
.
pathname
.
charAt
(
0
)
&&
(
d
.
pathname
=
"/"
+
d
.
pathname
),
d
.
sameOrigin
=!
b
.
hostname
||
b
.
hostname
===
document
.
domain
&&
b
.
port
===
c
.
port
&&
b
.
protocol
===
c
.
protocol
,
d
}},{}],
34
:
[
function
(
a
,
b
){
function
c
(){
var
a
=
m
.
info
=
window
.
BWEUM
.
info
;
if
(
a
&&
a
.
agent
&&
a
.
licenseKey
&&
a
.
applicationID
&&
i
&&
i
.
body
){
m
.
proto
=
"https"
===
l
.
split
(
":"
)[
0
]
||
a
.
sslForHttp
?
"https://"
:
"http://"
,
g
(
"mark"
,[
"onload"
,
f
()]);
var
b
=
i
.
createElement
(
"script"
);
b
.
src
=
0
==
a
.
agent
.
indexOf
(
"//"
)?
a
.
agent
:
m
.
proto
+
a
.
agent
,
b
.
src
+=
"?v=411.4.9 "
,
i
.
body
.
appendChild
(
b
)}}
function
d
(){
o
||
"complete"
===
i
.
readyState
&&
e
()}
function
e
(){
g
(
"mark"
,[
"domContent"
,
f
()])}
function
f
(){
return
(
new
Date
).
getTime
()}
var
g
=
a
(
"handle"
),
h
=
window
,
i
=
h
.
document
,
j
=
"addEventListener"
,
k
=
"attachEvent"
,
l
=
(
""
+
location
).
split
(
"?"
)[
0
],
m
=
b
.
exports
=
{
offset
:
window
.
apmFirstbyte
||
f
(),
origin
:
l
,
features
:{}};
g
(
"mark"
,[
"firstbyte"
,
window
.
apmFirstbyte
||
f
()]),
"complete"
===
document
.
readyState
?(
e
(),
c
()):
i
[
j
]?(
i
[
j
](
"DOMContentLoaded"
,
e
,
!
1
),
h
[
j
](
"load"
,
c
,
!
1
)):(
i
[
k
](
"onreadystatechange"
,
d
),
h
[
k
](
"onload"
,
c
));
var
n
=!
1
,
o
=!
1
;
try
{
n
=
null
==
window
.
frameElement
&&
document
.
documentElement
}
catch
(
m
){}
n
&&
n
.
doScroll
&&!
function
p
(){
if
(
!
o
){
try
{
n
.
doScroll
(
"left"
)}
catch
(
a
){
return
setTimeout
(
p
,
50
)}
o
=!
0
,
e
()}}()},{
handle
:
33
}],
33
:
[
function
(
a
,
b
){
function
c
(
a
,
b
,
c
){
return
d
.
listeners
(
a
).
length
?
d
.
emit
(
a
,
b
,
c
):(
e
[
a
]
||
(
e
[
a
]
=
[]),
void
e
[
a
].
push
(
b
))}
var
d
=
a
(
"ee"
).
create
(),
e
=
{};
b
.
exports
=
c
,
c
.
ee
=
d
,
d
.
q
=
e
},{
ee
:
31
}],
36
:
[
function
(
a
,
b
){
function
c
(
a
,
b
,
c
){
b
||
(
b
=
0
),
"undefined"
==
typeof
c
&&
(
c
=
a
?
a
.
length
:
0
);
for
(
var
d
=-
1
,
e
=
c
-
b
||
0
,
f
=
new
Array
(
0
>
e
?
0
:
e
);
++
d
<
e
;)
f
[
d
]
=
a
[
b
+
d
];
return
f
}
b
.
exports
=
c
},{}],
31
:
[
function
(
a
,
b
){
function
c
(
a
){
function
b
(
b
,
c
,
g
){
a
&&
a
(
b
,
c
,
g
),
g
||
(
g
=
{});
var
i
=
h
(
b
),
j
=
i
.
length
,
k
=
{};
try
{
k
=
f
(
g
,
e
,
d
)}
catch
(
l
){}
for
(
var
m
=
0
;
j
>
m
;
m
++
)
i
[
m
].
apply
(
k
,
c
);
return
k
}
function
g
(
a
,
b
){
j
[
a
]
=
h
(
a
).
concat
(
b
)}
function
h
(
a
){
return
j
[
a
]
||
[]}
function
i
(){
return
c
(
b
)}
var
j
=
{};
return
{
on
:
g
,
emit
:
b
,
create
:
i
,
listeners
:
h
,
_events
:
j
}}
function
d
(){
return
{}}
var
e
=
"bw@context"
,
f
=
a
(
"gos"
);
b
.
exports
=
c
()},{
gos
:
32
}],
32
:
[
function
(
a
,
b
){
function
c
(
a
,
b
,
c
){
if
(
d
.
call
(
a
,
b
))
return
a
[
b
];
var
e
=
c
();
if
(
Object
.
defineProperty
&&
Object
.
keys
)
try
{
return
Object
.
defineProperty
(
a
,
b
,{
value
:
e
,
writable
:
!
0
,
enumerable
:
!
1
}),
e
}
catch
(
f
){}
try
{
a
[
b
]
=
e
}
catch
(
f
){}
return
e
}
var
d
=
Object
.
prototype
.
hasOwnProperty
;
b
.
exports
=
c
},{}]},{},[]),
a
=
function
c
(
b
,
d
,
e
){
function
f
(
h
,
i
){
if
(
!
d
[
h
]){
if
(
!
b
[
h
]){
var
j
=
"function"
==
typeof
a
&&
a
;
if
(
!
i
&&
j
)
return
j
(
h
,
!
0
);
if
(
g
)
return
g
(
h
,
!
0
);
var
k
=
new
Error
(
"Cannot find module '"
+
h
+
"'"
);
throw
k
.
code
=
"MODULE_NOT_FOUND"
,
k
}
var
l
=
d
[
h
]
=
{
exports
:{}};
b
[
h
][
0
].
call
(
l
.
exports
,
function
(
a
){
var
c
=
b
[
h
][
1
][
a
];
return
f
(
c
?
c
:
a
)},
l
,
l
.
exports
,
c
,
b
,
d
,
e
)}
return
d
[
h
].
exports
}
for
(
var
g
=
"function"
==
typeof
a
&&
a
,
h
=
0
;
h
<
e
.
length
;
h
++
)
f
(
e
[
h
]);
return
f
}({
1
:[
function
(
a
){
a
(
"loader"
),
a
(
"errorload"
),
a
(
"xhrload"
),
a
(
"perfload"
)},{
errorload
:
5
,
loader
:
34
,
perfload
:
6
,
xhrload
:
7
}],
7
:
[
function
(
a
){
function
b
(
a
){
if
(
"string"
==
typeof
a
&&
a
.
length
)
return
a
.
length
;
if
(
"object"
!=
typeof
a
)
return
void
0
;
if
(
"undefined"
!=
typeof
ArrayBuffer
&&
a
instanceof
ArrayBuffer
&&
a
.
byteLength
)
return
a
.
byteLength
;
if
(
"undefined"
!=
typeof
Blob
&&
a
instanceof
Blob
&&
a
.
size
)
return
a
.
size
;
if
(
"undefined"
!=
typeof
FormData
&&
a
instanceof
FormData
)
return
void
0
;
try
{
return
JSON
.
stringify
(
a
).
length
}
catch
(
b
){
return
void
0
}}
function
c
(
a
,
b
){
return
b
}
function
d
(
a
){
a
.
send
=
o
.
wrapOld
(
a
.
send
,
"send-xhr-"
,
c
),
a
.
onreadystatechange
=
o
.
wrapOld
(
a
.
onreadystatechange
,
"iexhr-onreadystatechange-"
,
c
),
a
.
onerror
=
o
.
wrapOld
(
a
.
onerror
,
"iexhr-onerror-"
,
c
)}
function
e
(
a
){
var
c
=
this
.
params
,
d
=
this
.
metrics
;
if
(
!
this
.
ended
){
if
(
this
.
ended
=!
0
,
a
.
removeEventListener
)
for
(
var
e
=
0
;
m
>
e
;
e
++
)
a
.
removeEventListener
(
l
[
e
],
this
.
listener
,
!
1
);
if
(
!
c
.
aborted
){
if
(
d
.
duration
=
(
new
Date
).
getTime
()
-
this
.
startTime
,
4
===
a
.
readyState
){
c
.
status
=
a
.
status
;
var
f
=
a
.
responseType
,
g
=
"arraybuffer"
===
f
||
"blob"
===
f
||
"json"
===
f
?
a
.
response
:
a
.
responseText
,
h
=
b
(
g
);
h
&&
(
d
.
rxSize
=
h
)}
else
c
.
status
=
0
;
d
.
cbTime
=
this
.
cbTime
,
c
&&
c
.
pathname
&&
c
.
pathname
.
indexOf
(
"beacon/resources"
)
<
0
&&
i
(
"xhr"
,[
c
,
d
,
this
.
startTime
,
this
.
creatType
])}}}
function
f
(
a
,
b
){
var
c
=
j
(
b
),
d
=
a
.
params
;
d
.
host
=
c
.
hostname
+
":"
+
c
.
port
,
d
.
pathname
=
c
.
pathname
,
a
.
sameOrigin
=
c
.
sameOrigin
}
var
g
=
window
,
h
=
(
g
.
performance
,
window
.
XMLHttpRequest
);
if
(
h
&&
h
.
prototype
&&!
/CriOS/
.
test
(
navigator
.
userAgent
)){
a
(
"loader"
).
features
.
xhr
=!
0
;
var
i
=
a
(
"handle"
),
j
=
a
(
"parse-url"
),
k
=
a
(
"ee"
),
l
=
[
"load"
,
"error"
,
"abort"
,
"timeout"
],
m
=
l
.
length
,
n
=
a
(
"loader_id"
),
o
=
a
(
"wrap-function"
)(
k
);
a
(
"wrap-events"
),
a
(
"wrap-xhr"
),
k
.
on
(
"new-xhr"
,
function
(){
this
.
totalCbs
=
0
,
this
.
called
=
0
,
this
.
cbTime
=
0
,
this
.
end
=
e
,
this
.
ended
=!
1
,
this
.
xhrGuids
=
{}}),
k
.
on
(
"open-xhr-start"
,
function
(
a
){
this
.
params
=
{
method
:
a
[
0
]},
f
(
this
,
a
[
1
]),
this
.
metrics
=
{}}),
k
.
on
(
"open-xhr-end"
,
function
(
a
,
b
){
b
.
__oldie
&&
d
(
b
)}),
k
.
on
(
"send-xhr-start"
,
function
(
a
,
c
){
var
d
=
this
.
metrics
,
e
=
a
[
0
],
f
=
this
;
if
(
d
&&
e
){
var
g
=
b
(
e
);
g
&&
(
d
.
txSize
=
g
)}
if
(
this
.
startTime
=
(
new
Date
).
getTime
(),
this
.
listener
=
function
(
a
){
try
{
"abort"
===
a
.
type
&&
(
f
.
params
.
aborted
=!
0
),(
"load"
!==
a
.
type
||
f
.
called
===
f
.
totalCbs
&&
(
f
.
onloadCalled
||
"function"
!=
typeof
c
.
onload
))
&&
f
.
end
&&
f
.
end
(
c
)}
catch
(
b
){
try
{
k
.
emit
(
"internal-error"
,[
b
])}
catch
(
d
){}}},
c
.
addEventListener
)
for
(
var
h
=
0
;
m
>
h
;
h
++
)
c
.
addEventListener
(
l
[
h
],
this
.
listener
,
!
1
)}),
k
.
on
(
"iexhr-onreadystatechange-start"
,
function
(
a
,
b
){
if
(
1
==
b
.
readyState
){
var
d
=
b
.
onreadystatechange
;
setTimeout
(
function
(){
b
.
onreadystatechange
!==
d
&&
(
b
.
onreadystatechange
=
o
.
wrapOld
(
b
.
onreadystatechange
,
"iexhr-onreadystatechange-"
,
c
))},
0
)}
4
==
b
.
readyState
&&
(
this
.
xhrCbStart
=
(
new
Date
).
getTime
())}),
k
.
on
(
"iexhr-onreadystatechange-end"
,
function
(
a
,
b
){
var
c
=
this
;
this
.
xhrCbStart
&&
k
.
emit
(
"xhr-cb-time"
,[(
new
Date
).
getTime
()
-
this
.
xhrCbStart
,
this
.
onload
,
b
],
b
),
4
==
b
.
readyState
&&
c
.
end
(
b
)}),
k
.
on
(
"xhr-cb-time"
,
function
(
a
,
b
,
c
){
this
.
cbTime
+=
a
,
b
?
this
.
onloadCalled
=!
0
:
this
.
called
+=
1
,
this
.
called
!==
this
.
totalCbs
||!
this
.
onloadCalled
&&
"function"
==
typeof
c
.
onload
||
this
.
end
(
c
)}),
k
.
on
(
"xhr-load-added"
,
function
(
a
,
b
){
var
c
=
""
+
n
(
a
)
+!!
b
;
this
.
xhrGuids
&&!
this
.
xhrGuids
[
c
]
&&
(
this
.
xhrGuids
[
c
]
=!
0
,
this
.
totalCbs
+=
1
)}),
k
.
on
(
"xhr-load-removed"
,
function
(
a
,
b
){
var
c
=
""
+
n
(
a
)
+!!
b
;
this
.
xhrGuids
&&
this
.
xhrGuids
[
c
]
&&
(
delete
this
.
xhrGuids
[
c
],
this
.
totalCbs
-=
1
)}),
k
.
on
(
"addEventListener-end"
,
function
(
a
,
b
){
b
instanceof
XMLHttpRequest
&&
"load"
===
a
[
0
]
&&
k
.
emit
(
"xhr-load-added"
,[
a
[
1
],
a
[
2
]],
b
)}),
k
.
on
(
"removeEventListener-end"
,
function
(
a
,
b
){
b
instanceof
XMLHttpRequest
&&
"load"
===
a
[
0
]
&&
k
.
emit
(
"xhr-load-removed"
,[
a
[
1
],
a
[
2
]],
b
)}),
k
.
on
(
"fn-start"
,
function
(
a
,
b
,
c
){
b
instanceof
XMLHttpRequest
&&
(
"onload"
===
c
&&
(
this
.
onload
=!
0
),(
"load"
===
(
a
[
0
]
&&
a
[
0
].
type
)
||
this
.
onload
)
&&
(
this
.
xhrCbStart
=
(
new
Date
).
getTime
()))}),
k
.
on
(
"fn-end"
,
function
(
a
,
b
){
this
.
xhrCbStart
&&
k
.
emit
(
"xhr-cb-time"
,[(
new
Date
).
getTime
()
-
this
.
xhrCbStart
,
this
.
onload
,
b
],
b
)})}},{
ee
:
31
,
handle
:
33
,
loader
:
34
,
loader_id
:
35
,
"parse-url"
:
38
,
"wrap-events"
:
28
,
"wrap-function"
:
39
,
"wrap-xhr"
:
30
}],
35
:
[
function
(
a
,
b
){
function
c
(
a
){
var
b
=
typeof
a
;
return
!
a
||
"object"
!==
b
&&
"function"
!==
b
?
-
1
:
a
===
window
?
0
:
f
(
a
,
e
,
function
(){
return
d
++
})}
var
d
=
1
,
e
=
"bw@id"
,
f
=
a
(
"gos"
);
b
.
exports
=
c
},{
gos
:
32
}],
6
:
[
function
(
a
){
var
b
=
window
.
performance
;
if
(
b
&&
b
.
timing
&&
b
.
getEntriesByType
){
var
c
=
a
(
"ee"
),
d
=
a
(
"handle"
),
e
=
(
a
(
"wrap-timer"
),
a
(
"loader"
));
e
.
features
.
stn
=!
0
,
c
.
on
(
"fn-start"
,
function
(
a
){
var
b
=
a
[
0
];
b
instanceof
Event
&&
(
this
.
bstStart
=
Date
.
now
())}),
c
.
on
(
"fn-end"
,
function
(
a
,
b
){
var
c
=
a
[
0
];
c
instanceof
Event
&&
d
(
"bst"
,[
c
,
b
,
this
.
bstStart
,
Date
.
now
()])})}},{
ee
:
31
,
handle
:
33
,
loader
:
34
,
"wrap-timer"
:
29
}],
5
:
[
function
(
a
){
function
b
(
a
,
b
,
d
,
g
,
i
){
try
{
j
?
j
-=
1
:
e
(
"err"
,[
i
||
new
c
(
a
,
b
,
d
)])}
catch
(
k
){
try
{
e
(
"ierr"
,[
k
,(
new
Date
).
getTime
(),
!
0
])}
catch
(
l
){}}
return
"function"
==
typeof
h
?
h
.
apply
(
this
,
f
(
arguments
)):
!
1
}
function
c
(
a
,
b
,
c
){
this
.
message
=
a
||
"Uncaught error with no additional information"
,
this
.
sourceURL
=
b
,
this
.
line
=
c
}
function
d
(
a
){
e
(
"err"
,[
a
,(
new
Date
).
getTime
()])}
var
e
=
a
(
"handle"
),
f
=
a
(
"lodash._slice"
),
g
=
a
(
"ee"
),
h
=
window
.
onerror
,
i
=!
1
,
j
=
0
;
a
(
"loader"
).
features
.
err
=!
0
,
window
.
onerror
=
b
,
window
.
BWEUM
.
noticeError
=
d
;
var
k
=
window
.
XMLHttpRequest
;
try
{
throw
new
Error
}
catch
(
l
){
"stack"
in
l
&&
(
a
(
"wrap-timer"
),
"addEventListener"
in
window
&&
a
(
"wrap-events"
),
k
&&
k
.
prototype
&&
k
.
prototype
.
addEventListener
&&
a
(
"wrap-xhr"
),
i
=!
0
)}
g
.
on
(
"fn-start"
,
function
(){
i
&&
(
j
+=
1
)}),
g
.
on
(
"fn-err"
,
function
(
a
,
b
,
c
){
i
&&
(
this
.
thrown
=!
0
,
d
(
c
))}),
g
.
on
(
"fn-end"
,
function
(){
i
&&!
this
.
thrown
&&
j
>
0
&&
(
j
-=
1
)}),
g
.
on
(
"internal-error"
,
function
(
a
){
e
(
"ierr"
,[
a
,(
new
Date
).
getTime
(),
!
0
])})},{
ee
:
31
,
handle
:
33
,
loader
:
34
,
"lodash._slice"
:
36
,
"wrap-events"
:
28
,
"wrap-timer"
:
29
,
"wrap-xhr"
:
30
}],
30
:
[
function
(
a
,
b
){
function
c
(){
j
.
inPlace
(
this
,
m
,
"fn-"
)}
function
d
(
a
,
b
){
j
.
inPlace
(
b
,[
"onreadystatechange"
],
"fn-"
)}
function
e
(
a
){
a
.
open
=
j
.
wrapOld
(
a
.
open
,
"open-xhr-"
,
f
)}
function
f
(
a
,
b
){
return
b
}
var
g
=
a
(
"ee"
).
create
(),
h
=
a
(
"wrap-events"
),
i
=
a
(
"wrap-function"
),
j
=
i
(
g
),
k
=
i
(
h
),
l
=
window
.
XMLHttpRequest
,
m
=
[
"onload"
,
"onerror"
,
"onabort"
,
"onloadstart"
,
"onloadend"
,
"onprogress"
,
"ontimeout"
];
b
.
exports
=
g
,
window
.
_ApmXMLHttpRequest
=
window
.
XMLHttpRequest
,
window
.
XMLHttpRequest
=
function
(
a
){
var
b
=
new
l
(
a
);
try
{
g
.
emit
(
"new-xhr"
,[],
b
),
l
.
prototype
.
addEventListener
?(
k
.
inPlace
(
b
,[
"addEventListener"
,
"removeEventListener"
],
"-"
,
function
(
a
,
b
){
return
b
}),
b
.
addEventListener
(
"readystatechange"
,
c
,
!
1
)):(
b
.
__oldie
=!
0
,
e
(
b
))}
catch
(
d
){
try
{
g
.
emit
(
"internal-error"
,[
d
])}
catch
(
f
){}}
return
b
},
window
.
XMLHttpRequest
.
prototype
=
l
.
prototype
,
j
.
inPlace
(
XMLHttpRequest
.
prototype
,[
"open"
,
"send"
],
"-xhr-"
,
f
),
g
.
on
(
"send-xhr-start"
,
d
),
g
.
on
(
"open-xhr-start"
,
d
)},{
ee
:
31
,
"wrap-events"
:
28
,
"wrap-function"
:
39
}],
29
:
[
function
(
a
,
b
){
function
c
(
a
,
b
,
c
){
var
d
=
a
[
0
];
"string"
==
typeof
d
&&
(
d
=
new
Function
(
d
)),
a
[
0
]
=
e
(
d
,
"fn-"
,
null
,
c
)}
var
d
=
(
a
(
"lodash._slice"
),
a
(
"ee"
).
create
()),
e
=
a
(
"wrap-function"
)(
d
);
b
.
exports
=
d
,
e
.
inPlace
(
window
,[
"setTimeout"
,
"setInterval"
,
"setImmediate"
],
"setTimer-"
),
d
.
on
(
"setTimer-start"
,
c
)},{
ee
:
31
,
"lodash._slice"
:
36
,
"wrap-function"
:
39
}],
28
:
[
function
(
a
,
b
){
function
c
(
a
){
f
.
inPlace
(
a
,[
"addEventListener"
,
"removeEventListener"
],
"-"
,
d
)}
function
d
(
a
){
return
a
[
1
]}
var
e
=
(
a
(
"lodash._slice"
),
a
(
"ee"
).
create
()),
f
=
a
(
"wrap-function"
)(
e
),
g
=
a
(
"gos"
);
if
(
b
.
exports
=
e
,
c
(
window
),
"getPrototypeOf"
in
Object
){
for
(
var
h
=
document
;
h
&&!
h
.
hasOwnProperty
(
"addEventListener"
);)
h
=
Object
.
getPrototypeOf
(
h
);
h
&&
c
(
h
);
for
(
var
i
=
XMLHttpRequest
.
prototype
;
i
&&!
i
.
hasOwnProperty
(
"addEventListener"
);)
i
=
Object
.
getPrototypeOf
(
i
);
i
&&
c
(
i
)}
else
Object
.
prototype
.
hasOwnProperty
.
call
(
XMLHttpRequest
,
"addEventListener"
)
&&
c
(
XMLHttpRequest
.
prototype
);
e
.
on
(
"addEventListener-start"
,
function
(
a
){
if
(
a
[
1
]){
var
b
=
a
[
1
];
"function"
==
typeof
b
?
this
.
wrapped
=
a
[
1
]
=
g
(
b
,
"bw@wrapped"
,
function
(){
return
f
(
b
,
"fn-"
,
null
,
b
.
name
||
"anonymous"
)}):
"function"
==
typeof
b
.
handleEvent
&&
f
.
inPlace
(
b
,[
"handleEvent"
],
"fn-"
)}}),
e
.
on
(
"removeEventListener-start"
,
function
(
a
){
var
b
=
this
.
wrapped
;
b
&&
(
a
[
1
]
=
b
)})},{
ee
:
31
,
gos
:
32
,
"lodash._slice"
:
36
,
"wrap-function"
:
39
}],
39
:
[
function
(
a
,
b
){
function
c
(
a
){
return
!
(
a
&&
"function"
==
typeof
a
&&
a
.
apply
&&!
a
[
f
])}
var
d
=
a
(
"ee"
),
e
=
a
(
"lodash._slice"
),
f
=
"bw@wrapper"
,
g
=
Object
.
prototype
.
hasOwnProperty
;
b
.
exports
=
function
(
a
){
function
b
(
a
,
b
,
d
,
g
,
i
){
function
j
(){
var
c
=
this
;
return
h
(
a
,
b
,
c
,
e
(
arguments
),
d
,
g
,
i
)}
if
(
c
(
a
))
return
a
;
b
||
(
b
=
""
);
try
{
j
[
f
]
=!
0
}
catch
(
k
){}
return
l
(
a
,
j
),
j
}
function
h
(
a
,
b
,
c
,
d
,
e
,
f
){
var
d
,
c
,
g
,
h
;
try
{
g
=
e
&&
e
(
d
,
c
)
||
{}}
catch
(
i
){
m
([
i
,
""
,[
d
,
c
,
f
],
g
])}
_apmfnName
=
a
.
name
||
""
,
k
(
b
+
"start"
,[
d
,
c
,
f
,
_apmfnName
],
g
);
try
{
return
h
=
a
.
apply
(
c
,
d
)}
catch
(
j
){
var
l
=
window
.
console
;
throw
void
0
!=
l
&&
l
.
error
&&
l
.
log
&&
void
0
!=
j
.
stack
&&
(
l
.
log
(
"OneAPM catch error"
),
l
.
error
(
j
.
stack
)),
k
(
b
+
"err"
,[
d
,
c
,
j
],
g
),
j
}
finally
{
k
(
b
+
"end"
,[
d
,
c
,
h
,
_apmfnName
],
g
)}}
function
i
(
a
,
b
,
c
){
var
a
=
a
||
function
(){},
b
=
b
||
"-"
;
return
function
(){
var
d
=
this
;
return
h
(
a
,
b
,
d
,
e
(
arguments
),
c
)}}
function
j
(
a
,
d
,
e
,
f
){
e
||
(
e
=
""
);
var
g
,
h
,
i
,
j
=
"-"
===
e
.
charAt
(
0
);
for
(
i
=
0
;
i
<
d
.
length
;
i
++
)
h
=
d
[
i
],
g
=
a
[
h
],
c
(
g
)
||
(
a
[
h
]
=
b
(
g
,
j
?
h
+
e
:
e
,
f
,
h
,
a
))}
function
k
(
b
,
c
,
d
){
try
{
a
.
emit
(
b
,
c
,
d
)}
catch
(
e
){
m
([
e
,
b
,
c
,
d
])}}
function
l
(
a
,
b
){
if
(
Object
.
defineProperty
&&
Object
.
keys
)
try
{
var
c
=
Object
.
keys
(
a
);
return
c
.
forEach
(
function
(
c
){
Object
.
defineProperty
(
b
,
c
,{
get
:
function
(){
return
a
[
c
]},
set
:
function
(
b
){
return
a
[
c
]
=
b
,
b
}})}),
b
}
catch
(
d
){
m
([
d
])}
for
(
var
e
in
a
)
g
.
call
(
a
,
e
)
&&
(
b
[
e
]
=
a
[
e
]);
return
b
}
function
m
(
b
){
try
{
a
.
emit
(
"internal-error"
,
b
)}
catch
(
c
){}}
return
a
||
(
a
=
d
),
b
.
inPlace
=
j
,
b
.
flag
=
f
,
b
.
wrapOld
=
i
,
b
}},{
ee
:
31
,
"lodash._slice"
:
36
}]},{},[
1
]),
window
.
BWEUM
.
require
=
a
}();
</script>
<!-- end oneapm agent -->
<link
rel=
"dns-prefetch"
href=
"//cdn.yoho.cn"
>
<link
rel=
"dns-prefetch"
href=
"//static.yohobuy.com"
>
<link
rel=
"dns-prefetch"
href=
"//img12.static.yhbimg.com"
>
...
...
package.json
View file @
e232f76
{
"name"
:
"yohobuy-node"
,
"version"
:
"5.
1.6
"
,
"version"
:
"5.
2.0
"
,
"private"
:
true
,
"description"
:
"A New Yohobuy Project With Express"
,
"repository"
:
{
...
...
@@ -44,6 +44,7 @@
"md5"
:
"^2.1.0"
,
"moment"
:
"^2.14.1"
,
"morgan"
:
"^1.7.0"
,
"oneapm"
:
"^1.2.20"
,
"passport"
:
"^0.3.2"
,
"passport-douban"
:
"0.0.1"
,
"passport-local"
:
"^1.0.0"
,
...
...
public/img/cart/row.png
0 → 100644
View file @
e232f76
2.78 KB
public/img/sprite.cart.png
View file @
e232f76
1.18 KB
|
W:
|
H:
1.33 KB
|
W:
|
H:
2-up
Swipe
Onion skin
public/js/cart/easypay.page.js
View file @
e232f76
...
...
@@ -13,19 +13,11 @@ var $pdUsed = $('#pay-delivery-used');
var
$balance
=
$
(
'#balance-detail'
);
var
couponsTpl
=
Hbs
.
compile
(
$
(
'#coupons-tpl'
).
html
());
var
coinTpl
=
Hbs
.
compile
(
$
(
'#yoho-coin-tpl'
).
html
());
var
promotionTpl
=
Hbs
.
compile
(
$
(
'#promotion-list-tpl'
).
html
());
var
$coin
=
$
(
'#coin-used'
);
var
$coinTip
=
$
(
'#coin-tip'
);
var
$coinSure
=
$
(
'#coin-sure'
);
var
coinMax
=
+
$coin
.
data
(
'max'
);
var
coinStatus
=
{
err
:
'请输入一个正整数'
,
max
:
'您的有货币不足'
,
success
:
'抵扣'
,
maxUse
:
'您最多使用'
,
muPostfix
:
'个有货币'
};
var
queryInfo
;
var
pkgCache
=
{};
...
...
@@ -67,16 +59,18 @@ function updateUsedPdShow(info) {
}
// 订单计算
function
compute
()
{
var
coinUsed
=
$coin
.
data
(
'coin'
);
// 传有货币数量则使用有货币,否者不使用,更改订单总价有货币使用数量重置为0
function
compute
(
coin
)
{
var
d
=
{
cartType
:
window
.
queryString
().
type
,
deliveryWay
:
$
(
'input[name="delivery-way-radio"]:checked'
).
val
(),
paymentType
:
$
(
'#payment-way'
).
data
(
'id'
),
coin
:
coin
Used
?
parseInt
(
coinUsed
,
10
)
:
0
coin
:
coin
?
parseInt
(
coin
,
10
)
:
0
};
var
couponCode
=
$
(
'#coupons-sure'
).
data
(
'coupons'
);
$coin
.
data
(
'coin'
,
d
.
coin
);
if
(
couponCode
)
{
d
.
couponCode
=
couponCode
;
}
...
...
@@ -103,9 +97,14 @@ function compute() {
var
res
;
if
(
data
.
code
===
200
)
{
res
=
data
.
data
;
// update yoho coin max use num
$coin
.
data
(
'max'
,
res
.
canUseCoinNum
);
// update yoho coin using
$
(
'#using-coin-cont'
).
html
(
coinTpl
(
res
));
// update last order amount
$
(
'#sum-row em'
).
html
(
res
.
last_order_amount
);
...
...
@@ -178,63 +177,32 @@ if ($('#use-coupons').length) {
}
// 有货币
if
(
$coin
)
{
$coin
.
data
(
$coin
.
data
());
// 防止人为页面更改有货币使用数量
}
$
(
'#use-coin, #coin-sure, #coin-cancel'
).
click
(
function
()
{
$
(
'.coin-trigger'
).
toggleClass
(
'hide'
);
});
$coin
.
on
(
'propertychange input'
,
function
()
{
var
c
=
$
.
trim
(
$coin
.
val
());
var
err
=
true
;
if
(
c
===
''
)
{
// 输入框为空,确定按钮不可点
$coinTip
.
addClass
(
'vhide'
);
$coinTip
.
text
(
coinStatus
.
err
);
return
;
}
else
if
(
!
/^
[
1-9
]\d
*$/
.
test
(
c
))
{
// 验证输入不为正整数
$coinTip
.
text
(
coinStatus
.
err
);
}
else
if
(
+
c
>
coinMax
)
{
// 有货币不足
$coinTip
.
text
(
coinStatus
.
max
);
}
else
if
(
+
c
>
$
(
'#sum-row'
).
data
(
'amount'
)
*
100
)
{
// 输入的有货币大于订单额度
$coinTip
.
text
(
coinStatus
.
maxUse
+
(
$
(
'#sum-row'
).
data
(
'amount'
)
*
100
)
+
coinStatus
.
muPostfix
);
}
else
{
err
=
false
;
$coinTip
.
text
(
coinStatus
.
success
+
(
c
/
100
).
toFixed
(
2
)
+
'元'
);
// 已使用面板的数据显示更新
// $coinUsed.html(c);
// $coinDeduction.html((c / 100).toFixed(2));
}
if
(
err
)
{
$coinSure
.
addClass
(
'disable'
);
$coinTip
.
removeClass
(
'vhide'
);
}
else
{
$coinSure
.
removeClass
(
'disable'
);
$coinTip
.
addClass
(
'vhide'
);
}
});
$coinSure
.
click
(
function
()
{
if
(
$coinSure
.
hasClass
(
'disable'
))
{
var
data
=
$coin
.
data
();
if
(
$coinSure
.
hasClass
(
'disable'
)
||
data
.
coin
===
data
.
max
)
{
return
;
}
$coin
.
data
(
'coin'
,
$
.
trim
(
$coin
.
val
()));
// coin change trigger compute
compute
();
compute
(
data
.
max
);
});
$
(
'#coin-cancel'
).
click
(
function
()
{
$coin
.
val
(
''
).
data
(
'coin'
,
''
);
$coinTip
.
addClass
(
'vhide'
).
text
(
''
);
var
data
=
$coin
.
data
();
if
(
data
.
coin
*
1
===
0
)
{
return
;
}
// coin cancel trigger compute
compute
();
...
...
@@ -242,11 +210,13 @@ $('#coin-cancel').click(function() {
// 结算信息列表中修改有货币按钮
$
(
'.balance-detail'
).
on
(
'click'
,
'.modify-coin'
,
function
()
{
$
(
'
.coin-trigger'
).
filter
(
'.use-coin'
).
addClass
(
'hide'
).
end
().
filter
(
'.using-coin'
).
removeClass
(
'hide
'
);
$
(
'
#use-coin'
).
trigger
(
'click
'
);
});
// delivery way change trigger compute
$
(
'input[name="delivery-way-radio"]'
).
change
(
compute
);
$
(
'input[name="delivery-way-radio"]'
).
change
(
function
()
{
compute
();
});
// 去支付
$
(
'#go-pay'
).
click
(
function
()
{
...
...
public/js/cart/order/invoice.js
View file @
e232f76
...
...
@@ -49,7 +49,7 @@ function validateInvoice($el) {
function
pkgInvoice
()
{
var
$contentChecked
=
$
(
'input[name="invoice-content"]:checked'
);
var
pkg
=
{
invocesType
:
$
(
'.el-invoice'
).
hasClass
(
'focus'
)
?
'
1'
:
'2
'
,
invocesType
:
$
(
'.el-invoice'
).
hasClass
(
'focus'
)
?
'
2'
:
'1
'
,
invoicesTitle
:
$
(
'input[name="invoice-title"]'
).
prop
(
'checked'
)
?
'个人'
:
$
(
'#company-name'
).
val
(),
invoicesContent
:
$contentChecked
.
val
(),
invoicesContentName
:
$contentChecked
.
data
(
'name'
)
...
...
public/js/channel/channel.page.js
View file @
e232f76
...
...
@@ -43,8 +43,6 @@ if ($.inArray(homePage, ['boys', 'girls', 'kids', 'lifestyle']) > -1) {
});
}
lazyLoad
(
$
(
'img.lazy'
));
if
(
homePage
===
'boys'
)
{
$
(
'.slide-container'
).
slider
({
...
...
@@ -73,3 +71,18 @@ $('.new-user-proList').slider2({
shownum
:
5
,
isCircle
:
false
});
if
(
window
.
cookie
(
'_UID'
))
{
// 判断是否有新人专享
$
.
ajax
({
type
:
'GET'
,
url
:
'/channel/isNewUserAjax'
,
data
:
{},
success
:
function
(
res
)
{
if
(
!
res
.
isNewUser
)
{
$
(
'.new-user'
).
addClass
(
'hide'
);
}
}
});
}
...
...
public/js/common/data-yas.js
View file @
e232f76
...
...
@@ -99,8 +99,7 @@ function yasEvent(op, parameter) {
parameter
=
$
.
extend
({
C_ID
:
CID
},
parameter
);
console
.
info
(
op
);
console
.
info
(
parameter
);
window
.
_yas
.
sendCustomInfo
({
op
:
op
,
param
:
JSON
.
stringify
(
parameter
)
...
...
public/js/passport/login/index.js
View file @
e232f76
...
...
@@ -55,6 +55,7 @@ var $accountInput1 = $('#account1'),
$captchaImgInput
=
$
(
'#captcha'
),
$captchaImgWrapper
=
$
(
'.captcha-wrap'
),
$captchaImgPic
=
$captchaImgWrapper
.
find
(
'#captcha-img'
),
$showCaptchImg
=
false
,
getCaptchaImgVal
=
function
()
{
return
$
.
trim
(
$captchaImgInput
.
val
());
},
...
...
@@ -281,6 +282,19 @@ accountChangeEvent.add(function(type) {
$qrCodeOverLayer
.
empty
();
initQrCode
();
// eslint-disable-line
}
// 密码登录的图形验证码
if
(
type
===
AccountLoginData
.
PasswordLogin
.
name
)
{
if
(
$showCaptchImg
)
{
$captchaImgWrapper
.
removeClass
(
'hide'
);
}
}
if
(
type
===
AccountLoginData
.
SMSLogin
.
name
)
{
if
(
$showCaptchImg
)
{
$captchaImgWrapper
.
addClass
(
'hide'
);
}
}
});
// 保留已输入的帐号信息
...
...
@@ -303,6 +317,7 @@ mobileTipShowOnce.add(function() {
refreshSmsImgCallBack
.
add
(
function
()
{
$smsCaptchaImgPic
.
attr
(
'src'
,
CAPTCHA_IMG_URL
+
$
.
now
());
$smsCaptchaImgInput
.
val
(
''
);
});
/** ************************************************************************/
...
...
@@ -641,6 +656,11 @@ function validateCaptchaSmsAsync() {
isSmsCheckedSuccessFlag
=
true
;
defer
.
resolve
();
}
else
if
(
result
.
code
===
501
)
{
showCaptchaSmsTip
(
result
.
message
);
$captchaSmsTokenHideInput
.
val
(
''
);
defer
.
reject
();
}
else
{
showCaptchaSmsTip
(
'验证码不正确'
);
$captchaSmsTokenHideInput
.
val
(
''
);
...
...
@@ -743,7 +763,7 @@ function smsCaptchaImgAsync() {
}
function
validateSmsCaptchaImg
()
{
smsCaptchaImgLocal
()
return
smsCaptchaImgLocal
()
.
then
(
smsCaptchaImgAsync
)
.
then
(
hideSmsCaptchaImgTip
);
}
...
...
@@ -848,7 +868,6 @@ function validateWithPasswordMode() {
// 短信验证过程
function
validateWithSmsMode
()
{
return
validateAccount
()
.
then
(
validateSmsCaptchaImg
)
.
then
(
validateCaptchaSms
);
}
...
...
@@ -901,31 +920,31 @@ function preSmsLoginWithValidate() {
var
defer
=
$
.
Deferred
();
// eslint-disable-line
if
(
account
===
''
)
{
showAccountTip
1
(
'请输入手机号'
);
showAccountTip
2
(
'请输入手机号'
);
defer
.
reject
();
return
defer
.
reject
().
promise
();
}
if
(
smsImg
===
''
)
{
showSmsCaptchaImgTip
(
'请输入图形证码'
);
defer
.
reject
();
return
defer
.
reject
().
promise
();
}
if
(
password
===
''
)
{
showCaptchaSmsTip
(
'请输入短信验证码'
);
defer
.
reject
();
return
defer
.
reject
().
promise
();
}
if
(
password
===
''
&&
account
===
''
)
{
// 账户名和密码都为空的情况下点击登陆,只在账户输入框后显示错误提示
showAccountTip
1
(
'请输入手机号和短信验证码'
);
showAccountTip
2
(
'请输入手机号和短信验证码'
);
$captchaSmsTip
.
addClass
(
'hide'
);
$captchaSmsInput
.
addClass
(
'error'
);
defer
.
reject
();
return
defer
.
reject
().
promise
();
}
return
defer
.
resolve
().
promise
();
...
...
@@ -946,7 +965,7 @@ function loginAsync() {
areaCode
:
getAreaCodeVal
(),
account
:
currentLogin
.
getAccountVal
(),
password
:
currentLogin
.
creditableToken
(),
captcha
:
currentLogin
.
type
()
===
'password'
?
getCaptchaImgVal
()
:
getSmsCaptchaImgVal
()
,
captcha
:
currentLogin
.
type
()
===
'password'
?
getCaptchaImgVal
()
:
''
,
isRemember
:
getRememberMeVal
(),
loginType
:
currentLogin
.
type
()
}
...
...
@@ -978,6 +997,7 @@ function showCaptchaImgPic() {
$captchaImgPic
.
attr
(
'src'
,
CAPTCHA_IMG_URL
+
$
.
now
());
$captchaImgInput
.
val
(
''
);
$captchaImgWrapper
.
removeClass
(
'hide'
);
$showCaptchImg
=
true
;
}
// 设置 refer 信息
...
...
@@ -1087,10 +1107,12 @@ $captchaSmsBtn.on('click', function() {
return
;
}
validateAccount
().
then
(
function
()
{
disable60sSendSmsBtn
();
return
sendCaptchaSmsAsync
();
});
validateAccount
()
.
then
(
validateSmsCaptchaImg
)
.
then
(
function
()
{
disable60sSendSmsBtn
();
return
sendCaptchaSmsAsync
();
});
});
// 记住登录状态
...
...
public/js/product/detail.page.js
View file @
e232f76
...
...
@@ -24,7 +24,7 @@ var $main = $('.main'),
skn
=
$main
.
data
(
'skn'
),
deposit
=
$main
.
data
(
'deposit'
)
===
'Y'
,
secKill
=
$main
.
data
(
'seckill'
)
===
'Y'
,
limitCode
=
encodeURIComponent
(
$main
.
data
(
'limitcode'
)
);
limitCode
=
$main
.
data
(
'limitcode'
);
var
SLIDETIME
=
200
;
...
...
@@ -39,15 +39,19 @@ var oldtatus = {
html
:
'<a class="coupon-btn">去使用</a>'
};
var
BRAND_FAV
=
{
add
:
'add'
,
cancel
:
'cancel'
};
var
$saleReturn
=
$
(
'#saleReturn'
);
var
dialogTpl
=
require
(
'hbs/product/coupon-dialog.hbs'
);
var
$goodsIdArr
=
[],
pageNum
=
1
;
var
$goodsIdArr
=
[];
function
productUrl
(
s
)
{
return
window
.
location
.
href
+
'?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"'
+
s
+
'"}}'
;
function
limitedProductUrl
(
s
)
{
return
window
.
location
.
href
+
'?openby:yohobuy={"action":"go.limitpurchase","params":{"lp":"'
+
s
+
'"}}'
;
}
function
isEmpty
(
el
)
{
...
...
@@ -151,7 +155,7 @@ bindEvent.add(function() {
var
uid
=
getUid
();
// eslint-disable-line
if
(
!
uid
)
{
return
$
.
Deferred
().
reject
({
refer
:
window
.
signinUrl
()
}).
promise
();
// eslint-disable-line
return
$
.
Deferred
().
reject
({
data
:
{
refer
:
window
.
signinUrl
()}
}).
promise
();
// eslint-disable-line
}
return
$
.
getJSON
(
'/product/detail/coupon'
,
{
...
...
@@ -161,10 +165,8 @@ bindEvent.add(function() {
if
(
result
.
code
===
200
)
{
defer
.
resolve
();
}
else
if
(
result
.
code
===
400
)
{
defer
.
reject
({
refer
:
window
.
signinUrl
()});
}
else
{
defer
.
reject
();
defer
.
reject
(
result
);
}
return
defer
.
promise
();
...
...
@@ -410,7 +412,7 @@ bindEvent.add(function() {
$qrcode
.
qrcode
({
render
:
'table'
,
size
:
140
,
text
:
productUrl
(
skn
)
text
:
limitedProductUrl
(
limitCode
)
});
}
...
...
@@ -630,9 +632,9 @@ bindEvent.add(function() {
function
acquireCoupon
(
$ele
)
{
var
couponId
=
$ele
.
data
(
'id'
);
var
status
=
$ele
.
data
(
'status'
);
var
i
=
$ele
.
data
(
'i'
);
var
$item
=
$
(
$couponItem
.
get
(
i
));
var
status
=
$item
.
data
(
'status'
);
switch
(
status
)
{
case
1
:
...
...
@@ -642,9 +644,11 @@ bindEvent.add(function() {
$item
.
data
(
'status'
,
3
);
}).
fail
(
function
(
err
)
{
if
(
err
.
refer
)
{
return
window
.
jumpUrl
(
err
.
refer
);
if
(
err
.
data
&&
err
.
data
.
refer
)
{
return
window
.
jumpUrl
(
err
.
data
.
refer
);
}
alert
(
err
.
message
);
});
break
;
default
:
...
...
@@ -652,7 +656,8 @@ bindEvent.add(function() {
}
}
// 增加事件
// 清定原来的事件,增加新的事件
clickAcquireCouponEvent
.
empty
();
clickAcquireCouponEvent
.
add
(
acquireCoupon
);
});
...
...
@@ -669,12 +674,14 @@ $(document).on('click', '.status', function() {
// 品牌收藏
$
(
'#brand-favour'
).
click
(
function
()
{
var
$this
=
$
(
this
);
var
type
=
$this
.
hasClass
(
'coled'
)
?
BRAND_FAV
.
cancel
:
BRAND_FAV
.
add
;
$
.
ajax
({
type
:
'POST'
,
url
:
'/product/index/favoriteBrand'
,
data
:
{
brandId
:
$this
.
data
(
'id'
)
brandId
:
$this
.
data
(
'id'
),
type
:
type
}
}).
then
(
function
(
data
)
{
if
(
data
.
code
===
200
)
{
...
...
@@ -1001,6 +1008,7 @@ $('.comments').on('click', '.img-preview .img-thumb', function() {
$t
.
removeClass
(
'active'
);
}
});
$
(
'.comments'
).
on
(
'click'
,
'.img-preview [data-role="preview-close"]'
,
function
()
{
var
$img
=
$
(
this
).
closest
(
'.img-preview'
).
find
(
'.img-wrap img'
),
...
...
@@ -1020,6 +1028,7 @@ $('.comments').on('click', '.img-preview [data-role="preview-left"]', function()
$img
.
data
(
'rotate'
,
rotate
);
$img
.
css
(
'transform'
,
'rotate('
+
rotate
+
'deg)'
);
});
$
(
'.comments'
).
on
(
'click'
,
'.img-preview [data-role="preview-right"]'
,
function
()
{
var
$img
=
$
(
this
).
closest
(
'.img-preview'
).
find
(
'.img-wrap img'
),
...
...
@@ -1048,44 +1057,21 @@ function randomString(len) {
/*
* 页面加载完
*/
function
initPageYas
(
pNum
)
{
var
loadYas
=
{},
starIndex
=
(
parseInt
(
pNum
,
10
)
-
1
)
*
5
,
endIndex
=
parseInt
(
pNum
,
10
)
*
5
;
var
pageGoods
=
$goodsIdArr
.
slice
(
starIndex
,
endIndex
);
loadYas
=
{
function
initPageYas
()
{
var
loadYas
=
{
REC_POSE
:
100013
,
REC_ID
:
randomString
(
40
),
PRD_ID
:
pageGoods
.
join
(
','
),
PRD_NUM
:
pageGoods
.
length
,
PRD_ID
:
$goodsIdArr
.
join
(
','
),
PRD_NUM
:
$goodsIdArr
.
length
,
ORDER_CODE
:
''
,
ACTION_ID
:
0
,
PAGE_NUM
:
pNum
PAGE_NUM
:
1
};
// 关键词搜索结果页展示时
yas
.
givePoint
(
'YB_CHOOSE_FOR_YOU_Y'
,
loadYas
);
}
/*
* 左右箭头埋点
*/
function
arrowYas
(
$arrow
)
{
var
totalPage
=
Math
.
ceil
(
$goodsIdArr
.
length
/
5
);
if
(
$arrow
.
hasClass
(
'prev'
)
&&
pageNum
>
1
)
{
pageNum
--
;
}
if
(
$arrow
.
hasClass
(
'next'
)
&&
pageNum
<
totalPage
)
{
pageNum
++
;
}
initPageYas
(
pageNum
);
}
// 店铺推荐
function
loadRecommend
()
{
$
.
ajax
({
...
...
@@ -1103,18 +1089,21 @@ function loadRecommend() {
if
(
data
.
code
===
200
)
{
if
(
pro
.
length
===
0
)
{
$
(
'.individual-comment'
).
find
(
'.block-title .title:first-child'
).
addClass
(
'hide'
);
$
(
'.individual-comment'
).
find
(
'.block-title'
).
find
(
'.title'
)
.
addClass
(
'cur'
).
prev
(
'.sep'
).
addClass
(
'hide'
);
$
(
'#recommend-shop'
).
detach
();
fetchLatestWalk
();
// eslint-disable-line
return
;
}
$
(
'.individual-comment'
).
find
(
'.block-title .title'
).
eq
(
0
).
removeClass
(
'hide'
).
addClass
(
'cur'
);
$
(
'.individual-comment'
).
find
(
'.block-title .title'
).
eq
(
1
).
removeClass
(
'cur'
);
$
(
'.individual-comment'
).
find
(
'.block-title'
).
find
(
'.sep'
).
removeClass
(
'hide'
);
$
(
'#recommend-shop'
).
removeClass
(
'hide'
);
$
(
'#recommend-content'
).
append
(
html
);
$
(
'.recommend-slider'
).
slider2
({
shownum
:
5
,
isCircle
:
false
,
yasFun
:
arrowYas
isCircle
:
true
});
$
(
'.recommend-slider .img-item .goods-id'
).
each
(
function
()
{
...
...
@@ -1127,32 +1116,29 @@ function loadRecommend() {
}
// 页面加载完,埋点
initPageYas
(
pageNum
);
initPageYas
();
});
}
// 点击为您推荐商品埋点
$
(
'.recommend-slider .img-item'
).
click
(
function
()
{
var
$this
=
$
(
this
);
var
index
=
parseInt
(
$this
.
index
(),
10
)
+
1
;
var
page
=
index
/
5
<=
1
?
''
:
Math
.
ceil
(
index
/
5
)
+
''
;
var
num
=
index
%
5
?
index
%
5
+
''
:
'5'
;
var
loadYas
=
{
REC_POSE
:
100013
,
REC_ID
:
randomString
(
40
),
PRD_ID
:
$this
.
find
(
'.goods-id'
).
html
(),
PRD_NUM
:
page
+
num
,
ORDER_CODE
:
''
,
ACTION_ID
:
1
,
PAGE_NUM
:
page
===
''
?
1
:
page
};
// 点击为您推荐商品埋点
$
(
'.recommend-slider'
).
on
(
'click'
,
'.img-item'
,
function
()
{
var
$this
=
$
(
this
);
var
proId
=
$this
.
find
(
'.goods-id'
).
html
();
var
loadYas
=
{
REC_POSE
:
100013
,
REC_ID
:
randomString
(
40
),
PRD_ID
:
proId
,
PRD_NUM
:
$goodsIdArr
.
indexOf
(
proId
)
+
1
,
ORDER_CODE
:
''
,
ACTION_ID
:
1
,
PAGE_NUM
:
1
};
// 关键词搜索结果页展示时
yas
.
givePoint
(
'YB_CHOOSE_FOR_YOU_Y'
,
loadYas
);
});
});
}
// 关键词搜索结果页展示时
yas
.
givePoint
(
'YB_CHOOSE_FOR_YOU_Y'
,
loadYas
);
});
window
.
loadRecommend
=
loadRecommend
;
...
...
@@ -1228,6 +1214,7 @@ bindEvent.fire();
}
});
// 品牌收藏
$
.
ajax
({
type
:
'GET'
,
url
:
'/product/index/isfav'
,
...
...
@@ -1235,7 +1222,7 @@ bindEvent.fire();
brandId
:
$
(
'#brand-favour'
).
data
(
'id'
)
}
}).
then
(
function
(
result
)
{
if
(
result
.
code
===
200
)
{
if
(
result
.
code
===
200
&&
result
.
data
)
{
$
(
'#brand-favour'
).
addClass
(
'coled'
);
}
});
...
...
@@ -1244,4 +1231,3 @@ bindEvent.fire();
// 数据懒加载
dataLazyLoad
.
init
({
cls
:
'.datalazyload'
,
threshold
:
0
});
...
...
public/js/product/index/brand.js
View file @
e232f76
...
...
@@ -12,6 +12,11 @@ var $brandFavor = $('#brand-favor'),
id
=
$brandFavor
.
data
(
'id'
),
isFavorite
=
$shopFavor
.
find
(
'i'
).
hasClass
(
'coled'
);
var
BRAND_FAV
=
{
add
:
'add'
,
cancel
:
'cancel'
};
/**
* 品牌收藏
*/
...
...
@@ -20,7 +25,8 @@ $brandFavor.on('click', function() {
type
:
'post'
,
url
:
'/product/index/favoriteBrand'
,
data
:
{
brandId
:
id
brandId
:
id
,
type
:
$brandFavor
.
find
(
'i'
).
hasClass
(
'coled'
)
?
BRAND_FAV
.
cancel
:
BRAND_FAV
.
add
}
}).
then
(
function
(
res
)
{
if
(
res
.
code
===
200
)
{
...
...
public/js/product/index/top-coupon.js
View file @
e232f76
...
...
@@ -115,7 +115,7 @@ function getCouponInfo() {
// 设置优惠券领取状态
function
setPicked
(
info
)
{
if
(
info
)
{
info
.
dom
.
text
(
'已领取'
);
info
.
dom
.
addClass
(
'picked'
).
text
(
'已领取'
);
info
.
status
=
3
;
}
}
...
...
public/scss/cart/_order-ensure.css
View file @
e232f76
...
...
@@ -492,6 +492,95 @@
}
}
.using-coin
{
text-align
:
left
;
li
{
padding-bottom
:
10px
;
}
.red
{
color
:
#db6976
;
}
.help-icon
{
float
:
right
;
cursor
:
pointer
;
&:hover
+
.coin-tip-help
{
display
:
block
;
}
}
.coin-tip-help
{
width
:
304px
;
padding
:
6px
10px
;
line-height
:
2
;
border
:
1px
solid
#000
;
background-color
:
#fff
;
position
:
absolute
;
margin-left
:
56px
;
margin-top
:
6px
;
display
:
none
;
&:before
{
content
:
''
;
width
:
12px
;
height
:
6px
;
background-image
:
url('/cart/row.png')
;
display
:
block
;
position
:
absolute
;
top
:
-6px
;
right
:
10px
;
}
>
p
:first-child
{
font-weight
:
700
;
}
.rs-text
{
color
:
#999
;
}
}
.coin-use-hide
{
color
:
#d4d4d4
;
}
.coin-box
{
display
:
inline-block
;
width
:
70px
;
height
:
24px
;
line-height
:
24px
;
text-align
:
center
;
border
:
1px
solid
#d4d4d4
;
margin
:
0
6px
;
}
.btns
{
margin-top
:
10px
;
text-align
:
left
;
span
{
padding
:
4px
14px
;
cursor
:
pointer
;
border
:
1px
solid
#ccc
;
}
.sure-btn
{
color
:
#fff
;
background-color
:
#000
;
border-color
:
#000
;
margin-right
:
20px
;
}
.coin-help
{
float
:
right
;
color
:
#5291f7
;
}
}
}
.coin-sum-row
,
.coin-tip-row
{
padding
:
10px
0
;
...
...
public/scss/passport/_login.css
View file @
e232f76
...
...
@@ -54,6 +54,14 @@
}
}
.sms-captcha-img-wrap
{
position
:
relative
;
.err-tip
{
left
:
335px
;
}
}
/* 验证码 */
.captcha
{
float
:
left
;
...
...
public/scss/product/_detail.css
View file @
e232f76
...
...
@@ -1246,7 +1246,7 @@
border-top
:
none
;
.goods
{
width
:
101
0px
;
width
:
99
0px
;
margin
:
0
auto
;
height
:
auto
;
...
...
@@ -1254,6 +1254,10 @@
float
:
left
;
width
:
180px
;
margin-right
:
22px
;
&:nth-child(5n)
{
margin-right
:
0
;
}
}
}
...
...
@@ -1407,7 +1411,7 @@
li
{
float
:
left
;
width
:
20
0
px
;
width
:
20
2
px
;
height
:
280px
;
overflow
:
hidden
;
}
...
...
public/scss/product/_top-coupon.css
View file @
e232f76
...
...
@@ -62,7 +62,7 @@
.cp-info
{
width
:
130px
;
padding
:
1
6
px
0
0
16px
;
padding
:
1
2
px
0
0
16px
;
float
:
left
;
>
p
{
...
...
@@ -72,8 +72,10 @@
}
.price
{
font-size
:
3
8
px
;
font-size
:
3
6
px
;
font-weight
:
500
;
display
:
block
;
margin-bottom
:
4px
;
}
.term
{
...
...
@@ -95,6 +97,12 @@
padding
:
10px
20px
;
}
.picked
{
width
:
60px
;
padding
:
10px
;
line-height
:
40px
;
}
&
.num1
{
.coupon-title
{
width
:
230px
;
...
...
@@ -120,6 +128,7 @@
font-size
:
40px
;
position
:
absolute
;
margin-left
:
-270px
;
margin-bottom
:
0
;
}
>
p
{
...
...
@@ -136,9 +145,11 @@
}
}
.picked
,
.pick-btn
{
width
:
100px
;
line-height
:
40px
;
padding
:
10px
20px
;
white-space
:
nowrap
;
}
}
...
...
@@ -152,6 +163,10 @@
width
:
224px
;
padding
:
12px
16px
0
;
.price
{
margin-bottom
:
0
;
}
.limit-text
{
text-align
:
right
;
margin-top
:
-20px
;
...
...
@@ -165,9 +180,11 @@
}
}
.picked
,
.pick-btn
{
width
:
80px
;
line-height
:
40px
;
padding
:
10px
20px
;
white-space
:
nowrap
;
}
}
...
...
@@ -202,7 +219,6 @@
.btn-end
{
background
:
#b5b5b5
;
}
}
}
...
...
@@ -275,7 +291,6 @@
width
:
94px
;
}
}
}
.top-coupon-dialog
{
...
...
Please
register
or
login
to post a comment