<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>薪资管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="../../../layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="../../../layuiadmin/style/admin.css" media="all">
<style>
.layui-card {
margin-bottom: 15px;
}
.layui-btn {
margin-right: 10px;
}
.search-area {
margin-bottom: 15px;
}
.layui-form-item {
margin-bottom: 15px;
}
.salary-calc {
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
margin-bottom: 15px;
}
.salary-calc .layui-form-item {
margin-bottom: 5px;
}
/* 添加考勤页面中的样式 */
.search-area {
padding: 20px;
background-color: #f8f8f8;
border-radius: 4px;
margin-bottom: 15px;
}
.btn-area {
padding: 15px;
background-color: #f8f8f8;
border-radius: 4px;
margin-bottom: 15px;
}
</style>
</head>
<body>
<div class="layui-card layadmin-header">
<div class="layui-breadcrumb" lay-filter="breadcrumb">
<a lay-href="">员工系统</a>
<a><cite>薪资管理</cite></a>
<a><cite>薪资信息</cite></a>
</div>
</div>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-header">薪资信息表</div>
<div class="layui-card-body">
<!-- 操作按钮区域 - 使用考勤页面的样式 -->
<div class="btn-area">
<button class="layui-btn layui-btn-normal" id="add-btn">
<i class="layui-icon"></i> 新增
</button>
<button class="layui-btn layui-btn-danger" id="delete-btn">
<i class="layui-icon"></i> 删除
</button>
<button class="layui-btn layui-btn-warm" id="export-btn">
<i class="layui-icon"></i> 导出
</button>
</div>
<!-- 搜索区域 - 使用考勤页面的样式 -->
<div class="search-area">
<div class="layui-inline">
<input class="layui-input" name="id" id="test-table-demoReload" placeholder="搜索ID" autocomplete="off">
</div>
<button class="layui-btn" id="search-btn">搜索</button>
<button class="layui-btn layui-btn-primary" id="reset-btn">重置</button>
</div>
<table class="layui-hide" id="test-table-reload" lay-filter="user"></table>
<!-- 操作列模板 -->
<script type="text/html" id="table-bar">
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="delete">删除</a>
<a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="edit">编辑</a>
</script>
</div>
</div>
</div>
</div>
</div>
<!-- 新增薪资模态框(参考考勤页面结构) -->
<div id="addModal" style="display: none; padding: 20px;">
<form class="layui-form" lay-filter="salary-form">
<input type="hidden" name="sid">
<div class="layui-form-item">
<label class="layui-form-label">员工ID</label>
<div class="layui-input-block">
<input type="number" name="eid" required lay-verify="required" class="layui-input" placeholder="请输入员工ID">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">部门ID</label>
<div class="layui-input-block">
<input type="number" name="departmentid" required lay-verify="required" class="layui-input" placeholder="请输入部门ID">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">薪资等级</label>
<div class="layui-input-block">
<input type="number" name="slevel" class="layui-input" placeholder="请输入薪资等级">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">薪资月份</label>
<div class="layui-input-block">
<input type="text" name="smonth" required lay-verify="required" class="layui-input" id="addSmonth" placeholder="格式:YYYY-MM">
</div>
</div>
<div class="salary-calc">
<div class="layui-form-item">
<label class="layui-form-label">基本工资</label>
<div class="layui-input-block">
<input type="number" name="sbase" step="0.01" class="layui-input calc-trigger" placeholder="请输入基本工资" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">奖金</label>
<div class="layui-input-block">
<input type="number" name="sbonus" step="0.01" class="layui-input calc-trigger" placeholder="请输入奖金" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">津贴</label>
<div class="layui-input-block">
<input type="number" name="sallowance" step="0.01" class="layui-input calc-trigger" placeholder="请输入津贴" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">加班费</label>
<div class="layui-input-block">
<input type="number" name="sovertime" step="0.01" class="layui-input calc-trigger" placeholder="请输入加班费" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">扣款</label>
<div class="layui-input-block">
<input type="number" name="sdeductions" step="0.01" class="layui-input calc-trigger" placeholder="请输入扣款" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">社保</label>
<div class="layui-input-block">
<input type="number" name="sinsurance" step="0.01" class="layui-input calc-trigger" placeholder="请输入社保" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">公积金</label>
<div class="layui-input-block">
<input type="number" name="sprovidentfund" step="0.01" class="layui-input calc-trigger" placeholder="请输入公积金" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">个税</label>
<div class="layui-input-block">
<input type="number" name="stax" step="0.01" class="layui-input calc-trigger" placeholder="请输入个税" value="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">实发工资</label>
<div class="layui-input-block">
<input type="number" name="netsalary" step="0.01" class="layui-input" placeholder="自动计算" readonly>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">调整原因</label>
<div class="layui-input-block">
<textarea name="sreason" class="layui-textarea" placeholder="请输入调整原因"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发放状态</label>
<div class="layui-input-block">
<select name="paymentstatus">
<option value="">请选择发放状态</option>
<option value="已发放">已发放</option>
<option value="未发放">未发放</option>
<option value="发放中">发放中</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发放日期</label>
<div class="layui-input-block">
<input type="text" name="paymentdate" class="layui-input" id="addPaymentDate" placeholder="格式:YYYY-MM-DD">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="submitAdd">确认添加</button>
<button type="button" class="layui-btn layui-btn-primary" id="closeAddModal">取消</button>
</div>
</div>
</form>
</div>
<script src="../../../layuiadmin/layui/layui.js"></script>
<script>
layui.config({
base: '../../../layuiadmin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'table', 'jquery', 'form', 'layer', 'laydate'], function(){
var table = layui.table;
var $ = layui.jquery;
var form = layui.form;
var layer = layui.layer;
var laydate = layui.laydate;
// 方法级渲染
var tableIns = table.render({
elem: '#test-table-reload',
id: 'empTable',
url: '/salary/showsalary',
method: 'GET',
cols: [[
{checkbox: true, fixed: true},
{field:'sid', title: '薪水ID', width: 100, sort: true},
{field:'eid', title: '员工ID', width: 100},
{field:'departmentid', title: '部门ID', width: 100},
{field:'slevel', title: '薪资等级', width: 100},
{field:'smonth', title: '月份', width: 120},
{field:'sbase', title: '基本工资', width: 120},
{field:'sbonus', title: '奖金', width: 120},
{field:'sallowance', title: '津贴', width: 120},
{field:'sovertime', title: '加班费', width: 120},
{field:'netsalary', title: '实发工资', width: 120},
{field:'paymentstatus', title: '发放状态', width: 120},
{field:'paymentdate', title: '发放日期', width: 150},
{title: '操作', width: 150, toolbar: '#table-bar', fixed: 'right'}
]],
page: true,
limit: 5,
limits: [5, 10, 15],
height: 'full-200',
parseData: function(res) {
return {
"code": res.code,
"msg": res.msg,
"count": res.count,
"data": res.data
};
}
});
// 搜索按钮点击事件
$('#search-btn').on('click', function() {
var sid = $('#test-table-demoReload').val();
table.reload('empTable', {
page: { curr: 1 },
where: { sid: sid }
});
});
// 重置按钮点击事件
$('#reset-btn').on('click', function() {
$('#test-table-demoReload').val('');
table.reload('empTable', {
page: { curr: 1 },
where: { sid: '' }
});
});
// 新增按钮点击事件 - 使用考勤页面的方式
$('#add-btn').on('click', function() {
// 初始化日期选择器
initLaydate();
// 打开添加模态框
layer.open({
type: 1,
title: '新增薪资记录',
content: $('#addModal'),
area: ['800px', '700px'],
fixed: true,
shade: 0.3,
success: function() {
form.render(); // 重新渲染表单
// 绑定计算事件
$('.calc-trigger').on('input', calculateNetSalary);
// 初始化计算
calculateNetSalary();
}
});
});
// 初始化日期选择器(参考考勤页面)
function initLaydate() {
// 薪资月份(仅月份)
laydate.render({
elem: '#addSmonth',
type: 'month',
format: 'yyyy-MM',
placeholder: '请选择薪资月份'
});
// 发放日期(仅日期)
laydate.render({
elem: '#addPaymentDate',
type: 'date',
format: 'yyyy-MM-dd',
placeholder: '请选择发放日期'
});
}
// 计算实发工资
function calculateNetSalary() {
var sbase = parseFloat($('input[name="sbase"]').val()) || 0;
var sbonus = parseFloat($('input[name="sbonus"]').val()) || 0;
var sallowance = parseFloat($('input[name="sallowance"]').val()) || 0;
var sovertime = parseFloat($('input[name="sovertime"]').val()) || 0;
var sdeductions = parseFloat($('input[name="sdeductions"]').val()) || 0;
var sinsurance = parseFloat($('input[name="sinsurance"]').val()) || 0;
var sprovidentfund = parseFloat($('input[name="sprovidentfund"]').val()) || 0;
var stax = parseFloat($('input[name="stax"]').val()) || 0;
// 计算实发工资:应发工资 - 扣款 - 社保 - 公积金 - 个税
var netSalary = sbase + sbonus + sallowance + sovertime - sdeductions - sinsurance - sprovidentfund - stax;
$('input[name="netsalary"]').val(netSalary.toFixed(2));
}
// 监听添加表单提交(参考考勤页面)
form.on('submit(submitAdd)', function(data) {
var formData = data.field;
// 确保数值字段是数字类型
formData.sbase = parseFloat(formData.sbase) || 0;
formData.sbonus = parseFloat(formData.sbonus) || 0;
formData.sallowance = parseFloat(formData.sallowance) || 0;
formData.sovertime = parseFloat(formData.sovertime) || 0;
formData.sdeductions = parseFloat(formData.sdeductions) || 0;
formData.sinsurance = parseFloat(formData.sinsurance) || 0;
formData.sprovidentfund = parseFloat(formData.sprovidentfund) || 0;
formData.stax = parseFloat(formData.stax) || 0;
formData.netsalary = parseFloat(formData.netsalary) || 0;
// 发送添加请求
$.ajax({
url: '/salary/add',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(formData),
success: function(res) {
if (res.code === 0) {
layer.msg('添加成功!', {icon: 1, time: 1500});
layer.closeAll(); // 关闭模态框
tableIns.reload(); // 刷新表格
} else {
layer.msg('添加失败:' + res.msg, {icon: 2, time: 2000});
}
},
error: function(xhr, status, error) {
console.error('请求错误:', error, xhr.responseText);
layer.msg('网络异常:' + error, {icon: 2, time: 2000});
}
});
return false; // 阻止表单默认提交
});
// 关闭添加模态框(取消按钮)
$('#closeAddModal').on('click', function() {
layer.closeAll('page');
// 清空表单
document.querySelector('form[lay-filter="salary-form"]').reset();
form.render();
});
// 批量删除按钮点击事件
$('#delete-btn').on('click', function() {
var checkStatus = table.checkStatus('empTable');
var selectedData = checkStatus.data;
if (selectedData.length === 0) {
layer.msg('请选择要删除的数据');
return;
}
var ids = selectedData.map(function(item) {
return item.sid;
});
layer.confirm('确定要删除选中的 ' + ids.length + ' 条数据吗?', function(index) {
$.ajax({
url: '/salary/delete',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(ids),
success: function(res) {
if (res.code === 0) {
layer.msg('删除成功');
tableIns.reload();
} else {
layer.msg(res.msg);
}
},
error: function() {
layer.msg('网络错误,请重试');
}
});
layer.close(index);
});
});
// 导出按钮点击事件
$('#export-btn').on('click', function() {
// 创建一个隐藏的iframe来触发下载
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = '/salary/export';
document.body.appendChild(iframe);
setTimeout(function() {
document.body.removeChild(iframe);
}, 3000);
layer.msg('导出请求已发送,请稍候...');
});
// 表格行操作事件
table.on('tool(user)', function(obj) {
var data = obj.data;
if (obj.event === 'delete') {
layer.confirm('确定要删除这条记录吗?', function(index) {
$.ajax({
url: '/salary/delete',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify([data.sid]),
success: function(res) {
if (res.code === 0) {
layer.msg('删除成功');
tableIns.reload();
} else {
layer.msg(res.msg);
}
}
});
layer.close(index);
});
} else if (obj.event === 'edit') {
// 获取完整数据
$.ajax({
url: '/salary/' + data.sid,
type: 'GET',
success: function(res) {
if (res.code === 0) {
openFormDialog('编辑薪资记录', res.data);
} else {
layer.msg(res.msg);
}
},
error: function() {
layer.msg('获取数据失败');
}
});
}
});
// 打开表单对话框(编辑用)
function openFormDialog(title, data) {
// 这里保留原有的编辑功能实现
// 由于代码较长,此处省略具体实现
// 实际使用时需要保留原有的编辑功能代码
layer.msg('编辑功能待开发');
}
});
</script>
</body>
</html>package edu.cdut.controller;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import edu.cdut.entity.Salary;
import edu.cdut.mapper.SalaryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/salary")
public class SalaryController {
@Autowired
private SalaryMapper salaryMapper;
@GetMapping("/showsalary")
public Map<String, Object> showSalaryAll(
@RequestParam(required = false) Integer sid,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "5") Integer limit
) {
Map<String, Object> result = new HashMap<>();
result.put("code", 0);
result.put("msg", "");
QueryWrapper<Salary> queryWrapper = new QueryWrapper<>();
if (sid != null) {
queryWrapper.eq("sid", sid);
}
Page<Salary> salaryPage = new Page<>(page, limit);
Page<Salary> pageResult = salaryMapper.selectPage(salaryPage, queryWrapper);
result.put("count", (salaryMapper.selectList (new QueryWrapper<>()).size()));
result.put("data", pageResult.getRecords());
return result;
}
// 根据ID获取单条薪资记录
@GetMapping("/{id}")
public Map<String, Object> getSalaryById(@PathVariable Integer id) {
Map<String, Object> result = new HashMap<>();
try {
Salary salary = salaryMapper.selectById(id);
if (salary != null) {
result.put("code", 0);
result.put("data", salary);
result.put("msg", "查询成功");
} else {
result.put("code", 1);
result.put("msg", "记录不存在");
}
} catch (Exception e) {
result.put("code", 1);
result.put("msg", "查询失败:" + e.getMessage());
}
return result;
}
// 导出Excel
@GetMapping("/export")
public void exportSalary(HttpServletResponse response) throws IOException {
List<Salary> salaryList = salaryMapper.selectList(null);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("薪资数据", "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
// 使用EasyExcel导出
EasyExcel.write(response.getOutputStream(), Salary.class)
.sheet("薪资数据")
.doWrite(salaryList);
}
// 添加薪资记录
@PostMapping("/add")
public Map<String, Object> addSalary(@RequestBody Salary salary) {
Map<String, Object> result = new HashMap<>();
try {
// 设置创建时间和更新时间
salary.setCreatetime(LocalDateTime.now());
salary.setUpdatetime(LocalDateTime.now());
int insertResult = salaryMapper.insert(salary);
if (insertResult > 0) {
result.put("code", 0);
result.put("msg", "添加成功");
} else {
result.put("code", 1);
result.put("msg", "添加失败");
}
} catch (Exception e) {
result.put("code", 1);
result.put("msg", "添加失败:" + e.getMessage());
}
return result;
}
// 更新薪资记录
@PostMapping("/update")
public Map<String, Object> updateSalary(@RequestBody Salary salary) {
Map<String, Object> result = new HashMap<>();
try {
// 设置更新时间
salary.setUpdatetime(LocalDateTime.now());
int updateResult = salaryMapper.updateById(salary);
if (updateResult > 0) {
result.put("code", 0);
result.put("msg", "更新成功");
} else {
result.put("code", 1);
result.put("msg", "更新失败,记录不存在");
}
} catch (Exception e) {
result.put("code", 1);
result.put("msg", "更新失败:" + e.getMessage());
}
return result;
}
// 删除薪资记录
@PostMapping("/delete")
public Map<String, Object> deleteSalary(@RequestBody List<Integer> ids) {
Map<String, Object> result = new HashMap<>();
try {
int deleteResult = salaryMapper.deleteBatchIds(ids);
if (deleteResult > 0) {
result.put("code", 0);
result.put("msg", "删除成功");
} else {
result.put("code", 1);
result.put("msg", "删除失败");
}
} catch (Exception e) {
result.put("code", 1);
result.put("msg", "删除失败:" + e.getMessage());
}
return result;
}
}
//package edu.cdut.controller;
//
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import edu.cdut.entity.Salary;
//import edu.cdut.mapper.SalaryMapper;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.net.URLEncoder;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//@RestController
//@RequestMapping("/salary")
//public class SalaryController {
//
// @Autowired
// private SalaryMapper salaryMapper;
//
// @GetMapping("showsalary")
// public Map<String, Object> showSalaryAll(
// @RequestParam(required = false) Integer sid,
// @RequestParam(defaultValue = "1") Integer page,
// @RequestParam(defaultValue = "5") Integer limit
// ) {
// Map<String, Object> result = new HashMap<>();
// result.put("code", 0);
// result.put("msg", "");
//
// QueryWrapper<Salary> queryWrapper = new QueryWrapper<>();
// if (sid != null) {
// queryWrapper.eq("sid", sid);
// }
//
// Page<Salary> salaryMapperPage = new Page<>(page, limit);
// Page<Salary> pageResult = salaryMapper.selectPage(salaryMapperPage, queryWrapper);
//
// result.put("count", salaryMapper.selectCount(queryWrapper));
// result.put("data", pageResult.getRecords());
//
// return result;
// }
//
// // 导出Excel的单独方法
// @GetMapping("export")
// public void exportSalary(HttpServletResponse response) throws IOException {
// List<Salary> salaryList = salaryMapper.selectList(null);
//
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// response.setCharacterEncoding("utf-8");
// String fileName = URLEncoder.encode("薪资数据", "UTF-8");
// response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
//
// // 如果有EasyExcel依赖,取消注释下面这行
// // EasyExcel.write(response.getOutputStream(), Salary.class).sheet("薪资数据").doWrite(salaryList);
//
// // 如果没有EasyExcel,可以先返回JSON数据测试
// // 这里先简单返回成功信息
// response.getWriter().write("导出功能需要添加EasyExcel依赖");
// }
//
// // 添加薪资记录
// @PostMapping("/add")
// public Map<String, Object> addSalary(@RequestBody Salary salary) {
// Map<String, Object> result = new HashMap<>();
// try {
// int insertResult = salaryMapper.insert(salary);
// if (insertResult > 0) {
// result.put("code", 0);
// result.put("msg", "添加成功");
// } else {
// result.put("code", 1);
// result.put("msg", "添加失败");
// }
// } catch (Exception e) {
// result.put("code", 1);
// result.put("msg", "添加失败:" + e.getMessage());
// }
// return result;
// }
//
// // 删除薪资记录
// @PostMapping("/delete")
// public Map<String, Object> deleteSalary(@RequestBody List<Integer> ids) {
// Map<String, Object> result = new HashMap<>();
// try {
// int deleteResult = salaryMapper.deleteBatchIds(ids);
// if (deleteResult > 0) {
// result.put("code", 0);
// result.put("msg", "删除成功");
// } else {
// result.put("code", 1);
// result.put("msg", "删除失败");
// }
// } catch (Exception e) {
// result.put("code", 1);
// result.put("msg", "删除失败:" + e.getMessage());
// }
// return result;
// }
//}1.新增按钮点击输入数据后无法将数据储存到表格中2.编辑按钮点击后应该显示相应列的数据并且可以更改改后的数据应出现在表格数据中
最新发布