前端-胡立永 2 months ago
parent
commit
b09f08011f
6 changed files with 392 additions and 136 deletions
  1. +4
    -0
      App.vue
  2. +1
    -1
      components/base/tabbar.vue
  3. +263
    -0
      components/config/roleSelector.vue
  4. +51
    -112
      pages/index/index.vue
  5. +41
    -21
      pages/index/order.vue
  6. +32
    -2
      store/store.js

+ 4
- 0
App.vue View File

@ -1,9 +1,13 @@
<script>
export default {
onLaunch: function() {
//
this.$store.commit('initRole');
},
onShow: function() {
// this.$store.commit('initConfig')
//
this.$store.commit('initRole');
},
onHide: function() {
}


+ 1
- 1
components/base/tabbar.vue View File

@ -76,7 +76,7 @@
flex-direction: row;
height: 120rpx;
padding-bottom: env(safe-area-inset-bottom);
z-index: 999999;
z-index: 999;
bottom: 0;
left: 0;
color: #BCBCBC;


+ 263
- 0
components/config/roleSelector.vue View File

@ -0,0 +1,263 @@
<template>
<view class="roleSelector">
<uv-popup ref="popup" :round="30" :customStyle="{height: '60vh'}">
<view class="content">
<view class="header">
<view class="title">选择身份</view>
<view class="close-btn" @click="close">
<uv-icon name="close" size="20" color="#999"></uv-icon>
</view>
</view>
<view class="role-tip">请选择您的身份类型</view>
<view class="role-list">
<view
v-for="(role, index) in roleOptions"
:key="index"
:class="['role-item', selectedRole === role.value && 'active']"
@click="selectRole(role.value)">
<view class="role-icon">
<uv-icon :name="getRoleIcon(role.value)" size="20" :color="selectedRole === role.value ? '#007AFF' : '#666'"></uv-icon>
</view>
<view class="role-info">
<view class="role-name">{{ role.label }}</view>
<view class="role-desc">{{ getRoleDesc(role.value) }}</view>
</view>
<view class="role-check">
<uv-icon v-if="selectedRole === role.value" name="checkmark-circle" size="20" color="#007AFF"></uv-icon>
<uv-icon v-else name="close-circle" size="20" color="#ccc"></uv-icon>
</view>
</view>
</view>
<view class="action-buttons">
<view class="btn cancel" @click="close">取消</view>
<view class="btn confirm" @click="confirmRoleChange">确认</view>
</view>
</view>
</uv-popup>
</view>
</template>
<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
name: 'RoleSelector',
data() {
return {
selectedRole: '0'
}
},
computed: {
...mapState(['role']),
...mapGetters(['getRoleOptions']),
roleOptions() {
return this.getRoleOptions;
}
},
methods: {
...mapMutations(['switchRole']),
//
open() {
this.selectedRole = this.role;
this.$refs.popup.open('bottom');
},
//
close() {
this.$refs.popup.close();
},
//
selectRole(roleValue) {
this.selectedRole = roleValue;
},
//
confirmRoleChange() {
if (this.selectedRole !== this.role) {
// 使Vuex mutation
this.switchRole(this.selectedRole);
uni.showToast({
title: `已切换到${this.getCurrentRoleText(this.selectedRole)}`,
icon: 'success'
});
//
this.$emit('roleChanged', this.selectedRole);
}
this.close();
},
//
getRoleIcon(roleValue) {
switch(roleValue) {
case '0': return 'man';
case '1': return 'bag';
case '2': return 'man-add';
case '3': return 'setting';
default: return 'man';
}
},
//
getRoleDesc(roleValue) {
switch(roleValue) {
case '0': return '接单赚钱,自由工作';
case '1': return '发布订单,管理业务';
case '2': return '协助管理,处理订单';
case '3': return '区域管理,审核订单';
default: return '';
}
},
//
getCurrentRoleText(roleValue) {
const role = this.roleOptions.find(r => r.value === roleValue);
return role ? role.label : '用户/泵司';
}
}
}
</script>
<style lang="scss" scoped>
.roleSelector {
.content {
padding: 30rpx 20rpx;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
.title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.close-btn {
padding: 10rpx;
cursor: pointer;
}
}
.role-tip {
font-size: 28rpx;
color: #666;
margin-bottom: 30rpx;
text-align: center;
}
.role-list {
flex: 1;
display: flex;
flex-direction: column;
gap: 20rpx;
margin-bottom: 40rpx;
}
.role-item {
display: flex;
align-items: center;
padding: 25rpx 20rpx;
border-radius: 15rpx;
border: 2rpx solid #f0f0f0;
transition: all 0.3s ease;
cursor: pointer;
&.active {
border-color: #007AFF;
background-color: #f0f8ff;
}
&:hover {
background-color: #f8f8f8;
}
}
.role-icon {
width: 60rpx;
height: 60rpx;
border-radius: 30rpx;
background-color: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
}
.role-info {
flex: 1;
}
.role-name {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 8rpx;
}
.role-desc {
font-size: 24rpx;
color: #999;
line-height: 1.4;
}
.role-check {
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
}
.action-buttons {
display: flex;
gap: 20rpx;
padding-top: 20rpx;
border-top: 1rpx solid #f0f0f0;
.btn {
flex: 1;
height: 80rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
cursor: pointer;
transition: all 0.3s ease;
&.cancel {
background-color: #f5f5f5;
color: #666;
&:hover {
background-color: #e8e8e8;
}
}
&.confirm {
background-color: #007AFF;
color: #fff;
&:hover {
background-color: #0056CC;
}
}
}
}
}
</style>

