This commit is contained in:
parent
527d0ce3c1
commit
ad055f2554
|
|
@ -60,26 +60,26 @@ export const getPostTypeSelectListAPI = () => {
|
|||
// 获取标段工程下拉列表 ----- 携带查询条件的
|
||||
export function getLotProjectSelectListByConditionAPI(data) {
|
||||
return request({
|
||||
url: '/bmw/pmProject/listAll',
|
||||
method: 'GET',
|
||||
params: data,
|
||||
url: '/bmw/select/selectPro',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取分包商下拉列表 ----- 携带查询条件的
|
||||
export const getSubSelectListByConditionAPI = (data) => {
|
||||
return request({
|
||||
url: '/bmw/pmSub/listAll',
|
||||
method: 'GET',
|
||||
params: data,
|
||||
url: '/bmw/select/selectSub',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班组下拉列表 ----- 携带查询条件的
|
||||
export const getTeamSelectListByConditionAPI = (data) => {
|
||||
return request({
|
||||
url: '/bmw/pmSubTeam/listAll',
|
||||
method: 'GET',
|
||||
params: data,
|
||||
url: '/bmw/select/selectTeam',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<div class="attendance-calendar">
|
||||
<!-- 图例说明 -->
|
||||
<div class="legend" v-if="isShowLegend">
|
||||
<div class="legend">
|
||||
<div class="legend-item">
|
||||
<span class="legend-mark active"></span>
|
||||
<span>已打卡</span>
|
||||
|
|
@ -17,9 +16,9 @@
|
|||
</div>
|
||||
<!-- 循环展示每个月份的日历 -->
|
||||
<div
|
||||
v-for="(monthData, index) in monthDataList"
|
||||
:key="index"
|
||||
class="month-calendar"
|
||||
v-for="(monthData, index) in monthDataListNew"
|
||||
>
|
||||
<!-- 月份标题 -->
|
||||
<div class="calendar-header">
|
||||
|
|
@ -28,48 +27,32 @@
|
|||
|
||||
<!-- 星期标题 -->
|
||||
<div class="week-days">
|
||||
<div class="week-day" v-for="day in weekDays" :key="day">{{
|
||||
day
|
||||
}}</div>
|
||||
<div class="week-day" v-for="day in weekDays" :key="day">
|
||||
{{ day }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 日历主体 -->
|
||||
<div class="calendar-grid">
|
||||
<!-- 空白占位(月初) -->
|
||||
<div
|
||||
class="calendar-day empty"
|
||||
:key="'empty-start-' + i"
|
||||
v-for="(empty, i) in getFirstMonthEmptyDays(monthData)"
|
||||
v-for="(empty, i) in monthData.emptyStartDays"
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- 本月日期 -->
|
||||
<div
|
||||
:key="day"
|
||||
:key="day.dayIndex"
|
||||
class="calendar-day current-month"
|
||||
v-for="day in getDaysInMonth(monthData)"
|
||||
:class="getDayClass(monthData, day)"
|
||||
:class="getDayClass(day)"
|
||||
v-for="day in monthData.currentMonthDays"
|
||||
>
|
||||
<span class="day-number">{{ day }}</span>
|
||||
<!-- 当isActive为1时显示复选框 -->
|
||||
<!-- <el-checkbox
|
||||
v-if="getDayInfo(monthData, day)?.isActive === 1"
|
||||
class="day-checkbox"
|
||||
v-model="
|
||||
checkedDays[
|
||||
`${monthData.year}-${monthData.month}-${day}`
|
||||
]
|
||||
"
|
||||
@change="handleCheckboxChange(monthData, day, $event)"
|
||||
></el-checkbox> -->
|
||||
|
||||
<el-checkbox v-model="checked" />
|
||||
<span class="day-number">{{ day.dayIndex }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 空白占位(月末) -->
|
||||
<div
|
||||
class="calendar-day empty"
|
||||
v-for="(empty, i) in getLastMonthEmptyDays(monthData)"
|
||||
v-for="(empty, i) in monthData.emptyEndDays"
|
||||
:key="'empty-end-' + i"
|
||||
>
|
||||
</div>
|
||||
|
|
@ -82,16 +65,16 @@
|
|||
export default {
|
||||
name: 'AttendanceCalendar',
|
||||
props: {
|
||||
// 月份数据列表
|
||||
monthDataList: {
|
||||
// 时间范围
|
||||
timeRange: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
required: true,
|
||||
},
|
||||
|
||||
isShowLegend: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
// 考勤列表
|
||||
attendanceList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
|
|
@ -99,12 +82,10 @@ export default {
|
|||
weekDays: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
checkedDays: {}, // 存储复选框状态
|
||||
checked: false,
|
||||
monthDataListNew: [], // 日历的月份数据
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 初始化复选框状态
|
||||
this.initCheckedDays()
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 初始化复选框状态
|
||||
initCheckedDays() {
|
||||
|
|
@ -118,11 +99,110 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
// 初始化日历
|
||||
initCalendar(timeRange) {
|
||||
const startMonth = timeRange[0].split('-')[1]
|
||||
const endMonth = timeRange[1].split('-')[1]
|
||||
const year = timeRange[0].split('-')[0]
|
||||
|
||||
this.monthDataListNew = []
|
||||
|
||||
if (startMonth !== endMonth) {
|
||||
this.monthDataListNew.push({
|
||||
month: startMonth,
|
||||
year,
|
||||
emptyStartDays: this.getFirstMonthEmptyDays({
|
||||
month: startMonth,
|
||||
year,
|
||||
}),
|
||||
emptyEndDays: this.getLastMonthEmptyDays({
|
||||
month: startMonth,
|
||||
year,
|
||||
}),
|
||||
currentMonthDays: this.getDaysInMonthNew({
|
||||
month: startMonth,
|
||||
year,
|
||||
}),
|
||||
})
|
||||
this.monthDataListNew.push({
|
||||
month: endMonth,
|
||||
year,
|
||||
emptyStartDays: this.getFirstMonthEmptyDays({
|
||||
month: endMonth,
|
||||
year,
|
||||
}),
|
||||
emptyEndDays: this.getLastMonthEmptyDays({
|
||||
month: endMonth,
|
||||
year,
|
||||
}),
|
||||
currentMonthDays: this.getDaysInMonthNew({
|
||||
month: endMonth,
|
||||
year,
|
||||
}),
|
||||
})
|
||||
} else {
|
||||
this.monthDataListNew.push({
|
||||
month: startMonth,
|
||||
year,
|
||||
emptyStartDays: this.getFirstMonthEmptyDays({
|
||||
month: startMonth,
|
||||
year,
|
||||
}),
|
||||
emptyEndDays: this.getLastMonthEmptyDays({
|
||||
month: startMonth,
|
||||
year,
|
||||
}),
|
||||
currentMonthDays: this.getDaysInMonthNew({
|
||||
month: startMonth,
|
||||
year,
|
||||
}),
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 设置考勤列表信息
|
||||
initAttendanceList(attendanceList) {
|
||||
if (attendanceList.length > 0) {
|
||||
attendanceList.forEach((item) => {
|
||||
const year = item.einDay.split('-')[0]
|
||||
const month = item.einDay.split('-')[1]
|
||||
|
||||
this.monthDataListNew.forEach((j) => {
|
||||
if (j.year == year && j.month == month) {
|
||||
j.currentMonthDays.forEach((k) => {
|
||||
if (k.zeroIndex == item.einDay.split('-')[2]) {
|
||||
k.isAtt = item.isAtt
|
||||
k.isRepair = item.isRepair
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 获取指定月份的天数
|
||||
getDaysInMonth(monthData) {
|
||||
const year = parseInt(monthData.year)
|
||||
const month = parseInt(monthData.month)
|
||||
return new Date(year, month, 0).getDate()
|
||||
const days = new Date(year, month, 0).getDate()
|
||||
return days
|
||||
},
|
||||
|
||||
getDaysInMonthNew(monthData) {
|
||||
const year = parseInt(monthData.year)
|
||||
const month = parseInt(monthData.month)
|
||||
const days = new Date(year, month, 0).getDate()
|
||||
const dayList = []
|
||||
for (let i = 1; i <= days * 1; i++) {
|
||||
dayList.push({
|
||||
dayIndex: i,
|
||||
isAtt: null,
|
||||
isRepair: false,
|
||||
zeroIndex: i > 10 ? i : `0${i}`,
|
||||
})
|
||||
}
|
||||
return dayList
|
||||
},
|
||||
|
||||
// 获取月份第一天是星期几
|
||||
|
|
@ -136,10 +216,11 @@ export default {
|
|||
getFirstMonthEmptyDays(monthData) {
|
||||
return this.getFirstDayOfMonth(monthData)
|
||||
},
|
||||
|
||||
// 计算月末需要的空白格子数量
|
||||
getLastMonthEmptyDays(monthData) {
|
||||
console.log(monthData, 'monthData----')
|
||||
const totalDays = this.getDaysInMonth(monthData)
|
||||
|
||||
const lastDay = new Date(
|
||||
parseInt(monthData.year),
|
||||
parseInt(monthData.month) - 1,
|
||||
|
|
@ -148,46 +229,29 @@ export default {
|
|||
return 6 - lastDay
|
||||
},
|
||||
|
||||
// 获取某天的信息
|
||||
getDayInfo(monthData, day) {
|
||||
const dayStr = String(day).padStart(2, '0')
|
||||
return monthData.day.find((item) => item.dayIndex === dayStr)
|
||||
},
|
||||
|
||||
// 获取某天的样式类
|
||||
getDayClass(monthData, day) {
|
||||
const dayInfo = this.getDayInfo(monthData, day)
|
||||
|
||||
// 如果没有该天的数据,默认为非考勤范围
|
||||
if (!dayInfo) {
|
||||
return 'not-in-range'
|
||||
}
|
||||
|
||||
return {
|
||||
'not-in-range': !dayInfo.isRange,
|
||||
active: dayInfo.isActive === 1,
|
||||
inactive: dayInfo.isActive === 0,
|
||||
}
|
||||
},
|
||||
|
||||
// 处理复选框变化
|
||||
handleCheckboxChange(monthData, day, checked) {
|
||||
const dayStr = String(day).padStart(2, '0')
|
||||
this.$emit('checkbox-change', {
|
||||
year: monthData.year,
|
||||
month: monthData.month,
|
||||
day: dayStr,
|
||||
checked,
|
||||
})
|
||||
getDayClass(day) {
|
||||
if (!day.isRepair && day.isAtt === 0) return 'inactive'
|
||||
if (day.isRepair && day.isAtt === 1) return 'active'
|
||||
if (!day.isRepair) return 'is-no-att'
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
// 当月份数据变化时重新初始化复选框
|
||||
monthDataList: {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.initCheckedDays()
|
||||
timeRange: {
|
||||
handler(newVal) {
|
||||
console.log(newVal, 'newVal')
|
||||
this.initCalendar(newVal)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
attendanceList: {
|
||||
handler(newVal) {
|
||||
this.initAttendanceList(newVal)
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -196,9 +260,9 @@ export default {
|
|||
<style scoped>
|
||||
.attendance-calendar {
|
||||
font-family: 'Arial', sans-serif;
|
||||
max-width: 700px;
|
||||
max-width: 90%;
|
||||
min-width: 460px;
|
||||
margin: 0 auto;
|
||||
|
||||
padding: 20px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
|
|
@ -241,7 +305,7 @@ export default {
|
|||
text-align: center;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
padding: 10px 0;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.calendar-grid {
|
||||
|
|
@ -304,8 +368,8 @@ export default {
|
|||
.legend {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
|
@ -320,23 +384,24 @@ export default {
|
|||
|
||||
.legend-mark {
|
||||
display: inline-block;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.legend-mark.active {
|
||||
background-color: #19be6b;
|
||||
/* border: 1px solid #4cd964; */
|
||||
}
|
||||
|
||||
.legend-mark.inactive {
|
||||
background-color: #f56c6c;
|
||||
/* border: 1px solid #ff3b30; */
|
||||
}
|
||||
|
||||
.legend-mark.not-in-range {
|
||||
background-color: #ff9900;
|
||||
/* border: 1px solid #ddd; */
|
||||
}
|
||||
|
||||
.is-no-att {
|
||||
background-color: #999;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
size="small"
|
||||
ref="queryFormRef"
|
||||
label-width="auto"
|
||||
:model="queryParams"
|
||||
>
|
||||
<el-form-item>
|
||||
<el-date-picker
|
||||
|
|
@ -17,7 +16,9 @@
|
|||
value-format="yyyy-MM-dd"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="开始日期"
|
||||
v-model="queryParams.timeRange"
|
||||
@change="onHandleChangeTime"
|
||||
v-model="timeRange"
|
||||
:picker-options="pickerOptions"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
|
@ -55,7 +56,10 @@
|
|||
<el-row :gutter="6">
|
||||
<!-- 左侧考勤日历 -->
|
||||
<el-col :span="12">
|
||||
<!-- <AttendanceCalendar /> -->
|
||||
<AttendanceCalendar
|
||||
:timeRange="timeRange"
|
||||
:attendanceList="attendanceList"
|
||||
/>
|
||||
</el-col>
|
||||
|
||||
<!-- 右侧考勤表格 -->
|
||||
|
|
@ -109,12 +113,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
// import AttendanceCalendar from '@/components/AttendanceCalendar'
|
||||
import AttendanceCalendar from '@/components/AttendanceCalendar'
|
||||
import { getAttendanceDetailsListAPI } from '@/api/construction-person/attendance-manage/attendance-count'
|
||||
export default {
|
||||
name: 'AttendanceDetails',
|
||||
components: {
|
||||
// AttendanceCalendar,
|
||||
AttendanceCalendar,
|
||||
},
|
||||
props: {
|
||||
teamId: {
|
||||
|
|
@ -132,12 +136,10 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
queryParams: {
|
||||
timeRange: [
|
||||
new Date().toISOString().split('T')[0],
|
||||
new Date().toISOString().split('T')[0],
|
||||
],
|
||||
},
|
||||
timeRange: [
|
||||
new Date().toISOString().split('T')[0],
|
||||
new Date().toISOString().split('T')[0],
|
||||
],
|
||||
attendanceList: [],
|
||||
tableColumns: [
|
||||
{
|
||||
|
|
@ -162,22 +164,42 @@ export default {
|
|||
t_props: 'deviceName',
|
||||
},
|
||||
],
|
||||
// 日期选择器配置
|
||||
pickerOptions: {
|
||||
disabledDate: (time) => {
|
||||
// 禁用今天之后的日期
|
||||
return time.getTime() > Date.now()
|
||||
},
|
||||
onPick: ({ maxDate, minDate }) => {
|
||||
// 当选择第一个日期后,设置第二个日期的可选范围
|
||||
this.pickerOptions.minDate = minDate
|
||||
if (minDate) {
|
||||
const maxRangeDate = new Date(minDate)
|
||||
maxRangeDate.setMonth(minDate.getMonth() + 1)
|
||||
this.pickerOptions.maxDate = maxRangeDate
|
||||
} else {
|
||||
this.pickerOptions.maxDate = null
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查询
|
||||
handleQuery() {
|
||||
console.log('查询')
|
||||
this.getAttendanceDetailsListData()
|
||||
},
|
||||
// 重置
|
||||
resetQuery() {
|
||||
this.queryParams.timeRange = []
|
||||
this.timeRange = [
|
||||
new Date().toISOString().split('T')[0],
|
||||
new Date().toISOString().split('T')[0],
|
||||
]
|
||||
|
||||
this.getAttendanceDetailsListData()
|
||||
},
|
||||
// 导出
|
||||
onHandleExportAttendanceDetails() {
|
||||
console.log('导出')
|
||||
},
|
||||
onHandleExportAttendanceDetails() {},
|
||||
|
||||
// 获取考勤详情列表
|
||||
async getAttendanceDetailsListData() {
|
||||
|
|
@ -185,12 +207,36 @@ export default {
|
|||
teamId: this.teamId,
|
||||
proId: this.proId,
|
||||
idNumber: this.idNumber,
|
||||
startDate: this.queryParams.timeRange[0],
|
||||
endDate: this.queryParams.timeRange[1],
|
||||
startDate: this.timeRange[0],
|
||||
endDate: this.timeRange[1],
|
||||
}
|
||||
const { rows: res } = await getAttendanceDetailsListAPI(params)
|
||||
this.attendanceList = res
|
||||
},
|
||||
|
||||
// 时间change事件
|
||||
onHandleChangeTime(e) {
|
||||
if (e && e.length === 2) {
|
||||
const [start, end] = e
|
||||
const startDate = new Date(start)
|
||||
const endDate = new Date(end)
|
||||
// 计算两个日期之间的天数差
|
||||
const diffTime = Math.abs(endDate - startDate)
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
|
||||
// 如果超过31天,自动调整结束日期
|
||||
if (diffDays > 31) {
|
||||
const newEndDate = new Date(startDate)
|
||||
newEndDate.setDate(startDate.getDate() + 31)
|
||||
this.timeRange = [
|
||||
start,
|
||||
newEndDate.toISOString().split('T')[0],
|
||||
]
|
||||
this.$message.warning(
|
||||
'选择的时间范围不能超过31天,已自动调整',
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
|
|
|
|||
|
|
@ -921,16 +921,7 @@ export default {
|
|||
},
|
||||
|
||||
// 入场工程列表
|
||||
proSelectList: [
|
||||
{
|
||||
label: '工程1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '工程2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
proSelectList: [],
|
||||
// 工种列表
|
||||
postSelectList: [],
|
||||
// 入场分包列表
|
||||
|
|
@ -1226,11 +1217,17 @@ export default {
|
|||
onChangeProId(val) {
|
||||
if (!val) {
|
||||
this.keyInfoForm.proName = ''
|
||||
this.keyInfoForm.subId = ''
|
||||
this.keyInfoForm.teamId = ''
|
||||
this.subSelectList = []
|
||||
this.teamSelectList = []
|
||||
return
|
||||
}
|
||||
this.keyInfoForm.proName = this.proSelectList.find(
|
||||
(item) => item.value === val,
|
||||
).label
|
||||
|
||||
this.getSubSelectList({ proId: val })
|
||||
},
|
||||
// 工种选择
|
||||
onChangePostId(val) {
|
||||
|
|
@ -1246,11 +1243,15 @@ export default {
|
|||
onChangeSubId(val) {
|
||||
if (!val) {
|
||||
this.keyInfoForm.subName = ''
|
||||
this.keyInfoForm.teamId = ''
|
||||
this.teamSelectList = []
|
||||
return
|
||||
}
|
||||
this.keyInfoForm.subName = this.subSelectList.find(
|
||||
(item) => item.value === val,
|
||||
).label
|
||||
|
||||
this.getTeamSelectList({ subId: val })
|
||||
},
|
||||
// 入场班组选择
|
||||
onChangeTeamId(val) {
|
||||
|
|
@ -1391,33 +1392,33 @@ export default {
|
|||
|
||||
// 获取标段工程下拉列表
|
||||
async getLotProjectSelectList() {
|
||||
const { rows: res } = await getLotProjectSelectListByConditionAPI(
|
||||
const { data: res } = await getLotProjectSelectListByConditionAPI(
|
||||
{},
|
||||
)
|
||||
this.proSelectList = res.map((item) => {
|
||||
return {
|
||||
value: item.id,
|
||||
label: item.proName,
|
||||
label: item.name,
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取分包下拉列表
|
||||
async getSubSelectList() {
|
||||
const { rows: res } = await getSubSelectListByConditionAPI({})
|
||||
async getSubSelectList(data) {
|
||||
const { data: res } = await getSubSelectListByConditionAPI(data)
|
||||
this.subSelectList = res.map((item) => {
|
||||
return {
|
||||
value: item.id,
|
||||
label: item.subName,
|
||||
label: item.name,
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取班组下拉列表
|
||||
async getTeamSelectList() {
|
||||
const { rows: res } = await getTeamSelectListByConditionAPI({})
|
||||
async getTeamSelectList(data) {
|
||||
const { data: res } = await getTeamSelectListByConditionAPI(data)
|
||||
this.teamSelectList = res.map((item) => {
|
||||
return {
|
||||
value: item.id,
|
||||
label: item.teamName,
|
||||
label: item.name,
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
@ -1449,8 +1450,6 @@ export default {
|
|||
}
|
||||
})
|
||||
|
||||
this.getSubSelectList()
|
||||
this.getTeamSelectList()
|
||||
this.getLotProjectSelectList()
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue