|
|
- <template>
- <view class="content">
- <navbar title="员工管理" leftClick @leftClick="$utils.navigateBack" />
- <view class="header">
- <view class="title">员工管理</view>
- <view class="subtitle">管理企业员工信息和权限</view>
- </view>
-
- <!-- 搜索栏 -->
- <view class="search-bar">
- <view class="search-input">
- <uv-icon name="search" size="20" color="#999"></uv-icon>
- <input v-model="searchKeyword" placeholder="搜索员工姓名或手机号" @input="onSearch" />
- </view>
- <view class="add-btn" @click="addStaff">
- <uv-icon name="plus" size="20" color="#fff"></uv-icon>
- <text>添加</text>
- </view>
- </view>
-
- <!-- 统计信息 -->
- <view class="stats-container">
- <view class="stats-item">
- <view class="stats-number">{{ totalStaff }}</view>
- <view class="stats-label">总员工数</view>
- </view>
- <view class="stats-item">
- <view class="stats-number">{{ activeStaff }}</view>
- <view class="stats-label">在职员工</view>
- </view>
- <view class="stats-item">
- <view class="stats-number">{{ onlineStaff }}</view>
- <view class="stats-label">在线员工</view>
- </view>
- </view>
-
- <!-- 员工列表 -->
- <view class="staff-list">
- <view v-if="filteredStaffList.length === 0" class="empty-state">
- <view class="empty-icon">👥</view>
- <view class="empty-text">暂无员工信息</view>
- </view>
-
- <view v-for="(item, index) in filteredStaffList" :key="index" class="staff-item">
- <view class="staff-avatar">
- <image :src="item.avatar" mode="aspectFill"></image>
- <view class="online-status" :class="{online: item.isOnline}"></view>
- </view>
-
- <view class="staff-info">
- <view class="staff-header">
- <view class="name">{{ item.name }}</view>
- <view class="role-badge" :class="item.role">{{ getRoleText(item.role) }}</view>
- </view>
-
- <view class="staff-details">
- <text>手机:{{ item.phone }}</text>
- <text>部门:{{ item.department }}</text>
- <text>入职时间:{{ item.joinDate }}</text>
- </view>
-
- <view class="staff-stats">
- <view class="stat-item">
- <text class="stat-label">本月订单:</text>
- <text class="stat-value">{{ item.monthlyOrders }}</text>
- </view>
- <view class="stat-item">
- <text class="stat-label">评分:</text>
- <text class="stat-value">{{ item.rating }}分</text>
- </view>
- </view>
- </view>
-
- <view class="staff-actions">
- <view class="action-btn" @click="viewStaff(item)">
- <uv-icon name="eye" size="16" color="#007AFF"></uv-icon>
- </view>
- <view class="action-btn" @click="editStaff(item)">
- <uv-icon name="edit-pen" size="16" color="#ff9500"></uv-icon>
- </view>
- <view class="action-btn" @click="deleteStaff(item)">
- <uv-icon name="trash" size="16" color="#ff3b30"></uv-icon>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
-
- <script>
- import navbar from '@/components/base/navbar.vue'
-
- export default {
- name: 'StaffManage',
- components: {
- navbar
- },
- data() {
- return {
- searchKeyword: '',
- totalStaff: 15,
- activeStaff: 12,
- onlineStaff: 8,
- staffList: [
- {
- id: 1,
- name: '张师傅',
- phone: '13800138001',
- avatar: '/static/re/logo.png',
- role: 'driver',
- department: '运输部',
- joinDate: '2023-06-15',
- isOnline: true,
- monthlyOrders: 28,
- rating: 4.8
- },
- {
- id: 2,
- name: '李师傅',
- phone: '13800138002',
- avatar: '/static/re/logo.png',
- role: 'driver',
- department: '运输部',
- joinDate: '2023-08-20',
- isOnline: false,
- monthlyOrders: 22,
- rating: 4.6
- },
- {
- id: 3,
- name: '王主管',
- phone: '13800138003',
- avatar: '/static/re/logo.png',
- role: 'supervisor',
- department: '调度部',
- joinDate: '2023-03-10',
- isOnline: true,
- monthlyOrders: 45,
- rating: 4.9
- },
- {
- id: 4,
- name: '赵师傅',
- phone: '13800138004',
- avatar: '/static/re/logo.png',
- role: 'driver',
- department: '运输部',
- joinDate: '2023-09-05',
- isOnline: true,
- monthlyOrders: 31,
- rating: 4.7
- },
- {
- id: 5,
- name: '陈操作员',
- phone: '13800138005',
- avatar: '/static/re/logo.png',
- role: 'operator',
- department: '操作部',
- joinDate: '2023-11-12',
- isOnline: false,
- monthlyOrders: 18,
- rating: 4.5
- }
- ]
- }
- },
- computed: {
- filteredStaffList() {
- if (!this.searchKeyword) {
- return this.staffList;
- }
- return this.staffList.filter(staff =>
- staff.name.includes(this.searchKeyword) ||
- staff.phone.includes(this.searchKeyword)
- );
- }
- },
- onLoad() {
- uni.setNavigationBarTitle({
- title: '员工管理'
- });
- },
- methods: {
- onSearch() {
- // 搜索逻辑已在computed中实现
- },
- getRoleText(role) {
- switch(role) {
- case 'driver': return '司机';
- case 'supervisor': return '主管';
- case 'operator': return '操作员';
- default: return '员工';
- }
- },
- addStaff() {
- uni.navigateTo({
- url: '/pages_order/staff/addStaff'
- });
- },
- viewStaff(staff) {
- uni.navigateTo({
- url: `/pages_order/staff/staffDetail?id=${staff.id}`
- });
- },
- editStaff(staff) {
- uni.navigateTo({
- url: `/pages_order/staff/editStaff?id=${staff.id}`
- });
- },
- deleteStaff(staff) {
- uni.showModal({
- title: '确认删除',
- content: `确定要删除员工${staff.name}吗?此操作不可恢复。`,
- success: (res) => {
- if (res.confirm) {
- const index = this.staffList.findIndex(item => item.id === staff.id);
- if (index > -1) {
- this.staffList.splice(index, 1);
- this.totalStaff--;
- this.activeStaff--;
- if (staff.isOnline) {
- this.onlineStaff--;
- }
- uni.showToast({
- title: '删除成功',
- icon: 'success'
- });
- }
- }
- }
- });
- }
- }
- }
- </script>
-
- <style scoped lang="scss">
- .content {
- padding: 20rpx;
- min-height: 100vh;
- background-color: #f5f5f5;
- }
-
- .header {
- background-color: #fff;
- padding: 30rpx;
- border-radius: 10rpx;
- margin-bottom: 20rpx;
- text-align: center;
-
- .title {
- font-size: 36rpx;
- font-weight: bold;
- color: #333;
- margin-bottom: 10rpx;
- }
-
- .subtitle {
- font-size: 28rpx;
- color: #666;
- }
- }
-
- .search-bar {
- display: flex;
- gap: 20rpx;
- margin-bottom: 20rpx;
-
- .search-input {
- flex: 1;
- display: flex;
- align-items: center;
- padding: 20rpx;
- background-color: #fff;
- border-radius: 25rpx;
- gap: 15rpx;
-
- input {
- flex: 1;
- font-size: 28rpx;
- border: none;
- outline: none;
- }
- }
-
- .add-btn {
- display: flex;
- align-items: center;
- gap: 8rpx;
- padding: 20rpx 30rpx;
- background-color: #007AFF;
- color: #fff;
- border-radius: 25rpx;
- font-size: 28rpx;
- }
- }
-
- .stats-container {
- display: flex;
- background-color: #fff;
- border-radius: 10rpx;
- margin-bottom: 20rpx;
- padding: 30rpx 0;
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
-
- .stats-item {
- flex: 1;
- text-align: center;
-
- .stats-number {
- font-size: 48rpx;
- font-weight: bold;
- color: #007AFF;
- margin-bottom: 10rpx;
- }
-
- .stats-label {
- font-size: 24rpx;
- color: #666;
- }
- }
- }
-
- .staff-list {
- .empty-state {
- text-align: center;
- padding: 100rpx 0;
- background-color: #fff;
- border-radius: 10rpx;
-
- .empty-icon {
- font-size: 120rpx;
- margin-bottom: 20rpx;
- }
-
- .empty-text {
- font-size: 28rpx;
- color: #999;
- }
- }
-
- .staff-item {
- display: flex;
- background-color: #fff;
- border-radius: 10rpx;
- padding: 30rpx;
- margin-bottom: 20rpx;
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
-
- .staff-avatar {
- position: relative;
- width: 120rpx;
- height: 120rpx;
- margin-right: 20rpx;
-
- image {
- width: 100%;
- height: 100%;
- border-radius: 60rpx;
- }
-
- .online-status {
- position: absolute;
- bottom: 5rpx;
- right: 5rpx;
- width: 24rpx;
- height: 24rpx;
- border-radius: 12rpx;
- background-color: #ccc;
- border: 3rpx solid #fff;
-
- &.online {
- background-color: #34c759;
- }
- }
- }
-
- .staff-info {
- flex: 1;
-
- .staff-header {
- display: flex;
- align-items: center;
- margin-bottom: 15rpx;
- gap: 15rpx;
-
- .name {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- }
-
- .role-badge {
- padding: 6rpx 12rpx;
- border-radius: 15rpx;
- font-size: 22rpx;
- color: #fff;
-
- &.driver {
- background-color: #007AFF;
- }
-
- &.supervisor {
- background-color: #ff9500;
- }
-
- &.operator {
- background-color: #34c759;
- }
- }
- }
-
- .staff-details {
- font-size: 26rpx;
- color: #666;
- line-height: 1.4;
- margin-bottom: 15rpx;
-
- text {
- display: block;
- margin-bottom: 5rpx;
- }
- }
-
- .staff-stats {
- display: flex;
- gap: 30rpx;
-
- .stat-item {
- font-size: 24rpx;
-
- .stat-label {
- color: #666;
- }
-
- .stat-value {
- color: #007AFF;
- font-weight: bold;
- }
- }
- }
- }
-
- .staff-actions {
- display: flex;
- flex-direction: column;
- gap: 15rpx;
-
- .action-btn {
- width: 60rpx;
- height: 60rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: #f8f8f8;
- border-radius: 30rpx;
- }
- }
- }
- }
- </style>
|