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
"jshERP-boot/vscode:/vscode.git/clone" did not exist on "0b1540a86aac730811c5a068250b5178a32590dd"
Commit
104523c6
authored
Apr 19, 2019
by
Junling Bu
Browse files
doc
parents
70c31ee4
4ee32ff6
Changes
153
Expand all
Show 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