Commit e295ebac authored by huanghaoting's avatar huanghaoting

请假审批

parent bc9712e0
...@@ -77,3 +77,22 @@ export function getGeneralManagerNickName() { ...@@ -77,3 +77,22 @@ export function getGeneralManagerNickName() {
method: 'get' method: 'get'
}) })
} }
// 获取总经理的nick_name
export function getShenpiList(id) {
return request({
url: '/approvalConfiguration/getNodeList/'+id,
method: 'get'
})
}
// 更新节点和审批状态
export function batchUpdateLeaveApplicationByNodeIdAndApprovalStatus(data) {
return request({
url: '/application/application/updateNodeAndApprovalStatus',
method: 'put',
data: data
})
}
<template>
<div class="app-container">
<!-- 查询表单 -->
<div class="formSearch">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="120px">
<el-form-item label="姓名" prop="uname">
<el-input
v-model="queryParams.uname"
placeholder="请输入姓名"
clearable
@keyup.enter="handleQuery"
style="width: 220px"
/>
</el-form-item>
<el-form-item label="请假类型" prop="leaveType">
<el-select v-model="queryParams.leaveType" placeholder="请选择请假类型" clearable @keyup.enter="handleQuery"
style="width: 220px">
<el-option v-for="dict in leave_types" :key="dict.value" :label="dict.label"
:value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="审批状态" prop="approvalStatus">
<el-select v-model="queryParams.approvalStatus" placeholder="请选择审批状态" style="width: 220px" clearable>
<el-option v-for="dict in approval_status" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item style="padding-left: 5.4%">
<el-button @click="resetQuery" class="el-button-defalut">
<img src="@/assets/icons/common/reset.png" alt="重置图标">重置
</el-button>
<el-button type="primary" @click="handleQuery" class="el-button-primary">
<img src="@/assets/icons/common/search.png" alt="查询图标">查询
</el-button>
<el-button size="large" icon="ArrowDown" type="text" v-show="!isExpanded" @click="toggleSearch">
展开
</el-button>
<el-button size="large" type="text" icon="ArrowUp" v-show="isExpanded" @click="toggleSearch">
收起
</el-button>
</el-form-item>
<!-- 可折叠的查询条件 -->
<transition>
<div v-if="isExpanded">
<el-form-item label="申请日期" prop="requestDate">
<el-date-picker
v-model="queryParams.requestDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择申请日期"
clearable
@keyup.enter="handleQuery"
style="width: 220px"
/>
</el-form-item>
</div>
</transition>
</el-form>
</div>
<!-- 数据列表及操作 -->
<div class="contentTable">
<!-- 按钮区域 -->
<div style="margin-bottom: 30px">
<el-button class="el-button-defalut" type="default" @click="handleBatchReject">一键驳回</el-button>
<el-button class="el-button-primary" style="margin-left: 20px" type="primary" @click="handleBatchPass">
一键通过
</el-button>
</div>
<!-- 表格数据 -->
<div class="table-wrapper">
<el-table v-loading="loading" :data="applicationList" @selection-change="handleSelectionChange" :border="true">
<el-table-column type="selection" align="center"/>
<el-table-column v-if="showIndexColumn" label="序号" align="center" prop="id"/>
<el-table-column label="姓名" align="center" prop="uname"/>
<el-table-column label="申请日期" align="center" prop="requestDate">
<template #default="scope">
<span>{{ parseTime(scope.row.requestDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="请假类型" align="center" prop="leaveType">
<template #default="scope">
<dict-tag :options="leave_types" :value="scope.row.leaveType"/>
</template>
</el-table-column>
<el-table-column label="请假开始时间" align="center" prop="startTime" fit>
<template #default="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="请假结束时间" align="center" prop="endTime" fit>
<template #default="scope">
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="请假时长(小时)" align="center" prop="leavetimeHours"/>
<el-table-column label="请假天数" align="center" prop="leaveDaysSubtotal"/>
<el-table-column label="抵扣加班时长(小时)" align="center" prop="deductionOvertimeHours" width="180px"/>
<el-table-column label="审批状态" align="center">
<template #default="scope">
<dict-tag :options="approval_status" :value="getDisplayStatus(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="detail" label="详情" align="center" width="100px">
<template #default="scope">
<el-tooltip content="详情" placement="top">
<el-button link type="text" @click="handleView(scope.row)">
<img src="@/assets/icons/common/check.png" height="32" width="32"/>
</el-button>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="150px" height="56px">
<template #default="scope">
<el-button link type="primary" size="small" style="font-size: 15px" @click="handlePass(scope.row)">
通过
</el-button>
<el-button link type="danger" size="small" style="font-size: 15px" @click="handleReject(scope.row)">
驳回
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="pagination-container">
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, toRefs, onMounted, getCurrentInstance } from "vue";
import { useRouter } from "vue-router";
import useUserStore from '@/store/modules/user';
import {
listApplication,
getShenpiList,
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
} from "../../../api/application/application";
// ----- 状态及字典定义 -----
const userStore = useUserStore();
const router = useRouter();
const currentRole = ref(''); // 当前用户角色
const { proxy } = getCurrentInstance();
// 示例字典,实际可用你的 useDict
const { leave_types } = proxy.useDict("leave_types");
const { approval_status } = proxy.useDict("approval_status");
const showSearch = ref(true);
const isExpanded = ref(false);
const loading = ref(true);
const total = ref(0);
const applicationList = ref([]);
const ids = ref([]); // 存放表格选中行的 ID
const showIndexColumn = ref(false);
// 查询表单
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
// 其他查询条件省略
},
});
const { queryParams, form } = toRefs(data);
// ----- 辅助函数 -----
const toggleSearch = () => (isExpanded.value = !isExpanded.value);
const reset = () => {
form.value = {};
proxy.resetForm("applicationRef");
};
const handleSelectionChange = (selection) => {
ids.value = selection.map(item => item.id);
};
// ----- 核心逻辑函数 -----
/**
* 根据行数据和当前用户角色返回 dict‑tag 需要显示的状态值
* (仅示例保留,不需要可去掉)
*/
const getDisplayStatus = (row) => {
const status = Number(row.approvalStatus);
// 如果 nodeId=111 && approvalStatus=1,根据角色显示不同
if (row.nodeId === 112 && status === 1) {
if (currentRole.value === 'project-manager') {
return 2; // “已通过”
} else if (currentRole.value === 'general-manager') {
return 1; // “审批中”
}
}
return status;
};
/**
* 查询请假申请列表
*/
const getList = () => {
loading.value = true;
listApplication(queryParams.value)
.then((response) => {
applicationList.value = response.rows.map(row => ({
...row,
isSubmitted: false
}));
total.value = response.total;
// 如果当前角色是 general-manager,则只显示“请假天数 >= 3”的行
if (currentRole.value === 'general-manager') {
applicationList.value = applicationList.value.filter(
(item) => item.leaveDaysSubtotal >= 3
);
}
})
.finally(() => {
loading.value = false;
});
};
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
const resetQuery = () => {
proxy.resetForm("queryRef");
handleQuery();
};
const handleView = (row) => {
router.push({ path: 'leave/detail', query: { id: row.id, from: '/attendance/approval' } });
};
/**
* 单条“通过”
* 若请假天数 < 3,则 nodeId=111, approvalStatus=2
* 若请假天数 >= 3,则根据角色判断
*/
const handlePass = (row) => {
if (row.leaveDaysSubtotal < 3) {
const params = {
ids: [row.id],
nodeId: 111,
approvalStatus: 2
};
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus(params)
.then(() => {
console.log("更新成功");
getList();
})
.catch((err) => console.error("更新失败:", err));
} else {
userStore.getInfo()
.then(userInfo => {
const role = userInfo.roles[0];
let nodeIdVal, approvalStatusVal;
if (role === 'project-manager') {
nodeIdVal = 112;
approvalStatusVal = 1;
} else if (role === 'general-manager') {
nodeIdVal = 112;
approvalStatusVal = 2;
} else {
return Promise.reject("角色不匹配,无法更新");
}
const params = {
ids: [row.id],
nodeId: nodeIdVal,
approvalStatus: approvalStatusVal
};
return batchUpdateLeaveApplicationByNodeIdAndApprovalStatus(params);
})
.then(() => {
console.log("更新成功");
getList();
})
.catch(err => console.error("更新失败:", err));
}
};
/**
* 一键通过:对选中且请假天数 < 3 的记录设置 nodeId=111, approvalStatus=2
*/
const handleBatchPass = () => {
const rowsToPass = applicationList.value.filter(
(item) => ids.value.includes(item.id) && item.leaveDaysSubtotal < 3
);
if (!rowsToPass.length) {
console.warn("没有符合条件的记录");
return;
}
const params = {
ids: rowsToPass.map((row) => row.id),
nodeId: 111,
approvalStatus: 2
};
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus(params)
.then(() => {
console.log("批量通过成功");
getList();
})
.catch(err => console.error("批量通过出错:", err));
};
/**
* 单条“驳回”:不限制角色,nodeId=110, approvalStatus=3
*/
const handleReject = (row) => {
const params = {
ids: [row.id],
nodeId: 110,
approvalStatus: 3
};
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus(params)
.then(() => {
console.log("驳回成功");
getList();
})
.catch(err => console.error("驳回失败:", err));
};
/**
* 一键驳回:对选中的记录,nodeId=110, approvalStatus=3
*/
const handleBatchReject = () => {
const rowsToReject = applicationList.value.filter(
(item) => ids.value.includes(item.id)
);
if (!rowsToReject.length) {
console.warn("未选中任何记录");
return;
}
const params = {
ids: rowsToReject.map(row => row.id),
nodeId: 110,
approvalStatus: 3
};
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus(params)
.then(() => {
console.log("一键驳回成功");
getList();
})
.catch(err => console.error("一键驳回出错:", err));
};
// ----- 生命周期钩子 -----
onMounted(() => {
userStore.getInfo()
.then(userInfo => {
currentRole.value = userInfo.roles[0] || '';
console.log('当前用户角色:', currentRole.value);
getList();
})
.catch(err => console.error("获取用户信息失败:", err));
});
</script>
<style scoped>
.pagination-container {
margin-top: 12px;
margin-right: 285px;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment