This commit is contained in:
ylj20011123 2025-08-19 17:22:15 +08:00
parent 590499fb84
commit a6692879e0
6 changed files with 1207 additions and 404 deletions

View File

@ -1,4 +1,4 @@
<!-- 考勤统计 --> <!-- 考勤统计 - 重新设计版本 -->
<template> <template>
<page-meta :page-style="'overflow:' + (showPopup ? 'hidden' : 'visible')"></page-meta> <page-meta :page-style="'overflow:' + (showPopup ? 'hidden' : 'visible')"></page-meta>
<view class="main"> <view class="main">
@ -13,7 +13,7 @@
<view class="select"> <view class="select">
<view class="content"> <view class="content">
<view class="uni-input">{{ serviceInfo.SERVERPART_NAME ? serviceInfo.SERVERPART_NAME : <view class="uni-input">{{ serviceInfo.SERVERPART_NAME ? serviceInfo.SERVERPART_NAME :
'' }} '请选择服务区' }}
</view> </view>
<image class="rightArrow" <image class="rightArrow"
src="https://eshangtech.com/ShopICO/ahyd-BID/commercial/rightArrow.svg"></image> src="https://eshangtech.com/ShopICO/ahyd-BID/commercial/rightArrow.svg"></image>
@ -26,15 +26,17 @@
<!-- 考勤统计的列表 --> <!-- 考勤统计的列表 -->
<view class="attendanceListBox" :style="{ paddingTop: (menu.bottom + 30) + 'px' }"> <view class="attendanceListBox" :style="{ paddingTop: (menu.bottom + 30) + 'px' }">
<view class="onDutyPersonBoxHeader"> <!-- 头部标题和筛选 -->
<text class="title">考勤统计</text> <view class="headerSection">
<!-- 居中的日历时间 --> <!-- 时间选择器 -->
<view class="dateSelector">
<view class="dateBox"> <view class="dateBox">
<view class="centerDateBox"> <view class="centerDateBox">
<image class="arrowIcon" src="https://eshangtech.com/cyy_DIB/leftArrowIcon.png" <image class="arrowIcon" src="https://eshangtech.com/cyy_DIB/leftArrowIcon.png"
@click="handleChangeDate(2)" /> @click="handleChangeDate(2)" />
<view class="center"> <view class="center">
<text class="date-text">{{ selectDate ? $util.cutDate(new Date(selectDate), 'YYYY-MM') : "" <text class="date-text">{{ selectDate ? $util.cutDate(new Date(selectDate), 'YYYY-MM') :
""
}}</text> }}</text>
<!-- <text class="date-icon">📅</text> --> <!-- <text class="date-icon">📅</text> -->
</view> </view>
@ -42,89 +44,163 @@
@click="handleChangeDate(1)" /> @click="handleChangeDate(1)" />
</view> </view>
</view> </view>
</view>
<view class="filterBadge" v-if="attendanceStatisticsData.length > 0">
<text class="badgeText">{{ attendanceStatisticsData.length }}</text>
<view class="attendanceStatisticsItem" v-for="(item, index) in attendanceStatisticsData" :key="index"
:style="{
borderTopRightRadius: index === 0 ? '0' : '',
borderTopLeftRadius: index === 0 ? '0' : '',
marginBottom: index + 1 === attendanceStatisticsData.length ? '0' : '24rpx'
}">
<view class="attendanceStatisticsItemTop">
<view class="eventsItem" style="margin-bottom: 16rpx;">
<view class="eventsHaveImgLabel">
<image class="eventsHaveImg" src="https://eshangtech.com/cyy_DIB/personIcon.png" />
<view class="eventsHaveLabel">联系人</view>
</view> </view>
<view class="eventsValue">{{ item.userName || "" }}</view>
</view>
<view class="eventsItem">
<view class="eventsHaveImgLabel">
<image class="eventsHaveImg" src="https://eshangtech.com/cyy_DIB/phoneLabelIcon.png" />
<view class="eventsHaveLabel">联系电话</view>
</view>
<view class="eventsValue">{{ item.phone || "" }}</view>
</view> </view>
</view> </view>
<view class="line"></view> <!-- 统计汇总卡片 -->
<view class="summaryCards" v-if="attendanceStatisticsData.length > 0">
<view class="summaryCard">
<view class="attendanceStatisticsItemTop attendanceStatisticsItemBottom"> <view class="cardIcon scheduleIcon">📋</view>
<view class="eventsItem"> <view class="cardContent">
<view class="eventsHaveImgLabel"> <text class="cardNumber">{{ getSummaryData().totalSchedule }}</text>
<view class="eventsHaveLabel">当月排班</view> <text class="cardLabel">总排班</text>
</view> </view>
<view class="eventsValue">{{ item.scheduleTotal || "" }}</view>
</view> </view>
<view class="eventsItem"> <view class="summaryCard">
<view class="eventsHaveImgLabel"> <view class="cardIcon attendIcon"></view>
<view class="eventsHaveLabel">出勤</view> <view class="cardContent">
<text class="cardNumber">{{ getSummaryData().totalAttend }}</text>
<text class="cardLabel">总出勤</text>
</view> </view>
<view class="eventsValue">{{ item.attendTotal || "" }}</view>
</view> </view>
<view class="eventsItem"> <view class="summaryCard">
<view class="eventsHaveImgLabel"> <view class="cardIcon lateIcon"></view>
<view class="eventsHaveLabel">休息</view> <view class="cardContent">
<text class="cardNumber">{{ getSummaryData().totalLate }}</text>
<text class="cardLabel">迟到次数</text>
</view> </view>
<view class="eventsValue">{{ item.restTotal || "" }}</view>
</view> </view>
<view class="eventsItem"> <view class="summaryCard">
<view class="eventsHaveImgLabel"> <view class="cardIcon earlyIcon">🏃</view>
<view class="eventsHaveLabel">迟到</view> <view class="cardContent">
<text class="cardNumber">{{ getSummaryData().totalEarly }}</text>
<text class="cardLabel">早退次数</text>
</view> </view>
<view class="eventsValue">{{ item.lateTotal || "" }}</view>
</view>
<view class="eventsItem" style="margin-bottom: 0;">
<view class="eventsHaveImgLabel">
<view class="eventsHaveLabel">早退</view>
</view>
<view class="eventsValue">{{ item.earlyTotal || "" }}</view>
</view> </view>
</view> </view>
<!-- 员工考勤列表 -->
<view class="employeeList">
<view class="employeeCard" v-for="(item, index) in attendanceStatisticsData" :key="index">
<!-- 员工基本信息 -->
<view class="employeeHeader">
<!-- 左侧头像 + 带图标信息 -->
<view class="leftSection">
<view class="avatar">{{ getFirstChar(item.userName) }}</view>
<view class="iconInfoSection">
<view class="nameRow">
<image class="personIcon" src="https://eshangtech.com/cyy_DIB/personIcon.png">
</image>
<text class="employeeName">{{ item.userName || "-" }}</text>
</view>
<view class="phoneRow">
<image class="phoneIcon" src="https://eshangtech.com/cyy_DIB/phoneLabelIcon.png">
</image>
<text class="phoneNumber">{{ item.phone || item.userCode || "-" }}</text>
</view> </view>
</view> </view>
</view> </view>
<!-- 右侧无图标信息 -->
<view class="rightSection">
<text class="employeeJob">{{ item.userJob || "" }}</text>
<view class="workTypeBadge"
:class="(item.workType === '班' || item.workType === '差' || item.workType === '出' ? 'work' : 'rest')">
<text class="workTypeText">{{ item.workType || '正常' }}</text>
</view>
</view>
</view>
<!-- 考勤统计数据 -->
<view class="attendanceStats">
<view class="statItem">
<text class="statLabel">排班</text>
<text class="statValue">{{ item.scheduleTotal || 0 }}</text>
</view>
<view class="statItem">
<text class="statLabel">出勤</text>
<text class="statValue success">{{ item.attendTotal || 0 }}</text>
</view>
<view class="statItem">
<text class="statLabel">休息</text>
<text class="statValue">{{ item.restTotal || 0 }}</text>
</view>
<view class="statItem">
<text class="statLabel">迟到</text>
<text class="statValue warning">{{ item.lateTotal || 0 }}</text>
</view>
<view class="statItem">
<text class="statLabel">早退</text>
<text class="statValue danger">{{ item.earlyTotal || 0 }}</text>
</view>
</view>
<!-- 当日打卡详情 -->
<view class="clockDetails" v-if="false">
<text class="sectionTitle">当日打卡记录</text>
<view class="clockRow">
<view class="clockItem">
<view class="clockIcon inIcon">🕐</view>
<view class="clockInfo">
<text class="clockLabel">上班打卡</text>
<text class="clockTime">{{ (item.dutyClockInTime && item.dutyClockInTime.trim()) ||
"未打卡" }}</text>
<text class="lateInfo" v-if="item.lateNum && item.lateNum > 0">迟到{{
formatDuration(item.lateNum) }}</text>
</view>
</view>
<view class="clockItem">
<view class="clockIcon outIcon">🕕</view>
<view class="clockInfo">
<text class="clockLabel">下班打卡</text>
<text class="clockTime">{{ (item.offDutyClockInTime &&
item.offDutyClockInTime.trim()) || "未打卡" }}</text>
<text class="earlyInfo" v-if="item.earlyNum && item.earlyNum > 0">早退{{
formatDuration(item.earlyNum) }}</text>
</view>
</view>
</view>
<view class="locationInfo" v-if="item.offDutyClockInPlace">
<image class="locationIcon" src="https://eshangtech.com/cyy_DIB/locationIcon.png" />
<text class="locationText">下班打卡地{{ item.offDutyClockInPlace }}</text>
</view>
</view>
</view>
</view>
<!-- 空数据状态 -->
<view class="emptyState" v-if="attendanceStatisticsData.length === 0 && !loading">
<text class="emptyText">暂无考勤数据</text>
<text class="emptyDesc">请选择其他时间或服务区查看</text>
</view>
</view>
<!-- 日历组件 -->
<uni-calendar ref="calendar" :insert="false" :mask-closable="true" @confirm="onCalendarConfirm"
@close="onCalendarClose" />
</view>
</template> </template>
<script> <script>
import request from "@/util/index.js"; import request from "@/util/index.js";
import { formatTime } from '@/util/dateTime/index.js' import { formatTime } from '@/util/dateTime/index.js'
export default { export default {
data() { data() {
const nowDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD') // const nowDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD')
return { return {
menu: {}, menu: {},
serviceInfo: {}, serviceInfo: {},
showPopup: false, showPopup: false,
selectDate: nowDay,// selectDate: nowDay,
attendanceStatisticsData: [], attendanceStatisticsData: [],
isFirst: true, isFirst: true,
seatInfo: {} seatInfo: {},
loading: false
} }
}, },
onLoad() { onLoad() {
@ -143,18 +219,64 @@ export default {
this.isFirst = false this.isFirst = false
}, },
methods: { methods: {
//
getFirstChar(name) {
return name ? name.charAt(0).toUpperCase() : '?'
},
//
formatDuration(minutes) {
if (!minutes || minutes <= 0) return ''
const hours = Math.floor(minutes / 60)
const mins = minutes % 60
if (hours > 0) {
return mins > 0 ? `${hours}小时${mins}分钟` : `${hours}小时`
}
return `${mins}分钟`
},
//
getSummaryData() {
const data = this.attendanceStatisticsData
return {
totalSchedule: data.reduce((sum, item) => sum + (item.scheduleTotal || 0), 0),
totalAttend: data.reduce((sum, item) => sum + (item.attendTotal || 0), 0),
totalLate: data.reduce((sum, item) => sum + (item.lateTotal || 0), 0),
totalEarly: data.reduce((sum, item) => sum + (item.earlyTotal || 0), 0)
}
},
//
showCalendar() {
this.$refs.calendar.open()
},
//
onCalendarConfirm(e) {
console.log('选择日期:', e)
this.selectDate = e.fulldate
this.handleGetData(this.serviceInfo.SERVERPART_NAME)
},
//
onCalendarClose() {
console.log('日历关闭')
},
// //
async handleGetData(SERVERPART_NAME) { async handleGetData(SERVERPART_NAME) {
let req = { let req = {
bsessionKey: "0B30475A94674D608022885F7763959B", bsessionKey: "0B30475A94674D608022885F7763959B",
workTime: new Date(this.selectDate).getTime(), workTime: new Date(this.selectDate).getTime(),
saName: SERVERPART_NAME || "",// saName: SERVERPART_NAME || "",
phone: "",// phone: "",
} }
this.loading = true
uni.showLoading({ uni.showLoading({
title: "加载中..." title: "加载中..."
}) })
try {
const data = await new Promise((resolve, reject) => { const data = await new Promise((resolve, reject) => {
uni.request({ uni.request({
url: "https://fwqznxj.yciccloud.com:9081/ynjt/pushManage/queryUserSchedule", url: "https://fwqznxj.yciccloud.com:9081/ynjt/pushManage/queryUserSchedule",
@ -166,11 +288,13 @@ export default {
success(res) { success(res) {
resolve(res.data.data) resolve(res.data.data)
}, },
fail(err) {
reject(err)
}
}); });
}); });
uni.hideLoading()
let list = data let list = data || []
if (list && list.length > 0) { if (list && list.length > 0) {
list.forEach((item) => { list.forEach((item) => {
@ -179,7 +303,20 @@ export default {
}) })
} }
this.attendanceStatisticsData = list this.attendanceStatisticsData = list
console.log('最终数据:', this.attendanceStatisticsData)
} catch (error) {
console.error('获取考勤数据失败:', error)
uni.showToast({
title: '获取数据失败',
icon: 'none'
})
this.attendanceStatisticsData = []
} finally {
this.loading = false
uni.hideLoading()
}
}, },
// //
async handleGetServerpartDetail(id) { async handleGetServerpartDetail(id) {
let currentService = uni.getStorageSync("currentService"); let currentService = uni.getStorageSync("currentService");
@ -190,29 +327,31 @@ export default {
latitude: this.seatInfo.latitude, latitude: this.seatInfo.latitude,
longitude: this.seatInfo.longitude, longitude: this.seatInfo.longitude,
}; };
console.log('req', req);
uni.showLoading({ uni.showLoading({
title: "加载中...", title: "加载中...",
}); });
try {
const data = await request.$webJavaGet( const data = await request.$webJavaGet(
"/third-party/getServerPartInfo", "/third-party/getServerPartInfo",
req req
); );
uni.hideLoading();
let obj = data.Result_Data; let obj = data.Result_Data;
this.serviceInfo = obj; this.serviceInfo = obj;
this.$forceUpdate(); this.$forceUpdate();
} catch (error) {
console.log('this.serviceInfo', this.serviceInfo); console.error('获取服务区信息失败:', error)
} finally {
uni.hideLoading();
}
}, },
// //
handleChangeService() { handleChangeService() {
this.$util.toNextRoute("navigateTo", "/pages/map/index?type=attendanceStatus"); this.$util.toNextRoute("navigateTo", "/pages/map/index?type=attendanceStatus");
}, },
handleBack() { handleBack() {
uni.navigateBack({ uni.navigateBack({
delta: 1 delta: 1
@ -247,12 +386,13 @@ export default {
@bg: #f8f9fa; @bg: #f8f9fa;
@muted: #666; @muted: #666;
@card: #fff; @card: #fff;
@shadow: 0 2px 8px rgba(0, 0, 0, 0.1); @shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
@primary: #27B25F; @primary: #27B25F;
@primary2: #4CCC7F; @primary2: #4CCC7F;
@ok: #2ed573; @success: #2ed573;
@warn: #ff9f43; @warning: #ff9f43;
@danger: #ff4757; @danger: #ff4757;
@info: #3742fa;
.main { .main {
width: 100vw; width: 100vw;
@ -267,7 +407,6 @@ export default {
left: 0; left: 0;
top: 0; top: 0;
width: 100vw; width: 100vw;
// background: #fff;
background-image: url("https://eshangtech.com/minTestImg/pageBg.png"); background-image: url("https://eshangtech.com/minTestImg/pageBg.png");
z-index: 99; z-index: 99;
display: flex; display: flex;
@ -279,7 +418,6 @@ export default {
width: 100%; width: 100%;
height: 24px; height: 24px;
position: absolute; position: absolute;
// left: 16px;
z-index: 99999999999; z-index: 99999999999;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
@ -322,37 +460,18 @@ export default {
.uni-input { .uni-input {
padding: 0; padding: 0;
background: transparent; background: transparent;
font-size: 28rpx; font-size: 14px;
font-family: PingFangSC-Semibold, PingFang SC; font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600; font-weight: 600;
color: #160002; color: #160002;
} }
.area {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #786B6C;
line-height: 40px;
margin-left: 4px;
}
.rightArrow { .rightArrow {
width: 12px; width: 12px;
height: 12px; height: 12px;
} }
.noticeText {
font-size: 24rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
color: #B6BACB;
line-height: 40rpx;
white-space: nowrap;
} }
} }
}
} }
} }
} }
@ -363,23 +482,20 @@ export default {
box-sizing: border-box; box-sizing: border-box;
padding: 0 32rpx; padding: 0 32rpx;
.onDutyPersonBoxHeader { .headerSection {
background: @bg; margin-bottom: 32rpx;
padding: 0 30rpx;
border-bottom: 1rpx solid #e9ecef;
font-weight: 700;
font-size: 28rpx;
color: #2c3e50;
display: flex;
justify-content: space-between;
align-items: center;
border-top-left-radius: 8rpx;
border-top-right-radius: 8rpx;
.dateSelector {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx;
box-shadow: @shadow;
background: @card;
border-radius: 16rpx;
.dateBox { .dateBox {
box-sizing: border-box; box-sizing: border-box;
padding: 16rpx 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -388,7 +504,6 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10rpx; gap: 10rpx;
padding: 10rpx 20rpx;
border-radius: 30rpx; border-radius: 30rpx;
background-color: #fff; background-color: #fff;
// border: 2rpx solid #27B35F; // border: 2rpx solid #27B35F;
@ -408,77 +523,375 @@ export default {
} }
} }
.filterBadge {
background: @primary;
border-radius: 20rpx;
padding: 0 8rpx;
.badgeText {
color: #fff;
font-size: 24rpx;
font-weight: 600;
}
}
}
} }
.attendanceStatisticsItem { .summaryCards {
width: 100%; width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-bottom: 16rpx;
.summaryCard {
width: calc(50% - 8rpx);
box-sizing: border-box; box-sizing: border-box;
padding: 24rpx; margin-bottom: 16rpx;
background: @card;
border-radius: 16rpx;
padding: 32rpx 24rpx;
box-shadow: @shadow; box-shadow: @shadow;
border-radius: 8rpx;
background-color: #fff;
.attendanceStatisticsItemTop {
width: 100%;
flex-wrap: wrap;
.eventsItem {
width: 50%;
display: inline-block;
display: flex; display: flex;
align-items: center; align-items: center;
.eventsHaveImgLabel { .cardIcon {
display: flex; font-size: 40rpx;
width: 200rpx; margin-right: 20rpx;
align-items: center; width: 60rpx;
text-align: center;
.eventsHaveImg { &.scheduleIcon {
width: 30rpx; opacity: 0.8;
height: 30rpx;
margin-right: 16rpx;
margin-top: 6rpx;
} }
.eventsHaveLabel { &.attendIcon {
width: 154rpx; opacity: 0.8;
font-size: 24rpx; }
&.lateIcon {
opacity: 0.8;
}
&.earlyIcon {
opacity: 0.8;
} }
} }
.eventsLabel { .cardContent {
width: 200rpx;
text-align: left;
font-size: 24rpx;
}
.eventsValue {
flex: 1; flex: 1;
font-size: 24rpx;
}
}
}
.line {
width: 100%;
height: 2rpx;
background-color: #dad9d3;
margin: 24rpx 0;
}
.attendanceStatisticsItemBottom {
display: flex; display: flex;
flex-wrap: wrap; flex-direction: column;
.cardNumber {
font-size: 28rpx;
font-weight: 700;
color: #2c3e50;
line-height: 1.2;
}
.cardLabel {
font-size: 24rpx;
color: @muted;
}
}
}
}
.employeeList {
.employeeCard {
background: @card;
border-radius: 20rpx;
margin-bottom: 32rpx;
box-shadow: @shadow;
overflow: hidden;
.employeeHeader {
padding: 32rpx;
border-bottom: 2rpx solid #dcdddf;
display: flex;
align-items: flex-start;
justify-content: space-between;
/* 左侧区域:头像 + 带图标信息 */
.leftSection {
display: flex;
align-items: flex-start;
flex: 1;
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
background: linear-gradient(135deg, @primary, @primary2);
color: #fff;
font-size: 28rpx;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
margin-right: 24rpx;
flex-shrink: 0;
}
.iconInfoSection {
display: flex;
flex-direction: column;
gap: 12rpx;
flex: 1;
padding-top: 8rpx;
.nameRow {
display: flex;
align-items: center; align-items: center;
.eventsItem { .personIcon {
width: 24rpx;
height: 24rpx;
margin-right: 8rpx;
}
.employeeName {
font-size: 28rpx;
font-weight: 600;
color: #2c3e50;
line-height: 1.3;
}
}
.phoneRow {
display: flex;
align-items: center;
.phoneIcon {
width: 20rpx;
height: 20rpx;
margin-right: 8rpx;
}
.phoneNumber {
font-size: 24rpx;
color: #666;
}
}
}
}
/* 右侧区域:无图标信息 */
.rightSection {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 12rpx;
padding-top: 8rpx;
.employeeJob {
font-size: 24rpx;
color: @muted;
text-align: right;
}
.workTypeBadge {
padding: 4rpx 10rpx;
border-radius: 12rpx;
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 40rpx;
&.normal {
border-color: @info;
background: rgba(55, 66, 250, 0.1);
.workTypeText {
color: @info;
}
}
&.work {
border-color: @success;
background: #27B25F;
.workTypeText {
color: #fff;
}
}
&.rest {
background: rgba(154, 153, 152, 0.1);
.workTypeText {
color: #424141;
}
}
.workTypeText {
font-size: 20rpx;
font-weight: 500;
line-height: 1;
}
}
}
}
.attendanceStats {
padding: 24rpx;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
// gap: 24rpx 16rpx;
.statItem {
display: flex;
flex-direction: column;
align-items: center;
min-width: 120rpx;
.statLabel {
font-size: 24rpx;
color: @muted;
margin-bottom: 8rpx;
}
.statValue {
font-size: 28rpx;
font-weight: 700;
color: #2c3e50;
&.success {
color: @success;
}
&.warning {
color: @warning;
}
&.danger {
color: @danger;
}
}
}
}
.clockDetails {
padding: 32rpx;
border-top: 2rpx solid #f8f9fa;
background: #fbfcfd;
.sectionTitle {
font-size: 28rpx;
font-weight: 600;
color: #2c3e50;
margin-bottom: 24rpx;
}
.clockRow {
display: flex;
justify-content: space-between;
gap: 24rpx;
margin-bottom: 12rpx;
.clockItem {
flex: 1;
display: flex;
align-items: flex-start;
.clockIcon {
font-size: 32rpx;
margin-right: 16rpx;
margin-top: 4rpx;
&.inIcon {
opacity: 0.8;
}
&.outIcon {
opacity: 0.8;
}
}
.clockInfo {
flex: 1;
display: flex;
flex-direction: column;
.clockLabel {
font-size: 24rpx;
color: @muted;
margin-bottom: 4rpx;
}
.clockTime {
font-size: 24rpx;
font-weight: 600;
color: #2c3e50;
margin-bottom: 4rpx;
white-space: nowrap;
}
.lateInfo {
font-size: 20rpx;
color: @warning;
}
.earlyInfo {
font-size: 20rpx;
color: @danger;
}
}
}
}
.locationInfo {
display: flex;
align-items: center;
padding: 16rpx 20rpx;
background: #fff;
border-radius: 12rpx;
.locationIcon {
width: 24rpx;
height: 24rpx;
margin-right: 12rpx;
}
.locationText {
font-size: 24rpx;
color: @muted;
}
}
}
}
}
.emptyState {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 40rpx;
.emptyIcon {
width: 120rpx;
height: 120rpx;
margin-bottom: 32rpx;
opacity: 0.6;
}
.emptyText {
font-size: 32rpx;
color: @muted;
margin-bottom: 16rpx; margin-bottom: 16rpx;
} }
.emptyDesc {
font-size: 24rpx;
color: #bbb;
text-align: center;
line-height: 1.5;
} }
} }
} }
} }
</style> </style>

View File

@ -64,8 +64,9 @@
</view> </view>
<!-- 插入日历 即悬浮框 --> <!-- 插入日历 即悬浮框 -->
<uni-calendar ref="calendar" class="selectDateCalendar" :clear-date="true" :date="selectDate" :insert="false" <uni-calendar ref="calendar" class="selectDateCalendar" :mask-closable="true" :clear-date="true"
:startDate="info.startDate" :range="info.range" @confirm="handleChangeTime" /> :date="selectDate" :insert="false" :startDate="info.startDate" :range="info.range"
@confirm="handleChangeTime" />
<view class="thingBox"> <view class="thingBox">
@ -74,18 +75,19 @@
<view class="emergency-header"> <view class="emergency-header">
<view class="emergency-title"> <view class="emergency-title">
<text>🚨 应急事件</text> <text>🚨 应急事件</text>
<!-- <view class="emergency-count">{{ 2 }}</view> --> <view class="emergency-count">{{ emergencyListLength }}</view>
</view> </view>
<!-- <text>👉</text> --> <!-- <text>👉</text> -->
</view> </view>
</view> </view>
<!-- 一般警告提醒 --> <!-- 一般警告提醒 -->
<view class="warning-banner" @click="showEmergencyDetails(2)"> <view class="warning-banner" @click="showEmergencyDetails(2)">
<view class="emergency-header"> <view class="emergency-header">
<view class="emergency-title"> <view class="emergency-title">
<text> 日常问题</text> <text> 日常问题</text>
<!-- <view class="emergency-count">{{ 2 }}</view> --> <view class="emergency-count">{{ dailyListLength }}</view>
</view> </view>
<!-- <text>👉</text> --> <!-- <text>👉</text> -->
</view> </view>
@ -486,29 +488,112 @@ export default {
], ],
showPopup: false, showPopup: false,
userDetail: null, userDetail: null,
isFirst: true isFirst: true,
emergencyListLength: 0,
dailyListLength: 0,
}; };
}, },
onLoad() { onLoad() {
this.menu = uni.getMenuButtonBoundingClientRect() this.menu = uni.getMenuButtonBoundingClientRect()
let currentService = uni.getStorageSync('currentService') let currentService = uni.getStorageSync('currentService')
// currentService
if (currentService && (currentService.Serverpart_ID || currentService.SERVERPART_ID)) {
this.handleGetServerpartDetail(currentService.Serverpart_ID || currentService.SERVERPART_ID) this.handleGetServerpartDetail(currentService.Serverpart_ID || currentService.SERVERPART_ID)
this.handleGetCurrentServiceAttendanceData(currentService.SERVERPART_NAME) this.handleGetCurrentServiceAttendanceData(currentService.SERVERPART_NAME)
this.handleGetEventsData(currentService.SERVERPART_NAME)
} else {
console.warn('onLoad: currentService 为空或无效')
//
}
}, },
onShow() { onShow() {
let currentService = uni.getStorageSync('currentService') let currentService = uni.getStorageSync('currentService')
console.log('currentService', currentService); console.log('currentService', currentService);
if (currentService.Serverpart_ID !== this.serviceInfo.SERVERPART_ID && !this.isFirst) { // currentService
this.handleGetServerpartDetail(currentService.Serverpart_ID) if (!currentService || (!currentService.Serverpart_ID && !currentService.SERVERPART_ID)) {
this.handleGetCurrentServiceAttendanceData(currentService.SERVERPART_NAME) console.warn('currentService 为空或无效,跳过更新');
this.isFirst = false;
return;
}
// ID
const currentServiceId = currentService.Serverpart_ID || currentService.SERVERPART_ID;
const currentServiceName = currentService.SERVERPART_NAME;
//
if (currentServiceId && currentServiceId !== this.serviceInfo.SERVERPART_ID && !this.isFirst) {
this.emergencyListLength = 0
this.dailyListLength = 0
this.handleGetServerpartDetail(currentServiceId);
this.handleGetCurrentServiceAttendanceData(currentServiceName);
this.handleGetEventsData(currentServiceName)
} else { } else {
this.isFirst = false this.isFirst = false;
} }
}, },
methods: { methods: {
//
async handleGetEventsData(saName) {
const req = {
bsessionKey: "EA65F66FA29B47FD8072A4AFC66967B3",
saName: saName || this.serviceInfo.SERVERPART_NAME
}
console.log('reqreq', req);
const data = await new Promise((resolve, reject) => {
uni.request({
url: "https://fwqznxj.yciccloud.com:9081/ynjt/pushManage/queryEmergency",
method: "POST",
data: req,
header: {
"content-type": "application/x-www-form-urlencoded",
},
success(res) {
resolve(res.data.data)
},
});
});
let emergencyList = data
const req2 = {
bsessionKey: "0DAF3A5982D54A619D4B63A34CA20C55",
saName: saName || this.serviceInfo.SERVERPART_NAME
}
const data2 = await new Promise((resolve, reject) => {
uni.request({
url: "https://fwqznxj.yciccloud.com:9081/ynjt/pushManage/queryQuestions",
method: "POST",
data: req2,
header: {
"content-type": "application/x-www-form-urlencoded",
},
success(res) {
resolve(res.data.data)
},
});
});
let dailyList = data2
console.log('emergencyListemergencyListemergencyList', emergencyList);
console.log('dailyListdailyListdailyListdailyListdailyList', dailyList);
this.emergencyListLength = emergencyList && emergencyList.length > 0 ? emergencyList.length : "0"
this.dailyListLength = dailyList && dailyList.length > 0 ? dailyList.length : "0"
},
// //
async handleGetCurrentServiceAttendanceData(SERVERPART_NAME) { async handleGetCurrentServiceAttendanceData(SERVERPART_NAME) {
//
if (!SERVERPART_NAME) {
console.warn('handleGetCurrentServiceAttendanceData: SERVERPART_NAME 为空,跳过请求');
return;
}
let req = { let req = {
bsessionKey: "0B30475A94674D608022885F7763959B", bsessionKey: "0B30475A94674D608022885F7763959B",
workTime: new Date(this.selectDate).getTime(), workTime: new Date(this.selectDate).getTime(),
@ -583,13 +668,19 @@ export default {
}, },
// //
async handleGetServerpartDetail(id) { async handleGetServerpartDetail(id) {
// ID
if (!id) {
console.warn('handleGetServerpartDetail: id 为空,跳过请求');
return;
}
let currentService = uni.getStorageSync("currentService"); let currentService = uni.getStorageSync("currentService");
let seatInfo = uni.getStorageSync("seatInfo"); let seatInfo = uni.getStorageSync("seatInfo");
this.seatInfo = JSON.parse(seatInfo); this.seatInfo = JSON.parse(seatInfo || '{}');
let req = { let req = {
ServerpartId: id || currentService.Serverpart_ID || currentService.SERVERPART_ID, ServerpartId: id,
latitude: this.seatInfo.latitude, latitude: this.seatInfo.latitude || 0,
longitude: this.seatInfo.longitude, longitude: this.seatInfo.longitude || 0,
}; };
console.log('req', req); console.log('req', req);
@ -597,8 +688,8 @@ export default {
title: "加载中...", title: "加载中...",
}); });
const data = await request.$webJavaGet( const data = await request.$webGet(
"/third-party/getServerPartInfo", "/CommercialApi/BaseInfo/GetServerpartInfo",
req req
); );
uni.hideLoading(); uni.hideLoading();
@ -644,10 +735,12 @@ export default {
}); });
}, },
// //
handleChangeTime(e) { async handleChangeTime(e) {
console.log('e', e); console.log('e', e);
// this.selectDate = e.detail.value // this.selectDate = e.detail.value
this.selectDate = e.fulldate this.selectDate = e.fulldate
await this.handleGetCurrentServiceAttendanceData(this.serviceInfo.SERVERPART_NAME)
}, },
// tab // tab
handleChangeTab(e) { handleChangeTab(e) {
@ -673,10 +766,9 @@ export default {
this.$util.toNextRoute('navigateTo', `/pages/summaryOfPortraits/index?index=0`) this.$util.toNextRoute('navigateTo', `/pages/summaryOfPortraits/index?index=0`)
} else if (value === 3) { } else if (value === 3) {
this.$util.toNextRoute('navigateTo', `/pages/attendanceStatus/attendanceStatistics`) this.$util.toNextRoute('navigateTo', `/pages/attendanceStatus/attendanceStatistics`)
} else if (value === 5) {
this.$util.toNextRoute('navigateTo', `/pages/attendanceStatus/roster`)
} }
// else if (value === 5) {
// this.$util.toNextRoute('navigateTo', `/pages/attendanceStatus/roster`)
// }
}, },
// //
viewStaffDetails(obj) { viewStaffDetails(obj) {
@ -771,10 +863,12 @@ export default {
.uni-input { .uni-input {
padding: 0; padding: 0;
background: transparent; background: transparent;
font-size: 28rpx; font-size: 14px;
font-family: PingFangSC-Semibold, PingFang SC; font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600; font-weight: 600;
color: #160002; color: #160002;
line-height: 50rpx;
height: 50rpx;
} }
.area { .area {
@ -957,7 +1051,7 @@ export default {
padding: 0 32rpx; padding: 0 32rpx;
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 50rpx; gap: 16rpx;
margin-top: 24rpx; margin-top: 24rpx;
.personItem { .personItem {
@ -1000,7 +1094,7 @@ export default {
padding: 0 32rpx; padding: 0 32rpx;
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 50rpx; gap: 16rpx;
margin-top: 24rpx; margin-top: 24rpx;
.emergency-banner { .emergency-banner {

View File

@ -22,34 +22,81 @@
</view> </view>
</view> </view>
<view class="rosterContent"> <view class="rosterContent">
<view class="rosterContentTop"> <!-- 月份和员工选择器 -->
<view> <view class="selectorRow">
<picker> <view class="dateBox">
{{ selectPerson || "-" }}
</picker>
</view>
<!-- 居中的日历时间 -->
<!-- <view class="dateBox">
<view class="centerDateBox"> <view class="centerDateBox">
<image class="arrowIcon" src="https://eshangtech.com/cyy_DIB/leftArrowIcon.png" <image class="arrowIcon" src="https://eshangtech.com/cyy_DIB/leftArrowIcon.png"
@click="handleChangeDate(2)" /> @click="handleChangeDate(2)" />
<view class="center"> <view class="center">
<text class="date-text">{{ selectDate ? $util.cutDate(new Date(selectDate), 'YYYY-MM') : "" <text class="date-text">{{ selectDate ? $util.cutDate(new Date(selectDate), 'YYYY-MM') :
""
}}</text> }}</text>
<!-- <text class="date-icon">📅</text> -->
</view> </view>
<image class="arrowIcon" src="https://eshangtech.com/cyy_DIB/rightArrowIcon.png" <image class="arrowIcon" src="https://eshangtech.com/cyy_DIB/rightArrowIcon.png"
@click="handleChangeDate(1)" /> @click="handleChangeDate(1)" />
</view> </view>
</view> -->
</view> </view>
<view class="calendarBpx">
<uni-calendar ref="calendar" class="selectDateCalendar" :insert="true" :startDate="info.startDate" <!-- 员工选择器 -->
:selected="selectedList" /> <view class="employeeSelector">
<picker @change="handleEmployeeChange" :value="selectedEmployeeIndex" :range="userList"
:range-key="'userName'">
<view class="employeePickerBox">
<view class="selectedEmployee">{{ userList[selectedEmployeeIndex] ?
userList[selectedEmployeeIndex].userName :
'请选择员工' }}
</view>
<image class="rightArrow"
src="https://eshangtech.com/ShopICO/ahyd-BID/commercial/rightArrow.svg"></image>
</view>
</picker>
</view>
</view>
<!-- 员工信息 -->
<view v-if="selectedEmployee" class="employeeDetail">
<view class="employeeCard">
<view class="employeeInfo">
<view class="employeeName">{{ selectedEmployee.userName }}</view>
<view class="employeeJob">{{ selectedEmployee.psnJob }}</view>
<image class="phoneIcon" src="https://eshangtech.com/cyy_DIB/phoneIcon.png" />
<view class="employeePhone">{{ selectedEmployee.phone }}</view>
</view>
</view>
</view>
<!-- 日历格式排班表 -->
<view v-if="selectedEmployee" class="calendarRoster">
<view class="weekHeader">
<view v-for="(weekName, index) in weekNames" :key="index" class="weekHeaderItem"
:class="{ 'weekend': index === 0 || index === 6 }">
{{ weekName }}
</view>
</view>
<view class="calendarGrid">
<view v-for="i in firstDayOfWeek" :key="`empty-${i}`" class="calendarCell empty"></view>
<view v-for="day in monthDays" :key="day.date" class="calendarCell" :class="{
'weekend': day.isWeekend,
'today': day.isToday
}">
<view class="dateNumber">{{ day.day }}</view>
<view class="scheduleInfo" :class="{
'work': selectedEmployee && selectedEmployee[`day${day.day}`] && !selectedEmployee[`day${day.day}`].toString().toLowerCase().includes('休'),
'rest': selectedEmployee && selectedEmployee[`day${day.day}`] && selectedEmployee[`day${day.day}`].toString().toLowerCase().includes('休'),
'empty': !selectedEmployee || !selectedEmployee[`day${day.day}`]
}">
{{ selectedEmployee && selectedEmployee[`day${day.day}`] ?
(selectedEmployee[`day${day.day}`].toString().toLowerCase().includes('休') ? '休' : '班') : ''
}}
</view>
</view>
</view>
</view> </view>
</view> </view>
@ -59,55 +106,109 @@
<script> <script>
export default { export default {
data() { data() {
const now = new Date()
const currentYear = now.getFullYear()
const currentMonthIndex = now.getMonth()
const nowDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD') // const nowDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD') //
return { return {
menu: {}, menu: {},
serviceInfo: {},
selectDate: nowDay,// selectDate: nowDay,//
selectPerson: "张三", serviceInfo: {},
selectedList: [ currentYear: currentYear,
{ currentMonth: currentMonthIndex,
date: '2025-08-11', selectedEmployeeIndex: 0,
info: "班", selectedEmployee: null,
}, weekNames: ['日', '一', '二', '三', '四', '五', '六'],
{ // 使
date: '2025-08-12', rosterData: [],
info: "班", userList: [],//
color: "#000" selectUser: "",//
}, isFirst: true,
{ monthDays: [],
date: '2025-08-13', firstDayOfWeek: ""
info: "班",
},
{
date: '2025-08-14',
info: "班",
},
{
date: '2025-08-15',
info: "班"
},
{
date: '2025-08-16',
info: "休",
},
{
date: '2025-08-17',
info: "休",
},
{
date: '2025-08-18',
info: "班",
}
]
} }
}, },
computed: {
// (0=, 1=, ..., 6=)
// firstDayOfWeek() {
// const firstDay = new Date(this.currentYear, this.currentMonth, 1)
// return firstDay.getDay()
// }
},
onLoad() { onLoad() {
this.menu = uni.getMenuButtonBoundingClientRect() this.menu = uni.getMenuButtonBoundingClientRect()
let currentService = uni.getStorageSync('currentService') let currentService = uni.getStorageSync('currentService')
this.serviceInfo = currentService this.serviceInfo = currentService
this.handleGetNewMonthData()
//
this.loadRosterData(currentService.SERVERPART_NAME)
},
onShow() {
let currentService = uni.getStorageSync('currentService')
console.log('currentService', currentService);
// currentService
if (!currentService || (!currentService.Serverpart_ID && !currentService.SERVERPART_ID)) {
console.warn('currentService 为空或无效,跳过更新');
this.isFirst = false;
return;
}
// ID
const currentServiceId = currentService.Serverpart_ID || currentService.SERVERPART_ID;
const currentServiceName = currentService.SERVERPART_NAME;
//
if (currentServiceId && currentServiceId !== this.serviceInfo.SERVERPART_ID && !this.isFirst) {
this.serviceInfo = currentService
this.rosterData = []
this.userList = []
this.selectUser = null
this.loadRosterData(currentServiceName)
} else {
this.isFirst = false;
}
}, },
methods: { methods: {
handleGetNewMonthData() {
const year = this.currentYear
const month = this.currentMonth
console.log('yearyearyear', year);
console.log('monthmonthmonthmonth', month);
const daysInMonth = new Date(year, month + 1, 0).getDate()
const today = new Date()
const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`
const days = []
const weekTexts = ['日', '一', '二', '三', '四', '五', '六']
for (let day = 1; day <= daysInMonth; day++) {
const date = new Date(year, month, day)
const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`
const weekDay = date.getDay()
days.push({
day: day,
date: dateStr,
weekDay: weekDay,
weekText: weekTexts[weekDay],
isWeekend: weekDay === 0 || weekDay === 6,
isToday: dateStr === todayStr
})
}
this.monthDays = days
const firstDay = new Date(this.currentYear, this.currentMonth, 1)
this.firstDayOfWeek = firstDay.getDay()
},
handleChangeService() {
this.$util.toNextRoute("navigateTo", "/pages/map/index?type=attendanceStatus");
},
// //
async handleChangeDate(type) { async handleChangeDate(type) {
// type 1 2 // type 1 2
@ -126,7 +227,91 @@ export default {
const d = String(last.getDate()).padStart(2, '0'); const d = String(last.getDate()).padStart(2, '0');
this.selectDate = `${y}-${m}-${d}`; this.selectDate = `${y}-${m}-${d}`;
// currentMonth0-11
this.currentYear = y
this.currentMonth = last.getMonth() // 使
this.handleGetNewMonthData()
this.handleGetCurrentUserScheduleInfo()
}, },
//
handleBack() {
uni.navigateBack()
},
//
handleEmployeeChange(e) {
console.log('eee', e);
this.selectedEmployeeIndex = Number(e.detail.value)
this.selectUser = this.userList && this.userList.length > 0 ? this.userList[this.selectedEmployeeIndex] : ""
this.handleGetCurrentUserScheduleInfo()
},
//
async loadRosterData(SERVERPART_NAME) {
//
let req = {
bsessionKey: "0B30475A94674D608022885F7763959B",
workTime: new Date(this.selectDate).getTime(),
saName: SERVERPART_NAME || "",//
phone: "",//
}
uni.showLoading({
title: "加载中..."
})
const data = await new Promise((resolve, reject) => {
uni.request({
url: "https://fwqznxj.yciccloud.com:9081/ynjt/pushManage/queryUserSchedule",
method: "POST",
data: req,
header: {
"content-type": "application/x-www-form-urlencoded",
},
success(res) {
resolve(res.data.data)
},
});
});
uni.hideLoading()
console.log('人员列表', data);
this.userList = data
this.selectedEmployeeIndex = 0
this.selectUser = data && data.length > 0 ? data[0] : ""
console.log('this.selectUserthis.selectUserthis.selectUser', this.selectUser);
await this.handleGetCurrentUserScheduleInfo()
},
//
async handleGetCurrentUserScheduleInfo() {
this.selectedEmployee = null
let req = {
bsessionKey: "20ED2B50179D4877853C4DED45D8179E",
date: new Date(this.selectDate).getTime(),
phone: this.selectUser.phone
}
const data = await new Promise((resolve, reject) => {
uni.request({
url: "https://fwqznxj.yciccloud.com:9081/ynjt/pushManage/queryWorkDetails",
method: "POST",
data: req,
header: {
"content-type": "application/x-www-form-urlencoded",
},
success(res) {
resolve(res.data.data)
},
});
});
console.log('datadatadatadatadata', data);
this.selectedEmployee = data[0]
}
} }
} }
</script> </script>
@ -143,7 +328,6 @@ export default {
@warn: #ff9f43; @warn: #ff9f43;
@danger: #ff4757; @danger: #ff4757;
.main { .main {
width: 100vw; width: 100vw;
min-height: 100vh; min-height: 100vh;
@ -158,7 +342,6 @@ export default {
left: 0; left: 0;
top: 0; top: 0;
width: 100vw; width: 100vw;
// background: #fff;
background-image: url("https://eshangtech.com/minTestImg/pageBg.png"); background-image: url("https://eshangtech.com/minTestImg/pageBg.png");
z-index: 99; z-index: 99;
display: flex; display: flex;
@ -170,7 +353,6 @@ export default {
width: 100%; width: 100%;
height: 24px; height: 24px;
position: absolute; position: absolute;
// left: 16px;
z-index: 99999999999; z-index: 99999999999;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
@ -219,31 +401,12 @@ export default {
color: #160002; color: #160002;
} }
.area {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #786B6C;
line-height: 40px;
margin-left: 4px;
}
.rightArrow { .rightArrow {
width: 12px; width: 12px;
height: 12px; height: 12px;
} }
.noticeText {
font-size: 24rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
color: #B6BACB;
line-height: 40rpx;
white-space: nowrap;
} }
} }
}
} }
} }
} }
@ -253,18 +416,20 @@ export default {
width: 100%; width: 100%;
background-color: #fff; background-color: #fff;
box-sizing: border-box; box-sizing: border-box;
padding: 0 24rpx; padding: 0 24rpx 8rpx;
border-radius: 8rpx; border-radius: 8rpx;
.rosterContentTop { /* 选择器行布局 */
width: 100%; .selectorRow {
display: flex; display: flex;
gap: 24rpx;
padding: 24rpx 0;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
}
.dateBox { .dateBox {
box-sizing: border-box; box-sizing: border-box;
padding: 16rpx 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -273,7 +438,6 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10rpx; gap: 10rpx;
padding: 10rpx 20rpx;
border-radius: 30rpx; border-radius: 30rpx;
background-color: #fff; background-color: #fff;
// border: 2rpx solid #27B35F; // border: 2rpx solid #27B35F;
@ -293,52 +457,169 @@ export default {
} }
} }
/* 员工选择器 */
.employeeSelector {
.employeePickerBox {
display: flex;
align-items: center;
justify-content: space-between;
// padding: 20rpx 24rpx;
// background: #f8f9fa;
border-radius: 30rpx;
// border: 2rpx solid #e0e0e0;
.selectedEmployee {
font-size: 24rpx;
font-weight: 400;
color: #000;
margin-right: 8rpx;
} }
.calendarBpx { .rightArrow {
/deep/ .uni-calendar-item__weeks-box-item { width: 26rpx;
width: calc(100% / 7); height: 26rpx;
}
.uni-calendar-item__weeks-box-circle {
display: none;
} }
} }
/deep/ .uni-calendar-item--checked { /* 员工信息卡片 */
background-color: transparent; .employeeDetail {
color: #000 !important; margin-bottom: 32rpx;
opacity: 1 !important;
.employeeCard {
background: #fff;
border-radius: 12rpx;
padding: 16rpx 24rpx;
box-shadow: @shadow;
.employeeInfo {
display: flex;
align-items: center;
.employeeName {
font-size: 28rpx;
font-weight: 600;
color: #333;
margin-right: 24rpx;
} }
/deep/ .uni-calendar-item--isDay { .employeeJob {
background-color: transparent; font-size: 24rpx;
color: #000 !important; color: @primary;
opacity: 1 !important; background: rgba(39, 178, 95, 0.1);
padding: 0 16rpx;
border-radius: 20rpx;
margin-right: 24rpx;
} }
/deep/ .uni-calendar-item--isDay-text { .phoneIcon {
white-space: nowrap; width: 24rpx;
height: 24rpx;
margin-right: 8rpx;
}
.employeePhone {
font-size: 24rpx;
color: #666;
}
}
}
}
/* 日历格式排班表 */
.calendarRoster {
background: #fff;
border-radius: 12rpx;
// padding: 32rpx;
box-shadow: @shadow;
margin-bottom: 32rpx;
/* 星期标题 */
.weekHeader {
display: flex;
border-bottom: 2rpx solid #e0e0e0;
// margin-bottom: 16rpx;
.weekHeaderItem {
flex: 1;
text-align: center;
padding: 16rpx 0;
font-size: 28rpx;
font-weight: 600;
color: #333;
&.weekend {
color: @danger;
}
}
}
/* 日历网格 */
.calendarGrid {
display: flex;
flex-wrap: wrap;
width: 100%;
.calendarCell {
width: 14.28%;
height: 120rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 1rpx solid #f0f0f0;
box-sizing: border-box;
position: relative;
&.empty {
background-color: #fafafa;
}
&.today {
background-color: rgba(39, 178, 95, 0.1);
border: 2rpx solid @primary;
}
&.weekend {
.dateNumber {
// color: @danger;
}
}
.dateNumber {
font-size: 24rpx;
font-weight: 500;
color: #333;
margin-bottom: 4rpx;
}
.scheduleInfo {
font-size: 24rpx;
padding: 2rpx 4rpx;
border-radius: 4rpx;
font-weight: 500;
text-align: center;
line-height: 1;
&.work {
// background-color: #333;
color: #000; color: #000;
} }
/deep/ .uni-calendar__backtoday { &.rest {
display: none; // background-color: #f5f5f5;
// color: #999;
color: red;
} }
/* === info 文字颜色控制 === */ &.empty {
.selectDateCalendar ::v-deep .uni-calendar__info { visibility: hidden;
color: #000 !important; }
/* 默认黑色 */ }
} }
/* 如果 info 等于“休”,文字改为红色 */
.selectDateCalendar ::v-deep .uni-calendar__info[title="休"],
.selectDateCalendar ::v-deep .uni-calendar__info[data-info="休"] {
color: red !important;
} }
} }
} }
} }

