commit message

This commit is contained in:
Chopper
2021-05-13 10:56:04 +08:00
commit ec3e958037
728 changed files with 132685 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
<template>
<Breadcrumb>
<BreadcrumbItem
v-for="item in currentPath"
:to="item.path"
:key="item.name"
>{{ itemTitle(item) }}</BreadcrumbItem>
</Breadcrumb>
</template>
<script>
export default {
name: 'breadcrumbNav',
props: {
currentPath: Array
},
methods: {
itemTitle (item) {
if (typeof item.title == 'object') {
return this.$t(item.title.i18n);
} else {
return item.title;
}
}
}
};
</script>

View File

@@ -0,0 +1,44 @@
<template>
<div class="foot">
<Row type="flex" justify="space-around" class="help">
<a class="item" href="https://pickmall.com" target="_blank">{{ $t('help') }}</a>
<a class="item" href="https://pickmall.com" target="_blank">{{ $t('privacy') }}</a>
<a class="item" href="https://pickmall.com" target="_blank">{{ $t('terms') }}</a>
</Row>
<Row type="flex" justify="center" class="copyright">
Copyright © 2020 - Present
<a
href="http://lili.cn"
target="_blank"
style="margin:0 5px;"
>lili-shop</a> {{ $t('rights') }}
</Row>
</div>
</template>
<script>
export default {
name: "footer"
};
</script>
<style lang="scss" scoped>
.foot {
position: fixed;
bottom: 4vh;
width: 368px;
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
.help {
margin: 0 auto;
margin-bottom: 1vh;
width: 60%;
.item {
color: rgba(0, 0, 0, 0.45);
}
:hover {
color: rgba(0, 0, 0, 0.65);
}
}
}
</style>

View File

@@ -0,0 +1,80 @@
<template>
<div @click="handleChange" v-if="showFullScreenBtn" class="full-screen-btn-con">
<Tooltip :content="value ? '退出全屏' : '全屏'" placement="bottom">
<Icon :type="value ? 'ios-contract' : 'ios-expand'" :size="24"></Icon>
</Tooltip>
</div>
</template>
<script>
export default {
name: "fullScreen",
props: {
value: {
type: Boolean,
default: false
}
},
computed: {
showFullScreenBtn() {
return window.navigator.userAgent.indexOf("MSIE") < 0;
}
},
methods: {
handleFullscreen() {
let main = document.body;
if (this.value) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
} else {
if (main.requestFullscreen) {
main.requestFullscreen();
} else if (main.mozRequestFullScreen) {
main.mozRequestFullScreen();
} else if (main.webkitRequestFullScreen) {
main.webkitRequestFullScreen();
} else if (main.msRequestFullscreen) {
main.msRequestFullscreen();
}
}
},
handleChange() {
this.handleFullscreen();
}
},
created() {
let isFullscreen =
document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.fullScreen ||
document.mozFullScreen ||
document.webkitIsFullScreen;
isFullscreen = !!isFullscreen;
document.addEventListener("fullscreenchange", () => {
this.$emit("input", !this.value);
this.$emit("on-change", !this.value);
});
document.addEventListener("mozfullscreenchange", () => {
this.$emit("input", !this.value);
this.$emit("on-change", !this.value);
});
document.addEventListener("webkitfullscreenchange", () => {
this.$emit("input", !this.value);
this.$emit("on-change", !this.value);
});
document.addEventListener("msfullscreenchange", () => {
this.$emit("input", !this.value);
this.$emit("on-change", !this.value);
});
this.$emit("input", isFullscreen);
}
};
</script>

View File

@@ -0,0 +1,27 @@
<template>
<div>
<Row class="header">
<img src="../../assets/logo.png" class="logo" width="220px">
<!-- <div class="description">{{ $t('LILISHOP-ADMIN') }}</div> -->
</Row>
</div>
</template>
<script>
export default {
name: "header",
};
</script>
<style lang="scss" scoped>
.header {
margin-bottom: 6vh;
text-align: center;
display: flex;
justify-content: center !important;
}
.logo {
transform: scale(2);
}
</style>

View File

@@ -0,0 +1,32 @@
<template>
<div class="lang-icon">
<Dropdown @on-click="langChange">
<Icon type="md-globe" size="26"/>
<DropdownMenu slot="list">
<DropdownItem name="zh-CN">简体中文</DropdownItem>
<DropdownItem name="en-US">English</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
</template>
<script>
export default {
name: "langSwitch",
methods: {
langChange(v) {
this.$i18n.locale = v;
this.$store.commit("switchLang", v);
}
}
};
</script>
<style lang="scss" scoped>
.lang-icon {
position: fixed;
top: 2vh;
right: 1.5vw;
cursor: pointer;
}
</style>

View File