+ 51
- 112
pages/index/index.vue View File

@ -94,82 +94,46 @@
<!-- 身份切换浮窗 -->
<view class="role-float-btn" @click="showRoleModal">
<uv-icon name="person" size="24" color="#fff"></uv-icon>
<uv-icon name="man" size="24" color="#fff"></uv-icon>
</view>
<!-- 身份切换弹窗 -->
<uv-modal
:show="showModal"
@close="closeModal"
@cancel="closeModal"
@confirm="confirmRoleChange"
title="选择身份"
confirmText="确认"
cancelText="取消">
<view class="role-modal-content">
<view class="role-tip">请选择您的身份类型</view>
<view class="role-list">
<view
v-for="(role, index) in roleOptions"
:key="index"
:class="['role-item', selectedRole === role.value && 'active']"
@click="selectRole(role.value)">
<view class="role-icon">
<uv-icon :name="getRoleIcon(role.value)" size="20" :color="selectedRole === role.value ? '#007AFF' : '#666'"></uv-icon>
</view>
<view class="role-info">
<view class="role-name">{{ role.label }}</view>
<view class="role-desc">{{ getRoleDesc(role.value) }}</view>
</view>
<view class="role-check">
<uv-icon v-if="selectedRole === role.value" name="checkmark-circle" size="20" color="#007AFF"></uv-icon>
<uv-icon v-else name="radio-button-off" size="20" color="#ccc"></uv-icon>
</view>
</view>
</view>
</view>
</uv-modal>
<!-- 角色选择组件 -->
<role-selector ref="roleSelector" @roleChanged="onRoleChanged"></role-selector>
</view>
</template>
<script>
import tabber from '@/components/base/tabbar.vue'
import roleSelector from '@/components/config/roleSelector.vue'
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
components: {
tabber,
},
tabber,
roleSelector,
},
data() {
return {
area: '长沙',
isSticky: false,
num1: '1000+',
num2: '5000+',
currentRole: '0', // 0-/1-2-3-
roleOptions: [
{ value: '0', label: '用户/泵司' },
{ value: '1', label: '企业用户' },
{ value: '2', label: '员工' },
{ value: '3', label: '区域管理员' }
],
notice: {
content: '砼聚人平台全新上线,欢迎大家使用!'
},
leftIcon: false,
rightIcon: false,
videoUrl: 'https://relief.oss-cn-hangzhou.aliyuncs.com/home.mp4',
//
showModal: false,
selectedRole: '0'
videoUrl: 'https://relief.oss-cn-hangzhou.aliyuncs.com/home.mp4'
}
},
computed: {
currentRoleText() {
const role = this.roleOptions.find(r => r.value === this.currentRole);
return role ? role.label : '用户/泵司';
}
...mapState(['role']),
...mapGetters(['currentRoleText'])
},
onShow() {
this.loadData();
//
this.initRole();
//
const intersectionObserver = uni.createIntersectionObserver(this);
intersectionObserver.relativeToViewport({ top: 0 }).observe('.banner-div', (res) => {
@ -180,11 +144,16 @@
}
});
//
//
this.area = uni.getStorageSync('area') || '长沙';
this.currentRole = uni.getStorageSync('role') || '0';
//
uni.$on('roleChanged', (newRole) => {
console.log('角色已变更为:', newRole);
});
},
methods: {
...mapMutations(['initRole']),
//
clickNotify() {
uni.navigateTo({ url: '/pages_order/base/notify' });
@ -211,71 +180,18 @@
},
//
showRoleSelector() {
const itemList = this.roleOptions.map(role => role.label);
uni.showActionSheet({
itemList: itemList,
success: (res) => {
const selectedRole = this.roleOptions[res.tapIndex];
this.switchRole(selectedRole.value);
}
});
},
//
switchRole(roleValue) {
this.currentRole = roleValue;
uni.setStorageSync('role', roleValue);
uni.showToast({
title: `已切换到${this.currentRoleText}`,
icon: 'success'
});
//
setTimeout(() => {
uni.switchTab({
url: '/pages/index/order'
});
}, 1000);
this.$refs.roleSelector.open();
},
//
showRoleModal() {
this.selectedRole = this.currentRole;
this.showModal = true;
this.$refs.roleSelector.open();
},
//
closeModal() {
this.showModal = false;
},
//
selectRole(roleValue) {
this.selectedRole = roleValue;
},
//
confirmRoleChange() {
if (this.selectedRole !== this.currentRole) {
this.switchRole(this.selectedRole);
}
this.closeModal();
//
onRoleChanged(newRole) {
console.log('角色已变更为:', newRole);
},
//
getRoleIcon(roleValue) {
switch(roleValue) {
case '0': return 'person';
case '1': return 'business';
case '2': return 'people';
case '3': return 'settings';
default: return 'person';
}
},
//
getRoleDesc(roleValue) {
switch(roleValue) {
case '0': return '接单赚钱,自由工作';
case '1': return '发布订单,管理业务';
case '2': return '协助管理,处理订单';
case '3': return '区域管理,审核订单';
default: return '';
}
}
}
}
</script>
@ -427,4 +343,27 @@
color: #333;
margin-right: 8rpx;
}
.role-float-btn {
position: fixed;
bottom: 200rpx;
right: 30rpx;
width: 100rpx;
height: 100rpx;
background: linear-gradient(135deg, #007AFF 0%, #0056CC 100%);
border-radius: 50rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 20rpx rgba(0, 122, 255, 0.3);
z-index: 999;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
box-shadow: 0 4rpx 10rpx rgba(0, 122, 255, 0.2);
}
}
</style>

+ 41
- 21
pages/index/order.vue View File

@ -27,6 +27,7 @@ import UserHall from '@/components/user/hall.vue'
import StaffHall from '@/components/staff/hall.vue'
import EnterpriseHall from '@/components/enterprise/hall.vue'
import RegionHall from '@/components/region/hall.vue'
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
components: {
@ -42,6 +43,8 @@ export default {
}
},
computed: {
...mapState(['role']),
...mapGetters(['currentRoleText']),
pageTitle() {
const roleNum = Number(this.role);
if (roleNum === 0) {
@ -58,35 +61,52 @@ export default {
}
},
onShow() {
this.role = uni.getStorageSync('role') || '1';
//
this.initRole();
//
uni.setNavigationBarTitle({ title: this.pageTitle });
//
uni.$on('roleChanged', this.handleRoleChange);
//
this.$nextTick(() => {
try {
const roleNum = Number(this.role);
if (roleNum === 0) {
this.$refs.us && this.$refs.us.loadPage && this.$refs.us.loadPage();
} else if (roleNum === 1) {
this.$refs.eh && this.$refs.eh.loadPage && this.$refs.eh.loadPage();
} else if (roleNum === 2) {
this.$refs.ss && this.$refs.ss.loadPage && this.$refs.ss.loadPage();
} else if (roleNum === 3) {
this.$refs.rh && this.$refs.rh.loadPage && this.$refs.rh.loadPage();
}
} catch (e) {
console.log('组件方法调用失败:', e);
}
});
this.refreshCurrentComponent();
},
onHide() {
//
uni.$off('roleChanged', this.handleRoleChange);
},
methods: {
//
switchRole(newRole) {
this.role = newRole;
uni.setStorageSync('role', newRole);
...mapMutations(['initRole']),
//
handleRoleChange(newRole) {
console.log('订单页面收到角色变更:', newRole);
//
uni.setNavigationBarTitle({ title: this.pageTitle });
//
this.$nextTick(() => {
this.refreshCurrentComponent();
});
},
//
refreshCurrentComponent() {
this.$nextTick(() => {
try {
const roleNum = Number(this.role);
if (roleNum === 0) {
this.$refs.us && this.$refs.us.loadPage && this.$refs.us.loadPage();
} else if (roleNum === 1) {
this.$refs.eh && this.$refs.eh.loadPage && this.$refs.eh.loadPage();
} else if (roleNum === 2) {
this.$refs.ss && this.$refs.ss.loadPage && this.$refs.ss.loadPage();
} else if (roleNum === 3) {
this.$refs.rh && this.$refs.rh.loadPage && this.$refs.rh.loadPage();
}
} catch (e) {
console.log('组件方法调用失败:', e);
}
});
}
}
}


+ 32
- 2
store/store.js View File

@ -10,9 +10,24 @@ const store = new Vuex.Store({
state: {
configList: {}, //配置列表
userInfo : {}, //用户信息
role : 0,
role : '0', // 当前角色:0-用户/泵司,1-企业,2-员工,3-区域管理员
roleOptions: [
{ value: '0', label: '用户/泵司' },
{ value: '1', label: '企业用户' },
{ value: '2', label: '员工' },
{ value: '3', label: '区域管理员' }
],
},
getters: {
// 获取当前角色文本
currentRoleText: (state) => {
const role = state.roleOptions.find(r => r.value === state.role);
return role ? role.label : '用户/泵司';
},
// 获取角色选项
getRoleOptions: (state) => {
return state.roleOptions;
}
},
mutations: {
// 初始化配置
@ -83,6 +98,20 @@ const store = new Vuex.Store({
}
})
},
// 切换角色
switchRole(state, roleValue) {
state.role = roleValue;
uni.setStorageSync('role', roleValue);
// 触发全局事件通知角色变更
uni.$emit('roleChanged', roleValue);
},
// 初始化角色
initRole(state) {
const savedRole = uni.getStorageSync('role');
if (savedRole) {
state.role = savedRole;
}
},
// 退出登录
logout(state){
uni.showModal({
@ -90,8 +119,9 @@ const store = new Vuex.Store({
success(r) {
if(r.confirm){
state.userInfo = {}
state.role = false
state.role = '0'
uni.removeStorageSync('token')
uni.removeStorageSync('role')
uni.reLaunch({
url: '/pages/index/index'
})


Loading…
Cancel
Save