<template>
<BasicModal :defaultFullscreen="true" :title="modalTitle" destroyOnClose v-bind="$attrs" @ok="handleSubmit" @register="registerModal">
<!-- <BasicForm @register="registerForm" name="AttAttendanceFillForm" />-->
<a-row justify="center">
<a-col :span="20">
<h1 style="text-align: center; margin-bottom: 20px">{{ title }}</h1>
</a-col>
</a-row>
<a-spin :spinning="spinning" tip="加载中,请稍后.......">
<BasicTable @register="registerTable" @edit-change="onEditChange">
<template #tableTitle>
<a-button type="primary" @click="onAddUser">{{ t('common.addUser') }}</a-button>
</template>
<!--字段回显插槽-->
<template #bodyCell="{ column, record, index, text }">
<a-switch
v-if="column.dataIndex === 'isSecondQD'"
v-model:checked="record.isSecondQD"
:checkedValue="1"
:disabled="currentEditKeyRef && currentEditKeyRef === record.key"
:unCheckedValue="0"
size="small"
@change="handleIsOutsourceChange(record)" />
</template>
<!--操作栏-->
<template #action="{ record, column }">
<TableAction :actions="createActions(record, column)" />
</template>
</BasicTable>
</a-spin>
<!-- <a-divider v-if="bool">操作记录</a-divider>
<a-row v-if="bool">
<a-col :span="12">
<insert-record ref="insertRecordRef" :fill-id="record.id" />
</a-col>
<a-col :span="12">
<remove-record ref="removeRecordRef" :fill-id="record.id" />
</a-col>
</a-row>-->
<template #centerFooter>
<a-button v-if="isDetail" :loading="loading" type="primary" @click="getExportAttendanceDetail">{{ t('common.export') }}</a-button>
<a-button
v-if="record.submitStatus == 0 || record.submitStatus == 3 || record.submitStatus == 6"
:loading="loading"
type="primary"
@click="handleSuccessA">
{{ t('common.submitText') }}
</a-button>
</template>
</BasicModal>
<RepeatedlyFillModal @register="registerRepeatedlyFillModal" />
<AddUserModal ref="addUserModal" @register="registerAddUserModal" @success="handleSuccess" />
<UpdateRecordModal ref="updateRecordModal" @register="registerUpdateRecordModal" @success="handleUpdateRecordSuccess" />
<RejectedModal ref="rejectedModal" @register="registerRejectedModal" @success="handleRejectedSuccess" />
</template>
<script lang="ts" setup>
import { computed, ref, unref, watch } from 'vue'
import { BasicModal, useModal, useModalInner } from '/@/components/Modal'
import { addAttendance, check, deleteAttendance, updateAttendance } from '@/views/informationReview/departAttendanceReview/AttAttendanceFill.api'
import { exportAttendanceDetail, exportReportAttendanceView, getViewMap, submitAttendance, getHoliday } from '../attendanceManagement.api'
import { JVxeColumns, JVxeColumns1, JVxeColumns2 } from '@/views/informationReview/departAttendanceReview/AttAttendanceFill.data'
import AddUserModal from '@/views/informationReview/departAttendanceReview/components/AddUserTable.vue'
import UpdateRecordModal from '@/views/informationReview/departAttendanceReview/components/UpdateRecordModal.vue'
import RejectedModal from '@/views/informationReview/departAttendanceReview/components/RejectedModal.vue'
import dayjs from 'dayjs'
import { getDictItems } from '@/api/common/api'
import { JVxeTypes } from '@/components/jeecg/JVxeTable/types'
import { useMessage } from '/@/hooks/web/useMessage'
const { createMessage, createConfirm } = useMessage()
import { useGlobSetting } from '@/hooks/setting'
import { getFileAccessHttpUrl } from '@/utils/common/compUtils'
import { defHttp } from '@/utils/http/axios'
import { useI18n } from '/@/hooks/web/useI18n'
import RepeatedlyFillModal from '@/views/performance/attendanceManagementOut/components/RepeatedlyFillModal.vue'
import { ActionItem, BasicColumn, BasicTable, EditRecordRow, TableAction } from '@/components/Table'
import { useListPage } from '@/hooks/system/useListPage'
import { editServiceProvider, queryByServiceProvider } from '@/views/performance/attendanceManagementOut/attendanceManagement.api'
import { ServiceProviderDetailsColumn } from '@/views/performance/attendanceManagementOut/attendanceManagement.data'
import { cloneDeep } from 'lodash-es'
import { basisColumn, userType1Columns } from '@/views/performance/attendanceManagement/attendanceManagement.data'
const { t } = useI18n()
//注册model
const [registerAddUserModal, { openModal }] = useModal()
const [registerRepeatedlyFillModal, { openModal: openRepeatedlyFillModal }] = useModal()
const [registerRejectedModal, { openModal: openRejectedModal }] = useModal()
const [registerUpdateRecordModal, { openModal: openUpdateRecordModal }] = useModal()
// Emits声明
const emit = defineEmits(['register', 'success'])
const isUpdate = ref(true)
const isDetail = ref(false)
const loading = ref(false)
const spinning = ref(false)
const currentEditKeyRef = ref('')
const fillId = ref('')
const editingRowId = ref<string | null>(null)
const editClass = ref('')
const insertRecordRef = ref()
const updateRecordModal = ref()
const updateRecordCount = updateRecordModal.value?.totalRecord
const removeRecordRef = ref()
const tableRef = ref(null)
const record = ref({})
const apiData = ref([])
// 新增:定义响应式列配置
const dynamicColumns = ref<BasicColumn[]>([])
const departOptions = ref([])
const postOptions = ref([])
const isOnPlatformStateOptions = ref([])
const errorData = ref<Array<Object>>([])
const options = ref([
{
value: '0',
text: '√',
title: '√'
},
{
value: '9',
text: '—',
title: '—'
},
{
value: '-1',
//这里标题要加空格否则在下拉选时会显示-1
text: ` `,
title: ` `
}
])
// 动态计算列配置:编辑态与非编辑态
const tableColumns = computed(async () => {
const dynamicColumns = []
const base = [...basisColumn]
departOptions.value = await getDictItems('kf@NGQwYmY4Y2E2MjQ1NTQ5OTQ0YmM1MTEwNzY3ZTQ2NjBiNmUyOGU1MmU4MjMxMDFkNmYxNDkwN2U5MWM5MDViYg==')
postOptions.value = await getDictItems('kf@ZDRmYzkzZDdkYjFiNDAzN2IxZTAwNjViMTA3Zjc2ZDFjZGNmNGVlZTI4ZjgzNWRhNjJhOGJkOTM1MTFlNjY4YQ==')
const depart = {
dataIndex: 'originalDepart',
title: t('edu.departAttendanceReview.depart'),
width: 100,
align: 'center',
editRow: true,
editComponent: 'Select',
editComponentProps: {
options: departOptions
},
fixed: 'left'
}
//按照给的文件在序号列后添加部门列
base.splice(1, 0, depart)
const basisLeftColumn = [
{
dataIndex: 'originalPost',
title: t('edu.departAttendanceReview.originalPost'),
width: 100,
align: 'center',
editRow: true,
editComponent: 'Select',
editComponentProps: {
options: postOptions
},
fixed: 'left'
},
{
dataIndex: 'isSecondQD',
title: t('edu.departAttendanceReview.employeeType'),
width: 80,
align: 'center',
editRow: true,
editComponent: 'Switch',
editValueMap: (value) => {
return value ? 1 : 0
},
fixed: 'left'
}
]
//userType为1时动态添加的列
const type1Columns = []
//判断是平台还是纯二线科室
if (record.value.departType && record.value.departType == 1) {
const userType1Columns: BasicColumn = [
{ dataIndex: 'road', width: 80, title: t('edu.departAttendanceReview.road') },
{ dataIndex: 'wharf', width: 80, title: t('edu.departAttendanceReview.wharf') },
{ dataIndex: 'reform', width: 80, title: t('edu.departAttendanceReview.reform') },
{ dataIndex: 'production', width: 80, title: t('edu.departAttendanceReview.production') },
{ dataIndex: 'await1', width: 80, title: t('edu.departAttendanceReview.await1') },
{ dataIndex: 'other', width: 80, title: t('edu.departAttendanceReview.other') },
{ dataIndex: 'goAbroad1', width: 80, title: t('edu.departAttendanceReview.goAbroad1') },
{ dataIndex: 'goAbroad2', width: 80, title: t('edu.departAttendanceReview.goAbroad2') },
{
dataIndex: 'project',
title: t('edu.attendanceManagement.project'),
width: 80,
align: 'center',
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.project')}`
}
},
{
dataIndex: 'secondNight',
title: t('edu.attendanceManagement.secondNight'),
width: 80,
align: 'center',
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.secondNight')}`
}
},
{
dataIndex: 'extraWork',
title: t('edu.attendanceManagement.extraWork'),
width: 80,
align: 'center',
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.extraWork')}`
}
},
{
title: t('edu.attendanceManagement.allowance'),
dataIndex: 'allowance',
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.allowance')}`
}
},
{
title: t('edu.attendanceManagement.postCoefficient'),
dataIndex: 'postCoefficient',
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.postCoefficient')}`
}
},
{
title: t('edu.attendanceManagement.productionCoefficient'),
dataIndex: 'productionCoefficient',
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.productionCoefficient')}`
}
},
{
dataIndex: 'subsidy',
title: t('edu.attendanceManagement.subsidy'),
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.subsidy')}`
}
},
{
dataIndex: 'subsidyB',
title: t('edu.attendanceManagement.subsidyB'),
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.subsidyB')}`
}
},
//不一定要注释掉的字段????
/* {
dataIndex: 'competition',
title: t('edu.attendanceManagement.competition'),
width: 80,
align: 'center',
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.competition')}`
}
},*/
/* {
dataIndex: 'reissue',
title: t('edu.attendanceManagement.reissue'),
width: 80,
align: 'center',
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.reissue')}`
}
},
{
dataIndex: 'deduction',
title: t('edu.attendanceManagement.deduction'),
width: 80,
align: 'center',
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.deduction')}`
}
},*/
{
dataIndex: 'remark',
width: 80,
editRow: true,
title: t('edu.attendanceManagement.remark')
},
{
key: 'workDays',
title: t('edu.departAttendanceReview.workDays'),
width: 80,
align: 'center',
fixed: 'right'
}
]
type1Columns.push(...userType1Columns)
} else {
const userType2Columns = [
{
title: t('edu.attendanceManagement.allowance'),
dataIndex: 'allowance',
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.allowance')}`
}
},
{
title: t('edu.attendanceManagement.postCoefficient'),
dataIndex: 'postCoefficient',
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.postCoefficient')}`
}
},
{
title: t('edu.attendanceManagement.productionCoefficient'),
dataIndex: 'productionCoefficient',
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.productionCoefficient')}`
}
},
{
dataIndex: 'subsidy',
title: t('edu.attendanceManagement.subsidy'),
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.subsidy')}`
}
},
{
dataIndex: 'subsidyB',
title: t('edu.attendanceManagement.subsidyB'),
width: 80,
align: 'center',
editRow: true,
editComponent: 'InputNumber',
editComponentProps: {
placeholder: `请输入${t('edu.attendanceManagement.subsidyB')}`
}
}
]
type1Columns.push(...userType2Columns)
}
const month = record.value?.attendanceMonth
const days = dayjs(month).daysInMonth()
const daysColumn: BasicColumn[] = []
for (let i = 1; i <= days; i++) {
daysColumn.push({
title: `${i}`,
dataIndex: `dayValue${i}`,
align: 'center',
// 关键修改:动态宽度基于编辑状态
width: editingRowId.value ? 110 : 35,
editRow: true,
editComponent: 'Select',
editComponentProps: {
options: isOnPlatformStateOptions
}
})
}
dynamicColumns.push(...base, ...basisLeftColumn, ...daysColumn, ...type1Columns)
return dynamicColumns
})
// 修改:在状态变化时更新列配置
watch(
editingRowId,
() => {
dynamicColumns.value = [...tableColumns]
},
{ immediate: true }
)
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
spinning.value = true
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: false, okText: '提交', height: 600 })
isUpdate.value = !!data?.isUpdate
isDetail.value = data.record.submitStatus != 1 && data.record.submitStatus != 2 && data.record.submitStatus != 5
if (unref(isUpdate)) {
//表单赋值
record.value = data?.record
fillId.value = data?.record.id
const resOptions = await getDictItems('platformProduceState')
options.value.push(...resOptions)
isOnPlatformStateOptions.value = await getDictItems('isOnPlatformState')
apiData.value = await getViewMap({ fillId: record.value.id, isMainTable: 1 })
await handleFetchSuccess()
spinning.value = false
}
})
const { tableContext } = useListPage({
tableProps: {
dataSource: apiData,
searchInfo: {
fillId: fillId,
isMainTable: 1
},
scroll: { y: 400 },
//这里这样写是因为要动态添加列为了不污染原始数组
columns: [...dynamicColumns.value],
actionColumn: {
title: '操作',
width: 180,
fixed: 'right'
},
pagination: false
}
})
const [registerTable, { reload, setColumns, getColumns, getDataSource, setTableData, setLoading }, { rowSelection, selectedRowKeys }] = tableContext
//处理接口数据为日期列赋值
async function handleFetchSuccess() {
const newData = []
for (const item of apiData.value) {
item.isSecondQD = item.employeeType == 3 ? 1 : 0
const recordList = item.recordList
let production = 0
let road = 0
let wharf = 0
let reform = 0
let await1 = 0
let night = 0
let other = 0
let project = 0
let competition = 0
let goAbroad1 = 0
let goAbroad2 = 0
for (let i = 0; i < recordList.length; i++) {
const day = recordList[i].attendanceDay
const status = recordList[i].attendanceStatus
//表格在非编辑状态时将日期列展示成文本
item[`dayValue${day}`] = options.value.find((option) => option.value == status)?.text
console.log('item[`dayValue${day}`]', item[`dayValue${day}`])
if (status == 4) {
production += 1
night += 1
} else if (status == 1) {
road += 1
} else if (status == 2) {
wharf += 1
night += 1
} else if (status == 3) {
reform += 1
night += 1
} else if (status == 5) {
await1 += 1
night += 1
} else if (item.employeeType == 3 && (status == 0 || status == 11 || status == 12)) {
other += 1
} else if (status == 14) {
goAbroad1 += 1
} else if (status == 16) {
goAbroad2 += 1
} else if (status == 15) {
project += 1
} else if (status == 17) {
competition += 1
}
}
// 循环结束后统一赋值
item.production = production
item.road = road
item.wharf = wharf
item.reform = reform
item.await1 = await1
item.night = night
item.other = other
item.project = project
item.competition = competition
item.goAbroad1 = goAbroad1
item.goAbroad2 = goAbroad2
// 修改出勤天数计算逻辑,同样考虑工作日
const cqts = recordList.filter((dayItem) => {
//除了 未出勤-1 病假8 年假13 外都算出勤,且必须是工作日
return (
dayItem.attendanceStatus &&
dayItem.attendanceStatus != '-1' &&
dayItem.attendanceStatus != '8' &&
dayItem.attendanceStatus != '13' &&
dayItem.attendanceStatus != '1'
)
})
item.workDays = cqts.length
newData.push(item)
}
setTableData(newData)
await reload()
}
//是否二线开关变化时根据节假日接口勾选考勤
async function handleIsOutsourceChange(row) {
const month = row.attendanceMonth
const hlidayList = await getHoliday({ date: dayjs(month).format('YYYYMM') })
if (row.isSecondQD == 1) {
row.employeeType = 3
const recordList = row.recordList
const holidayList = hlidayList.map((item) => item.date)
let workDays = 0
let records = []
for (let i = 0; i < recordList.length; i++) {
const day = recordList[i].attendanceDay
const oldRecord = recordList.find((item) => item.attendanceDay == day)
const dateStr = `${month}-${day.toString().padStart(2, '0')}`
const formattedDate = dayjs(dateStr).format('YYYYMMDD')
// 只有在工作日才处理考勤状态统计
if (!holidayList.includes(formattedDate)) {
row[`dayValue${day}`] = '0'
workDays += 1
//const status = recordList[i].attendanceStatus;
} else {
// 周末设置为空或特定值
row[`dayValue${day}`] = '-1' // 或者其他默认值
}
const newRecord = {
attendanceDay: day,
attendanceMonth: row.attendanceMonth,
attendanceStatus: row[`dayValue${day}`],
employeeType: row.employeeType,
id: oldRecord?.id,
recordId: oldRecord?.id
}
records.push(newRecord)
}
row.workDays = workDays
const updateList = { handleType: 'update', handleContent: `修改:${row.realname}从不是二线员工变为二线员工` }
const params = { ...row, fillId: record.value.id, recordList: records, updateList: [updateList] }
await updateAttendance(params)
} else {
row.employeeType = row.isOutsource == 1 ? 2 : 1
const recordList = row.recordList
let records = []
for (let i = 0; i < recordList.length; i++) {
const day = recordList[i].attendanceDay
const oldRecord = recordList.find((item) => item.attendanceDay == day)
const newRecord = {
attendanceDay: day,
attendanceMonth: row.attendanceMonth,
attendanceStatus: row[`dayValue${day}`],
employeeType: row.employeeType,
id: oldRecord?.id,
recordId: oldRecord?.id
}
records.push(newRecord)
}
const updateList = { handleType: 'update', handleContent: `修改:${row.realname}从二线员工变为不是二线员工` }
const params = { ...row, fillId: record.value.id, recordList: records, updateList: [updateList] }
await updateAttendance(params)
}
}
async function handleEdit(row: EditRecordRowindex) {
currentEditKeyRef.value = row.key
editingRowId.value = row.key
for (let i = 0; i < row.recordList.length; i++) {
const day = row.recordList[i].attendanceDay
//表格在编辑状态时将日期列展示成值匹配下拉选项
const status = options.value.find((item) => item.text == row[`dayValue${day}`])?.value
row[`dayValue${day}`] = status
}
/* const rowElement = document.querySelector(`.ant-table-row[data-index="${index}"]`)
if (rowElement) {
rowElement.classList.add('editable-row')
}*/
row.onEdit?.(true)
}
function handleCancel(record: EditRecordRow) {
currentEditKeyRef.value = ''
editingRowId.value = ''
for (let i = 0; i < record.recordList.length; i++) {
const day = record.recordList[i].attendanceDay
//表格在非编辑状态时将日期列展示成文本
record[`dayValue${day}`] = options.value.find((option) => option.value == record[`dayValue${day}`])?.text
}
record.onEdit?.(false, false)
}
async function handleSave(record: EditRecordRow) {
// 校验
createMessage.loading({ content: '正在保存...', duration: 0, key: 'saving' })
const valid = await record.onValid?.()
if (valid) {
try {
const data = cloneDeep(record.editValueRefs)
//TODO 此处将数据提交给服务器保存
//await editServiceProvider(params)
// 保存之后提交编辑状态
const pass = await record.onEdit?.(false, true)
if (pass) {
currentEditKeyRef.value = ''
editingRowId.value = ''
for (let i = 0; i < record.recordList.length; i++) {
const day = record.recordList[i].attendanceDay
//表格在非编辑状态时将日期列展示成文本
record[`dayValue${day}`] = options.value.find((option) => option.value == record[`dayValue${day}`])?.text
}
}
createMessage.success({ content: '数据已保存', key: 'saving' })
await reload()
} catch (error) {
createMessage.error({ content: '保存失败', key: 'saving' })
}
} else {
createMessage.error({ content: '请填写正确的数据', key: 'saving' })
}
}
function onEditChange({ column, value, record }) {
console.log(value, 'value')
//在编辑的时候要在这里为record.editValueRefs赋最新值
/*if (column.dataIndex == 'attendanceCondition') {
record.editValueRefs.attendanceCondition = value
} else if (column.dataIndex == 'attendanceNum') {
record.editValueRefs.attendanceNum = Number(value)
} else if (column.dataIndex == 'awaitCondition') {
record.editValueRefs.awaitCondition = value
} else if (column.dataIndex == 'wgAwait') {
record.editValueRefs.wgAwait = Number(value)
} else if (column.dataIndex == 'changeCondition') {
record.editValueRefs.changeCondition = value
} else if (column.dataIndex == 'remark') {
record.editValueRefs.remark = value
}*/
}
function handleDelete(record: EditRecordRow) {}
function handleEditRecords(record: EditRecordRow) {}
// 操作栏
function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
onClick: handleEdit.bind(null, record)
},
{
label: '删除',
onClick: handleDelete.bind(null, record)
},
{
label: '修改记录',
onClick: handleEditRecords.bind(null, record)
}
]
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record, column)
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record, column)
}
},
{
label: '修改记录',
onClick: handleEditRecords.bind(null, record)
}
]
}
// 获取表格数据并对考勤记录进行处理
async function loadVxeData() {}
//设置标题
const modalTitle = ref('生产状态')
const title = computed(() => `${record.value?.departName}平台在职员工${record.value?.attendanceMonth}月考勤`)
//新增人员后组装参数回调保存接口
async function handleSuccess(rows) {}
function onLookEditRecord({ row }) {}
// 提交
async function handleSuccessA() {}
// 导出
async function getExportAttendanceDetail() {
loading.value = true
let orderList = <Array<Object>>[
{
order: '01',
field: 'orderNum',
name: t('edu.attendanceManagement.orderNum')
},
{
order: '02',
field: 'realname',
name: t('edu.attendanceManagement.realname')
},
{
order: '03',
field: 'workNo',
name: t('edu.attendanceManagement.workNo')
},
{
order: '04',
field: 'originalPostName',
name: t('edu.attendanceManagement.post')
},
{
order: '05',
field: 'employeeType',
name: t('edu.attendanceManagement.isOutsource')
}
]
//从第六列开始加动态天数列
const month = record.value.attendanceMonth
const days = dayjs(month).daysInMonth()
for (let i = 0; i < days; i++) {
orderList.push({
order: 5 + i >= 10 ? 5 + i : '0' + (5 + i),
field: 'dayValue' + (i + 1),
name: i + 1
})
}
if (record.value.userType == 2) {
let orderListLength = orderList.length
orderList.push({ order: orderListLength + 1, field: 'foodAllowance', name: '伙食补助' })
}
// 这里在导出时判断一下userType是1时添加allowance出勤津贴、postCoefficient岗位系数、productionCoefficient部门系数字段
if (record.value.userType == 1) {
const leftList = [
{
order: '',
field: 'allowance',
name: t('edu.attendanceManagement.allowance')
},
{
order: '',
field: 'postCoefficient',
name: t('edu.attendanceManagement.postCoefficient')
},
{
order: '',
field: 'productionCoefficient',
name: t('edu.attendanceManagement.productionCoefficient')
},
{ order: '', field: 'road', name: t('edu.departAttendanceReview.road') },
{ order: '', field: 'wharf', name: t('edu.departAttendanceReview.wharf') },
{ order: '', field: 'reform', name: t('edu.departAttendanceReview.reform') },
{ order: '', field: 'production', name: t('edu.departAttendanceReview.production') },
{ order: '', field: 'await1', name: t('edu.departAttendanceReview.await1') },
{ order: '', field: 'other', name: t('edu.departAttendanceReview.other') },
{ order: '', field: 'goAbroad1', name: t('edu.departAttendanceReview.goAbroad1') },
{ order: '', field: 'goAbroad2', name: t('edu.departAttendanceReview.goAbroad2') }
]
let orderListLength = orderList.length
leftList.forEach((item, index) => {
item.order = orderListLength + 1 + index
orderList.push(item)
})
}
const endList = [
{
order: '',
field: 'subsidy',
name: t('edu.attendanceManagement.subsidy')
},
{
order: '',
field: 'subsidyB',
name: t('edu.attendanceManagement.subsidyB')
},
{
order: '',
field: 'project',
name: t('edu.attendanceManagement.project')
},
{
order: '',
field: 'competition',
name: t('edu.attendanceManagement.competition')
},
{
order: '',
field: 'extraWork',
name: t('edu.attendanceManagement.extraWork')
},
{
order: '',
field: 'secondNight',
name: t('edu.attendanceManagement.secondNight')
},
{
order: '',
field: 'reissue',
name: t('edu.attendanceManagement.reissue')
},
{
order: '',
field: 'deduction',
name: t('edu.attendanceManagement.deduction')
},
{
order: '',
field: 'remark',
name: t('edu.attendanceManagement.remark')
},
{
order: '',
field: 'workDays',
name: t('edu.attendanceManagement.workDays')
}
]
let orderListLength = orderList.length
endList.forEach((item, index) => {
item.order = orderListLength + 1 + index
orderList.push(item)
})
let recordList = []
let list = tableRef.value?.getTableData()
for (let i in list) {
let item = list[i]
console.log('导出行数据::::', item)
let pushObj = {
realname: item.realname,
workNo: item.workNo,
originalPostName: item.monthPostName || item.originalPostName,
employeeType: item.employeeType == 3 ? '是' : '否',
allowance: item.allowance,
postCoefficient: item.postCoefficient,
productionCoefficient: item.productionCoefficient,
subsidy: item.subsidy,
subsidyB: item.subsidyaBWork,
secondNight: item.secondNight,
road: item.road,
wharf: item.wharf,
reform: item.reform,
production: item.production,
await1: item.await1,
other: item.other,
extraWork: item.extraWork,
project: item.project,
competition: item.competition,
workDays: item.workDays,
reissue: item.reissue,
deduction: item.deduction,
remark: item.remark,
orderNum: item.orderNum || i + 1
}
item.recordList.forEach((dayItem) => {
//这里从下拉选择的数组中找到对应的值不再写死
const find = options.value.find((item) => {
return item.value == dayItem.attendanceStatus
})
console.log(find, 'find')
pushObj['dayValue' + dayItem.attendanceDay] = find ? find.text : ''
})
recordList.push(pushObj)
}
recordList.forEach((item, index) => {
for (let i = 0; i < days; i++) {
if (!item['dayValue' + (i + 1)]) {
recordList[index]['dayValue' + (i + 1)] = ''
}
}
})
let title = `${record.value?.departName}平台在职员工${record.value?.attendanceMonth}月考勤`
const value = await exportAttendanceDetail({ title: title, exportType: '1', orderList: orderList, recordList: recordList })
const url = getFileAccessHttpUrl(value)
if (url) {
window.open(url)
}
loading.value = false
}
async function handleUpdateRecordSuccess() {
await loadVxeData()
}
async function handleRejectedSuccess(v) {
try {
setModalProps({ confirmLoading: true })
await check({ id: record.value.id, ...v })
//关闭弹窗
closeModal()
//刷新列表
emit('success')
} catch ({ errorFields }) {
return Promise.reject(errorFields)
} finally {
setModalProps({ confirmLoading: false })
}
}
function onRejected() {
openRejectedModal(true, {
isUpdate: true,
showFooter: true
})
}
async function onDeleteRow(props) {
await deleteAttendance({ fillId: record.value.id, realname: props.row.realname, username: props.row.username })
// 异步调用删除方法
tableRef.value?.removeRows(props.row)
}
function handleValueChange({ row, col, value, oldValue }) {
//这里需要添加判断当col.key 是dayValue开头的时执行
// 更严格的检查
if (col.key && col.key.startsWith('dayValue')) {
// 提取所有包含 dayValue 的字段值,按数字顺序组成数组
const dayKeys = Object.keys(row)
.filter((key) => key.startsWith('dayValue'))
.map((key) => {
// 提取字段名中的数字部分(例如 "dayValue3" -> 3)
const dayNum = parseInt(key.replace('dayValue', ''))
return { key, dayNum, value: row[key] }
})
.sort((a, b) => a.dayNum - b.dayNum) // 按天数排序
.map((item) => item.key) // 只提取键
if (dayKeys.includes(col.key)) {
if (row[col.key] == '4') {
row.production += 1
row.night += 1
} else if (row[col.key] == '1') {
row.road += 1
} else if (row[col.key] == '2') {
row.wharf += 1
row.night += 1
} else if (row[col.key] == '3') {
row.reform += 1
row.night += 1
} else if (row[col.key] == '5') {
row.await1 += 1
row.night += 1
} else if (row.employeeType === 3 && (row[col.key] == '0' || row[col.key] == '11' || row[col.key] == '12')) {
row.other += 1
} else if (row[col.key] == '14') {
row.goAbroad1 += 1
} else if (row[col.key] == '16') {
row.goAbroad2 += 1
} else if (row[col.key] == '15') {
row.project += 1
}
console.log('row', row)
}
const recordList = row.recordList
//如果勾选状态为未出勤-1 病假8 年假13属于未出勤,出勤天数-1
if (value == '-1' || value == '8' || value == '13') {
row.workDays = row.workDays - 1
}
const dayNum = parseInt(col.key.replace('dayValue', ''))
const oldRecord = recordList.find((item) => item.attendanceDay == dayNum)
const newRecord = {
attendanceDay: dayNum,
attendanceMonth: row.attendanceMonth,
attendanceStatus: value,
employeeType: row.employeeType,
id: oldRecord?.id,
recordId: oldRecord?.id
}
const oldText = options.value.find((item) => item.value == oldValue)?.text
const Text = options.value.find((item) => item.value == value)?.text
const updateList = { handleType: 'update', handleContent: `修改:第${dayNum}天考勤状态从${oldText}变为${Text}` }
const params = { ...row, fillId: record.value.id, recordList: [newRecord], updateList: [updateList] }
console.log('params', params)
updateAttendance(params)
} else {
let handleContent
if (col.options) {
const oldText = col.options.find((item) => item.value == oldValue)?.text
const Text = col.options.find((item) => item.value == value)?.text
handleContent = `修改:${col.title}从${oldText}变为${Text}`
} else {
handleContent = `修改:${col.title}从${oldValue}变为${value}`
}
const updateList = { handleType: 'update', handleContent: handleContent }
const params = { ...row, fillId: record.value.id, recordList: [], updateList: [updateList] }
console.log('params', params)
updateAttendance(params)
}
}
function onAddUser() {
openModal(true, {
isUpdate: false,
showFooter: true,
record: { depart: record.value?.depart, attendanceMonth: record.value?.attendanceMonth, isOutsource: 0 }
})
}
//表单提交事件
async function handleSubmit(v) {
openRejectedModal(true, {
isUpdate: false,
showFooter: true
})
}
</script>
<style lang="less" scoped>
/* 新增:编辑行的高亮样式 */
.editing-row {
background-color: #f0f7ff;
/* 编辑状态下列宽强制生效 */
:deep(td) {
min-width: 110px !important;
max-width: 110px !important;
}
}
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-calendar-picker) {
width: 100%;
}
</style>
根据row的editRow是否等于true动态改变columns数组中title包含dayValue列的宽度
最新发布