Files
delivery-uniapp/pages/user/salary/salaryList.vue
2026-01-24 17:45:54 +08:00

184 lines
4.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<s-layout :title="titleText" class="salary-list-page">
<view class="page-wrap">
<scroll-view class="list" scroll-y>
<view class="salary-item" v-for="item in items" :key="item.id">
<view class="left">
<text class="date">{{ item.date }}</text>
<text class="desc" :class="{ 'muted': !item.desc }">{{ item.desc || '' }}</text>
</view>
<text
class="amount"
:class="{ positive: item.amount >= 0, negative: item.amount < 0 }"
>
{{ formatSigned(item.amount) }}
</text>
</view>
<view v-if="!items.length" class="empty">没有更多了~</view>
</scroll-view>
</view>
</s-layout>
</template>
<script setup>
import { ref } from 'vue';
import PayWalletApi from '@/sheep/api/pay/wallet';
import { onShow } from '@dcloudio/uni-app';
const items = ref([]);
const year = ref('');
const month = ref('');
const titleText = ref('薪资明细');
function pad(n) {
if (!n && n !== 0) return n;
return String(n).padStart(2, '0');
}
function formatSigned(val) {
const n = Number(val) || 0;
const sign = n > 0 ? '+' : n < 0 ? '' : '+';
// 保留两位小数
return `${sign}${Math.abs(n).toFixed(2)}`;
}
function toDateString(t) {
const d = t ? new Date(t) : null;
if (!d || isNaN(d.getTime())) return '';
const y = d.getFullYear();
const m = pad(d.getMonth() + 1);
const day = pad(d.getDate());
return `${y}-${m}-${day}`;
}
// 本地回退示例明细(供开发查看)
const testList = [
{ id: 't1', date: '2025-10-31', desc: '配送订单佣金收入23.9 时段考勤收入23.21', amount: 71.89 },
{ id: 't2', date: '2025-10-30', desc: '配送订单佣金收入23.9 时段考勤收入23.21', amount: 71.89 },
{ id: 't3', date: '2025-10-31', desc: '配送订单佣金收入23.9 时段考勤收入23.21', amount: 71.89 },
{ id: 't4', date: '2025-10-30', desc: '配送订单佣金收入23.9 时段考勤收入23.21', amount: 71.89 },
];
// 加载并过滤流水(按 year/month
async function loadList() {
try {
const res = await PayWalletApi.getWalletTransactionPage({ page: 1, size: 200 });
let records = [];
if (res && res.code === 0) {
if (Array.isArray(res.data)) {
records = res.data;
} else if (res.data && Array.isArray(res.data.records)) {
records = res.data.records;
}
}
// 若有返回,则客户端过滤指定年月
if (records && records.length) {
const filtered = records.filter((r) => {
const t = r.createTime ?? r.createdAt ?? r.time ?? r.create_date ?? r.date;
if (!t) return false;
const d = new Date(t);
if (isNaN(d.getTime())) return false;
const y = d.getFullYear();
const m = d.getMonth() + 1;
return Number(y) === Number(year.value) && Number(m) === Number(month.value);
});
items.value = filtered.map((r, idx) => {
const t = r.createTime ?? r.createdAt ?? r.time ?? r.create_date ?? r.date;
return {
id: r.id ?? `r-${idx}`,
date: toDateString(t),
desc: r.remark ?? r.note ?? r.title ?? r.typeName ?? '',
amount: Number(r.amount ?? r.price ?? r.income ?? r.value ?? r.money ?? 0),
};
});
// 如果过滤后为空则回退到示例数据,便于开发查看
if (!items.value.length) {
items.value = testList;
}
return;
}
} catch (e) {
// ignore
}
// 无接口返回,使用回退示例
items.value = testList;
}
// 获取路由参数uni-app 页面可通过 getCurrentPages 读取 options
function initParams() {
try {
const pages = getCurrentPages();
const cur = pages[pages.length - 1] || {};
const opts = cur.options || {};
year.value = opts.year || opts.y || String(new Date().getFullYear());
month.value = opts.month || opts.m || String(new Date().getMonth() + 1);
titleText.value = `${String(year.value).slice(-2)}${pad(month.value)}月薪资`;
} catch (e) {
year.value = String(new Date().getFullYear());
month.value = String(new Date().getMonth() + 1);
titleText.value = `${String(year.value).slice(-2)}${pad(month.value)}月薪资`;
}
}
// 页面显示时初始化并加载
onShow(() => {
initParams();
loadList();
});
</script>
<style scoped>
.page-wrap {
padding: 16px;
background: transparent;
min-height: 100vh;
}
.list {
margin-top: 8px;
}
.salary-item {
background: #fff;
padding: 14px 12px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #f0f0f0;
}
.salary-item .left {
flex: 1;
}
.date {
color: #333;
font-weight: 600;
display: block;
margin-bottom: 6px;
}
.desc {
color: #999;
font-size: 13px;
display: block;
}
.desc.muted {
opacity: 0.8;
}
.amount {
width: 160rpx;
text-align: right;
font-weight: 700;
}
.amount.positive {
color: #e74c3c;
}
.amount.negative {
color: #2db7a3;
}
.empty {
text-align: center;
color: #bbb;
padding: 20px 0;
}
</style>