@@ -0,0 +1,82 @@
<template>
<div class="message-con">
<Dropdown trigger="click">
<a href="javascript:void(0)">
{{ value > 0 ? "有" + value + "条未读消息" : "无未读消息" }}
<Icon v-if="value!=0" type="ios-arrow-down"></Icon>
</a>
<DropdownMenu v-if="value!=0" slot="list">
<DropdownItem v-if="res.balanceCash" @click.native="navigateTo('deposit')">
<Badge :count="res.balanceCash">待处理预存款提现申请 </Badge>
</DropdownItem>
<DropdownItem v-if="res.complain" @click.native="navigateTo('orderComplaint')">
<Badge :count="res.complain">待处理投诉审核 </Badge>
</DropdownItem>
<DropdownItem v-if="res.distributionCash" @click.native="navigateTo('distribution')">
<Badge :count="res.distributionCash">待处理分销商提现申请 </Badge>
</DropdownItem>
<DropdownItem v-if="res.goods" @click.native="navigateTo('applyGoods')">
<Badge :count="res.goods">待处理商品审核 </Badge>
</DropdownItem>
<DropdownItem v-if="res.refund" @click.native="navigateTo('afterSaleOrder')">
<Badge :count="res.refund">待处理售后申请 </Badge>
</DropdownItem>
<DropdownItem v-if="res.store" @click.native="navigateTo('shopAuth')">
<Badge :count="res.store">待处理店铺入驻审核 </Badge>
</DropdownItem>
<DropdownItem v-if="res.waitPayBill" @click.native="navigateTo('accountStatementBill')">
<Badge :count="res.waitPayBill">待与商家对账</Badge>
</DropdownItem>
<div></div>
</DropdownMenu>
</Dropdown>
</div>
</template>
<script>
export default {
name: "messageTip",
data() {
return {
value: 0,
empty: false,
};
},
props: {
res: {
type: null,
},
},
mounted() {
this.init();
},
methods: {
navigateTo(name) {
this.$router.push({
name,
});
},
init() {
Object.keys(this.res).forEach((item) => {
this.value = parseInt(this.value) + parseInt(this.res[item]);
});
},
},
};
</script>
<style scoped lang="scss">
/deep/ .ivu-select-dropdown {
text-align: left;
}
.message-con {
margin-right: 10px;
}
/deep/ .ivu-dropdown-item{
padding: 7px 20px !important;
}
/deep/ .ivu-badge-count{
right: -10px !important;
}
</style>

View File

@@ -0,0 +1,44 @@
<template>
<Menu
ref="sideMenu"
:active-name="$route.name"
:open-names="singleOpenName"
theme="light"
width="110px"
@on-select="changeMenu"
>
<template v-for="item in menuList">
<MenuItem :name="item.name" :key="item.name">
{{item.title}}
</MenuItem>
</template>
</Menu>
</template>
<script>
export default {
name: "sidebarMenu",
data() {
return {
singleOpenName: []
};
},
props: {
menuList: {
type:Array,
default:[]
},
openNames: {
type: Array
}
},
methods: {
},
};
</script>
<style lang="scss" scoped>
@import "../styles/menu.scss";
</style>

View File

@@ -0,0 +1,73 @@
<template>
<div>
<template v-for="(item, index) in menuList">
<div style="text-align: center;" :key="index">
<Dropdown
transfer
v-if="item.children.length !== 1"
placement="right-start"
:key="index"
@on-click="changeMenu"
>
<Button style="width: 70px;height: 42px;margin-left: -5px;padding:10px 0;" type="text">
<Icon :size="20" :color="iconColor" :type="item.icon"></Icon>
</Button>
<DropdownMenu style="width: 200px;" slot="list">
<template v-for="(child, i) in item.children">
<DropdownItem :name="child.name" :key="i">
<Icon :type="child.icon"></Icon>
<span style="padding-left:10px;">{{ itemTitle(child) }}</span>
</DropdownItem>
</template>
</DropdownMenu>
</Dropdown>
<Dropdown transfer v-else placement="right-start" :key="index" @on-click="changeMenu">
<Button
@click="changeMenu(item.children[0].name)"
style="width: 70px;height: 42px;margin-left: -5px;padding:10px 0;"
type="text"
>
<Icon :size="20" :color="iconColor" :type="item.children[0].icon || item.icon"></Icon>
</Button>
<DropdownMenu style="width: 200px;" slot="list">
<DropdownItem :name="item.children[0].name" :key="'d' + index">
<Icon :type="item.children[0].icon || item.icon"></Icon>
<span style="padding-left:10px;">{{ itemTitle(item.children[0]) }}</span>
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
</template>
</div>
</template>
<script>
export default {
name: "sidebarMenuShrink",
props: {
menuList: {
type: Array
},
iconColor: {
type: String,
default: "white"
},
menuTheme: {
type: String,
default: "dark"
}
},
methods: {
changeMenu(active) {
this.$emit("on-change", active);
},
itemTitle(item) {
if (typeof item.title == "object") {
return this.$t(item.title.i18n);
} else {
return item.title;
}
}
}
};
</script>

