1379 lines
48 KiB
Vue
1379 lines
48 KiB
Vue
<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>
|