606 lines
14 KiB
Vue
606 lines
14 KiB
Vue
<template>
|
|
<view>
|
|
<view class="aside-container">
|
|
<view class="aside-headimg">
|
|
<uni-dropdown>
|
|
<view slot="dropdown-link" class="head-box" @click="$refs.moreMenu.close()">
|
|
<image :src="$util.img(defaultImg.store)" v-if="!storeInfo || !storeInfo.store_image || logoError" mode="aspectFit"></image>
|
|
<image :src="$util.img(storeInfo.store_image)" v-else @error="$util.img(defaultImg.store)" mode="aspectFit"></image>
|
|
</view>
|
|
<view slot="dropdown">
|
|
<view class="dropdown-menu">
|
|
<view class="menu-item" v-if="userInfo" @click="changePassword">
|
|
{{ userInfo ? userInfo.username : '' }}
|
|
<text class="iconfont iconqianhou2"></text>
|
|
</view>
|
|
<view class="menu-item">门店名称:{{ storeInfo ? storeInfo.store_name : '' }}</view>
|
|
|
|
<view class="menu-item" @click="switchStore()" v-if="storeList.length > 1">切换门店</view>
|
|
|
|
<view class="menu-item logout" @click="$refs.logout.open()">
|
|
退出登录
|
|
<text class="iconfont icontuichu"></text>
|
|
</view>
|
|
<view class="arrow"></view>
|
|
</view>
|
|
</view>
|
|
</uni-dropdown>
|
|
</view>
|
|
<view class="menu-wrap">
|
|
<block v-for="(item, index) in menu" :key="index">
|
|
<view class="menu-item" :class="{ active: index == first }" @click="firstMenu(item, index)">
|
|
<view class="iconfont" :class="item.icon"></view>
|
|
<view>{{ item.title }}</view>
|
|
</view>
|
|
</block>
|
|
</view>
|
|
</view>
|
|
|
|
<uni-popup ref="passwordPopup">
|
|
<view class="password-popup">
|
|
<view class="head">修改密码</view>
|
|
<view class="common-form body">
|
|
<view class="common-form-item">
|
|
<view class="form-label">
|
|
<text class="required">*</text>
|
|
原密码
|
|
</view>
|
|
<view class="form-input-inline"><input type="text" :password="true" v-model="codeData.old_pass" class="form-input" placeholder="请输入原密码" /></view>
|
|
</view>
|
|
<view class="common-form-item">
|
|
<view class="form-label">
|
|
<text class="required">*</text>
|
|
新密码
|
|
</view>
|
|
<view class="form-input-inline"><input type="text" :password="true" v-model="codeData.new_pass" class="form-input" placeholder="请输入新密码" /></view>
|
|
</view>
|
|
<view class="common-form-item">
|
|
<view class="form-label">
|
|
<text class="required">*</text>
|
|
确认新密码
|
|
</view>
|
|
<view class="form-input-inline">
|
|
<input type="text" :password="true" v-model="codeData.confirm_new_pass" class="form-input" placeholder="请输入新密码" />
|
|
</view>
|
|
</view>
|
|
<view class="common-btn-wrap">
|
|
<button type="default" class="primary-btn screen-btn" @click="modifyPasswordFn">确定</button>
|
|
<button type="default" class="default-btn" @click="$refs.passwordPopup.close()">取消</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uni-popup>
|
|
|
|
<uni-popup ref="moreMenu">
|
|
<scroll-view scroll-y="true" class="more-menu-scroll common-scrollbar">
|
|
<view class="more-menu">
|
|
<block v-for="(item, secondIndex) in moreMenu" :key="secondIndex">
|
|
<block v-if="item.children && item.children.length">
|
|
<view class="title">{{ item.title }}</view>
|
|
<view class="child-menu-wrap">
|
|
<block v-for="(thirditem, thirdIndex) in item.children" :key="thirdIndex">
|
|
<view
|
|
class="menu-item"
|
|
:class="{ active: secondIndex == second && thirdIndex == third }"
|
|
@click="thirdMenu(thirditem, secondIndex, thirdIndex)"
|
|
>
|
|
<view class="iconfont" :class="thirditem.icon"></view>
|
|
<view>{{ thirditem.title }}</view>
|
|
</view>
|
|
</block>
|
|
</view>
|
|
</block>
|
|
</block>
|
|
</view>
|
|
</scroll-view>
|
|
</uni-popup>
|
|
|
|
<uni-popup ref="storePop">
|
|
<view class="pop-box store-select">
|
|
<view class="pop-header">
|
|
<view class="pop-header-text">选择门店</view>
|
|
<view class="pop-header-close" @click="$refs.storePop.close()"><i class="iconguanbi1 iconfont"></i></view>
|
|
</view>
|
|
<scroll-view scroll-y="true" class="common-scrollbar pop-content">
|
|
<view class="content-lists">
|
|
<view
|
|
class="content-items"
|
|
v-for="(item, index) in storeList"
|
|
@click="selectStore(item)"
|
|
:key="index"
|
|
:class="{ active: storeInfo && storeInfo.store_id == item.store_id }"
|
|
>
|
|
<view class="item-img">
|
|
<image v-if="item.store_image" :src="$util.img(item.store_image, { size: 'small' })" @error="$util.img(defaultImg.store)" mode="aspectFit"></image>
|
|
<image v-else :src="$util.img(defaultImg.store)" mode="aspectFit"></image>
|
|
</view>
|
|
<view class="item-info">
|
|
<view class="item-name">{{ item.store_name }}</view>
|
|
<view class="item-phone">
|
|
<i class="iconfont iconshijian"></i>
|
|
{{ item.open_date ? item.open_date : '营业时间请联系管理员' }}
|
|
</view>
|
|
<view class="item-addr">
|
|
<i class="iconfont icondizhi"></i>
|
|
{{ item.full_address }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
<view class="pop-bottom"><button class="primary-btn" @click="$refs.storePop.close()">确定</button></view>
|
|
</view>
|
|
</uni-popup>
|
|
|
|
<uni-popup ref="logout" type="center">
|
|
<view class="logout-popup">
|
|
<view class="title">确定退出系统?系统将自动交班</view>
|
|
<view class="btn">
|
|
<button type="primary" class="default-btn btn save" @click="$refs.logout.close()">取消</button>
|
|
<button type="primary" class="primary-btn btn" @click="logout">确定</button>
|
|
</view>
|
|
</view>
|
|
</uni-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapState } from 'vuex';
|
|
|
|
export default {
|
|
name: 'LayoutAside',
|
|
props: {},
|
|
created() {
|
|
this.getStoreList();
|
|
},
|
|
data() {
|
|
return {
|
|
moreMenu: [],
|
|
moreIndex: 0,
|
|
logoError: false,
|
|
storeList: [],
|
|
codeData: {
|
|
old_pass: '',
|
|
new_pass: '',
|
|
confirm_new_pass: ''
|
|
}
|
|
};
|
|
},
|
|
computed: {
|
|
...mapState(['first', 'second', 'third', 'currRoute', 'addon', 'userInfo', 'menu'])
|
|
},
|
|
watch: {
|
|
storeInfo: function() {
|
|
this.$store.dispatch('getUserGroup');
|
|
},
|
|
menu: function() {
|
|
this.checkPageAuth();
|
|
}
|
|
},
|
|
methods: {
|
|
firstMenu(data, index) {
|
|
// #ifdef H5
|
|
if (data.path == this.$route.path) return;
|
|
// #endif
|
|
// #ifdef APP-PLUS
|
|
if (data.path == '/' + this.$mp.page.route) return;
|
|
// #endif
|
|
|
|
if (data.children && data.childshow) {
|
|
this.moreMenu = data.children;
|
|
this.moreIndex = index;
|
|
this.$refs.moreMenu.open('left');
|
|
} else {
|
|
this.$refs.moreMenu.close('left');
|
|
this.$util.redirectTo(data.path, data.query ?? {});
|
|
}
|
|
},
|
|
thirdMenu(data, second, third) {
|
|
this.$refs.moreMenu.close('left');
|
|
this.$util.redirectTo(data.path, data.query ?? {});
|
|
},
|
|
logout() {
|
|
this.$api.sendRequest({
|
|
url: '/cashier/storeapi/store/changeshifts',
|
|
success: res => {
|
|
if (res.code == 0 && res.data) {
|
|
this.$refs.logout.close();
|
|
uni.removeStorage({
|
|
key: 'cashier_token',
|
|
success: () => {
|
|
this.$store.commit('setStoreInfo', null);
|
|
this.$store.commit('setMemberInfo', null);
|
|
this.$store.commit('setUserInfo', null);
|
|
this.$store.commit('setMenu', []);
|
|
this.$util.redirectTo('/pages/login/login', {}, 'reLaunch');
|
|
}
|
|
});
|
|
} else {
|
|
this.isSub = false;
|
|
this.$util.showToast({
|
|
title: res.message
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
switchStore() {
|
|
this.$refs.storePop.open('center');
|
|
},
|
|
changePassword() {
|
|
this.$refs.passwordPopup.open('center');
|
|
},
|
|
modifyPasswordFn() {
|
|
if (this.codeData.new_pass != this.codeData.confirm_new_pass) {
|
|
this.$util.showToast({
|
|
title: '两次密码输入不一致,请重新输入'
|
|
});
|
|
return false;
|
|
}
|
|
this.$api.sendRequest({
|
|
url: '/cashier/storeapi/user/modifypassword',
|
|
data: this.codeData,
|
|
success: res => {
|
|
this.$util.showToast({
|
|
title: res.message
|
|
});
|
|
if (res.code >= 0) {
|
|
this.codeData.old_pass = '';
|
|
this.codeData.new_pass = '';
|
|
this.codeData.confirm_new_pass = '';
|
|
uni.removeStorageSync('cashier_token');
|
|
this.$refs.passwordPopup.close();
|
|
setTimeout(() => {
|
|
this.$util.redirectTo('/pages/login/login');
|
|
}, 500);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
selectStore(data) {
|
|
uni.setStorageSync('store_id', data.store_id);
|
|
this.$store.dispatch('getStoreInfo');
|
|
this.$refs.storePop.close();
|
|
this.$forceUpdate();
|
|
},
|
|
getStoreList() {
|
|
this.$api.sendRequest({
|
|
url: '/cashier/storeapi/store/lists',
|
|
success: res => {
|
|
if (res.code == 0 && res.data) this.storeList = res.data;
|
|
}
|
|
});
|
|
},
|
|
/**
|
|
* 检测页面是否有权限
|
|
*/
|
|
checkPageAuth() {
|
|
this.$api.sendRequest({
|
|
url: '/cashier/storeapi/store/checkpageauth',
|
|
data: {
|
|
page: this.currRoute
|
|
},
|
|
success: res => {
|
|
if (res.code && res.code == -10012) {
|
|
this.$util.redirectTo('/pages/index/no_permission', {}, 'redirectTo');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
/deep/ .aside-headimg .dropdown-box {
|
|
left: 0 !important;
|
|
right: unset !important;
|
|
}
|
|
|
|
.aside-container {
|
|
position: fixed;
|
|
top: $statusbar-height;
|
|
width: $aside-width;
|
|
height: 100vh;
|
|
background-color: #272738;
|
|
font-size: 0.12rem;
|
|
color: #fff;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.aside-headimg {
|
|
width: 100%;
|
|
height: 0.8rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
|
|
.head-box {
|
|
image {
|
|
border-radius: 50%;
|
|
width: 0.4rem;
|
|
height: 0.4rem;
|
|
}
|
|
}
|
|
}
|
|
|
|
.menu-wrap {
|
|
height: calc(100vh - #{$header-height} - #{$statusbar-height});
|
|
overflow-y: scroll;
|
|
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.menu-item {
|
|
text-align: center;
|
|
color: #cccccc;
|
|
font-size: 0.14rem;
|
|
line-height: 1;
|
|
padding: 0.15rem 0;
|
|
cursor: pointer;
|
|
|
|
.iconfont {
|
|
font-size: 0.2rem;
|
|
margin-bottom: 0.1rem;
|
|
}
|
|
|
|
&.active {
|
|
background: $primary-color;
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.more-menu-scroll {
|
|
height: calc(100vh - #{$statusbar-height});
|
|
margin-top: $statusbar-height;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.more-menu {
|
|
width: 3rem;
|
|
background: #fff;
|
|
box-sizing: content-box;
|
|
padding-left: $aside-width;
|
|
height: 100%;
|
|
|
|
.title {
|
|
font-size: 0.2rem;
|
|
font-weight: 400;
|
|
color: #303133;
|
|
line-height: 0.36rem;
|
|
padding: 0.2rem;
|
|
}
|
|
}
|
|
|
|
.child-menu-wrap {
|
|
padding: 0 0.2rem;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
|
|
.menu-item {
|
|
width: 0.8rem;
|
|
height: 0.8rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
font-size: 0.14rem;
|
|
color: #303133;
|
|
background: #f5f5f5;
|
|
cursor: pointer;
|
|
margin: 0 0.1rem 0.1rem 0;
|
|
|
|
&:nth-child(3n + 3) {
|
|
margin-right: 0;
|
|
}
|
|
|
|
view {
|
|
line-height: 1;
|
|
}
|
|
|
|
.iconfont {
|
|
font-size: 0.23rem;
|
|
margin-bottom: 0.1rem;
|
|
}
|
|
|
|
&.active {
|
|
background-color: rgba($color: $primary-color, $alpha: 0.2);
|
|
color: $primary-color;
|
|
}
|
|
}
|
|
}
|
|
|
|
/deep/ .uni-popup {
|
|
z-index: 999;
|
|
}
|
|
.dropdown-menu {
|
|
padding: 0rem 0;
|
|
margin-top: 0.15rem;
|
|
background-color: #fff;
|
|
border: 0.01rem solid #ebeef5;
|
|
border-radius: 0.04rem;
|
|
box-shadow: 0 0.01rem 0.12rem 0 rgba(0, 0, 0, 0.1);
|
|
position: relative;
|
|
width: 3rem;
|
|
|
|
.arrow {
|
|
position: absolute;
|
|
top: -0.1rem;
|
|
left: 0.08rem;
|
|
width: 0;
|
|
height: 0;
|
|
border-left: 0.1rem solid transparent;
|
|
border-right: 0.1rem solid transparent;
|
|
border-bottom: 0.1rem solid #fff;
|
|
}
|
|
|
|
.menu-item {
|
|
width: calc(100% - 0.2rem);
|
|
height: 0.57rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin: 0 0.1rem;
|
|
padding: 0.05rem 0.05rem;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
color: #303133;
|
|
box-sizing: border-box;
|
|
border-bottom: 0.01rem solid #e6e6e6;
|
|
&:hover {
|
|
color: $primary-color;
|
|
}
|
|
.iconfont {
|
|
color: #999;
|
|
}
|
|
&:nth-child(3) {
|
|
border: 0;
|
|
}
|
|
&.logout {
|
|
margin: 0;
|
|
background-color: #eff0f4;
|
|
padding: 0.05rem 0.15rem;
|
|
width: 100%;
|
|
}
|
|
}
|
|
}
|
|
|
|
.pop-box {
|
|
background: #ffffff;
|
|
width: 6rem;
|
|
height: 4rem;
|
|
.pop-header {
|
|
padding: 0 0.15rem 0 0.2rem;
|
|
height: 0.5rem;
|
|
line-height: 0.5rem;
|
|
border-bottom: 0.01rem solid #f0f0f0;
|
|
font-size: 0.14rem;
|
|
color: #333;
|
|
overflow: hidden;
|
|
border-radius: 0.02rem 0.2rem 0 0;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
.pop-header-text {
|
|
}
|
|
.pop-header-close {
|
|
cursor: pointer;
|
|
i {
|
|
font-size: 0.18rem;
|
|
}
|
|
}
|
|
}
|
|
.pop-content {
|
|
height: calc(100% - 1.05rem);
|
|
overflow-y: scroll;
|
|
padding: 0.2rem;
|
|
box-sizing: border-box;
|
|
}
|
|
.pop-bottom {
|
|
padding: 0.1rem;
|
|
height: 0.65rem;
|
|
border-top: 0.01rem solid #eee;
|
|
button {
|
|
width: 1rem;
|
|
}
|
|
}
|
|
}
|
|
// 选择门店
|
|
.store-select {
|
|
.content-lists {
|
|
width: calc(100% - 0.2rem);
|
|
padding-bottom: 0.2rem;
|
|
.content-items {
|
|
cursor: pointer;
|
|
border-width: 0.01rem;
|
|
border-color: #cccccc;
|
|
border-style: solid;
|
|
padding: 0.15rem;
|
|
border-radius: 0.03rem;
|
|
margin-bottom: 0.1rem;
|
|
display: flex;
|
|
.item-info {
|
|
margin-left: 0.1rem;
|
|
.item-name {
|
|
font-size: 0.16rem;
|
|
font-weight: 600;
|
|
}
|
|
.item-phone {
|
|
margin-top: 0.08rem;
|
|
color: #999;
|
|
i {
|
|
margin-right: 0.05rem;
|
|
font-size: 0.14rem;
|
|
}
|
|
}
|
|
.item-addr {
|
|
margin-top: 0.03rem;
|
|
color: #999;
|
|
i {
|
|
font-size: 0.14rem;
|
|
margin-right: 0.05rem;
|
|
}
|
|
}
|
|
}
|
|
.item-img {
|
|
width: 0.7rem;
|
|
height: 0.7rem;
|
|
image {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
&.active {
|
|
border-color: $primary-color;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.password-popup {
|
|
background-color: #fff;
|
|
width: 4.5rem;
|
|
.head {
|
|
padding: 0 0.2rem;
|
|
height: 0.5rem;
|
|
line-height: 0.5rem;
|
|
margin-bottom: 0.1rem;
|
|
}
|
|
.body {
|
|
padding: 0 0.1rem 0.2rem 0.3rem;
|
|
}
|
|
}
|
|
|
|
.logout-popup {
|
|
width: 3rem;
|
|
min-height: 1.5rem;
|
|
border-radius: 0.06rem;
|
|
background: #ffffff;
|
|
padding: 0.4rem 0.15rem 0;
|
|
box-sizing: border-box;
|
|
.title {
|
|
font-size: 0.16rem;
|
|
text-align: center;
|
|
}
|
|
.btn {
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-top: 0.3rem;
|
|
.btn {
|
|
width: 36%;
|
|
height: auto;
|
|
padding: 0 0.15rem;
|
|
margin: 0;
|
|
height: 0.35rem;
|
|
}
|
|
.btn:last-child {
|
|
margin-left: 0.25rem;
|
|
}
|
|
}
|
|
}
|
|
</style>
|