View File

@@ -0,0 +1,81 @@
<template>
<div class="ivu-shrinkable-menu">
<!-- 一级菜单 -->
<Menu ref="sideMenu" width="110px" theme="dark" :active-name="currNav" @on-select="selectNav">
<MenuItem v-for="(item, i) in navList" :key="i" :name="item.name">
{{item.title}}
</MenuItem>
</Menu>
<!-- 二级菜单 -->
<Menu
ref="childrenMenu"
:active-name="$route.name"
width="130px"
@on-select="changeMenu"
>
<template v-for="item in menuList">
<MenuGroup :title="item.title" :key="item.id" style="padding-left:0;">
<MenuItem :name="menu.name" v-for="menu in item.children" :key="menu.name">
{{menu.title}}
</MenuItem>
</MenuGroup>
</template>
</Menu>
</div>
</template>
<script>
import util from "@/libs/util.js";
export default {
name: "shrinkableMenu",
data () {
return {
}
},
computed: {
menuList() {
return this.$store.state.app.menuList;
},
navList() {
return this.$store.state.app.navList;
},
},
watch: {
// 监听路由变化
$route: {
handler: function (val, oldVal) {
console.log(val);
}
},
menuList: {
handler: function (val, oldVal) {
}
}
},
mounted() {
},
methods: {
changeMenu(name) { //二级路由点击
this.$router.push({
name: name
});
},
selectNav(name) {
this.$store.commit("setCurrNav", name);
this.setStore("currNav", name);
// if (this.$route.name != "home_index") {
// this.$router.push({
// name: "home_index"
// });
// }
util.initRouter(this);
},
}
};
</script>
<style lang="scss" scoped>
@import "./styles/menu.scss";
</style>

View File

@@ -0,0 +1,23 @@
.ivu-shrinkable-menu{
height: calc(100% - 60px);
width: 240px;
display: flex;
}
.ivu-menu-vertical .ivu-menu-item-group-title {
padding-left: 5px;
}
.ivu-btn-text:hover {
background-color: rgba(255,255,255,.2) !important;
}
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
background-color: #fff;
&:hover{
background-color: #fff;
}
}
.ivu-menu-vertical{
overflow-y: auto;
}
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
color: #ed3f14;
}

View File