View File

@ -228,8 +228,8 @@
</view> </view>
<view class="revenueMoney"> <view class="revenueMoney">
<NumberScroll v-if="currentMoney" :number="currentMoney" /> <!-- <NumberScroll v-if="currentMoney" :number="currentMoney" /> -->
<!-- <text class="moneyText">{{currentMoney}}</text>--> <text class="moneyText">{{ currentMoney }}</text>
<text class="moneyLabel">实时对客销售/</text> <text class="moneyLabel">实时对客销售/</text>
</view> </view>
</view> </view>
@ -616,7 +616,8 @@ export default {
StatisticsDate: this.nowDay, StatisticsDate: this.nowDay,
}; };
const res = await request.$webGet("CommercialApi/Revenue/GetCurRevenue", req) const res = await request.$webGet("CommercialApi/Revenue/GetCurRevenue", req)
this.currentMoney = res.Result_Data.CurRevenueAmount.toFixed(2); // this.currentMoney = res.Result_Data.CurRevenueAmount.toFixed(2);
this.currentMoney = res.Result_Data.CurRevenueAmount.toLocaleString('zh-CN')
}, },
// //
@ -1249,14 +1250,18 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-top: 24rpx; // margin-top: 24rpx;
margin-top: 4rpx;
.moneyText { .moneyText {
font-size: 44rpx; display: inline-flex;
font-family: DINAlternate-Bold, DINAlternate; font-family: DINAlternate-Bold, DINAlternate;
font-weight: bold; font-weight: bold;
font-size: 36rpx;
color: #160002; color: #160002;
margin-right: 8rpx; line-height: 40rpx;
text-align: right;
font-style: normal;
} }
.moneyLabel { .moneyLabel {
@ -1267,7 +1272,6 @@ export default {
color: #a69e9f; color: #a69e9f;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
margin-bottom: 12rpx;
} }
} }

