Toggle navigation
Toggle navigation
This project
Loading...
Sign in
fe
/
yohoblk-wap
·
Commits
Go to a project
GitLab
Go to group
Project
Activity
Files
Commits
Pipelines
0
Builds
0
Graphs
Milestones
Issues
0
Merge Requests
0
Members
Labels
Wiki
Forks
Network
Create a new issue
Download as
Plain Diff
Browse Files
Authored by
zhangxiaoru
8 years ago
Commit
4a17996d8c456854febfb5218ea6c3af805fbe92
2 parents
cefd571a
8453cb81
nerge feature/ssr
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
360 additions
and
27 deletions
app.js
apps/channel/controllers/channel.js
apps/channel/views/action/cindex.hbs
apps/product/controllers/detail.js
apps/product/controllers/product-list.js
apps/product/views/action/pdetail.hbs
apps/product/views/action/product-list.hbs
config/common.js
public/js/product/detail.page.js
public/vue/component/resources/index.vue
public/vue/product/list/index.vue
utils/helpers.js
app.js
View file @
4a17996
...
...
@@ -22,6 +22,7 @@ const session = require('express-session');
const
memcached
=
require
(
'connect-memcached'
);
const
pkg
=
require
(
'./package.json'
);
const
devtools
=
require
(
'./doraemon/middleware/devtools'
);
const
_
=
require
(
'lodash'
);
const
uuid
=
require
(
'uuid'
);
const
app
=
express
();
...
...
@@ -48,10 +49,11 @@ if (app.locals.devEnv) {
app
.
use
(
global
.
yoho
.
hbs
({
extname
:
'.hbs'
,
defaultLayout
:
'layout'
,
layoutsDir
:
path
.
join
(
__dirname
,
'doraemon/views'
),
partialsDir
:
path
.
join
(
__dirname
,
'doraemon/views/partial'
),
views
:
path
.
join
(
__dirname
,
'doraemon/views'
),
helpers
:
global
.
yoho
.
helpers
helpers
:
_
.
assign
(
global
.
yoho
.
helpers
,
require
(
'./utils/helpers'
))
}));
app
.
use
(
favicon
(
path
.
join
(
__dirname
,
'/public/favicon.ico'
)));
...
...
apps/channel/controllers/channel.js
View file @
4a17996
...
...
@@ -5,19 +5,40 @@
*/
'use strict'
;
const
channelModel
=
require
(
'../models/channel'
);
const
channelMap
=
{
men
:
'9ee58aadd9559d07207fe4a98843eaac'
,
women
:
'3ad8826fc89fb0d023a4cd06a6991219'
,
lifestyle
:
'aa8d34c85934c2ccc16e2babd3eb5e47'
};
const
_
=
require
(
'lodash'
);
/**
* 频道选择页
*/
module
.
exports
=
{
index
(
req
,
res
)
{
index
(
req
,
res
,
next
)
{
let
channel
=
req
.
path
.
split
(
'/'
)[
1
]
||
req
.
yoho
.
channel
;
res
.
render
(
'cindex'
,
{
module
:
'channel'
,
page
:
'home'
,
channel
:
channel
});
channelModel
.
getResourcesData
({
contentCode
:
channelMap
[
channel
]
}).
then
(
result
=>
{
const
resources
=
result
.
slice
(
0
,
3
);
_
.
each
(
resources
,
(
resource
)
=>
{
// 只拿第一个数据
if
(
_
.
isArray
(
resource
.
data
))
{
resource
.
data
=
[
resource
.
data
[
0
]];
}
});
res
.
locals
.
resources
=
resources
;
res
.
render
(
'index'
,
{
module
:
'channel'
,
page
:
'home'
,
channel
:
channel
});
}).
catch
(
next
);
},
channel
(
req
,
res
,
next
)
{
channelModel
.
getChannelData
().
then
(
result
=>
{
...
...
apps/channel/views/action/cindex.hbs
View file @
4a17996
<div
id=
"channel"
>
<channel></channel>
<div
id=
"ssr"
class=
"resources"
style=
"position: absolute; top: 2.25rem;"
>
{{#
resources
}}
{{#if
focus
}}
<div
class=
"focus-floor"
style=
"height: 9.1rem;"
>
{{#
data
}}
<a
href=
"
{{
this
.
url
}}
"
title=
"
{{
this
.
title
}}
"
>
<img
src=
"
{{
image2
this
.
src
w
=
750
h
=
365
q
=
60
}}
"
width=
"100%"
alt=
""
>
</a>
{{/
data
}}
</div>
{{/if}}
{{#if
titleImage
}}
<div
class=
"title-image"
>
{{#
data
}}
<div
class=
"floor-header"
>
{{
title
}}
<a
class=
"more"
href=
"
{{
moreUrl
}}
"
>
{{#
eq
moreName
'...'
}}
<span
class=
"icon icon-more"
></span>
{{^}}
<!--<span>
{{{
moreName
}}}
</span>-->
{{/
eq
}}
</a>
</div>
<a
class=
"image"
href=
"
{{
image
.
url
}}
"
>
<img
src=
"
{{
image2
image
.
src
w
=
750
h
=
365
q
=
60
}}
"
width=
"100%"
alt=
""
>
</a>
</div>
{{/
data
}}
{{/if}}
{{/
resources
}}
</div>
<channel>
</channel>
</div>
...
...
apps/product/controllers/detail.js
View file @
4a17996
...
...
@@ -35,18 +35,32 @@ const saveRecentGoodInCookies = (oldSkns, res, addSkns) => {
* 商品详情
*/
const
component
=
{
index
(
req
,
res
)
{
index
(
req
,
res
,
next
)
{
const
pid
=
req
.
params
[
0
],
goodsId
=
req
.
params
[
1
],
cnAlphabet
=
req
.
params
[
2
];
res
.
render
(
'pdetail'
,
{
module
:
'product'
,
page
:
'detail'
,
pid
:
pid
,
goodsId
:
goodsId
,
cnAlphabet
:
cnAlphabet
});
let
params
=
{
product_id
:
_
.
toString
(
pid
),
uid
:
req
.
user
.
uid
||
0
};
model
.
product
(
params
).
then
(
product
=>
{
product
=
product
.
data
||
{};
product
.
formatPrice
=
product
.
formatSalesPrice
!==
'0'
?
product
.
formatSalesPrice
:
product
.
formatMarketPrice
;
product
.
isDiscount
=
product
.
marketPrice
>
product
.
salesPrice
;
console
.
log
(
product
);
res
.
render
(
'detail'
,
{
module
:
'product'
,
page
:
'detail'
,
pid
:
pid
,
goodsId
:
goodsId
,
cnAlphabet
:
cnAlphabet
,
product
:
product
});
}).
catch
(
next
);
},
product
(
req
,
res
,
next
)
{
const
pid
=
req
.
params
[
0
];
// , goodsId = req.params[1];
...
...
apps/product/controllers/product-list.js
View file @
4a17996
...
...
@@ -8,11 +8,17 @@ const searchModel = require('../models/search');
/* 搜索 页面 */
exports
.
index
=
(
req
,
res
)
=>
{
res
.
render
(
'product-list'
,
{
module
:
'product'
,
page
:
'list'
});
exports
.
index
=
(
req
,
res
,
next
)
=>
{
const
params
=
req
.
query
;
searchModel
.
products
(
params
).
then
(
result
=>
{
res
.
render
(
'product-list'
,
{
navTitle
:
params
.
title
||
params
.
sort_name
,
module
:
'product'
,
page
:
'list'
,
list
:
result
&&
result
.
data
?
result
.
data
.
productList
:
[]
});
}).
catch
(
next
);
};
/* 查询 产品列表 method:GET */
...
...
apps/product/views/action/pdetail.hbs
View file @
4a17996
<div
id=
"app"
class=
"product-page"
data-pid=
"
{{
pid
}}
"
data-goods-id=
"
{{
goodsId
}}
"
>
<app/>
{{#
product
}}
<div
class=
"ssr show-box first-box"
>
<div
class=
"image-carousel"
>
<div
class=
"swipe"
>
<div
class=
"swipe-items-wrap"
>
{{#
each
goodsList
}}
{{#if
colorImage
}}
<div
class=
"swipe-item
{{#if
@first
}}
active
{{/if}}
"
>
<img
width=
"100%"
alt=
""
src=
"
{{
image2
colorImage
w
=
750
h
=
1000
q
=
80
}}
"
></div>
{{/if}}
{{/
each
}}
</div>
</div>
</div>
<div
class=
"title-box"
>
<h1
class=
"line-clamp-2"
>
{{
productName
}}
</h1>
{{#if
isDiscount
}}
<i
class=
"price strike-through"
>
{{
formatMarketPrice
}}
</i>
{{/if}}
<i
class=
"price
{{#if
isDiscount
}}
highlight
{{/if}}
"
>
{{
formatPrice
}}
</i>
</div>
</div>
{{#
brandInfo
}}
<div
class=
"ssr show-box brand"
>
<img
src=
"
{{
image2
brandIco
w
=
110
h
=
68
q
=
80
}}
"
>
<h2>
{{
brandName
}}
</h2>
<div
class=
"brand-go"
>
<span>
进入店铺
</span>
<span
class=
"icon icon-right"
></span>
</div>
<a
href=
"/product/shop/
{{
brandDomain
}}
"
></a>
</div>
{{/
brandInfo
}}
{{/
product
}}
<app/>
</div>
...
...
apps/product/views/action/product-list.hbs
View file @
4a17996
<div
id=
"ssr"
style=
"position: absolute; top: 0;"
>
<div
class=
"blk-header-wrap"
class=
"is-fixed"
>
<div
class=
"blk-header"
>
<div
class=
"blk-header-left"
>
<i
class=
"icon icon-left go-back-btn"
></i>
</div>
<div
class=
"blk-header-right"
>
</div>
<div
class=
"blk-header-main"
>
<span
class=
"blk-header-title"
>
{{
navTitle
}}
</span>
</div>
</div>
<div
class=
"blk-header-gap"
></div>
</div>
<ul
class=
"order-navs clearfix"
>
<li
class=
"order-item active"
>
<span
class=
"order-name"
>
默认
</span>
</li>
<li
class=
"order-item"
>
<span
class=
"order-name"
>
最新
</span>
</li>
<li
class=
"order-item"
>
<span
class=
"order-name"
>
价格
</span>
<span
class=
"order-icon"
>
<i
class=
"icon icon-sort-up"
></i>
<i
class=
"icon icon-sort-down"
></i>
</span>
</li>
<li
class=
"order-item"
>
<span
class=
"order-name"
>
折扣
</span>
<span
class=
"order-icon"
>
<i
class=
"icon icon-sort-up"
></i>
<i
class=
"icon icon-sort-down"
></i>
</span>
</li>
</ul>
<div
class=
"goods-box"
>
<ul
class=
"cardlist card-large clearfix"
>
{{#
list
}}
<li
class=
"card"
>
<div
class=
"card-pic"
>
<a
href=
"
{{
goodsUrl
this
}}
"
>
<img
src=
"
{{
resizeImage
defaultImages
372
499
}}
"
alt=
"
{{
productName
}}
"
>
</a>
</div>
<div
class=
"card-bd"
>
<h2
class=
"card-label"
>
<a
href=
"
{{
goodsUrl
this
}}
"
class=
"line-clamp-2"
>
{{
productName
}}
</a>
</h2>
{{#if
marketPrice
}}
<span
class=
"good-price"
class=
"old-price"
>
¥
{{
toFixed
marketPrice
}}
</span>
{{/if}}
<span
class=
"good-price
{{#if
marketPrice
}}
sale-price
{{/if}}
"
>
¥
{{
toFixed
salesPrice
}}
</span>
</div>
</li>
{{/
list
}}
</ul>
</div>
</div>
<div
id=
"product-list"
></div>
...
...
config/common.js
View file @
4a17996
...
...
@@ -40,9 +40,9 @@ module.exports = {
useOneapm
:
false
,
useCache
:
false
,
memcache
:
{
master
:
[
'192.168.102.205:12111'
],
slave
:
[
'192.168.102.205:12111'
],
session
:
[
'192.168.102.205:12111'
],
master
:
[
'127.0.0.1:11211'
],
slave
:
[
'127.0.0.1:11211'
],
session
:
[
'127.0.0.1:11211'
],
timeout
:
1000
,
retries
:
0
},
...
...
public/js/product/detail.page.js
View file @
4a17996
...
...
@@ -15,6 +15,17 @@ yoho.ready(() => {
el
:
'#app'
,
components
:
{
app
:
app
},
created
()
{
setTimeout
(()
=>
{
let
ssrs
=
document
.
querySelectorAll
(
'.ssr'
)
||
[];
ssrs
.
forEach
(
i
=>
{
if
(
i
)
{
i
.
remove
();
}
});
},
500
);
}
});
});
\ No newline at end of file
});
...
...
public/vue/component/resources/index.vue
View file @
4a17996
...
...
@@ -93,8 +93,12 @@
if (result.length) {
dataCache[param] = result;
}
setTimeout(()=> {
$('#ssr').remove();
}, 2000);
}).fail(() => {
tip('网络错误');
tip('网络错误');
});
}
},
...
...
public/vue/product/list/index.vue
View file @
4a17996
...
...
@@ -116,6 +116,12 @@
})
.always(() => {
self.inSearching = false;
// 完成后删除服务端渲染的元素
setTimeout(()=> {
$('#ssr').remove();
});
});
},
...
...
utils/helpers.js
0 → 100644
View file @
4a17996
'use strict'
;
const
url
=
require
(
'url'
);
const
_
=
require
(
'lodash'
);
const
config
=
require
(
'../config/common'
);
const
assetUrl
=
config
.
assetUrl
;
module
.
exports
=
{
imgSrc
:
function
(
imgSrc
)
{
return
url
.
resolve
(
assetUrl
,
imgSrc
);
},
image2
:
function
(
imageUrl
,
opts
)
{
if
(
imageUrl
&&
_
.
isString
(
imageUrl
))
{
let
params
=
opts
.
hash
;
let
urls
=
imageUrl
.
split
(
'?'
);
let
query
=
urls
[
1
]
||
''
;
let
uri
=
urls
[
0
];
if
(
uri
.
indexOf
(
'http:'
)
===
0
)
{
uri
=
uri
.
replace
(
'http:'
,
''
);
}
if
(
query
)
{
query
=
query
.
replace
(
/{width}/g
,
params
.
w
).
replace
(
/{height}/g
,
params
.
h
).
replace
(
/{mode}/g
,
(
params
.
mode
||
2
));
if
(
query
.
indexOf
(
'imageView2'
)
===
0
)
{
if
(
params
.
q
&&
query
.
indexOf
(
'/q/'
)
>
0
)
{
query
=
query
.
replace
(
/
\/
q
\/\d
+/g
,
'/q/'
+
params
.
q
);
}
else
if
(
params
.
q
)
{
query
+=
'/q/'
+
params
.
q
;
}
}
else
if
(
query
.
indexOf
(
'imageMogr2'
)
===
0
)
{
if
(
params
.
q
&&
query
.
indexOf
(
'/quality/'
)
>
0
)
{
query
=
query
.
replace
(
/
\/
quality
\/\d
+/g
,
'/quality/'
+
params
.
q
);
}
else
if
(
params
.
q
)
{
query
+=
'/quality/'
+
params
.
q
;
}
}
else
if
(
query
.
indexOf
(
'imageView/'
)
===
0
)
{
if
(
params
.
q
&&
query
.
indexOf
(
'/q/'
)
>
0
)
{
query
=
query
.
replace
(
/
\/
q
\/\d
+/g
,
'/q/'
+
params
.
q
);
}
else
if
(
params
.
q
)
{
query
+=
'/q/'
+
params
.
q
;
}
if
(
params
.
mode
)
{
query
=
query
.
replace
(
/imageView
\/\d{1}\/
/
,
'imageView/'
+
params
.
mode
+
'/'
);
}
}
}
else
{
query
=
'imageView2/2/interlace/1/q/'
+
(
params
.
q
||
75
);
}
return
uri
+
'?'
+
query
;
}
else
{
return
''
;
}
},
ifor
:
function
()
{
var
args
=
Array
.
prototype
.
slice
.
call
(
arguments
);
var
opt
=
args
[
args
.
length
-
1
];
var
isTrue
=
false
;
for
(
var
i
=
0
;
i
<
args
.
length
-
1
;
i
++
)
{
if
(
args
[
i
])
{
isTrue
=
true
;
break
;
}
}
if
(
isTrue
)
{
return
opt
.
fn
(
this
);
}
else
{
return
opt
.
inverse
(
this
);
}
},
/**
* 小于某zhi
*
* @param variable
* @param number
*/
within
:
function
(
variable
,
number
,
opt
)
{
if
(
variable
<
number
)
{
return
opt
.
fn
(
this
);
}
else
{
return
opt
.
inverse
(
this
);
}
},
eq
:
function
(
a
,
b
,
options
)
{
if
(
arguments
.
length
===
2
)
{
options
=
b
;
b
=
options
.
hash
.
compare
;
}
if
(
a
===
b
)
{
return
options
.
fn
(
this
);
}
return
options
.
inverse
(
this
);
},
goodsUrl
:
(
product
,
kind
)
=>
{
let
productId
,
goodsId
,
cnAlphabet
;
switch
(
kind
)
{
case
'collection'
:
productId
=
product
.
productId
;
goodsId
=
product
.
goodsId
;
cnAlphabet
=
product
.
cnAlphabet
;
break
;
default
:
productId
=
product
.
productId
;
goodsId
=
product
.
goodsList
[
0
].
goodsId
;
cnAlphabet
=
product
.
cnAlphabet
;
}
return
`
/
product
/
pro_$
{
productId
}
_$
{
goodsId
}
/${cnAlphabet}.html`
;
},
toFixed
:
(
value
,
num
)
=>
{
if
(
typeof
value
===
'undefined'
)
{
return
;
}
return
Number
(
value
).
toFixed
(
num
||
2
);
},
resizeImage
:
(
src
,
width
,
height
,
mode
)
=>
{
return
src
?
src
.
replace
(
/
(\{
width}|
\{
height}|
\{
mode}
)
/g
,
function
(
$0
)
{
const
dict
=
{
'{width}'
:
width
||
300
,
'{height}'
:
height
||
300
,
'{mode}'
:
mode
||
2
};
return
dict
[
$0
];
}).
replace
(
/https
?
:/
,
''
)
+
'/interlace/1'
:
''
;
}
};
...
...
Please
register
or
login
to post a comment