智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

546 lines
14 KiB

<!--员工-我的工资-->
<template>
<view class="main_box">
<view class="main_section">
<!-- 筛选条件 -->
<view class="filter_section">
<view class="filter_item">
<picker mode="date" fields="month" :value="selectedMonth" @change="onMonthChange">
<view class="picker_display">
<text>{{ selectedMonth || '选择月份' }}</text>
<text class="picker_arrow">></text>
</view>
</picker>
</view>
<view class="filter_btn" @click="loadSalaryList">查询</view>
</view>
<!-- 工资条列表 -->
<view class="salary_list" v-if="salaryList.length > 0">
<view
class="salary_item"
v-for="(item, index) in salaryList"
:key="item.id"
@click="viewSalaryDetail(item)"
>
<view class="salary_header">
<view class="salary_month">{{ formatMonth(item.salary_month) }}</view>
<view :class="['salary_status',getStatusClass(item.status)]">
{{ getStatusText(item.status) }}
</view>
</view>
<view class="salary_content">
<view class="salary_row">
<text class="label">基础工资:</text>
<text class="value">¥{{ formatMoney(item.base_salary) }}</text>
</view>
<view class="salary_row">
<text class="label">出勤工资:</text>
<text class="value">¥{{ formatMoney(item.work_salary) }}</text>
</view>
<view class="salary_row">
<text class="label">应发工资:</text>
<text class="value highlight">¥{{ formatMoney(item.gross_salary) }}</text>
</view>
<view class="salary_row">
<text class="label">实发工资:</text>
<text class="value net_salary">¥{{ formatMoney(item.net_salary) }}</text>
</view>
</view>
<view class="salary_footer">
<text class="view_detail">点击查看详情 ></text>
</view>
</view>
</view>
<!-- 暂无数据 -->
<view class="no_data" v-else-if="!loading">
<image class="no_data_icon" src="/static/images/no_data.png" mode="aspectFit"></image>
<text class="no_data_text">暂无工资数据</text>
</view>
<!-- 加载中 -->
<view class="loading" v-if="loading">
<text>加载中...</text>
</view>
</view>
<!-- 工资详情弹窗 -->
<view class="salary_modal" v-if="showDetail" @click="closeDetail">
<view class="modal_content" @click.stop>
<view class="modal_header">
<text class="modal_title">工资详情</text>
<text class="modal_close" @click="closeDetail">×</text>
</view>
<view class="modal_body" v-if="salaryDetail">
<view class="detail_section">
<view class="section_title">基础信息</view>
<view class="detail_row">
<text class="detail_label">工资月份:</text>
<text class="detail_value">{{ formatMonth(salaryDetail.salary_month) }}</text>
</view>
<view class="detail_row">
<text class="detail_label">基础工资:</text>
<text class="detail_value">¥{{ formatMoney(salaryDetail.base_salary) }}</text>
</view>
<view class="detail_row">
<text class="detail_label">满勤天数:</text>
<text class="detail_value">{{ salaryDetail.full_attendance_days }}天</text>
</view>
<view class="detail_row">
<text class="detail_label">出勤天数:</text>
<text class="detail_value">{{ salaryDetail.attendance }}天</text>
</view>
</view>
<view class="detail_section">
<view class="section_title">收入明细</view>
<view class="detail_row">
<text class="detail_label">出勤工资:</text>
<text class="detail_value">¥{{ formatMoney(salaryDetail.work_salary) }}</text>
</view>
<view class="detail_row" v-if="salaryDetail.mgr_performance > 0">
<text class="detail_label">管理绩效:</text>
<text class="detail_value">¥{{ formatMoney(salaryDetail.mgr_performance) }}</text>
</view>
<view class="detail_row" v-if="salaryDetail.performance_bonus > 0">
<text class="detail_label">销售提成:</text>
<text class="detail_value">¥{{ formatMoney(salaryDetail.performance_bonus) }}</text>
</view>
<view class="detail_row" v-if="salaryDetail.other_subsidies > 0">
<text class="detail_label">其他补贴:</text>
<text class="detail_value">¥{{ formatMoney(salaryDetail.other_subsidies) }}</text>
</view>
</view>
<view class="detail_section">
<view class="section_title">扣除明细</view>
<view class="detail_row" v-if="salaryDetail.deductions > 0">
<text class="detail_label">其他扣款:</text>
<text class="detail_value text_red">-¥{{ formatMoney(salaryDetail.deductions) }}</text>
</view>
<view class="detail_row" v-if="salaryDetail.social_security > 0">
<text class="detail_label">社保:</text>
<text class="detail_value text_red">-¥{{ formatMoney(salaryDetail.social_security) }}</text>
</view>
<view class="detail_row" v-if="salaryDetail.individual_income_tax > 0">
<text class="detail_label">个税:</text>
<text class="detail_value text_red">-¥{{ formatMoney(salaryDetail.individual_income_tax) }}</text>
</view>
</view>
<view class="detail_section">
<view class="section_title">工资汇总</view>
<view class="detail_row highlight_row">
<text class="detail_label">应发工资:</text>
<text class="detail_value highlight">¥{{ formatMoney(salaryDetail.gross_salary) }}</text>
</view>
<view class="detail_row net_salary_row">
<text class="detail_label">实发工资:</text>
<text class="detail_value net_salary">¥{{ formatMoney(salaryDetail.net_salary) }}</text>
</view>
</view>
<view class="detail_section" v-if="salaryDetail.remarks">
<view class="section_title">备注</view>
<view class="detail_remarks">{{ salaryDetail.remarks }}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
export default {
data() {
return {
selectedMonth: '',
salaryList: [],
loading: false,
showDetail: false,
salaryDetail: null,
}
},
onLoad() {
// 默认查询当月数据
const now = new Date();
this.selectedMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
this.loadSalaryList();
},
methods: {
// 月份选择
onMonthChange(e) {
this.selectedMonth = e.detail.value;
},
// 加载工资列表
async loadSalaryList() {
this.loading = true;
try {
const params = {};
if (this.selectedMonth) {
params.salary_month = this.selectedMonth;
}
const res = await memberApi.getSalaryList(params);
if (res.code === 1) {
this.salaryList = res.data.data || [];
} else {
uni.showToast({
title: res.msg || '获取数据失败',
icon: 'none'
});
}
} catch (error) {
console.error('获取工资列表失败:', error);
uni.showToast({
title: '网络错误,请稍后重试',
icon: 'none'
});
} finally {
this.loading = false;
}
},
// 查看工资详情
async viewSalaryDetail(item) {
try {
const res = await memberApi.getSalaryInfo({ id: item.id });
if (res.code === 1) {
this.salaryDetail = res.data;
this.showDetail = true;
} else {
uni.showToast({
title: res.msg || '获取详情失败',
icon: 'none'
});
}
} catch (error) {
console.error('获取工资详情失败:', error);
uni.showToast({
title: '网络错误,请稍后重试',
icon: 'none'
});
}
},
// 关闭详情弹窗
closeDetail() {
this.showDetail = false;
this.salaryDetail = null;
},
// 格式化月份显示
formatMonth(month) {
if (!month) return '';
return month.substring(0, 7).replace('-', '年') + '月';
},
// 格式化金额
formatMoney(amount) {
if (!amount && amount !== 0) return '0.00';
return Number(amount).toFixed(2);
},
// 获取状态文字
getStatusText(status) {
switch (status) {
case 1: return '未发放';
case 2: return '已发放';
default: return '未知';
}
},
// 获取状态样式类
getStatusClass(status) {
switch (status) {
case 1: return 'status_pending';
case 2: return 'status_paid';
default: return '';
}
}
}
}
</script>
<style lang="less" scoped>
.main_box {
background: #292929;
min-height: 100vh;
}
.main_section {
padding: 20rpx;
padding-bottom: 150rpx;
}
/* 筛选条件 */
.filter_section {
display: flex;
align-items: center;
background: #434544;
border-radius: 10rpx;
padding: 20rpx;
margin-bottom: 20rpx;
.filter_item {
flex: 1;
.picker_display {
display: flex;
justify-content: space-between;
align-items: center;
color: #D7D7D7;
font-size: 28rpx;
.picker_arrow {
color: #25a18b;
font-size: 24rpx;
}
}
}
.filter_btn {
background: #25a18b;
color: #fff;
padding: 15rpx 30rpx;
border-radius: 8rpx;
font-size: 26rpx;
margin-left: 20rpx;
}
}
/* 工资条列表 */
.salary_list {
.salary_item {
background: #434544;
border-radius: 10rpx;
padding: 30rpx;
margin-bottom: 20rpx;
.salary_header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 15rpx;
border-bottom: 1rpx solid #555;
.salary_month {
color: #fff;
font-size: 32rpx;
font-weight: bold;
}
.salary_status {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
&.status_pending {
background: rgba(255, 165, 0, 0.2);
color: #FFA500;
}
&.status_paid {
background: rgba(34, 197, 94, 0.2);
color: #22c55e;
}
}
}
.salary_content {
.salary_row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15rpx;
.label {
color: #D7D7D7;
font-size: 26rpx;
}
.value {
color: #fff;
font-size: 28rpx;
&.highlight {
color: #25a18b;
font-weight: bold;
}
&.net_salary {
color: #22c55e;
font-weight: bold;
font-size: 30rpx;
}
}
}
}
.salary_footer {
text-align: center;
margin-top: 20rpx;
padding-top: 15rpx;
border-top: 1rpx solid #555;
.view_detail {
color: #25a18b;
font-size: 24rpx;
}
}
}
}
/* 暂无数据 */
.no_data {
text-align: center;
padding: 100rpx 0;
color: #888;
.no_data_icon {
width: 150rpx;
height: 150rpx;
margin-bottom: 30rpx;
}
.no_data_text {
font-size: 28rpx;
}
}
/* 加载中 */
.loading {
text-align: center;
padding: 50rpx 0;
color: #888;
font-size: 28rpx;
}
/* 工资详情弹窗 */
.salary_modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
.modal_content {
background: #434544;
border-radius: 15rpx;
width: 90%;
max-height: 80%;
overflow: hidden;
.modal_header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #555;
.modal_title {
color: #fff;
font-size: 32rpx;
font-weight: bold;
}
.modal_close {
color: #888;
font-size: 40rpx;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.modal_body {
max-height: 60vh;
overflow-y: auto;
padding: 30rpx;
.detail_section {
margin-bottom: 40rpx;
.section_title {
color: #25a18b;
font-size: 28rpx;
font-weight: bold;
margin-bottom: 20rpx;
padding-bottom: 10rpx;
border-bottom: 1rpx solid #555;
}
.detail_row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15rpx;
.detail_label {
color: #D7D7D7;
font-size: 26rpx;
}
.detail_value {
color: #fff;
font-size: 26rpx;
&.highlight {
color: #25a18b;
font-weight: bold;
}
&.net_salary {
color: #22c55e;
font-weight: bold;
}
&.text_red {
color: #f56565;
}
}
}
&.highlight_row {
background: rgba(37, 161, 139, 0.1);
padding: 15rpx;
border-radius: 8rpx;
}
&.net_salary_row {
background: rgba(34, 197, 94, 0.1);
padding: 15rpx;
border-radius: 8rpx;
}
.detail_remarks {
background: #555;
padding: 20rpx;
border-radius: 8rpx;
color: #D7D7D7;
font-size: 26rpx;
line-height: 1.6;
}
}
}
}
}
</style>