update
This commit is contained in:
parent
590499fb84
commit
a6692879e0
@ -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>
|
||||||
@ -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 {
|
||||||
|
|||||||
@ -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}`;
|
||||||
|
|
||||||
|
// 修复:currentMonth应该是数字类型(0-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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user