@@ -0,0 +1,265 @@
<template>
<div
ref="scrollCon"
@DOMMouseScroll="handlescroll"
@mousewheel="handlescroll"
class="tags-outer-scroll-con"
>
<!-- <div class="close-all-tag-con">
<Dropdown transfer @on-click="handleTagsOption">
<Button size="small" type="primary">
<Icon type="md-arrow-dropdown"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="clearAll">{{ $t('closeAll') }}</DropdownItem>
<DropdownItem name="clearOthers">{{ $t('closeOthers') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
</div> -->
<ul v-show="visible" :style="{left: contextMenuLeft + 'px', top: contextMenuTop + 'px'}" class="contextmenu">
<li v-for="(item, key) of menuList" @click="handleTagsOption(key)" :key="key">{{item}}</li>
</ul>
<div ref="scrollBody" class="tags-inner-scroll-body" :style="{left: tagBodyLeft + 'px'}">
<transition-group name="taglist-moving-animation">
<Tag
type="dot"
v-for="item in pageTagsList"
ref="tagsPageOpened"
:key="item.name"
:name="item.name"
@on-close="closePage"
@click.native="linkTo(item)"
:closable="item.name=='home_index'?false:true"
:color="item.children?(item.children[0].name==currentPageName?'primary':'default'):(item.name==currentPageName?'primary':'default')"
@contextmenu.prevent.native="contextMenu(item, $event)"
>{{ itemTitle(item) }}</Tag>
</transition-group>
</div>
</div>
</template>
<script>
export default {
name: "tagsPageOpened",
data() {
return {
currentPageName: this.$route.name,
tagBodyLeft: 0,
visible: false,
contextMenuLeft: 0,
contextMenuTop: 0,
menuList: {
others: '关闭其他',
clearAll: '关闭所有'
},
refsTag: [],
tagsCount: 1
};
},
props: {
pageTagsList: Array,
beforePush: {
type: Function,
default: item => {
return true;
}
}
},
computed: {
title() {
return this.$store.state.app.currentTitle;
},
tagsList() {
return this.$store.state.app.pageOpenedList;
}
},
methods: {
itemTitle(item) {
if (typeof item.title == "object") {
return this.$t(item.title.i18n);
} else {
return item.title;
}
},
closePage(event, name) {
let pageOpenedList = this.$store.state.app.pageOpenedList;
let lastPageObj = pageOpenedList[0];
if (this.currentPageName == name) {
let len = pageOpenedList.length;
for (let i = 1; i < len; i++) {
if (pageOpenedList[i].name == name) {
if (i < len - 1) {
lastPageObj = pageOpenedList[i + 1];
} else {
lastPageObj = pageOpenedList[i - 1];
}
break;
}
}
} else {
let tagWidth = event.target.parentNode.offsetWidth;
this.tagBodyLeft = Math.min(this.tagBodyLeft + tagWidth, 0);
}
this.$store.commit("removeTag", name);
this.$store.commit("closePage", name);
pageOpenedList = this.$store.state.app.pageOpenedList;
localStorage.pageOpenedList = JSON.stringify(pageOpenedList);
if (this.currentPageName == name) {
this.linkTo(lastPageObj);
}
},
linkTo(item) {
if (this.$route.name == item.name) {
return;
}
let routerObj = {};
routerObj.name = item.name;
if (item.argu) {
routerObj.params = item.argu;
}
if (item.query) {
routerObj.query = item.query;
}
if (this.beforePush(item)) {
this.$router.push(routerObj);
}
},
handlescroll(e) {
var type = e.type;
let delta = 0;
if (type == "DOMMouseScroll" || type == "mousewheel") {
delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0) * 40;
}
let left = 0;
if (delta > 0) {
left = Math.min(0, this.tagBodyLeft + delta);
} else {
if ( this.$refs.scrollCon.offsetWidth - 100 < this.$refs.scrollBody.offsetWidth ) {
if ( this.tagBodyLeft < -( this.$refs.scrollBody.offsetWidth - this.$refs.scrollCon.offsetWidth + 100 ) ) {
left = this.tagBodyLeft;
} else {
left = Math.max(
this.tagBodyLeft + delta,
this.$refs.scrollCon.offsetWidth -
this.$refs.scrollBody.offsetWidth -
100
);
}
} else {
this.tagBodyLeft = 0;
}
}
this.tagBodyLeft = left;
},
handleTagsOption(type) {
if (type == "clearAll") {
this.$store.commit("clearAllTags");
this.$router.push({
name: "home_index"
});
} else {
this.$store.commit("clearOtherTags", this);
}
this.tagBodyLeft = 0;
},
moveToView(tag) {
if (tag.offsetLeft < -this.tagBodyLeft) {
// 标签在可视区域左侧
this.tagBodyLeft = -tag.offsetLeft + 10;
} else if (
tag.offsetLeft + 10 > -this.tagBodyLeft &&
tag.offsetLeft + tag.offsetWidth <
-this.tagBodyLeft + this.$refs.scrollCon.offsetWidth - 100
) {
// 标签在可视区域
this.tagBodyLeft = Math.min(
0,
this.$refs.scrollCon.offsetWidth -
100 -
tag.offsetWidth -
tag.offsetLeft -
20
);
} else {
// 标签在可视区域右侧
this.tagBodyLeft = -(
tag.offsetLeft -
(this.$refs.scrollCon.offsetWidth - 100 - tag.offsetWidth) +
20
);
}
},
contextMenu (item, e) {
this.visible = true
const offsetLeft = this.$el.getBoundingClientRect().left
this.contextMenuLeft = e.clientX - offsetLeft + 10
this.contextMenuTop = e.clientY - 64
},
closeMenu () {
this.visible = false
}
},
mounted() {
this.refsTag = this.$refs.tagsPageOpened;
setTimeout(() => {
this.refsTag.forEach((item, index) => {
if (this.$route.name == item.name) {
let tag = this.refsTag[index].$el;
this.moveToView(tag);
}
});
}, 1); // 这里不设定时器就会有偏移bug
this.tagsCount = this.tagsList.length;
},
watch: {
$route(to) {
this.currentPageName = to.name;
this.$nextTick(() => {
this.refsTag.forEach((item, index) => {
if (to.name == item.name) {
let tag = this.refsTag[index].$el;
this.moveToView(tag);
}
});
});
this.tagsCount = this.tagsList.length;
},
visible (value) {
if (value) {
document.body.addEventListener('click', this.closeMenu)
} else {
document.body.removeEventListener('click', this.closeMenu)
}
}
}
};
</script>
<style lang="scss">
@import "@/views/main.scss";
.contextmenu {
position: absolute;
margin: 0;
padding: 5px 0;
background: #fff;
z-index: 11000;
list-style-type: none;
border-radius: 4px;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .1);
li {
margin: 0;
padding: 5px 15px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
.ivu-tag-primary, .ivu-tag-primary.ivu-tag-dot .ivu-tag-dot-inner{
background: red;
}
</style>