View File

@ -727,9 +727,10 @@ export default {
font-size: 12px; font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400; font-weight: 400;
color: #160002; color: #fff;
// color: #160002;
padding: 0 6px; padding: 0 6px;
background: #EAEAEA; background: #43C677;
border-radius: 2px; border-radius: 2px;
display: inline-block; display: inline-block;
width: 80rpx; width: 80rpx;

View File

@ -83,6 +83,7 @@
* @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
* @property {Array} selected 打点期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}] * @property {Array} selected 打点期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
* @property {Boolean} showMonth 是否选择月份为背景 * @property {Boolean} showMonth 是否选择月份为背景
* @property {Boolean} maskClosable = [true|false] 点击蒙层是否关闭日历默认为false
* @event {Function} change 日期改变`insert :ture` 时生效 * @event {Function} change 日期改变`insert :ture` 时生效
* @event {Function} confirm 确认选择`insert :false` 时生效 * @event {Function} confirm 确认选择`insert :false` 时生效
* @event {Function} monthSwitch 切换月份时触发 * @event {Function} monthSwitch 切换月份时触发
@ -131,6 +132,10 @@
clearDate: { clearDate: {
type: Boolean, type: Boolean,
default: true default: true
},
maskClosable: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -208,8 +213,13 @@
this.init(this.date) this.init(this.date)
}, },
methods: { methods: {
// 穿 //
clean() {}, clean() {
//
if (this.maskClosable) {
this.close();
}
},
bindDateChange(e) { bindDateChange(e) {
const value = e.detail.value + '-1' const value = e.detail.value + '-1'
this.setDate(value) this.setDate(value)