ylj20011123 ff19b35f7b update
2025-08-14 19:32:58 +08:00

1379 lines
48 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<page-meta :page-style="'overflow:' + (showPopup ? 'hidden' : 'visible')"></page-meta>
<view class="main" :style="{ paddingTop: (menu.bottom + 14) + 'px' }">
<!-- 自定义的页面顶部内容 -->
<view class="summaryTab" :style="{ height: (menu.bottom + 14) + 'px' }">
<view class="leftArrow" :style="{ top: (menu.top + ((menu.height - 24) / 2)) + 'px' }">
<image class="img" src="https://eshangtech.com/ShopICO/ahyd-BID/commercial/navigation-left.svg"
@click="handleBack"></image>
<view class="picker" :style="{ top: (menu.bottom + 24) + 'px' }" @click="handleChangeService">
<view class="selectService">
<image class="img" src="https://eshangtech.com/ShopICO/ahyd-BID/commercial/fixed.svg"></image>
<view class="select">
<view class="content">
<view class="uni-input">{{ serviceInfo.SERVERPART_NAME ? serviceInfo.SERVERPART_NAME :
'' }}
</view>
<image class="rightArrow"
src="https://eshangtech.com/ShopICO/ahyd-BID/commercial/rightArrow.svg"></image>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 居中的日历时间 -->
<view class="dateBox">
<view class="centerDateBox" @click="open">
<text class="date-text">{{ selectDate }}</text>
<text class="date-icon">📅</text>
</view>
</view>
<!-- 插入日历 即悬浮框 -->
<uni-calendar ref="calendar" class="selectDateCalendar" :clear-date="true" :date="selectDate" :insert="false"
:startDate="info.startDate" :range="info.range" @confirm="handleChangeTime" />
<!-- 人员类型的tab -->
<view class="personTabBox">
<view :class="selectTab === 1 ? 'personItem personItemSelect' : 'personItem '" @click="handleChangeTab(1)">
<view class="personValue">3</view>
<view class="personLabel">在岗人员</view>
</view>
<view :class="selectTab === 2 ? 'personItem personItemSelect' : 'personItem '" @click="handleChangeTab(2)">
<view class="personValue">4</view>
<view class="personLabel">请假人员</view>
</view>
<!-- <view :class="selectTab === 3 ? 'personItem personItemSelect' : 'personItem '" @click="handleChangeTab(3)">
<view class="personValue">1</view>
<view class="personLabel">值班经理</view>
</view> -->
</view>
<!-- 特情事件提醒横幅 -->
<view class="emergency-banner" style="margin-top: 24rpx;" @click="showEmergencyDetails(1)">
<view class="emergency-header">
<view class="emergency-title">
<text>🚨 应急事件提醒</text>
<view class="emergency-count">{{ emergencyCount }}</view>
</view>
<text>👉</text>
</view>
</view>
<!-- 一般警告提醒 -->
<view class="warning-banner" @click="showEmergencyDetails(2)">
<view class="emergency-header">
<view class="emergency-title">
<text> 日常问题</text>
<view class="emergency-count">{{ warningCount }}</view>
</view>
<text>👉</text>
</view>
</view>
<!-- 在岗人员 -->
<view class="onDutyPersonBox">
<view class="onDutyPersonBoxHeader">
<text class="title">{{ selectTab === 1 ? "👥 当前在岗人员" : selectTab === 2 ? "📋 请假人员列表" : selectTab === 3
? "👑 值班经理信息" : ""
}}</text>
<view class="tab-indicators">
<view class="tab-dot" :class="{ active: selectTab === 1 }"></view>
<view class="tab-dot" :class="{ active: selectTab === 2 }"></view>
<view class="tab-dot" :class="{ active: selectTab === 3 }"></view>
</view>
</view>
<!-- 当前在岗人员 -->
<view class="onDutyPersonList" v-if="selectTab === 1">
<view class="onDutyPersonItem" v-for="(item, index) in onDutyPersonList" :key="index"
@click="viewStaffDetails(item)">
<view class="avatar">{{ item.name ? item.name.slice(0, 1) : "" }}</view>
<view class="staffInfo">
<view class="staffInfoLeft">
<view class="staffInfoTop">
<view class="staff-name">{{ item.name || "" }}</view>
<view class="staff-role">{{ item.post || "" }}</view>
</view>
<view class="staff-status">
<view class="status-badge status-online" v-if="item.status === 1">在岗</view>
<view class="status-badge status-absentee" v-if="item.status === 5">旷工</view>
<view class="status-badge status-beLate" v-if="item.status === 6">迟到</view>
</view>
</view>
<view class="staffInfoRight" @click.stop="handleCallPhone(item.phone)">
<image class="phoneIcon" src="https://eshangtech.com/cyy_DIB/phoneIcon.png" />
</view>
</view>
</view>
</view>
<!-- 请假人员 -->
<view class="EmployeesOnLeaveList" v-if="selectTab === 2">
<view class="EmployeesOnLeaveItem" v-for="(item, index) in EmployeesOnLeaveList" :key="index"
@click="viewStaffDetails(item)">
<view class="avatar">{{ item.name ? item.name.slice(0, 1) : "" }}</view>
<view class="staffInfo">
<view class="staffInfoLeft">
<view class="staffInfoTop">
<view class="staff-name">{{ item.name || "" }}</view>
<view class="staff-role">{{ item.post || "" }}</view>
</view>
<view class="staff-status">
<view class="status-badge status-rest" v-if="item.status === 2">休息</view>
<view class="status-badge status-adjust" v-if="item.status === 3">调休</view>
<view class="status-badge status-leave" v-if="item.status === 4">请假</view>
</view>
</view>
<view class="staffInfoRight" @click.stop="handleCallPhone(item.phone)">
<image class="phoneIcon" src="https://eshangtech.com/cyy_DIB/phoneIcon.png" />
</view>
</view>
</view>
</view>
<!-- 值班经理 -->
<view class="dutyManagerList" v-if="selectTab === 3">
<view class="dutyManagerItem" v-for="(item, index) in dutyManagerList" :key="index"
@click="viewStaffDetails(item)">
<view class="avatar manager-avatar">{{ item.name ? item.name.slice(0, 1) : "" }}</view>
<view class="staffInfoBox">
<view class="staffInfo">
<view class="staffInfoLeft">
<view class="staffInfoTop">
<view class="staff-name manager-name">{{ item.name || "" }}</view>
<view class="staff-role manager-role">👑{{ item.post || "" }}</view>
</view>
<view class="staff-status">
<view class="status-badge status-manager">值班中</view>
</view>
</view>
<view class="staffInfoRight" @click.stop="handleCallPhone(item.phone)">
<image class="phoneIcon" src="https://eshangtech.com/cyy_DIB/phoneIcon.png" />
</view>
</view>
<view class="staff-address">{{ item.address }}</view>
</view>
</view>
</view>
</view>
<!-- 其他跳转链接 -->
<view class="otherJumpUrl">
<view class="jumpItem" v-for="(item, index) in jumpItemList" :key="index"
:style="{ marginBottom: index < 4 ? '24rpx' : '' }" @click="handleClickJump(item.value)">
<image class="jumpIcon" :src="item.url" />
<view class="jumpText">{{ item.label }}</view>
</view>
</view>
<!-- 会员详情 -->
<uni-popup ref="popup" border-radius="10px 10px 0 0" @change="handlePopupChange">
<view class="userPopupBox" v-if="userDetail">
<view class="userBoxTitle">人员详情</view>
<view class="userDetailBox">
<view class="userAvatar">
<image class="userAvatarIcon" v-if="userDetail.url" :src="userDetail.url" />
<view class="userAvatarBox">{{ userDetail.name ? userDetail.name.slice(0, 1) : "" }}</view>
</view>
<view class="userDetailRight">
<view class="userDetailTop">
<view class="userDetailName">{{ userDetail.name || "" }}</view>
<view class="userDetailStatus" v-if="userDetail.status" :style="{
background: userDetail.status === 1 ? '#27B25F' : '',
color: userDetail.status === 1 ? '#fff' : '',
}">{{ userDetail.status === 1 ? '在岗' :
"" }}</view>
</view>
<view class="userDetailPostBox">
<span class="userDetailLabel">岗位</span>
<span class="userDetailValue">{{ userDetail.post || "" }}</span>
</view>
<view class="userDetailPhoneBox">
<span class="userDetailLabel">电话</span>
<span class="userDetailValue">{{ userDetail.phone || "" }}</span>
</view>
</view>
</view>
<view class="line"></view>
<view class="userBoxTitle">当前出勤情况</view>
<view class="attendanceStatusBox">
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">当前排班信息</view>
<view class="attendanceStatusValue">{{ userDetail.status === 1 ? '班' : userDetail.status === 2 ?
'休' : '' }}</view>
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">上班打卡地</view>
<view class="attendanceStatusValue">{{ userDetail.dutyPlace || "" }}</view>
<!-- dutyPlace -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">上班打卡时间</view>
<view class="attendanceStatusValue">{{ userDetail.dutyTime || "" }}</view>
<!-- dutyTime -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">迟到时长</view>
<view class="attendanceStatusValue">{{ userDetail.toLateTime || "" }}</view>
<!-- toLateTime -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">下班打卡地</view>
<view class="attendanceStatusValue">{{ userDetail.offWorkPlace || "" }}</view>
<!-- offWorkPlace -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">下班打卡时间</view>
<view class="attendanceStatusValue">{{ userDetail.offWorkTime || "" }}</view>
<!-- offWorkTime -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">早退时长</view>
<view class="attendanceStatusValue">{{ userDetail.earlyWorkTime || "" }}</view>
<!-- earlyWorkTime -->
</view>
</view>
<view class="line"></view>
<view class="userBoxTitle">考勤统计</view>
<view class="attendanceStatusBox">
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">当月排班天数</view>
<view class="attendanceStatusValue">{{ userDetail.monthDay || "" }}</view>
<!-- monthDay -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">出勤天数</view>
<view class="attendanceStatusValue">{{ userDetail.AttendanceDay || "" }}</view>
<!-- AttendanceDay -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">休息天数</view>
<view class="attendanceStatusValue">{{ userDetail.leaveDay || "" }}</view>
<!-- leaveDay -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">迟到天数</view>
<view class="attendanceStatusValue">{{ userDetail.beLateDay || "" }}</view>
<!-- beLateDay -->
</view>
<view class="attendanceStatusItem">
<view class="attendanceStatusLabel">早退天数</view>
<view class="attendanceStatusValue">{{ userDetail.leaveEarlyDay || "" }}</view>
<!-- leaveEarlyDay -->
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
data() {
const nowDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD') // 有数据的最近日期
return {
menu: {},
serviceInfo: {},
selectDate: nowDay,// 选中的时间
info: {
startDate: "2025-01-01"
},
selectTab: 1,
onDutyPersonList: [
{
name: "曹鑫",
post: "三级驻站经理",
status: 1,
phone: "13987822022",
service: "达连坝停车区-下行",
dutyPlace: "", // 上班打卡地
dutyTime: "2025-08-14 07:26",// 上班打卡时间
toLateTime: "",// 迟到时长
offWorkPlace: "",// 下班打卡地
offWorkTime: "",// 下班打卡时间
earlyWorkTime: "",// 早退时长
monthDay: "23",// 当月排班天数
AttendanceDay: "10",// 出勤天数
leaveDay: "8",// 休息天数
beLateDay: "",// 迟到天数
leaveEarlyDay: "1",// 早退天数
},
{
name: "陈艳雄",
post: "安全管理岗",
status: 1,
phone: "18787834836",
service: "昆西片区管理部",
dutyPlace: "", // 上班打卡地
dutyTime: "",// 上班打卡时间
toLateTime: "",// 迟到时长
offWorkPlace: "",// 下班打卡地
offWorkTime: "",// 下班打卡时间
earlyWorkTime: "",// 早退时长
monthDay: "23",// 当月排班天数
AttendanceDay: "0",// 出勤天数
leaveDay: "8",// 休息天数
beLateDay: "",// 迟到天数
leaveEarlyDay: "",// 早退天数
},
{
name: "陈芝丽",
post: "三级驻站经理",
status: 1,
phone: "15887779180",
service: "猫街停车区-下行",
dutyPlace: "", // 上班打卡地
dutyTime: "2025-08-14 07:11",// 上班打卡时间
toLateTime: "",// 迟到时长
offWorkPlace: "",// 下班打卡地
offWorkTime: "",// 下班打卡时间
earlyWorkTime: "",// 早退时长
monthDay: "23",// 当月排班天数
AttendanceDay: "11",// 出勤天数
leaveDay: "8",// 休息天数
beLateDay: "",// 迟到天数
leaveEarlyDay: "1",// 早退天数
}
],// 在岗人员 1 在岗 2 休息 3 调休 4 请假 5 旷工 6 迟到
EmployeesOnLeaveList: [
{
name: "高金平",
post: "三级驻站经理",
status: 2,
phone: "17787888023",
service: "大姚服务区-下行",
dutyPlace: "", // 上班打卡地
dutyTime: "",// 上班打卡时间
toLateTime: "",// 迟到时长
offWorkPlace: "",// 下班打卡地
offWorkTime: "",// 下班打卡时间
earlyWorkTime: "",// 早退时长
monthDay: "23",// 当月排班天数
AttendanceDay: "9",// 出勤天数
leaveDay: "8",// 休息天数
beLateDay: "",// 迟到天数
leaveEarlyDay: "",// 早退天数
},
{
name: "雷自云",
post: "三级驻站经理",
status: 2,
phone: "15825167023",
service: "永仁停车区-下行",
dutyPlace: "", // 上班打卡地
dutyTime: "",// 上班打卡时间
toLateTime: "",// 迟到时长
offWorkPlace: "",// 下班打卡地
offWorkTime: "",// 下班打卡时间
earlyWorkTime: "",// 早退时长
monthDay: "23",// 当月排班天数
AttendanceDay: "8",// 出勤天数
leaveDay: "8",// 休息天数
beLateDay: "",// 迟到天数
leaveEarlyDay: "1",// 早退天数
},
{
name: "刘凯峰",
post: "一级驻站副经理",
status: 2,
phone: "15198787593",
service: "恐龙山服务区-上行",
dutyPlace: "", // 上班打卡地
dutyTime: "",// 上班打卡时间
toLateTime: "",// 迟到时长
offWorkPlace: "",// 下班打卡地
offWorkTime: "",// 下班打卡时间
earlyWorkTime: "",// 早退时长
monthDay: "23",// 当月排班天数
AttendanceDay: "9",// 出勤天数
leaveDay: "8",// 休息天数
beLateDay: "",// 迟到天数
leaveEarlyDay: "",// 早退天数
},
{
name: "宋永鑫",
post: "一级驻站副经理",
service: "读书铺服务区-上行",
status: 2,
phone: "13649668882",
dutyPlace: "", // 上班打卡地
dutyTime: "",// 上班打卡时间
toLateTime: "",// 迟到时长
offWorkPlace: "",// 下班打卡地
offWorkTime: "",// 下班打卡时间
earlyWorkTime: "",// 早退时长
monthDay: "23",// 当月排班天数
AttendanceDay: "13",// 出勤天数
leaveDay: "8",// 休息天数
beLateDay: "",// 迟到天数
leaveEarlyDay: "",// 早退天数
}
],// 请假人员列表
dutyManagerList: [
{ name: "王五", post: "经理", status: 1, phone: "6666", address: "G56杭瑞高速主干道昆明至滇西方向" },
],// 值班经理
jumpItemList: [
{ label: "特情事件", value: 1, url: "" },
{ label: "设施状态", value: 2, url: "" },
{ label: "考勤统计", value: 3, url: "" },
{ label: "请假管理", value: 4, url: "" },
{ label: "排班表", value: 5, url: "" },
{ label: "通知公告", value: 6, url: "" },
],
showPopup: false,
userDetail: null
};
},
onLoad() {
this.menu = uni.getMenuButtonBoundingClientRect()
let currentService = uni.getStorageSync('currentService')
this.serviceInfo = currentService
},
methods: {
open() {
this.$refs.calendar.open()
},
handlePopupChange(e) {
this.showPopup = e.show
console.log('e', e);
if (!e.show) {
this.userDetail = null
}
},
handleBack() {
uni.navigateBack({
delta: 1
});
},
// 改变查询时间
handleChangeTime(e) {
console.log('e', e);
// this.selectDate = e.detail.value
this.selectDate = e.fulldate
},
// 切换tab
handleChangeTab(e) {
this.selectTab = e
},
// 打电话
handleCallPhone(phone) {
uni.makePhoneCall({
phoneNumber: phone
});
},
// 跳转应急事件页面
showEmergencyDetails(type) {
// type 1 应急事件 2 日常问题
this.$util.toNextRoute("navigateTo", `/pages/attendanceStatus/emergencyEvents?type=${type}`);
},
// 跳转其他页面
handleClickJump(value) {
if (value === 2) {
this.$util.toNextRoute("navigateTo", `/pages/attendanceStatus/serviceFacility`);
}
},
// 会员详情信息
viewStaffDetails(obj) {
this.$refs.popup.open('center')
this.userDetail = obj
}
},
onUnload() {
}
};
</script>
<style lang="less" scoped>
@bg: #f8f9fa;
@muted: #666;
@card: #fff;
@shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
@primary: #27B25F;
@primary2: #4CCC7F;
@ok: #2ed573;
@warn: #ff9f43;
@danger: #ff4757;
.main {
width: 100vw;
min-height: 100vh;
// background-image: url("https://eshangtech.com/minTestImg/pageBg.png");
background-color: #fff;
box-sizing: border-box;
padding-bottom: env(safe-area-inset-bottom);
.summaryTab {
position: fixed;
left: 0;
top: 0;
width: 100vw;
// background: #fff;
background-image: url("https://eshangtech.com/minTestImg/pageBg.png");
z-index: 99;
display: flex;
align-items: center;
box-sizing: border-box;
padding-bottom: 16px;
.leftArrow {
width: 100%;
height: 24px;
position: absolute;
// left: 16px;
z-index: 99999999999;
box-sizing: border-box;
display: flex;
align-items: center;
padding: 0 32rpx;
.img {
width: 24px;
height: 24px;
margin-right: 8px;
z-index: 99;
}
.picker {
.selectService {
display: flex;
align-items: center;
.img {
width: 40px;
height: 40px;
z-index: 2;
}
.select {
height: 32px;
background: #fff;
border-radius: 0 16px 16px 0;
transform: translateX(-40px);
box-sizing: border-box;
padding-left: 35px;
padding-right: 8rpx;
display: flex;
align-items: center;
.content {
display: flex;
align-items: center;
.uni-input {
padding: 0;
background: transparent;
font-size: 14px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #160002;
}
.area {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #786B6C;
line-height: 40px;
margin-left: 4px;
}
.rightArrow {
width: 12px;
height: 12px;
}
.noticeText {
font-size: 24rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
color: #B6BACB;
line-height: 40rpx;
white-space: nowrap;
}
}
}
}
}
}
}
.dateBox {
width: 100vw;
box-sizing: border-box;
padding: 16rpx 0;
display: flex;
align-items: center;
justify-content: center;
.centerDateBox {
display: flex;
align-items: center;
gap: 10rpx;
padding: 10rpx 20rpx;
border-radius: 30rpx;
background-color: #fff;
border: 2rpx solid #27B35F;
// background: rgba(255, 255, 255, .15);
.date-text {
font-size: 28rpx;
font-weight: 700;
}
}
}
.selectDateCalendar {
/deep/ .uni-calendar-item__weeks-box-item {
width: calc(100% / 7);
}
/deep/ .uni-calendar-item--checked {
background-color: #3CC071;
}
/deep/ .uni-calendar-item--isDay {
background-color: #3CC071;
color: #fff !important;
}
/deep/ .uni-calendar-item--isDay-text {
white-space: nowrap;
color: #000;
}
/deep/ .uni-calendar__backtoday {
background-color: #3CC071;
color: #fff;
}
}
.personTabBox {
width: 100%;
box-sizing: border-box;
padding: 0 32rpx;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 50rpx;
margin-top: 24rpx;
.personItem {
background: #fff;
padding: 30rpx;
border-radius: 24rpx;
text-align: center;
box-shadow: @shadow;
.personValue {
font-size: 30rpx;
font-weight: 600;
color: @primary;
margin-bottom: 8rpx;
}
.personLabel {
font-size: 24rpx;
color: @muted;
}
}
.personItemSelect {
background: linear-gradient(135deg, @primary, @primary2);
color: #fff;
.personValue {
color: #fff;
}
.personLabel {
color: rgba(255, 255, 255, .9);
}
}
}
.emergency-banner {
background: linear-gradient(135deg, @danger, #ff3838);
color: #fff;
padding: 20rpx 30rpx;
margin: 0 30rpx 30rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(255, 71, 87, .3);
border-left: 8rpx solid #ff1744;
.emergency-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
.emergency-title {
font-weight: 700;
font-size: 28rpx;
display: flex;
align-items: center;
gap: 16rpx;
}
.emergency-count {
background: rgba(255, 255, 255, .3);
padding: 4rpx 16rpx;
border-radius: 24rpx;
font-size: 24rpx;
font-weight: 700;
}
}
.emergency-preview {
font-size: 24rpx;
opacity: .9;
}
}
.warning-banner {
background: linear-gradient(135deg, @warn, #ff8c00);
color: #fff;
padding: 20rpx 30rpx;
margin: 0 30rpx 30rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(255, 159, 67, .3);
border-left: 8rpx solid #ff8c00;
.emergency-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
}
.emergency-title {
font-weight: 700;
font-size: 28rpx;
display: flex;
align-items: center;
gap: 16rpx;
}
.emergency-count {
background: rgba(255, 255, 255, .3);
padding: 4rpx 16rpx;
border-radius: 24rpx;
font-size: 24rpx;
font-weight: 700;
}
.emergency-preview {
font-size: 24rpx;
opacity: .9;
}
}
.onDutyPersonBox {
width: calc(100% - 64rpx);
margin: 32rpx;
background: #fff;
border-radius: 24rpx;
overflow: hidden;
box-shadow: @shadow;
.onDutyPersonBoxHeader {
background: @bg;
padding: 30rpx;
border-bottom: 1rpx solid #e9ecef;
font-weight: 700;
font-size: 28rpx;
color: #2c3e50;
display: flex;
justify-content: space-between;
align-items: center;
.tab-indicators {
display: flex;
gap: 16rpx;
.tab-dot {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: #ddd;
&.active {
background: @primary;
}
}
}
}
.onDutyPersonList {
.onDutyPersonItem {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f1f3f4;
&:last-child {
border-bottom: none;
}
.avatar {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
background: linear-gradient(270deg, #27B25F 0%, #4CCC7F 100%);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-weight: 700;
margin-right: 30rpx;
font-size: 28rpx;
}
.staffInfo {
flex: 1;
display: flex;
align-items: center;
.staffInfoLeft {
flex: 1;
.staffInfoTop {
display: flex;
align-items: center;
margin-bottom: 8rpx;
.staff-name {
font-weight: 600;
font-size: 26rpx;
}
.staff-role {
color: @muted;
font-size: 24rpx;
margin-left: 16rpx;
}
}
.staff-status {
font-size: 24rpx;
.status-badge {
display: inline-block;
padding: 6rpx 16rpx;
border-radius: 20rpx;
font-size: 22rpx;
font-weight: 700;
&.status-online {
background: #d4edda;
color: #155724;
}
&.status-absentee {
background: #ff0000;
color: #fff;
}
&.status-beLate {
background: #f8d7da;
color: #721c24;
}
}
}
}
.staffInfoRight {
width: 100rpx;
display: flex;
align-items: center;
justify-content: center;
.phoneIcon {
width: 40rpx;
height: 40rpx;
margin-left: 8rpx;
background-color: #fff;
border-radius: 50%;
}
}
}
}
}
.EmployeesOnLeaveList {
.EmployeesOnLeaveItem {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f1f3f4;
&:last-child {
border-bottom: none;
}
.avatar {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
background: linear-gradient(270deg, #27B25F 0%, #4CCC7F 100%);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-weight: 700;
margin-right: 30rpx;
font-size: 28rpx;
}
.staffInfo {
flex: 1;
display: flex;
align-items: center;
.staffInfoLeft {
flex: 1;
.staffInfoTop {
display: flex;
align-items: center;
margin-bottom: 8rpx;
.staff-name {
font-weight: 600;
font-size: 26rpx;
}
.staff-role {
color: @muted;
font-size: 24rpx;
margin-left: 16rpx;
}
}
.staff-status {
font-size: 24rpx;
.status-badge {
display: inline-block;
padding: 6rpx 16rpx;
border-radius: 20rpx;
font-size: 22rpx;
font-weight: 700;
&.status-rest {
background: #F6F6F6;
color: #9FA6A3;
}
&.status-adjust {
background: #fff3cd;
color: #856404;
}
&.status-leave {
background: #FF8B3F;
color: #fff;
}
}
}
}
.staffInfoRight {
width: 100rpx;
display: flex;
align-items: center;
justify-content: center;
.phoneIcon {
width: 40rpx;
height: 40rpx;
margin-left: 8rpx;
background-color: #fff;
border-radius: 50%;
}
}
}
}
}
.dutyManagerList {
.dutyManagerItem {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f1f3f4;
background: #E7F8EE;
border: 4rpx solid #27B25F;
border-radius: 24rpx;
margin: 20rpx;
box-shadow: 0 8rpx 24rpx #E7F8EE;
.avatar {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
background: linear-gradient(270deg, #27B25F 0%, #4CCC7F 100%);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-weight: 700;
margin-right: 30rpx;
font-size: 28rpx;
}
.manager-avatar {
background: linear-gradient(135deg, #27B25F, #4CCC7F);
border: 6rpx solid #27B25F;
box-shadow: 0 4rpx 16rpx #E7F8EE;
}
.manager-name {
color: #27B25F;
font-size: 36rpx;
}
.manager-role {
color: #ff9800;
font-weight: 700;
}
.manager-actions {
display: flex;
flex-direction: column;
gap: 16rpx;
.contact-btn,
.locate-btn {
background: linear-gradient(135deg, #ff9800, #f57c00);
border: none;
color: #fff;
width: 72rpx;
height: 72rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
}
}
.staffInfoBox {
flex: 1;
.staffInfo {
display: flex;
align-items: center;
margin-bottom: 6rpx;
.staffInfoLeft {
flex: 1;
.staffInfoTop {
display: flex;
align-items: center;
margin-bottom: 6rpx;
.staff-name {
font-weight: 700;
font-size: 32rpx;
}
.staff-role {
color: @muted;
font-size: 26rpx;
margin-left: 16rpx;
}
}
.staff-status {
font-size: 24rpx;
margin-bottom: 6rpx;
.status-badge {
display: inline-block;
padding: 6rpx 16rpx;
border-radius: 20rpx;
font-size: 22rpx;
font-weight: 700;
&.status-online {
background: #d4edda;
color: #155724;
}
&.status-break {
background: #fff3cd;
color: #856404;
}
&.status-offline {
background: #f8d7da;
color: #721c24;
}
&.status-manager {
background: linear-gradient(135deg, #27B25F, #4CCC7F);
color: #fff;
border: 1rpx solid #27B25F;
}
}
}
}
.staffInfoRight {
width: 100rpx;
display: flex;
align-items: center;
justify-content: center;
.phoneIcon {
width: 40rpx;
height: 40rpx;
margin-left: 8rpx;
background-color: #E7F8EE;
border-radius: 50%;
}
}
}
.staff-address {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #716F69;
line-height: 36rpx;
text-align: left;
font-style: normal;
}
}
}
}
}
.otherJumpUrl {
width: calc(100% - 64rpx);
margin: 0 32rpx;
background-color: #fff;
box-shadow: @shadow;
box-sizing: border-box;
padding: 24rpx;
border-radius: 24rpx;
display: flex;
flex-wrap: wrap;
.jumpItem {
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.jumpIcon {
width: 48rpx;
height: 48rpx;
margin-bottom: 16rpx;
}
.jumpText {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #716F69;
line-height: 36rpx;
text-align: left;
font-style: normal;
}
}
}
.userPopupBox {
width: 90vw;
height: 80vh;
background-color: #fff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 24rpx;
overflow-y: auto;
.userBoxTitle {
width: 100%;
font-size: 28rpx;
font-weight: 600;
}
.userDetailBox {
width: 100%;
margin-top: 16rpx;
display: flex;
align-items: center;
.userAvatar {
width: 180rpx;
height: 180rpx;
margin-right: 20rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
.userAvatarIcon {
width: 100%;
height: 100%;
border-radius: 50%;
}
.userAvatarBox {
width: 70%;
height: 70%;
border-radius: 50%;
background: linear-gradient(270deg, #27B25F 0%, #4CCC7F 100%);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-weight: 700;
margin-right: 30rpx;
font-size: 30rpx;
}
}
.userDetailRight {
flex: 1;
.userDetailTop {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.userDetailName {
display: inline-block;
max-width: 70%;
font-size: 26rpx;
font-weight: 600;
}
.userDetailStatus {
display: inline-block;
padding: 0 8rpx;
border-radius: 8rpx;
}
}
.userDetailPostBox,
.userDetailPhoneBox {
.userDetailLabel {
font-size: 26rpx;
font-weight: 600;
}
.userDetailValue {
font-size: 24rpx;
}
}
}
}
.line {
width: 100%;
height: 2rpx;
background-color: #e4e3e3;
margin: 16rpx 0;
}
.attendanceStatusBox {
width: 100%;
margin-top: 24rpx;
.attendanceStatusItem {
width: 100%;
margin-bottom: 16rpx;
display: flex;
align-items: center;
.attendanceStatusLabel {
width: 200rpx;
text-align: left;
font-size: 26rpx;
}
.attendanceStatusValue {
flex: 1;
font-size: 24rpx;
}
}
}
}
}
/* 通用 */
.muted {
color: @muted;
}
.ml8 {
margin-left: 8px;
}
.h1 {
font-size: 36rpx;
font-weight: 600;
}
.pad15 {
padding: 30rpx;
}
.m15 {
margin: 30rpx;
}
.p15 {
padding: 30rpx;
}
.noMargin {
margin: 0;
}
.noPad {
padding: 0;
}
</style>