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
yyq
8 years ago
Commit
5d0891a5396b65c614f4ca685084186429c88cc5
2 parents
e6ed1ef2
c2769d82
Merge branch 'master' into gray
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
225 additions
and
71 deletions
.eslintrc
app.js
apps/3party/controllers/sitemap.js
apps/guang/controllers/index.js
apps/product/controllers/detail.js
apps/product/controllers/list.js
apps/product/models/detail-service.js
config/cache.js
config/common.js
doraemon/middleware/htaccess/rules/www.js
doraemon/middleware/redis.js
package.json
utils/getTDK.js
.eslintrc
View file @
5d0891a
...
...
@@ -3,4 +3,4 @@
"parserOptions"
:
{
"sourceType"
:
"module"
}
}
}
\ No newline at end of file
...
...
app.js
View file @
5d0891a
...
...
@@ -35,6 +35,10 @@ const pkg = require('./package.json');
const
app
=
express
();
const
helpers
=
global
.
yoho
.
helpers
;
// tdk
global
.
yoho
.
redis
=
require
(
'./doraemon/middleware/redis'
);
const
tdk
=
require
(
'./utils/getTDK'
);
// NOTE: 这里修改了图片质量的参数
helpers
.
image
=
_
.
flow
(
helpers
.
image
,
fp
.
replace
(
/
\/
quality
\/\d
*$/
,
'/quality/90'
));
...
...
@@ -163,6 +167,24 @@ app.use((req, res, next) => {
next
();
});
// redis seo
app
.
use
((
req
,
res
,
next
)
=>
{
if
(
!
req
.
xhr
)
{
tdk
(
'url'
,
`
$
{
req
.
hostname
}
$
{
req
.
originalUrl
}
`
,
req
).
then
(
TDKObj
=>
{
if
(
TDKObj
[
0
])
{
req
.
tdk
=
{
title
:
TDKObj
[
1
],
keywords
:
TDKObj
[
2
],
description
:
TDKObj
[
3
]
};
}
next
();
});
}
else
{
return
next
();
}
});
const
logger
=
global
.
yoho
.
logger
;
// dispatcher
...
...
apps/3party/controllers/sitemap.js
View file @
5d0891a
...
...
@@ -72,7 +72,7 @@ const itemXmlData = () => {// eslint-disable-line
return
api
.
get
(
''
,
{
method
:
'web.product.bdPromotion'
},
{
cache
:
86400
}).
then
(
res
=>
{
_
.
forEach
(
_
.
get
(
res
,
'data'
,
''
),
val
=>
{
urls
.
push
({
url
:
`
https
:
$
{
helpers
.
getUrlBySkc
(
val
.
i
d
)}
`
,
url
:
`
https
:
$
{
helpers
.
getUrlBySkc
(
val
.
erpProductI
d
)}
`
,
changefreq
:
'daily'
,
priority
:
0.3
});
...
...
apps/guang/controllers/index.js
View file @
5d0891a
...
...
@@ -13,6 +13,7 @@ const headerModel = require('../../../doraemon/models/header');
const
ghelper
=
require
(
'../models/guang-helper'
);
const
urlHelper
=
require
(
'../models/url-helper'
);
const
querystring
=
require
(
'querystring'
);
const
tdk
=
require
(
'../../../utils/getTDK'
);
/**
* 首页文章列表 类型列表
...
...
@@ -254,7 +255,8 @@ exports.detail = (req, res, next) => {
reqCtx
.
getArticleBaseInfo
(
id
,
uid
,
udid
),
reqCtx
.
getArticleRelateBrand
(
id
),
reqCtx
.
getRecoArticles
(
gender
,
1
,
10
,
channel
),
reqCtx
.
getAds
(
channel
,
isAdDegrade
)
reqCtx
.
getAds
(
channel
,
isAdDegrade
),
tdk
(
'article'
,
id
,
req
)
];
if
(
info
.
authorId
)
{
...
...
@@ -277,6 +279,24 @@ exports.detail = (req, res, next) => {
res
.
set
(
'Cache-Control'
,
'no-cache'
);
}
let
title
,
keywords
,
description
;
if
(
ret
[
8
][
0
])
{
req
.
tdk
=
{
title
:
ret
[
8
][
1
],
keywords
:
ret
[
8
][
2
],
description
:
ret
[
8
][
3
]
};
}
title
=
`
$
{
info
.
title
}
|
YOHO
!
BUY
有货`
;
keywords
=
info
.
tag
.
length
>
0
?
`
$
{
info
.
tag
}
`
:
[
'Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,品牌服饰,男士护肤,'
,
'黑框眼镜,匡威,板鞋,i.t,izzue,5cm,eastpak,vans,lylescott,g-shock,new balance,lacoste,melissa,'
,
'casio,卡西欧手表,舒雅,jasonwood,odm,AAAA,香港购物,日本潮流'
].
join
(
''
);
description
=
info
.
desc
.
length
>
0
?
`
$
{
info
.
desc
}
`
:
'潮流商品搜索,上衣,衬衫,TEE,卫衣,冲锋衣,风衣,羽绒服,裤子,休闲鞋,板鞋,配饰,复古眼镜'
;
res
.
render
(
'guang/detail'
,
Object
.
assign
({
module
:
'guang'
,
page
:
'detail'
,
...
...
@@ -307,13 +327,9 @@ exports.detail = (req, res, next) => {
commentFirstPageUrl
:
'?pageSize=10'
}
},
{
title
:
`
$
{
info
.
title
}
|
YOHO
!
BUY
有货`
,
keywords
:
info
.
tag
.
length
>
0
?
`
$
{
info
.
tag
}
`
:
[
'Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,品牌服饰,男士护肤,'
,
'黑框眼镜,匡威,板鞋,i.t,izzue,5cm,eastpak,vans,lylescott,g-shock,new balance,lacoste,melissa,'
,
'casio,卡西欧手表,舒雅,jasonwood,odm,AAAA,香港购物,日本潮流'
].
join
(
''
),
description
:
info
.
desc
.
length
>
0
?
`
$
{
info
.
desc
}
`
:
'潮流商品搜索,上衣,衬衫,TEE,卫衣,冲锋衣,风衣,羽绒服,裤子,休闲鞋,板鞋,配饰,复古眼镜'
,
title
:
title
,
keywords
:
keywords
,
description
:
description
,
webNavHeader
:
channel
}));
});
...
...
apps/product/controllers/detail.js
View file @
5d0891a
...
...
@@ -31,7 +31,7 @@ const showMain = (req, res, next) => {
saveInCookies
:
null
};
return
service
.
showMainAsync
(
Object
.
assign
({
return
service
.
showMainAsync
(
req
,
Object
.
assign
({
skn
:
skn
,
channel
:
channel
,
gender
:
gender
...
...
apps/product/controllers/list.js
View file @
5d0891a
...
...
@@ -9,6 +9,7 @@ const list = require(`${mRoot}/list`);
const
listSeoMap
=
require
(
`
$
{
global
.
middleware
}
/seo/
listSeoMap
`
);
const
helpers
=
global
.
yoho
.
helpers
;
const
_
=
require
(
'lodash'
);
const
tdk
=
require
(
'../../../utils/getTDK'
);
// 搜索相关接口
const
searchApi
=
require
(
`
$
{
mRoot
}
/search-api`
)
;
...
...
@@ -22,58 +23,71 @@ const shop = (shopId, req, res, next, brandInfo) => {
shopId
=
parseInt
(
shopId
,
10
);
Object
.
assign
(
params
,
{
shopId
:
shopId
});
list
.
getShopInfo
(
shopId
,
req
.
user
.
uid
).
then
(
shopInfo
=>
{
let
pjax
=
params
.
_pjax
;
// 获取不到店铺信息跳转至首页
if
(
!
shopInfo
||
_
.
isEmpty
(
shopInfo
))
{
return
res
.
redirect
(
helpers
.
urlFormat
(
''
,
null
,
''
));
}
// 比较品牌域名与店铺域名是否一致,不一致跳转至店铺域名
if
(
!
pjax
&&
shopInfo
.
domain
&&
domain
&&
domain
!==
_
.
toLower
(
shopInfo
.
domain
))
{
res
.
redirect
(
helpers
.
urlFormat
(
''
,
params
,
shopInfo
.
domain
));
return
;
tdk
(
'shop'
,
shopId
,
req
).
then
(
TDKObj
=>
{
if
(
TDKObj
[
0
])
{
req
.
tdk
=
{
title
:
TDKObj
[
1
],
keywords
:
TDKObj
[
2
],
description
:
TDKObj
[
3
]
};
}
return
list
.
getShopInfo
(
shopId
,
req
.
user
.
uid
).
then
(
shopInfo
=>
{
let
pjax
=
params
.
_pjax
;
if
(
+
shopInfo
.
shopTemplateType
===
2
)
{
// 经典模板
// 获取不到店铺信息跳转至首页
if
(
!
shopInfo
||
_
.
isEmpty
(
shopInfo
))
{
return
res
.
redirect
(
helpers
.
urlFormat
(
''
,
null
,
''
));
}
if
(
pjax
)
{
list
.
getShopGoodsData
(
shopId
,
req
.
yoho
.
channel
,
params
,
shopInfo
).
then
(
result
=>
{
Object
.
assign
(
result
,
{
shopId
:
shopId
,
layout
:
false
});
res
.
render
(
'list/goods-list'
,
result
);
}).
catch
(
next
);
// 比较品牌域名与店铺域名是否一致,不一致跳转至店铺域名
if
(
!
pjax
&&
shopInfo
.
domain
&&
domain
&&
domain
!==
_
.
toLower
(
shopInfo
.
domain
))
{
res
.
redirect
(
helpers
.
urlFormat
(
''
,
params
,
shopInfo
.
domain
));
return
;
}
list
.
getShopData
(
shopId
,
req
.
yoho
.
channel
,
params
,
shopInfo
).
then
(
result
=>
{
Object
.
assign
(
result
,
{
page
:
'shop'
,
shopId
:
shopId
});
// 店铺装修为空则不cache
if
(
!
result
.
shopTopBanner
)
{
res
.
set
(
'Cache-Control'
,
'no-cache'
);
if
(
+
shopInfo
.
shopTemplateType
===
2
)
{
// 经典模板
if
(
pjax
)
{
list
.
getShopGoodsData
(
shopId
,
req
.
yoho
.
channel
,
params
,
shopInfo
).
then
(
result
=>
{
Object
.
assign
(
result
,
{
shopId
:
shopId
,
layout
:
false
});
res
.
render
(
'list/goods-list'
,
result
);
}).
catch
(
next
);
return
;
}
res
.
render
(
'list/shop-index'
,
result
);
}).
catch
(
next
);
}
else
{
// 基础模板
list
.
getBaseShopData
(
params
,
Object
.
assign
({
uid
:
req
.
user
.
uid
},
brandInfo
),
req
.
yoho
.
channel
,
shopId
).
then
(
result
=>
{
Object
.
assign
(
result
,
{
page
:
'list'
});
// 基础店铺装修为空则不cache
if
(
!
result
.
brand
||
!
result
.
brand
.
shopBanner
)
{
list
.
getShopData
(
shopId
,
req
.
yoho
.
channel
,
params
,
shopInfo
).
then
(
result
=>
{
Object
.
assign
(
result
,
{
page
:
'shop'
,
shopId
:
shopId
});
// 店铺装修为空则不cache
if
(
!
result
.
shopTopBanner
)
{
res
.
set
(
'Cache-Control'
,
'no-cache'
);
}
res
.
render
(
'list/brand'
,
result
);
res
.
render
(
'list/shop-index'
,
result
);
}).
catch
(
next
);
}
}
else
{
// 基础模板
list
.
getBaseShopData
(
params
,
Object
.
assign
({
uid
:
req
.
user
.
uid
},
brandInfo
),
req
.
yoho
.
channel
,
shopId
).
then
(
result
=>
{
Object
.
assign
(
result
,
{
page
:
'list'
});
// 基础店铺装修为空则不cache
if
(
!
result
.
brand
||
!
result
.
brand
.
shopBanner
)
{
res
.
set
(
'Cache-Control'
,
'no-cache'
);
}
res
.
render
(
'list/brand'
,
result
);
}).
catch
(
next
);
}
});
}).
catch
(
next
);
};
/**
...
...
apps/product/models/detail-service.js
View file @
5d0891a
...
...
@@ -35,6 +35,7 @@ const HeaderModel = require('../../../doraemon/models/header');
const
BLANK_STR
=
' '
;
const
BUNDLE_PRODUCE
=
2
;
// 量贩
const
BUNDLE_PACKAGE
=
1
;
// 套餐
const
tdk
=
require
(
'../../../utils/getTDK'
);
// 展览票
const
YOHOOD_TICKET
=
51335912
;
...
...
@@ -1514,7 +1515,7 @@ const _removeSalePrice = (productInfo) => {
/**
* 获取某一个商品详情主页面
*/
const
showMainAsync
=
(
data
)
=>
{
const
showMainAsync
=
(
req
,
data
)
=>
{
return
co
(
function
*
()
{
// 获取商品基本信息
let
productData
=
yield
productAPI
.
getProductAsync
({
skn
:
data
.
skn
},
data
.
uid
,
data
.
isStudent
,
data
.
vipLevel
);
...
...
@@ -1537,7 +1538,8 @@ const showMainAsync = (data) => {
_getSortNavAsync
(
smallSortId
,
data
.
gender
),
// 面包屑导航
HeaderModel
.
requestHeaderData
(
data
.
channel
),
// 通用头部数据
_getProductIntroAsync
(
productId
,
productSkn
),
// 商品详细介绍
curUserProduct
(
productData
)
// 商品详细价格
curUserProduct
(
productData
),
// 商品详细价格
tdk
(
'skn'
,
data
.
skn
,
req
)
// seo
]);
let
smallSortNavigator
=
requestData
[
0
];
...
...
@@ -1545,6 +1547,14 @@ const showMainAsync = (data) => {
let
productDescription
=
requestData
[
2
];
let
productInfo
=
requestData
[
3
];
if
(
requestData
[
4
][
0
])
{
req
.
tdk
=
{
title
:
requestData
[
4
][
1
],
keywords
:
requestData
[
4
][
2
],
description
:
requestData
[
4
][
3
]
};
}
// 拼装数据
let
result
=
{};
...
...
config/cache.js
View file @
5d0891a
...
...
@@ -15,8 +15,7 @@ const cachePage = {
'/lifestyle/'
:
30
*
SECOND
,
// 商品详情页
// '/product/\\/pro_([\\d]+)_([\\d]+)\\/(.*)/': 30 * MINUTE,
'/product/\\/p([\\d]+)(.*)/'
:
5
*
MINUTE
,
'/product/\\/([\\d]+)(.*)/'
:
5
*
MINUTE
,
// 逛
'/guang/'
:
1
*
MINUTE
,
...
...
config/common.js
View file @
5d0891a
...
...
@@ -17,18 +17,18 @@ module.exports = {
cookieDomain
:
'.yohobuy.com'
,
domains
:
{
// test3
singleApi
:
'http://api-test3.yohops.com:9999/'
,
api
:
'http://api-test3.yohops.com:9999/'
,
service
:
'http://service-test3.yohops.com:9999/'
,
serviceNotify
:
'http://service-test3.yohops.com:9999/'
,
global
:
'http://global-test-soa.yohops.com:9999/'
,
// singleApi: 'http://api-test3.yohops.com:9999/',
// api: 'http://api-test3.yohops.com:9999/',
// service: 'http://service-test3.yohops.com:9999/',
// serviceNotify: 'http://service-test3.yohops.com:9999/',
// global: 'http://global-test-soa.yohops.com:9999/',
// prod
// singleApi: 'http://single.yoho.cn/',
// api: 'http://api.yoho.cn/',
// service: 'http://service.yoho.cn/',
// serviceNotify: 'http://service.yoho.cn/',
// global: 'http://api-global.yohobuy.com/',
singleApi
:
'http://single.yoho.cn/'
,
api
:
'http://api.yoho.cn/'
,
service
:
'http://service.yoho.cn/'
,
serviceNotify
:
'http://service.yoho.cn/'
,
global
:
'http://api-global.yohobuy.com/'
,
// gray
// singleApi: 'http://single.gray.yohops.com/',
...
...
@@ -131,7 +131,26 @@ module.exports = {
},
zookeeperServer
:
'192.168.102.168:2188'
,
maxQps
:
1200
,
sessionMemcachedPrefix
:
'yohobuy_session:'
sessionMemcachedPrefix
:
'yohobuy_session:'
,
redis
:
{
connect
:
{
host
:
'127.0.0.1'
,
port
:
'6379'
,
retry_strategy
(
options
)
{
if
(
options
.
error
&&
options
.
error
.
code
===
'ECONNREFUSED'
)
{
console
.
log
(
'redis连接不成功'
);
}
if
(
options
.
total_retry_time
>
1000
*
60
*
60
*
6
)
{
console
.
log
(
'redis连接超时'
);
return
;
}
if
(
options
.
attempt
>
10
)
{
return
1000
*
60
*
60
*
0.5
;
}
return
Math
.
min
(
options
.
attempt
*
100
,
1000
);
}
}
}
};
if
(
isProduction
)
{
...
...
@@ -165,7 +184,26 @@ if (isProduction) {
open
:
false
,
url
:
'http://123.206.2.55/strategy'
},
zookeeperServer
:
'web.zookeeper.yohoops.org:2181'
zookeeperServer
:
'web.zookeeper.yohoops.org:2181'
,
redis
:
{
connect
:
{
host
:
'web.redis.yohoops.org'
},
port
:
'6379'
,
retry_strategy
(
options
)
{
if
(
options
.
error
&&
options
.
error
.
code
===
'ECONNREFUSED'
)
{
console
.
log
(
'redis连接不成功'
);
}
if
(
options
.
total_retry_time
>
1000
*
60
*
60
*
6
)
{
console
.
log
(
'redis连接超时'
);
return
;
}
if
(
options
.
attempt
>
10
)
{
return
1000
*
60
*
60
*
0.5
;
}
return
Math
.
min
(
options
.
attempt
*
100
,
1000
);
}
}
});
}
else
if
(
isTest
)
{
Object
.
assign
(
module
.
exports
,
{
...
...
doraemon/middleware/htaccess/rules/www.js
View file @
5d0891a
...
...
@@ -81,7 +81,6 @@ module.exports = [
{
type
:
TYPE
.
rewrite
,
origin
:
(
req
)
=>
{
console
.
log
(
req
.
path
);
return
req
.
path
===
'/erp2goods'
;
},
target
:
'/common/erp2goods'
...
...
doraemon/middleware/redis.js
0 → 100644
View file @
5d0891a
const
redis
=
require
(
'redis'
);
const
bluebird
=
require
(
'bluebird'
);
const
config
=
require
(
'../../config/common'
);
let
client
;
try
{
client
=
redis
.
createClient
(
config
.
redis
.
connect
);
bluebird
.
promisifyAll
(
redis
.
RedisClient
.
prototype
);
bluebird
.
promisifyAll
(
redis
.
Multi
.
prototype
);
client
.
on
(
'error'
,
function
()
{
global
.
yoho
.
redis
=
''
;
});
client
.
on
(
'connect'
,
function
()
{
global
.
yoho
.
redis
=
client
;
});
}
catch
(
e
)
{
global
.
yoho
.
redis
=
''
;
}
module
.
exports
=
client
;
...
...
package.json
View file @
5d0891a
...
...
@@ -44,15 +44,15 @@
"passport-sina"
:
"^0.1.0"
,
"passport-strategy"
:
"1.x.x"
,
"passport-weixin"
:
"^0.1.0"
,
"redis"
:
"^2.7.1"
,
"request"
:
"^2.81.0"
,
"request-ip"
:
"^1.2.2"
,
"request-promise"
:
"^3.0.0"
,
"serve-favicon"
:
"^2.3.0"
,
"sitemap"
:
"^1.12.0"
,
"urlencode"
:
"^1.1.0"
,
"uuid"
:
"^2.0.2"
,
"yoho-express-session"
:
"^2.0.0"
,
"yoho-node-lib"
:
"^0.2.2
3
"
,
"yoho-node-lib"
:
"^0.2.2
8
"
,
"yoho-zookeeper"
:
"^1.0.8"
},
"devDependencies"
:
{
...
...
utils/getTDK.js
0 → 100644
View file @
5d0891a
const
md5
=
require
(
'md5'
);
const
redis
=
global
.
yoho
.
redis
;
const
_
=
require
(
'lodash'
);
module
.
exports
=
(
type
,
query
,
req
)
=>
{
query
=
type
===
'url'
?
md5
(
query
)
:
query
;
if
(
redis
&&
_
.
get
(
req
.
app
.
locals
.
pc
,
'ci.tdk'
,
false
))
{
let
arr
=
[];
arr
.
push
(
redis
.
multi
([
[
'exists'
,
`
tdk
:
$
{
type
}
:
$
{
query
}
`
],
[
'hmget'
,
`
tdk
:
$
{
type
}
:
$
{
query
}
`
,
'key'
,
'title'
,
'keywords'
,
'description'
]
]).
execAsync
());
arr
.
push
(
new
Promise
((
resolve
)
=>
{
setTimeout
(
resolve
,
500
,
[]);
}));
return
Promise
.
race
(
arr
).
then
(
function
(
res
)
{
if
(
res
.
length
)
{
return
res
[
1
];
}
else
{
return
[];
}
});
}
else
{
return
Promise
.
resolve
([]);
}
};
...
...
Please
register
or
login
to post a comment