Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Litemall
Commits
104523c6
Commit
104523c6
authored
Apr 19, 2019
by
Junling Bu
Browse files
doc
parents
70c31ee4
4ee32ff6
Changes
153
Expand all
Hide whitespace changes
Inline
Side-by-side
litemall-vue/src/views/items/detail/mix.js
0 → 100755
View file @
104523c6
import
{
Sku
,
Popup
}
from
'
vant
'
;
export
default
{
props
:
{
selectSku
:
Object
},
data
()
{
return
{
showSku
:
false
,
showAddCartBtn
:
false
,
isSkuBuy
:
false
,
buyText
:
'
确定
'
};
},
methods
:
{
buyGoods
(
data
)
{
data
=
this
.
selectSkuData
(
data
);
this
.
showSku
=
false
;
this
.
$emit
(
'
update:selectSku
'
,
data
);
this
.
isSkuBuy
&&
this
.
$emit
(
'
skuBuy
'
,
data
);
},
selectSkuData
(
data
)
{
// debugger
if
(
data
.
selectedSkuComb
)
{
data
.
selectedSkuComb
.
sku_str
=
data
.
selectedSkuComb
.
props_str_arr
.
map
(
str
=>
str
.
match
(
/
[^
:
]
*:
([^
:
]
*
)
/
)[
1
])
.
join
(
'
,
'
);
}
else
{
data
.
selectedSkuComb
=
{};
}
return
data
;
},
skuClick
()
{
this
.
isSkuBuy
=
false
;
this
.
showSku
=
true
;
}
},
components
:
{
[
Sku
.
name
]:
Sku
,
[
Popup
.
name
]:
Popup
}
};
litemall-vue/src/views/items/list/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"item_list over-hide"
>
<form
action=
"/search"
>
<van-search
placeholder=
"请输入商品名称"
v-model=
"searchVal"
@
click=
"$router.push(
{ name: 'search' })"
showAction
/>
</form>
<van-tabs
v-model=
"tabActive"
@
disabled=
"toggleFilterModal(true)"
>
<van-tab
v-for=
"(tab, tabIndex) in tabsItem"
:title=
"tab.name"
:key=
"tab.type"
:disabled=
"tab.sort === false"
>
<InfinityScroll
:ref=
"'tabScrolls' + tabIndex"
class=
"full-page scroll-wrap fix-height"
:beforeRequest=
"beforeRequest"
:apiUrl=
"listApi"
@
onLoad=
"onLoad(tabIndex, $event)"
>
<item-group>
<item-card-hori
v-for=
"(item, i) in tab.items"
:key=
"i"
:goods=
"item"
@
click=
"itemClick(item.id)"
/>
</item-group>
</InfinityScroll>
</van-tab>
</van-tabs>
<van-popup
class=
"filterItem"
v-model=
"filterItemShow"
position=
"right"
>
<ul>
<li
v-for=
"(li, i) in filterItem"
:key=
"i"
@
click=
"filterMethod(i)"
:class=
"
{filter_active: li.isActive}"
>
{{
li
.
name
}}
<van-icon
name=
"success"
v-show=
"li.isActive"
class=
"float-r"
/>
</li>
</ul>
</van-popup>
<!--
<transition
name=
"fade"
>
<van-icon
name=
"arrowupcircle"
class=
"backTop"
@
click.native=
"backTop"
v-show=
"showArrow"
/>
</transition>
-->
</div>
</
template
>
<
script
>
import
{
GOODS_SEARCH
}
from
'
@/api/goods
'
;
import
ItemGroup
from
'
@/vue/components/item-group
'
;
import
ItemCardHori
from
'
@/vue/components/item-card-hori/
'
;
import
{
Search
,
Tab
,
Tabs
,
Popup
}
from
'
vant
'
;
// import { throttle } from 'lodash';
import
InfinityScroll
from
'
@/vue/components/infinity-scroll
'
;
export
default
{
name
:
'
Item-list
'
,
props
:
{
keyword
:
{
type
:
String
,
default
:
''
},
itemClass
:
{
type
:
[
String
,
Number
],
default
:
''
}
},
data
()
{
return
{
listApi
:
GOODS_SEARCH
,
shop_id
:
1
,
tabActive
:
0
,
tabsItem
:
[
{
name
:
'
默认
'
,
sort
:
''
,
items
:
[]
},
{
name
:
'
销量
'
,
sort
:
'
sold_quantity
'
,
items
:
[]
},
{
name
:
'
最新
'
,
sort
:
'
created_at
'
,
items
:
[]
}
// { name: '筛选', sort: false, items: [] }
],
is_haitao
:
0
,
filterItem
:
[
{
name
:
'
全部
'
,
filterType
:
2
,
isActive
:
true
},
{
name
:
'
店铺商品
'
,
filterType
:
0
,
isActive
:
false
},
{
name
:
'
海淘商品
'
,
filterType
:
1
,
isActive
:
false
}
],
isHaitao
:
2
,
searchVal
:
''
,
filterItemShow
:
false
// showArrow: false
};
},
computed
:
{
sortVal
()
{
const
{
tabActive
:
i
}
=
this
;
return
this
.
tabsItem
[
i
].
sort
;
}
},
created
()
{
// this.scrollShowArrow = throttle(this.scrollShowArrow, 100);
},
methods
:
{
onLoad
(
i
,
items
)
{
this
.
tabsItem
[
i
].
items
.
push
(...
items
);
},
beforeRequest
()
{
return
{
params
:
{
q
:
this
.
searchVal
,
shop_id
:
this
.
shop_id
,
cid
:
this
.
itemClass
,
sort
:
this
.
sortVal
,
is_haitao
:
this
.
isHaitao
}
};
},
// 滚动容器改变, 导致滚动监听失效, 暂时先注释了
// eventListen(isBind = true) {
// if (isBind) {
// this.$el.addEventListener('scroll', this.scrollShowArrow);
// } else {
// this.$el.removeEventListener('scroll', this.scrollShowArrow);
// }
// },
// scrollShowArrow() {
// this.showArrow = this.$el.scrollTop > 120;
// },
activeFilter
(
i
)
{
this
.
filterItem
.
forEach
((
item
,
index
)
=>
{
item
.
isActive
=
i
===
index
;
});
},
resetActiveTab
()
{
const
{
tabActive
:
i
}
=
this
;
this
.
tabsItem
[
i
].
items
=
[];
const
targetScroll
=
this
.
$refs
[
`tabScrolls
${
i
}
`
][
0
];
// debugger;
targetScroll
&&
targetScroll
.
resetInit
();
},
toggleFilterModal
(
status
)
{
this
.
filterItemShow
=
status
;
},
filterMethod
(
i
)
{
const
filterType
=
this
.
filterItem
[
i
].
filterType
;
if
(
filterType
===
this
.
isHaitao
)
return
;
this
.
isHaitao
=
filterType
;
this
.
activeFilter
(
i
);
this
.
toggleFilterModal
(
false
);
this
.
resetActiveTab
();
},
// backTop() {
// this.$el.scrollTop = 0;
// },
itemClick
(
id
)
{
this
.
$router
.
push
({
name
:
'
detail
'
,
params
:
{
itemId
:
id
}
});
}
},
components
:
{
InfinityScroll
,
[
ItemGroup
.
name
]:
ItemGroup
,
[
ItemCardHori
.
name
]:
ItemCardHori
,
[
Tab
.
name
]:
Tab
,
[
Tabs
.
name
]:
Tabs
,
[
Search
.
name
]:
Search
,
[
Popup
.
name
]:
Popup
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.fade-enter
,
.fade-leave-to
{
opacity
:
0
;
}
.fade-enter-active
,
.fade-leave-active
{
transition
:
all
0
.5s
;
}
.fix-height
{
padding-bottom
:
88px
;
}
.over-hide
{
overflow
:
hidden
;
}
.item_list
{
background-color
:
#fff
;
padding-bottom
:
0
;
}
.fixedTop
{
position
:
fixed
;
width
:
100%
;
top
:
0
;
z-index
:
999
;
}
.items_loading
{
margin
:
0
auto
;
}
.filterItem
{
width
:
40%
;
height
:
100%
;
li
{
padding
:
10px
;
&
.filter_active
{
color
:
$red
;
}
}
}
.backTop
{
position
:
fixed
;
right
:
20px
;
bottom
:
20px
;
font-size
:
24px
;
}
</
style
>
litemall-vue/src/views/items/search-result/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"item_list"
>
<form
action=
"/search"
class=
"fixedTop"
>
<van-search
placeholder=
"请输入商品名称"
v-model=
"searchVal"
@
search=
"resetInit"
showAction
/>
</form>
<van-list
v-model=
"loading"
:finished=
"finished"
:immediate-check=
"false"
:offset=
"100"
@
load=
"loadMore"
>
<item-group>
<item-card-hori
v-for=
"(item) in items"
:key=
"item.id"
:goods=
"item"
@
click=
"itemClick(item.id)"
/>
</item-group>
</van-list>
<is-empty
v-if=
"items.length === 0"
>
抱歉,没有找到符合条件商品
</is-empty>
<transition
name=
"fade"
>
<van-icon
name=
"arrowupcircle"
class=
"backTop"
@
click.native=
"backTop"
v-show=
"showArrow"
></van-icon>
</transition>
</div>
</
template
>
<
script
>
import
{
GOODS_SEARCH
}
from
'
@/api/goods
'
;
import
ItemGroup
from
'
@/vue/components/item-group/
'
;
import
IsEmpty
from
'
@/vue/components/is-empty/
'
;
import
ItemCardHori
from
'
@/vue/components/item-card-hori/
'
;
import
{
Search
,
List
}
from
'
vant
'
;
import
_
from
'
lodash
'
;
import
loadMore
from
'
@/vue/mixin/list-load-more
'
;
import
scrollFixed
from
'
@/vue/mixin/scroll-fixed
'
;
export
default
{
name
:
'
Item-list
'
,
props
:
{
keyword
:
{
type
:
String
,
default
:
''
}
},
mixins
:
[
loadMore
,
scrollFixed
],
data
()
{
return
{
isEmpty
:
false
,
shop_id
:
''
,
searchVal
:
''
,
showArrow
:
false
};
},
activated
()
{
this
.
searchVal
=
this
.
keyword
;
this
.
resetInit
();
this
.
eventListen
();
},
deactivated
()
{
document
.
getElementById
(
'
app
'
)
.
removeEventListener
(
'
scroll
'
,
this
.
scrollShowArrow
);
},
created
()
{
this
.
initData
();
this
.
scrollShowArrow
=
_
.
throttle
(
this
.
scrollShowArrow
,
100
);
},
methods
:
{
initData
()
{
// debugger;
this
.
items
=
[];
return
this
.
$reqGet
(
`/wx/goods/list`
,
{
keyword
:
this
.
searchVal
,
page
:
1
,
size
:
100
,
sort
:
'
name
'
,
order
:
'
desc
'
,
categoryId
:
0
},
{
hideLoading
:
true
}
).
then
(
res
=>
{
const
{
goodsList
,
filterCategoryList
}
=
res
.
data
.
data
;
_
.
each
(
goodsList
,
v
=>
{
v
.
pic_url
=
v
.
picUrl
;
});
this
.
items
.
push
(...
goodsList
);
// return page;
});
},
eventListen
()
{
document
.
getElementById
(
'
app
'
)
.
addEventListener
(
'
scroll
'
,
this
.
scrollShowArrow
);
},
scrollShowArrow
()
{
this
.
showArrow
=
document
.
getElementById
(
'
app
'
).
scrollTop
>
120
;
},
backTop
()
{
document
.
getElementById
(
'
app
'
).
scrollTop
=
0
;
},
itemClick
(
i
)
{
this
.
$router
.
push
({
name
:
'
detail
'
,
params
:
{
itemId
:
i
}
});
}
},
components
:
{
[
ItemGroup
.
name
]:
ItemGroup
,
[
ItemCardHori
.
name
]:
ItemCardHori
,
[
Search
.
name
]:
Search
,
[
List
.
name
]:
List
,
[
IsEmpty
.
name
]:
IsEmpty
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.fade-enter
,
.fade-leave-to
{
opacity
:
0
;
}
.fade-enter-active
,
.fade-leave-active
{
transition
:
all
0
.5s
;
}
.item_list
{
background-color
:
#fff
;
padding-top
:
50px
;
box-sizing
:
border-box
;
}
.fixedTop
{
position
:
fixed
;
width
:
100%
;
top
:
0
;
z-index
:
999
;
}
.items_loading
{
margin
:
0
auto
;
}
.backTop
{
position
:
fixed
;
right
:
20px
;
bottom
:
20px
;
font-size
:
24px
;
}
</
style
>
litemall-vue/src/views/items/search/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"item_search"
>
<form
action=
"/search"
@
submit=
"disabledSubmit"
>
<van-search
placeholder=
"请输入商品名称"
v-model=
"keyword"
@
search=
"enterSearch"
autofocus
/>
</form>
<div
class=
"item_search_content"
>
<div
class=
"item_search_text clearfix"
>
<div
class=
"float-l"
>
历史搜索
</div>
<div
class=
"float-r"
@
click=
"clearHistory"
>
<van-icon
name=
"lajitong"
style=
"font-size: 12px;margin-right: 3px"
/>
清空历史记录
</div>
</div>
<div
class=
"item_search_history"
>
<word-tag
v-for=
"(his, i) in wordHistory"
:key=
"i"
@
click=
"toSearchResult(his)"
>
{{
his
}}
</word-tag>
</div>
</div>
</div>
</
template
>
<
script
>
import
{
Search
}
from
'
vant
'
;
import
SrarchTag
from
'
./search-tag
'
;
export
default
{
data
()
{
return
{
keyword
:
''
,
focusStatus
:
true
,
wordHistory
:
[]
};
},
methods
:
{
enterSearch
()
{
const
keyword
=
this
.
keyword
;
this
.
pushHistoryTolocal
(
keyword
);
this
.
toSearchResult
(
keyword
);
},
toSearchResult
(
word
)
{
this
.
keyword
=
word
.
trim
();
this
.
$router
.
push
({
name
:
'
search-result
'
,
query
:
{
keyword
:
word
.
trim
()
}
});
},
pushHistoryTolocal
(
keyword
)
{
const
wordHistory
=
this
.
wordHistory
;
const
historyKeyWord
=
this
.
getKeyWordHistory
();
if
(
!!
keyword
.
trim
()
&&
historyKeyWord
.
indexOf
(
keyword
)
<
0
)
{
wordHistory
.
push
(
keyword
);
window
.
localStorage
.
setItem
(
'
keyword
'
,
wordHistory
.
join
(
'
|
'
));
}
},
getKeyWordHistory
()
{
const
listWord
=
window
.
localStorage
.
getItem
(
'
keyword
'
);
return
listWord
?
listWord
.
split
(
'
|
'
)
:
[];
},
clearHistory
()
{
this
.
$dialog
.
confirm
({
message
:
'
是否清空历史记录
'
})
.
then
(()
=>
{
window
.
localStorage
.
setItem
(
'
keyword
'
,
''
);
this
.
wordHistory
=
[];
});
},
disabledSubmit
()
{
return
false
;
}
},
activated
()
{
this
.
wordHistory
=
this
.
getKeyWordHistory
();
},
components
:
{
[
Search
.
name
]:
Search
,
[
SrarchTag
.
name
]:
SrarchTag
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.item_search
{
background-color
:
#fff
;
}
.item_search_content
{
padding
:
15px
10px
0
;
}
.item_search_text
{
font-size
:
$font-size-normal
;
color
:
$font-color-gray
;
margin-bottom
:
20px
;
}
.item_search_history
>
span
{
margin-right
:
10px
;
margin-bottom
:
10px
;
}
</
style
>
litemall-vue/src/views/items/search/search-tag.vue
0 → 100755
View file @
104523c6
<
template
>
<span
class=
"search_tag"
@
click=
"OnClick"
>
<slot></slot>
</span>
</
template
>
<
script
>
export
default
{
name
:
'
word-tag
'
,
methods
:
{
OnClick
()
{
this
.
$emit
(
'
click
'
);
}
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.search_tag
{
display
:
inline-block
;
font-size
:
12px
;
background-color
:
#f4f4f4
;
padding
:
3px
10px
;
border-radius
:
11px
;
min-width
:
20px
;
text-align
:
center
;
}
</
style
>
litemall-vue/src/views/items/tabbar-class-tree.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"class_tree clearfix"
>
<ul
class=
"class_tree_nav"
>
<li
v-for=
"(item ,index) in list"
:key=
"item.id"
:class=
"
{active_nav: navActive == index}"
@click="navclick(index)"
>
{{
item
.
name
}}
</li>
</ul>
<div
class=
"class_tree_content"
>
<div
class=
"class_tree_all"
>
<img
style=
"width:250px"
v-lazy=
"currentCategory.picUrl"
>
</div>
<div
class=
"box"
>
<span>
{{
currentCategory
.
desc
}}
</span>
</div>
<div
class=
"class_tree_items_wrap clearfix"
>
<div
@
click=
"classClick(item.id)"
:key=
"i"
v-for=
"(item, i) in goods"
>
<div
class=
"class_tree_item_img"
>
<img
:src=
"item.picUrl"
:alt=
"item.name"
>
</div>
<div
class=
"class_tree_item_name"
>
{{
item
.
name
}}
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
class-tree
'
,
model
:
{
prop
:
'
activeIndex
'
},
props
:
{
activeIndex
:
{
type
:
Number
,
default
:
0
},
list
:
{
type
:
Array
,
default
:
()
=>
[]
}
},
data
()
{
const
navActive
=
this
.
activeIndex
>=
this
.
list
.
length
?
0
:
this
.
activeIndex
;
return
{
navActive
,
goods
:
[],
currentCategory
:
{}
};
},
computed
:
{},
methods
:
{
changeList
(
data
)
{
this
.
goods
=
data
.
currentSubCategory
;
this
.
currentCategory
=
data
.
currentCategory
;
console
.
log
(
this
.
goods
);
},
allClick
()
{
this
.
$emit
(
'
all-click
'
);
},
navclick
(
i
)
{
this
.
navActive
=
i
;
this
.
$emit
(
'
nav-click
'
,
this
.
list
[
i
].
id
);
},
classClick
(
id
)
{
this
.
$emit
(
'
class-click
'
,
id
);
}
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
@import
'../../assets/scss/mixin'
;
.box
{
width
:
250px
;
height
:
20px
;
text-align
:
center
;
font-family
:
PingFangSC-Light
,
helvetica
,
'Heiti SC'
;
font-size
:
13px
;
position
:
absolute
;
top
:
95px
;
}
.box
span
{
line-height
:
20px
;
}
.class_tree
{
position
:
relative
;
background-color
:
#fff
;
overflow-x
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
overflow
:
hidden
;
height
:
100%
;
box-sizing
:
border-box
;
}
.class_tree_nav
{
float
:
left
;
width
:
100px
;
height
:
100%
;
background-color
:
#f8f8f8
;
overflow
:
scroll
;
>
li
{
@include
one-border
;
height
:
40px
;
line-height
:
40px
;
text-align
:
center
;
border-left
:
2px
solid
$bg-color
;
}
>
li
.active_nav
{
background-color
:
#fff
;
border-left
:
2px
solid
$red
;
color
:
$red
;
}
}
.class_tree_content
{
margin-left
:
100px
;
height
:
100%
;
overflow-x
:
hidden
;
overflow-y
:
scroll
;
.class_tree_all
{
text-align
:
right
;
padding-right
:
10px
;
height
:
40px
;
line-height
:
40px
;
color
:
$font-color-gray
;
font-size
:
$font-size-small
;
}
.van-icon-arrow
{
font-size
:
$font-size-small
;
}
.class_tree_items_wrap
{
padding
:
10px
20px
;
margin-right
:
-3%
;
margin-top
:
70px
;
text-align
:
center
;
>
div
{
float
:
left
;
padding-right
:
3%
;
box-sizing
:
border-box
;
width
:
33
.333%
;
margin-bottom
:
20px
;
}
img
{
max-width
:
100%
;
}
.class_tree_item_img
{
display
:
inline-block
;
max-width
:
100%
;
width
:
70px
;
height
:
70px
;
}
.class_tree_item_name
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
}
</
style
>
litemall-vue/src/views/items/tabbar-class.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"tab_class"
>
<div
class=
"tal_class_searchBox"
>
<van-search
placeholder=
"点击前往搜索"
/>
<div
class=
"tal_class_searchMask"
@
click=
"$router.push(
{ name: 'search' })">
</div>
</div>
<class-tree
ref=
"classTree"
class=
"height-fix42"
@
nav-click=
"changeCatalog"
@
class-click=
"toItemList"
@
all-click=
"toItemList"
:list=
"list"
></class-tree>
<is-empty
v-if=
"isEmpty"
>
抱歉,店主还未上架商品
</is-empty>
</div>
</
template
>
<
script
>
import
{
GOODS_CATEGORY
,
GOODS_CHANNGE_CATEGORY
}
from
'
@/api/goods
'
;
import
getLocationParam
from
'
core/utils/location-param
'
;
import
{
Search
}
from
'
vant
'
;
import
classTree
from
'
./tabbar-class-tree
'
;
import
IsEmpty
from
'
@/vue/components/is-empty
'
;
import
_
from
'
lodash
'
;
import
{
async
}
from
'
q
'
;
function
getIndex
(
arr
,
keyWord
)
{
let
index
=
0
;
_
.
each
(
arr
,
(
v
,
k
)
=>
{
if
(
v
.
id
===
keyWord
)
{
index
=
k
;
return
false
;
}
});
return
index
;
}
export
default
{
data
()
{
return
{
list
:
[],
subCategory
:
[],
isEmpty
:
false
};
},
created
()
{
this
.
initData
();
},
methods
:
{
initData
()
{
const
shop_id
=
getLocationParam
(
'
shop_id
'
);
this
.
$reqGet
(
`
${
GOODS_CATEGORY
}
`
).
then
(
res
=>
{
this
.
list
=
res
.
data
.
data
.
categoryList
;
this
.
$refs
.
classTree
.
changeList
(
res
.
data
.
data
);
this
.
subCategory
=
res
.
data
.
data
.
currentSubCategory
;
if
(
this
.
subCategory
.
length
===
0
)
this
.
isEmpty
=
true
;
});
},
removeNoChild
(
data
)
{
return
data
.
filter
(
item
=>
item
.
children
&&
item
.
children
.
length
);
},
changeCatalog
(
id
)
{
this
.
$reqGet
(
`
${
GOODS_CHANNGE_CATEGORY
}${
id
}
`
).
then
(
res
=>
{
let
index
=
getIndex
(
this
.
list
,
res
.
data
.
data
.
currentCategory
.
id
);
this
.
$refs
.
classTree
.
changeList
(
res
.
data
.
data
);
this
.
subCategory
=
res
.
data
.
data
.
currentSubCategory
;
if
(
this
.
subCategory
.
length
===
0
)
this
.
isEmpty
=
true
;
});
},
toItemList
(
id
)
{
this
.
$router
.
push
({
name
:
'
list
'
,
query
:
{
keyword
:
''
,
itemClass
:
id
}
});
}
},
components
:
{
[
Search
.
name
]:
Search
,
[
classTree
.
name
]:
classTree
,
[
IsEmpty
.
name
]:
IsEmpty
}
};
</
script
>
<
style
scoped
>
.tab_class
{
overflow
:
hidden
;
background-color
:
#fff
;
}
.height-fix
{
padding-bottom
:
42px
;
}
.tal_class_searchBox
{
position
:
relative
;
}
.tal_class_searchMask
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
z-index
:
9
;
}
</
style
>
litemall-vue/src/views/login/forget-reset/index.vue
0 → 100755
View file @
104523c6
<
template
>
<md-field-group
class=
"foget_view"
>
<md-field
v-model=
"password"
icon=
"lock"
:is-error=
"isErrow"
placeholder=
"请输入新密码"
/>
<md-field
v-model=
"passwordRepeat"
type=
"password"
icon=
"lock"
:is-error=
"isErrow"
placeholder=
"请再次输入密码"
/>
<div
class=
"red"
v-show=
"isErrow"
>
两次密码输入不一致
</div>
<div
class=
"foget_submit"
>
<van-button
size=
"large"
type=
"danger"
@
click=
"submitCode"
>
重置
</van-button>
</div>
</md-field-group>
</
template
>
<
script
>
import
field
from
'
@/vue/components/field/
'
;
import
fieldGroup
from
'
@/vue/components/field-group/
'
;
export
default
{
data
()
{
return
{
isErrow
:
true
,
password
:
''
,
passwordRepeat
:
''
};
},
methods
:
{
submitCode
()
{}
},
components
:
{
[
field
.
name
]:
field
,
[
fieldGroup
.
name
]:
fieldGroup
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
div
.foget_view
{
background-color
:
#fff
;
padding-top
:
30px
;
}
div
.foget_submit
{
padding-top
:
30px
;
padding-bottom
:
20px
;
}
</
style
>
litemall-vue/src/views/login/forget-status/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"payment_status"
>
<div
class=
"status_top"
>
<van-icon
:name=
"statusIcon"
:class=
"statusClass"
/>
<div>
{{
statusText
}}
</div>
</div>
<div
class=
"status_text"
><span
class=
"red"
>
3秒
</span>
后返回到登录页, 您也可以
<router-link
to=
"/login"
class=
"red"
>
点此登录
</router-link></div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
payment-status
'
,
props
:
{
status
:
String
},
data
()
{
return
{
isSuccess
:
true
};
},
computed
:
{
statusText
()
{
return
this
.
isSuccess
?
'
修改成功
'
:
'
修改失败
'
;
},
statusIcon
()
{
return
this
.
isSuccess
?
'
checked
'
:
'
fail
'
;
},
statusClass
()
{
return
this
.
isSuccess
?
'
success_icon
'
:
'
fail_icon
'
;
}
},
activated
()
{
this
.
isSuccess
=
this
.
status
===
'
success
'
;
}
};
</
script
>
<
style
lang=
"scss"
scopd
>
.payment_status
{
padding-top
:
30px
;
box-sizing
:
border-box
;
background-color
:
#fff
;
text-align
:
center
;
}
.status_top
{
margin-bottom
:
15px
;
i
{
margin-bottom
:
5px
;
}
>
div
{
font-size
:
18px
;
}
}
.status_text
{
color
:
$font-color-gray
;
margin-bottom
:
50px
;
}
.status_icon
{
font-size
:
80px
;
}
i
.success_icon
{
@extend
.status_icon
;
color
:
#06bf04
;
}
i
.fail_icon
{
@extend
.status_icon
;
color
:
#f44
;
}
</
style
>
litemall-vue/src/views/login/forget/index.vue
0 → 100755
View file @
104523c6
<
template
>
<md-field-group
class=
"foget_view"
>
<md-field
v-model=
"mobile"
icon=
"mobile"
placeholder=
"请输入手机号"
/>
<md-field
v-model=
"code"
icon=
"lock"
placeholder=
"请输入短信验证码"
>
<div
slot=
"rightIcon"
@
click=
"getCode"
class=
"getCode red"
>
<countdown
v-if=
"counting"
:time=
"60000"
@
countdownend=
"countdownend"
>
<template
slot-scope=
"props"
>
{{
+
props
.
seconds
||
60
}}
秒后获取
</
template
>
</countdown>
<span
v-else
>
获取验证码
</span>
</div>
</md-field
>
<div
class=
"foget_submit"
>
<van-button
size=
"large"
type=
"danger"
@
click=
"submitCode"
>
下一步
</van-button>
</div>
</md-field-group>
</template>
<
script
>
import
field
from
'
@/vue/components/field/
'
;
import
fieldGroup
from
'
@/vue/components/field-group/
'
;
export
default
{
data
()
{
return
{
counting
:
false
,
mobile
:
''
,
code
:
''
};
},
methods
:
{
submitCode
()
{
this
.
$router
.
push
({
name
:
'
forgetReset
'
});
},
getCode
()
{
this
.
counting
=
true
;
},
countdownend
()
{
this
.
counting
=
false
;
}
},
components
:
{
[
field
.
name
]:
field
,
[
fieldGroup
.
name
]:
fieldGroup
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
@import
'../../../assets/scss/mixin'
;
div
.foget_view
{
background-color
:
#fff
;
padding-top
:
30px
;
}
div
.foget_submit
{
padding-top
:
30px
;
padding-bottom
:
20px
;
}
.getCode
{
@include
one-border
(
left
);
text-align
:
center
;
}
.time_down
{
color
:
$red
;
}
</
style
>
litemall-vue/src/views/login/login-footer.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"text-desc text-center bottom_positon"
>
技术支持: litemall
</div>
</
template
>
<
script
>
export
default
{
name
:
'
login-footer
'
};
</
script
>
<
style
scoped
>
.bottom_positon
{
position
:
absolute
;
bottom
:
30px
;
width
:
100%
;
}
</
style
>
litemall-vue/src/views/login/login-header.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"store_header"
>
<div
class=
"store_avatar"
>
<img
src=
"../../assets/images/avatar_default.png"
alt=
"头像"
width=
"55"
height=
"55"
>
</div>
<div
class=
"store_name"
>
litemall-vue
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
login-header
'
};
</
script
>
<
style
lang=
"scss"
scoped
>
.store_header
{
text-align
:
center
;
padding
:
30px
0
;
.store_avatar
img
{
border-radius
:
50%
;
}
.store_name
{
padding-top
:
5px
;
font-size
:
16px
;
}
}
</
style
>
litemall-vue/src/views/login/login-request.vue
0 → 100755
View file @
104523c6
<
template
>
<div>
<md-field-group>
<md-field
v-model=
"account"
icon=
"username"
placeholder=
"随便输"
right-icon=
"clear-full"
v-validate=
"'required'"
name=
"user"
data-vv-as=
"帐号"
@
right-click=
"clearText"
/>
<md-field
v-model=
"password"
icon=
"lock"
placeholder=
"随便输"
:type=
"visiblePass ? 'text' : 'password'"
:right-icon=
"visiblePass ? 'eye-open' : 'eye-close'"
v-validate=
"'required'"
data-vv-as=
"密码"
name=
"password"
@
right-click=
"visiblePass = !visiblePass"
/>
<div
class=
"clearfix"
>
<div
class=
"float-r"
>
<router-link
to=
"/login/forget"
>
忘记密码
</router-link>
</div>
</div>
<van-button
size=
"large"
type=
"danger"
:loading=
"isLogining"
@
click=
"loginSubmit"
>
登录
</van-button>
</md-field-group>
<div
class=
"register clearfix"
>
<div
class=
"float-l connect"
>
<!--
<span
@
click=
"showKefu = true"
>
联系客服
</span>
-->
</div>
<div
class=
"float-r"
>
<router-link
to=
"/login/registerGetCode"
>
免费注册
</router-link>
</div>
</div>
<van-popup
v-model=
"showKefu"
>
<md-kefu
mobile=
"16454193338"
/>
</van-popup>
</div>
</
template
>
<
script
>
import
field
from
'
@/vue/components/field/
'
;
import
fieldGroup
from
'
@/vue/components/field-group/
'
;
import
md_kefu
from
'
@/vue/components/md-kefu/
'
;
import
{
USER_LOGIN
,
USER_PROFILE
}
from
'
@/api/user
'
;
import
{
setLocalStorage
}
from
'
core/utils/local-storage
'
;
import
{
emailReg
,
mobileReg
}
from
'
@/core/regexp
'
;
import
{
Popup
,
Toast
}
from
'
vant
'
;
export
default
{
name
:
'
login-request
'
,
data
()
{
return
{
account
:
''
,
password
:
''
,
visiblePass
:
false
,
showKefu
:
false
,
isLogining
:
false
,
userInfo
:
{}
};
},
methods
:
{
clearText
()
{
this
.
account
=
''
;
},
async
validate
()
{
const
result
=
await
this
.
$validator
.
validate
();
if
(
!
result
)
{
const
errMsg
=
this
.
errors
.
items
[
0
].
msg
;
Toast
(
errMsg
);
throw
new
Error
(
`表单验证:
${
errMsg
}
`
);
}
},
async
login
()
{
let
loginData
=
this
.
getLoginData
();
let
{
data
}
=
await
this
.
$reqPost
(
USER_LOGIN
,
loginData
);
this
.
userInfo
=
data
.
data
.
userInfo
;
console
.
log
(
this
.
userInfo
);
setLocalStorage
({
Authorization
:
data
.
data
.
token
});
this
.
getUserProfile
();
},
async
loginSubmit
()
{
this
.
isLogining
=
true
;
try
{
await
this
.
validate
();
await
this
.
login
();
this
.
isLogining
=
false
;
}
catch
(
err
)
{
console
.
log
(
err
.
message
);
this
.
isLogining
=
false
;
}
},
getUserProfile
()
{
// const {
// data: { data }
// } = await this.$reqGet(USER_PROFILE);
setLocalStorage
({
avatar
:
this
.
userInfo
.
avatarUrl
,
// user_id: data.user_id,
// background_image: data.background_image,
nickName
:
this
.
userInfo
.
nickName
});
this
.
routerRedirect
();
},
routerRedirect
()
{
// const { query } = this.$route;
// this.$router.replace({
// name: query.redirect || 'home',
// query: query
// });
window
.
location
=
'
#/user/
'
;
},
getLoginData
()
{
const
password
=
this
.
password
;
const
username
=
this
.
getUserType
(
this
.
account
);
return
{
username
:
this
.
account
,
password
:
password
};
},
getUserType
(
account
)
{
const
accountType
=
mobileReg
.
test
(
account
)
?
'
mobile
'
:
emailReg
.
test
(
account
)
?
'
email
'
:
'
username
'
;
return
accountType
;
}
},
components
:
{
[
field
.
name
]:
field
,
[
fieldGroup
.
name
]:
fieldGroup
,
[
md_kefu
.
name
]:
md_kefu
,
[
Popup
.
name
]:
Popup
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
@import
'../../assets/scss/mixin'
;
.register
{
padding-top
:
40px
;
color
:
$font-color-gray
;
a
{
color
:
$font-color-gray
;
}
>
div
{
width
:
50%
;
box-sizing
:
border-box
;
padding
:
0
20px
;
}
.connect
{
@include
one-border
(
right
);
text-align
:
right
;
}
}
</
style
>
litemall-vue/src/views/login/login.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"login"
>
<login-header
/>
<login-request
/>
<login-footer
/>
</div>
</
template
>
<
script
>
import
loginHeader
from
'
./login-header
'
;
import
loginRequest
from
'
./login-request
'
;
import
loginFooter
from
'
./login-footer
'
;
export
default
{
components
:
{
[
loginHeader
.
name
]:
loginHeader
,
[
loginRequest
.
name
]:
loginRequest
,
[
loginFooter
.
name
]:
loginFooter
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.login
{
position
:
relative
;
background-color
:
#fff
;
}
</
style
>
litemall-vue/src/views/login/register-getCode/index.vue
0 → 100755
View file @
104523c6
<
template
>
<md-field-group
class=
"register_view"
>
<div>
我们将发送验证码到您的手机
</div>
<md-field
v-model=
"mobile"
icon=
"mobile"
placeholder=
"请输入手机号"
/>
<div
class=
"register_submit"
>
<van-button
size=
"large"
type=
"danger"
@
click=
"submitCode"
>
下一步
</van-button>
</div>
<div
class=
"register_footer"
>
已有账号?
<router-link
to=
"/login"
class=
"red"
>
登录
</router-link>
</div>
</md-field-group>
</
template
>
<
script
>
import
field
from
'
@/vue/components/field/
'
;
import
fieldGroup
from
'
@/vue/components/field-group/
'
;
export
default
{
data
()
{
return
{
mobile
:
''
};
},
methods
:
{
submitCode
()
{
this
.
$router
.
push
({
name
:
'
registerSubmit
'
});
}
},
components
:
{
[
field
.
name
]:
field
,
[
fieldGroup
.
name
]:
fieldGroup
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
div
.register_view
{
background-color
:
#fff
;
padding-top
:
30px
;
}
div
.register_submit
{
padding-top
:
30px
;
padding-bottom
:
20px
;
}
.register_footer
{
text-align
:
right
;
color
:
$font-color-gray
;
}
</
style
>
litemall-vue/src/views/login/register-status/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"payment_status"
>
<div
class=
"status_top"
>
<van-icon
:name=
"statusIcon"
:class=
"statusClass"
/>
<div>
{{
statusText
}}
</div>
</div>
<div
class=
"status_text"
><span
class=
"red"
>
3秒
</span>
后返回到登录页, 您也可以
<router-link
to=
"/login"
class=
"red"
>
点此登录
</router-link></div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
payment-status
'
,
props
:
{
status
:
String
},
data
()
{
return
{
isSuccess
:
true
};
},
computed
:
{
statusText
()
{
return
this
.
isSuccess
?
'
注册成功
'
:
'
注册失败
'
;
},
statusIcon
()
{
return
this
.
isSuccess
?
'
checked
'
:
'
fail
'
;
},
statusClass
()
{
return
this
.
isSuccess
?
'
success_icon
'
:
'
fail_icon
'
;
}
},
activated
()
{
this
.
isSuccess
=
this
.
status
===
'
success
'
;
}
};
</
script
>
<
style
lang=
"scss"
scopd
>
.payment_status
{
padding-top
:
30px
;
box-sizing
:
border-box
;
background-color
:
#fff
;
text-align
:
center
;
}
.status_top
{
margin-bottom
:
15px
;
i
{
margin-bottom
:
5px
;
}
>
div
{
font-size
:
18px
;
}
}
.status_text
{
color
:
$font-color-gray
;
margin-bottom
:
50px
;
}
.status_icon
{
font-size
:
80px
;
}
i
.success_icon
{
@extend
.status_icon
;
color
:
#06bf04
;
}
i
.fail_icon
{
@extend
.status_icon
;
color
:
#f44
;
}
</
style
>
litemall-vue/src/views/login/register-submit/index.vue
0 → 100755
View file @
104523c6
<
template
>
<md-field-group
class=
"register_submit"
>
<md-field
v-model=
"code"
icon=
"mobile"
placeholder=
"请输入验证码"
>
<div
slot=
"rightIcon"
@
click=
"getCode"
class=
"getCode red"
>
<countdown
v-if=
"counting"
:time=
"60000"
@
countdownend=
"countdownend"
>
<template
slot-scope=
"props"
>
{{
+
props
.
seconds
||
60
}}
秒后获取
</
template
>
</countdown>
<span
v-else
>
获取验证码
</span>
</div>
</md-field>
<md-field
v-model=
"password"
icon=
"lock"
placeholder=
"请输入密码"
/>
<md-field
v-model=
"repeatPassword"
icon=
"lock"
placeholder=
"请再次确认密码"
/>
<div
class=
"register_submit_btn"
>
<van-button
type=
"danger"
size=
"large"
@
click=
"registerSubmit"
>
确定
</van-button>
</div>
</md-field-group>
</template>
<
script
>
import
field
from
'
@/vue/components/field/
'
;
import
fieldGroup
from
'
@/vue/components/field-group/
'
;
export
default
{
data
()
{
return
{
counting
:
true
,
code
:
''
,
password
:
''
,
repeatPassword
:
''
};
},
methods
:
{
registerSubmit
()
{
this
.
$router
.
push
({
name
:
'
registerStatus
'
,
params
:
{
status
:
'
success
'
}
});
},
getCode
()
{
this
.
counting
=
true
;
},
countdownend
()
{
this
.
counting
=
false
;
}
},
components
:
{
[
field
.
name
]:
field
,
[
fieldGroup
.
name
]:
fieldGroup
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
@import
'../../../assets/scss/mixin'
;
.register_submit
{
padding-top
:
40px
;
background-color
:
#fff
;
}
.register_submit_btn
{
padding-top
:
30px
;
}
.getCode
{
@include
one-border
(
left
);
text-align
:
center
;
}
.time_down
{
color
:
$red
;
}
</
style
>
litemall-vue/src/views/order/orderDetail/bottom-goods-info.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"order-goods"
>
<van-card
v-for=
"item in goodsInfo.orderGoods"
:key=
"item.id"
:title=
"item.goodsName"
desc=
"暂无描述"
:num=
"item.number"
:price=
"item.price +'.00'"
:thumb=
"item.picUrl"
></van-card>
<van-cell-group>
<!--
<van-field
v-model=
"remark"
placeholder=
"请输入备注"
label=
"订单备注"
>
-->
<!--
<template
slot=
"icon"
>
{{
remark
.
length
}}
/50
</
template
>
-->
<!-- </van-field> -->
<van-cell
title=
"商品金额"
>
<span
class=
"red"
>
{{goodsInfo.orderInfo.goodsPrice * 100 | yuan}}
</span>
</van-cell>
<van-cell
title=
"邮费"
:value=
"goodsInfo.orderInfo.freightPrice "
></van-cell>
<!-- <van-cell title="税费" value="¥8.96"></van-cell> -->
<!-- <van-cell title="优惠券">
<span class="red">-{{ goodsInfo.orderInfo.xxx * 100 || 0 | yuan}}</span>
</van-cell>-->
</van-cell-group>
</div>
</template>
<
script
>
import
{
Card
,
Field
}
from
'
vant
'
;
export
default
{
name
:
'
bottom-goods-info
'
,
props
:
{
goodsInfo
:
{
type
:
Object
,
default
:
()
=>
({})
}
},
data
()
{
return
{
remark
:
''
// goodsInfo: {}
};
},
created
()
{},
methods
:
{
// async init() {
// let { data } = await this.$reqGet(
// '/wx/cart/checkout?cartId=0&addressId=0&couponId=0&grouponRulesId=0'
// );
// debugger;
// this.goodsInfo = data.data;
// }
},
components
:
{
[
Card
.
name
]:
Card
,
[
Field
.
name
]:
Field
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.order-goods
{
background-color
:
#fff
;
}
</
style
>
litemall-vue/src/views/order/orderDetail/index.vue
0 → 100755
View file @
104523c6
This diff is collapsed.
Click to expand it.
litemall-vue/src/views/order/orderDetail/top-user-info.vue
0 → 100755
View file @
104523c6
<
template
>
<van-cell-group>
<van-cell
icon=
"dingwei"
isLink
:title=
"`$
{goodsInfo.orderInfo.consignee} ${goodsInfo.orderInfo.mobile}`"
:label="goodsInfo.orderInfo.address"
/>
<!--
<van-cell
class=
"daodian"
title=
"到店自提"
label=
"浙江省 杭州市 西湖区 创新创业园"
>
<van-checkbox
v-model=
"isDaoDian"
slot=
"icon"
></van-checkbox>
</van-cell>
-->
<!--
<van-cell
icon=
"id-card"
title=
"张三"
label=
"330327********1574"
isLink
/>
-->
</van-cell-group>
</
template
>
<
script
>
import
{
Checkbox
}
from
'
vant
'
;
export
default
{
name
:
'
top-user-info
'
,
props
:
{
goodsInfo
:
{
type
:
Object
,
default
:
()
=>
({})
}
},
data
()
{
return
{
isDaoDian
:
false
};
},
components
:
{
[
Checkbox
.
name
]:
Checkbox
}
};
</
script
>
<
style
lang=
"scss"
>
.daodian
{
.van-checkbox
.van-icon-success
{
height
:
16px
;
width
:
16px
;
font-size
:
$font-size-small
;
&
::before
{
line-height
:
16px
;
}
}
.van-checkbox__input
{
height
:
16px
;
}
.van-checkbox__label
{
margin-left
:
0
;
}
.shop_address
{
padding-left
:
25px
;
box-sizing
:
border-box
;
}
}
</
style
>
Prev
1
2
3
4
5
6
7
8
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment