944 lines
22 KiB
Vue
944 lines
22 KiB
Vue
<template>
|
||
<view class="container">
|
||
<!-- 自定义导航栏 -->
|
||
<wd-navbar :bordered="false"
|
||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(20px) !important;"
|
||
safeAreaInsetTop fixed placeholder>
|
||
<template #left>
|
||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
||
@click="toPages({type:'nav'})"></text>
|
||
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10"
|
||
@click="toPages({type:'home'})"></text>
|
||
<text class="li-text-42">员工权限</text>
|
||
</view>
|
||
</template>
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<template #right>
|
||
<view class="li-flex-center li-mr-200 li-pt-6" @click="handleAddStaff">
|
||
<text class="ri-add-line li-text-50"></text>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- #endif -->
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<template #right>
|
||
<view class="li-flex-center li-mr-25 li-pt-6" @click="handleAddStaff">
|
||
<text class="ri-add-line li-text-55"></text>
|
||
</view>
|
||
</template>
|
||
<!-- #endif -->
|
||
</wd-navbar>
|
||
<!-- 导航栏背景 -->
|
||
<view class="nav-bg-layer"></view>
|
||
|
||
<!-- 页面背景 -->
|
||
<view class="page-bg"></view>
|
||
|
||
<view class="content">
|
||
|
||
<!-- 员工列表 -->
|
||
<view class="staff-list li-w-92% li-mx-auto li-mt-20" v-if="filteredStaffList.length > 0">
|
||
<view
|
||
v-for="staff in filteredStaffList"
|
||
:key="staff.id"
|
||
class="staff-card"
|
||
@tap="openPermissionSetting(staff)"
|
||
>
|
||
<view class="card-header">
|
||
<view class="staff-avatar" v-if="staff.avatar">
|
||
<image :src="staff.avatar" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="staff-avatar default-avatar" v-else>
|
||
<text>{{staff.name.substring(0,1)}}</text>
|
||
</view>
|
||
|
||
<view class="staff-info">
|
||
<view class="staff-name">{{ staff.name }}</view>
|
||
<view class="staff-phone">
|
||
<text class="ri-phone-line phone-icon"></text>
|
||
<text>{{ staff.phone }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="right-area">
|
||
<view class="perm-count" :class="{'has-perm': staff.permissions.length > 0}">
|
||
{{ staff.permissions.length }}
|
||
</view>
|
||
<text class="ri-arrow-right-s-line action-icon"></text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="card-content" v-if="staff.permissions.length > 0">
|
||
<!-- 权限标签 -->
|
||
<view class="perm-tags">
|
||
<view
|
||
v-for="(perm, index) in staff.permissions.slice(0, 2)"
|
||
:key="perm"
|
||
class="perm-tag"
|
||
:class="getPermissionClass(perm)"
|
||
>
|
||
<text :class="getPermissionIcon(perm)"></text>
|
||
<text>{{ getPermissionName(perm) }}</text>
|
||
</view>
|
||
<view class="perm-tag more" v-if="staff.permissions.length > 2">
|
||
<text>+{{ staff.permissions.length - 2 }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="card-content" v-else>
|
||
<view class="no-perm-tag">
|
||
<text class="ri-lock-line"></text>
|
||
<text>暂无权限</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态 -->
|
||
<view class="empty-state" v-else>
|
||
<wd-empty description="暂无员工数据">
|
||
<wd-button type="primary" @click="handleAddStaff">添加员工</wd-button>
|
||
</wd-empty>
|
||
</view>
|
||
|
||
<!-- 底部权限设置面板 -->
|
||
<wd-popup v-model="showPermissionPopup" position="bottom" custom-style="border-radius: 20rpx 20rpx 0 0;" @close="handlePopupClose" :safe-area-inset-bottom="true">
|
||
<permission-settings
|
||
:staff="currentStaff"
|
||
:permissions="allPermissions"
|
||
@save="savePermissions"
|
||
@cancel="closePermissionSheet"
|
||
/>
|
||
</wd-popup>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, reactive, computed, nextTick } from 'vue';
|
||
import { useNavigation } from '@/hooks/useNavigation';
|
||
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
|
||
import PermissionSettings from '@/components/PermissionSettings.vue';
|
||
|
||
// 导航相关
|
||
const { toPages, hasMultiplePages, checkRouteStack } = useNavigation();
|
||
|
||
// 小区信息
|
||
const villageId = ref('');
|
||
const villageName = ref('阳光花园小区');
|
||
const villageAddress = ref('市政府北路123号');
|
||
|
||
// 搜索与筛选
|
||
const searchKeyword = ref('');
|
||
const currentFilter = ref('全部');
|
||
const filterOptions = ['全部', '配送权限', '维修权限'];
|
||
|
||
// 权限配置弹框搜索
|
||
const permissionSearchKeyword = ref('');
|
||
|
||
// 更多权限弹窗
|
||
const showMorePermissionsPopup = ref(false);
|
||
const currentStaffPermissions = ref([]);
|
||
|
||
// 弹窗管理
|
||
const showPermissionPopup = ref(false);
|
||
const currentStaff = ref(null);
|
||
const tempPermissions = reactive({});
|
||
|
||
// 员工列表数据 - 使用更多权限
|
||
const staffList = ref([
|
||
{
|
||
id: 1,
|
||
name: '张三',
|
||
phone: '13800138000',
|
||
avatar: '/static/swiper/1.png',
|
||
permissions: ['delivery', 'complaint'],
|
||
department: '配送部'
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '李四',
|
||
phone: '13800138001',
|
||
avatar: '/static/swiper/1.png',
|
||
permissions: ['delivery', 'maintenance', 'inspection', 'facility', 'visitor'],
|
||
department: '综合部'
|
||
},
|
||
{
|
||
id: 3,
|
||
name: '王五',
|
||
phone: '13800138002',
|
||
avatar: '/static/swiper/1.png',
|
||
permissions: ['maintenance', 'inspection'],
|
||
department: '工程部'
|
||
},
|
||
{
|
||
id: 4,
|
||
name: '赵六',
|
||
phone: '13800138003',
|
||
avatar: '/static/swiper/1.png',
|
||
permissions: [],
|
||
department: '客服部'
|
||
}
|
||
]);
|
||
|
||
// 所有权限列表
|
||
const allPermissions = [
|
||
{ value: 'delivery', label: '配送权限', icon: 'ri-truck-line', description: '允许配送相关的订单处理', colorClass: 'delivery-color', isCommon: true },
|
||
{ value: 'maintenance', label: '维修权限', icon: 'ri-tools-line', description: '允许接受维修工单和处理', colorClass: 'maintenance-color', isCommon: true },
|
||
{ value: 'finance', label: '财务管理', icon: 'ri-money-cny-circle-line', description: '允许处理财务相关事务', colorClass: 'finance-color', isCommon: true },
|
||
{ value: 'resident', label: '住户管理', icon: 'ri-user-line', description: '允许管理小区住户信息', colorClass: 'general-color', isCommon: false },
|
||
{ value: 'security', label: '安防权限', icon: 'ri-shield-line', description: '允许管理小区安防系统', colorClass: 'general-color', isCommon: false },
|
||
{ value: 'admin', label: '管理员权限', icon: 'ri-admin-line', description: '系统管理员权限', colorClass: 'admin-color', isCommon: false },
|
||
{ value: 'parking', label: '车位管理', icon: 'ri-parking-line', description: '允许管理小区车位', colorClass: 'general-color', isCommon: false },
|
||
{ value: 'visitor', label: '访客管理', icon: 'ri-user-location-line', description: '允许管理小区访客', colorClass: 'general-color', isCommon: false },
|
||
{ value: 'complaint', label: '投诉处理', icon: 'ri-customer-service-line', description: '允许处理业主投诉', colorClass: 'general-color', isCommon: true },
|
||
{ value: 'facility', label: '设施管理', icon: 'ri-building-4-line', description: '允许管理小区公共设施', colorClass: 'general-color', isCommon: false },
|
||
{ value: 'notice', label: '通知发布', icon: 'ri-notification-line', description: '允许发布小区通知', colorClass: 'general-color', isCommon: false },
|
||
{ value: 'inspection', label: '巡检权限', icon: 'ri-survey-line', description: '允许进行小区巡检记录', colorClass: 'maintenance-color', isCommon: true },
|
||
];
|
||
|
||
// 筛选后的员工列表
|
||
const filteredStaffList = computed(() => {
|
||
let result = staffList.value;
|
||
|
||
// 按关键词筛选
|
||
if (searchKeyword.value) {
|
||
result = result.filter(staff =>
|
||
staff.name.includes(searchKeyword.value) ||
|
||
staff.phone.includes(searchKeyword.value)
|
||
);
|
||
}
|
||
|
||
// 按权限筛选
|
||
if (currentFilter.value !== '全部') {
|
||
// 查找对应的权限代码
|
||
const permCode = allPermissions.find(p => p.label === currentFilter.value)?.value;
|
||
if (permCode) {
|
||
result = result.filter(staff => staff.permissions.includes(permCode));
|
||
}
|
||
}
|
||
|
||
return result;
|
||
});
|
||
|
||
// 常用权限和其他权限
|
||
const commonPermissions = computed(() => {
|
||
return allPermissions.filter(perm => perm.isCommon);
|
||
});
|
||
|
||
const otherPermissions = computed(() => {
|
||
return allPermissions.filter(perm => !perm.isCommon);
|
||
});
|
||
|
||
/**
|
||
* 获取权限图标
|
||
* @param {string} permCode 权限代码
|
||
* @returns {string} 图标class
|
||
*/
|
||
const getPermissionIcon = (permCode) => {
|
||
const perm = allPermissions.find(p => p.value === permCode);
|
||
return perm ? perm.icon : 'ri-lock-line';
|
||
};
|
||
|
||
/**
|
||
* 获取权限名称
|
||
* @param {string} permCode 权限代码
|
||
* @returns {string} 权限名称
|
||
*/
|
||
const getPermissionName = (permCode) => {
|
||
const perm = allPermissions.find(p => p.value === permCode);
|
||
return perm ? perm.label : '未知权限';
|
||
};
|
||
|
||
/**
|
||
* 获取权限样式类
|
||
* @param {string} permCode 权限代码
|
||
* @returns {string} 样式类名
|
||
*/
|
||
const getPermissionClass = (permCode) => {
|
||
const perm = allPermissions.find(p => p.value === permCode);
|
||
return perm ? perm.colorClass : '';
|
||
};
|
||
|
||
/**
|
||
* 获取激活的权限数量
|
||
*/
|
||
const getActivePermissionsCount = () => {
|
||
return Object.values(tempPermissions).filter(v => v === true).length;
|
||
};
|
||
|
||
/**
|
||
* 显示更多权限弹窗
|
||
* @param {Object} staff 员工信息
|
||
*/
|
||
const showMorePermissions = (staff) => {
|
||
currentStaff.value = staff;
|
||
currentStaffPermissions.value = staff.permissions;
|
||
showMorePermissionsPopup.value = true;
|
||
};
|
||
|
||
/**
|
||
* 获取小区信息
|
||
*/
|
||
const getVillageInfo = () => {
|
||
// 实际项目中从服务器获取小区信息
|
||
console.log('获取小区ID为', villageId.value, '的信息');
|
||
};
|
||
|
||
/**
|
||
* 获取员工列表
|
||
*/
|
||
const getStaffList = () => {
|
||
// 实际项目中从服务器获取员工列表
|
||
console.log('获取小区ID为', villageId.value, '的员工列表');
|
||
};
|
||
|
||
/**
|
||
* 处理搜索
|
||
*/
|
||
const handleSearch = () => {
|
||
console.log('搜索关键词:', searchKeyword.value);
|
||
// 这里可以实现搜索逻辑
|
||
};
|
||
|
||
/**
|
||
* 设置筛选条件
|
||
* @param {string} filter 筛选条件
|
||
*/
|
||
const setFilter = (filter) => {
|
||
currentFilter.value = filter;
|
||
console.log('筛选条件:', filter);
|
||
// 这里可以实现筛选逻辑
|
||
};
|
||
|
||
/**
|
||
* 处理添加员工
|
||
*/
|
||
const handleAddStaff = () => {
|
||
uni.navigateTo({
|
||
url: '/pagesB/permissions/addStaff'
|
||
});
|
||
};
|
||
|
||
/**
|
||
* 处理权限设置
|
||
* @param {Object} staff 员工信息
|
||
*/
|
||
const handleSetPermission = (staff) => {
|
||
currentStaff.value = staff;
|
||
|
||
// 重置临时权限状态
|
||
allPermissions.forEach(perm => {
|
||
tempPermissions[perm.value] = staff.permissions.includes(perm.value);
|
||
});
|
||
|
||
showPermissionPopup.value = true;
|
||
};
|
||
|
||
/**
|
||
* 保存权限设置
|
||
*/
|
||
const savePermissions = () => {
|
||
if (!currentStaff.value) return;
|
||
|
||
// 显示加载中提示
|
||
uni.showLoading({
|
||
title: '保存中...',
|
||
mask: true
|
||
});
|
||
|
||
// API调用示例
|
||
// 这里只是示例,实际项目中请替换为真实的API调用
|
||
const requestData = {
|
||
staffId: currentStaff.value.id,
|
||
permissions: currentStaff.value.permissions,
|
||
villageId: villageId.value
|
||
};
|
||
|
||
// 模拟API调用
|
||
setTimeout(() => {
|
||
// 实际项目中这里应该是真实的API调用,例如:
|
||
/*
|
||
uni.request({
|
||
url: 'https://api.example.com/staff/permissions',
|
||
method: 'POST',
|
||
data: requestData,
|
||
success: (res) => {
|
||
if (res.data.code === 0) {
|
||
// 更新本地数据
|
||
updateLocalStaffPermissions();
|
||
// 关闭弹窗并显示成功提示
|
||
closePermissionSheet();
|
||
uni.showToast({
|
||
title: '权限设置成功',
|
||
icon: 'success'
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: res.data.message || '保存失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
uni.showToast({
|
||
title: '网络错误,请重试',
|
||
icon: 'none'
|
||
});
|
||
console.error('保存权限失败:', err);
|
||
},
|
||
complete: () => {
|
||
uni.hideLoading();
|
||
}
|
||
});
|
||
*/
|
||
|
||
// 更新本地数据
|
||
updateLocalStaffPermissions();
|
||
|
||
// 隐藏加载提示
|
||
uni.hideLoading();
|
||
|
||
// 关闭弹窗并显示成功提示
|
||
closePermissionSheet();
|
||
uni.showToast({
|
||
title: '权限设置成功',
|
||
icon: 'success'
|
||
});
|
||
}, 800);
|
||
};
|
||
|
||
/**
|
||
* 更新本地员工权限数据
|
||
*/
|
||
const updateLocalStaffPermissions = () => {
|
||
const index = staffList.value.findIndex(item => item.id === currentStaff.value.id);
|
||
if (index !== -1) {
|
||
staffList.value[index] = {
|
||
...staffList.value[index],
|
||
permissions: [...currentStaff.value.permissions]
|
||
};
|
||
}
|
||
};
|
||
|
||
// 权限操作列表
|
||
const permissionActions = [
|
||
{ name: '配送权限', value: 'delivery', icon: 'ri-truck-line' },
|
||
{ name: '维修权限', value: 'maintenance', icon: 'ri-tools-line' },
|
||
{ name: '财务管理', value: 'finance', icon: 'ri-money-cny-circle-line' },
|
||
{ name: '住户管理', value: 'resident', icon: 'ri-user-line' },
|
||
{ name: '安防权限', value: 'security', icon: 'ri-shield-line' },
|
||
{ name: '管理员权限', value: 'admin', icon: 'ri-admin-line' },
|
||
{ name: '投诉处理', value: 'complaint', icon: 'ri-customer-service-line' },
|
||
{ name: '巡检权限', value: 'inspection', icon: 'ri-survey-line' },
|
||
];
|
||
|
||
// 切换权限筛选器
|
||
const handleFilterChange = (filter) => {
|
||
currentFilter.value = filter;
|
||
};
|
||
|
||
// 重置筛选
|
||
const resetFilter = () => {
|
||
currentFilter.value = '全部';
|
||
searchKeyword.value = '';
|
||
};
|
||
|
||
// 清除搜索关键词
|
||
const clearSearchKeyword = () => {
|
||
searchKeyword.value = '';
|
||
};
|
||
|
||
// 打开权限设置
|
||
const openPermissionSetting = (staff) => {
|
||
// 设置当前员工
|
||
currentStaff.value = {
|
||
...staff,
|
||
// 创建一个权限数组的副本,避免直接修改原始数据
|
||
permissions: [...staff.permissions]
|
||
};
|
||
|
||
// 显示弹窗
|
||
showPermissionPopup.value = true;
|
||
};
|
||
|
||
// 关闭权限设置面板
|
||
const closePermissionSheet = () => {
|
||
showPermissionPopup.value = false;
|
||
};
|
||
|
||
// 切换权限状态
|
||
const togglePermission = (permission) => {
|
||
if (!currentStaff.value) return;
|
||
|
||
const index = currentStaff.value.permissions.indexOf(permission);
|
||
|
||
if (index > -1) {
|
||
// 移除已有权限
|
||
currentStaff.value.permissions.splice(index, 1);
|
||
} else {
|
||
// 添加新权限
|
||
currentStaff.value.permissions.push(permission);
|
||
}
|
||
};
|
||
|
||
// 检查权限是否已启用
|
||
const hasPermission = (permission) => {
|
||
if (!currentStaff.value) return false;
|
||
return currentStaff.value.permissions.includes(permission);
|
||
};
|
||
|
||
// 页面加载
|
||
onLoad((options) => {
|
||
if (options.villageId) {
|
||
villageId.value = options.villageId;
|
||
// 获取小区信息和员工列表
|
||
getVillageInfo();
|
||
getStaffList();
|
||
}
|
||
checkRouteStack();
|
||
});
|
||
|
||
// 下拉刷新
|
||
onPullDownRefresh(() => {
|
||
getStaffList();
|
||
setTimeout(() => {
|
||
uni.stopPullDownRefresh();
|
||
}, 1000);
|
||
});
|
||
|
||
// 处理wd-popup组件的close事件
|
||
const handlePopupClose = () => {
|
||
// 处理逻辑
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 主容器 */
|
||
.container {
|
||
min-height: 100vh;
|
||
background-color: transparent;
|
||
position: relative;
|
||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, sans-serif;
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
/* 导航栏背景 */
|
||
.nav-bg-layer {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: calc(var(--status-bar-height) + 88rpx);
|
||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||
z-index: -1;
|
||
backdrop-filter: blur(10px);
|
||
-webkit-backdrop-filter: blur(10px);
|
||
}
|
||
|
||
/* 页面背景 */
|
||
.page-bg {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: linear-gradient(135deg, #f8fafd 0%, #eef2f9 100%);
|
||
z-index: -2;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
width: 100%;
|
||
height: 30%;
|
||
background: linear-gradient(135deg, rgba(76, 132, 255, 0.03), rgba(76, 132, 255, 0));
|
||
z-index: -1;
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 40%;
|
||
background: linear-gradient(315deg, rgba(76, 132, 255, 0.02), rgba(76, 132, 255, 0));
|
||
z-index: -1;
|
||
}
|
||
}
|
||
|
||
/* 添加按钮 */
|
||
.add-btn {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 50%;
|
||
background-color: #4080FF;
|
||
color: #FFFFFF;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 40rpx;
|
||
box-shadow: 0 4rpx 8rpx rgba(64, 128, 255, 0.3);
|
||
}
|
||
|
||
/* 内容区域 */
|
||
.content {
|
||
position: relative;
|
||
z-index: 2;
|
||
padding-bottom: 30rpx;
|
||
/* #ifdef MP-WEIXIN */
|
||
padding-bottom: constant(safe-area-inset-bottom);
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
/* #endif */
|
||
/* #ifdef APP-PLUS || H5 */
|
||
padding-bottom: 50rpx;
|
||
/* #endif */
|
||
}
|
||
|
||
/* 小区卡片 */
|
||
.village-card {
|
||
margin: 0 30rpx 30rpx;
|
||
background-color: #fff;
|
||
border-radius: 24rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 10rpx 30rpx rgba(31, 35, 172, 0.05);
|
||
}
|
||
|
||
.card-header {
|
||
padding: 36rpx 40rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.03);
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
background: radial-gradient(circle at top right, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0));
|
||
z-index: 1;
|
||
}
|
||
|
||
.village-name {
|
||
font-size: 36rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
position: relative;
|
||
z-index: 2;
|
||
}
|
||
|
||
.badge-container {
|
||
position: relative;
|
||
z-index: 2;
|
||
|
||
.badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 6rpx 20rpx;
|
||
background-color: rgba(76, 132, 255, 0.1);
|
||
border-radius: 30rpx;
|
||
color: #4C84FF;
|
||
|
||
.badge-num {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
margin-right: 6rpx;
|
||
}
|
||
|
||
.badge-text {
|
||
font-size: 24rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.card-content {
|
||
padding: 25rpx 40rpx;
|
||
|
||
.village-address {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
|
||
.address-icon {
|
||
color: #999;
|
||
margin-right: 10rpx;
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.address-text {
|
||
color: #666;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 搜索容器 */
|
||
.search-wrapper {
|
||
position: relative;
|
||
z-index: 3;
|
||
margin-bottom: 30rpx;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 50%;
|
||
left: -15%;
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, rgba(76, 132, 255, 0.1), rgba(76, 132, 255, 0));
|
||
z-index: -1;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: -20rpx;
|
||
right: -5%;
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, rgba(66, 211, 170, 0.06), rgba(66, 211, 170, 0));
|
||
z-index: -1;
|
||
}
|
||
}
|
||
|
||
/* 筛选容器 */
|
||
.filter-container {
|
||
margin: 0 0 20rpx;
|
||
position: relative;
|
||
z-index: 2;
|
||
}
|
||
|
||
/* 筛选标签 */
|
||
.filter-tabs {
|
||
white-space: nowrap;
|
||
padding: 0 30rpx 10rpx;
|
||
|
||
.filter-tab {
|
||
display: inline-block;
|
||
padding: 15rpx 32rpx;
|
||
margin-right: 15rpx;
|
||
background-color: #fff;
|
||
border-radius: 50rpx;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
box-shadow: 0 6rpx 12rpx rgba(76, 132, 255, 0.06);
|
||
transition: all 0.3s;
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
&:before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
|
||
z-index: -1;
|
||
}
|
||
|
||
&.active {
|
||
background-color: #4080FF;
|
||
color: #fff;
|
||
font-weight: 500;
|
||
box-shadow: 0 8rpx 16rpx rgba(64, 128, 255, 0.3);
|
||
|
||
&:before {
|
||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 员工列表 */
|
||
.staff-list {
|
||
padding: 0 30rpx;
|
||
}
|
||
|
||
/* 员工卡片 */
|
||
.staff-card {
|
||
padding: 24rpx;
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
margin-bottom: 16rpx;
|
||
position: relative;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
|
||
transition: all 0.3s;
|
||
// border-left: 3rpx solid #0070F0;
|
||
|
||
&:active {
|
||
transform: translateY(1rpx);
|
||
background-color: #fafafa;
|
||
}
|
||
|
||
.card-header {
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
|
||
.staff-avatar {
|
||
width: 64rpx;
|
||
height: 64rpx;
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
margin-right: 16rpx;
|
||
flex-shrink: 0;
|
||
background-color: #f2f8ff;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
&.default-avatar {
|
||
background-color: #0070F0;
|
||
color: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 26rpx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.staff-info {
|
||
flex: 1;
|
||
|
||
.staff-name {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.staff-phone {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.phone-icon {
|
||
font-size: 22rpx;
|
||
color: #999;
|
||
margin-right: 4rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.right-area {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.action-icon {
|
||
font-size: 32rpx;
|
||
color: #ddd;
|
||
margin-left: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.card-content {
|
||
margin-top: 12rpx;
|
||
}
|
||
}
|
||
|
||
/* 权限标签 */
|
||
.perm-tags {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
margin-top: 2rpx;
|
||
|
||
.perm-tag {
|
||
height: 38rpx;
|
||
line-height: 38rpx;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 0 10rpx;
|
||
background-color: #f0f7ff;
|
||
color: #0070F0;
|
||
font-size: 24rpx;
|
||
border-radius: 4rpx;
|
||
margin-right: 10rpx;
|
||
margin-bottom: 0;
|
||
|
||
text {
|
||
&:first-child {
|
||
margin-right: 4rpx;
|
||
font-size: 22rpx;
|
||
}
|
||
}
|
||
|
||
&.more {
|
||
background-color: #f0f0f0;
|
||
color: #999;
|
||
}
|
||
|
||
&.delivery-color {
|
||
background-color: #f0f7ff;
|
||
color: #0070F0;
|
||
}
|
||
|
||
&.maintenance-color {
|
||
background-color: #f0f7ff;
|
||
color: #0070F0;
|
||
}
|
||
|
||
&.finance-color {
|
||
background-color: #f0f7ff;
|
||
color: #0070F0;
|
||
}
|
||
|
||
&.admin-color {
|
||
background-color: #f0f7ff;
|
||
color: #0070F0;
|
||
}
|
||
|
||
&.general-color {
|
||
background-color: #f0f7ff;
|
||
color: #0070F0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.no-perm-tag {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.ri-lock-line {
|
||
margin-right: 4rpx;
|
||
}
|
||
}
|
||
|
||
/* 空状态 */
|
||
.empty-state {
|
||
padding: 100rpx 0;
|
||
}
|
||
|
||
.perm-count {
|
||
min-width: 32rpx;
|
||
height: 32rpx;
|
||
padding: 0 6rpx;
|
||
border-radius: 16rpx;
|
||
background-color: #0070F0;
|
||
color: #fff;
|
||
font-size: 22rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
</style> |