<template>
|
<view class="sales-account">
|
<PageHeader title="加油卡管理"
|
@back="goBack" />
|
<view class="search-section">
|
<view class="search-bar">
|
<view class="search-input">
|
<up-input class="search-text"
|
v-model="query.cardNumber"
|
placeholder="请输入加油卡号搜索"
|
clearable
|
@change="getList" />
|
</view>
|
<view class="filter-button"
|
@click="showFilter = true">
|
<up-icon name="list"
|
size="24"
|
color="#999"></up-icon>
|
</view>
|
</view>
|
</view>
|
|
<view v-if="cardList.length > 0"
|
class="ledger-list">
|
<view v-for="item in cardList"
|
:key="item.id"
|
class="ledger-item">
|
<view class="item-header">
|
<view class="item-left">
|
<view class="document-icon">
|
<up-icon name="rmb-circle"
|
size="16"
|
color="#ffffff"></up-icon>
|
</view>
|
<text class="item-id">{{ item.cardNumber || "-" }}</text>
|
</view>
|
<up-tag :text="statusLabel(item.status)"
|
:type="item.status === 'CANCELLED' ? 'error' : 'success'"
|
size="mini"
|
shape="circle" />
|
</view>
|
<up-divider></up-divider>
|
<view class="item-details">
|
<view class="detail-row">
|
<text class="detail-label">所属部门</text>
|
<text class="detail-value">{{ item.deptName || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">发卡单位</text>
|
<text class="detail-value">{{ item.issuer || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">期初余额</text>
|
<text class="detail-value">{{ formatAmount(item.initialBalance) }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">当前余额</text>
|
<text class="detail-value highlight">{{ formatAmount(item.currentBalance) }}</text>
|
</view>
|
<view class="detail-row"
|
v-if="item.remark">
|
<text class="detail-label">备注</text>
|
<text class="detail-value">{{ item.remark }}</text>
|
</view>
|
</view>
|
<view class="action-buttons">
|
<up-button class="action-btn"
|
size="small"
|
type="success"
|
@click="goRecharge(item)">充值管理</up-button>
|
<up-button class="action-btn"
|
size="small"
|
type="primary"
|
@click="goEdit(item)">编辑</up-button>
|
<up-button class="action-btn"
|
size="small"
|
@click="goDetail(item)">详情</up-button>
|
<up-button v-if="item.status !== 'CANCELLED'"
|
class="action-btn"
|
size="small"
|
type="warning"
|
plain
|
@click="handleCancelCard(item)">注销</up-button>
|
<up-button class="action-btn"
|
size="small"
|
type="error"
|
plain
|
@click="handleDelete(item)">删除</up-button>
|
</view>
|
</view>
|
</view>
|
<view v-else
|
class="no-data">
|
<text>暂无加油卡数据</text>
|
</view>
|
|
<view class="fab-button"
|
@click="goAdd">
|
<up-icon name="plus"
|
size="28"
|
color="#ffffff"></up-icon>
|
</view>
|
|
<FilterPanel v-model:show="showFilter"
|
:model-value="query"
|
title="加油卡筛选"
|
:fields="filterFields"
|
@search="onFilterSearch"
|
@reset="onFilterSearch" />
|
</view>
|
</template>
|
|
<script setup>
|
import { computed, reactive, ref } from "vue";
|
import { onShow } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import FilterPanel from "@/components/FilterPanel.vue";
|
import { getDept } from "@/api/collaborativeApproval/approvalProcess";
|
import { unwrapList } from "@/utils/list";
|
import {
|
delFuelCard,
|
listFuelCardPage,
|
updateFuelCard,
|
} from "@/api/inventoryManagement/vehicle";
|
|
const cardList = ref([]);
|
const showFilter = ref(false);
|
const deptOptions = ref([]);
|
|
const query = reactive({
|
cardNumber: "",
|
deptId: "",
|
});
|
|
const filterFields = computed(() => [
|
{
|
prop: "cardNumber",
|
label: "加油卡号",
|
type: "input",
|
placeholder: "请输入加油卡号",
|
},
|
{
|
prop: "deptId",
|
label: "所属部门",
|
type: "select",
|
options: deptOptions.value,
|
},
|
]);
|
|
const goBack = () => uni.navigateBack();
|
|
const goAdd = () => {
|
uni.removeStorageSync("fuelCardDetail");
|
uni.navigateTo({ url: "/pages/inventoryManagement/fuelCard/edit" });
|
};
|
|
const goEdit = item => {
|
uni.setStorageSync("fuelCardDetail", item || {});
|
uni.navigateTo({
|
url: `/pages/inventoryManagement/fuelCard/edit?id=${item.id}`,
|
});
|
};
|
|
const goDetail = item => {
|
uni.setStorageSync("fuelCardDetail", item || {});
|
uni.navigateTo({
|
url: `/pages/inventoryManagement/fuelCard/detail?id=${item.id}`,
|
});
|
};
|
|
const goRecharge = item => {
|
uni.setStorageSync("fuelCardDetail", item || {});
|
uni.navigateTo({
|
url: `/pages/inventoryManagement/fuelCard/recharge?id=${item.id}`,
|
});
|
};
|
|
const statusLabel = status => (status === "CANCELLED" ? "注销" : "正常");
|
|
const formatAmount = amount =>
|
amount === null || amount === undefined || amount === ""
|
? "-"
|
: `¥${Number(amount).toFixed(2)}`;
|
|
const getList = () => {
|
listFuelCardPage({
|
current: -1,
|
size: -1,
|
cardNumber: query.cardNumber || undefined,
|
deptId: query.deptId || undefined,
|
})
|
.then(res => {
|
cardList.value = unwrapList(res);
|
})
|
.catch(() => {
|
uni.showToast({ title: "查询失败", icon: "none" });
|
});
|
};
|
|
// FilterPanel 只回吐筛选值,写回 query 后统一查询
|
const onFilterSearch = values => {
|
Object.assign(query, values);
|
getList();
|
};
|
|
const handleCancelCard = item => {
|
if (!item?.id) return;
|
uni.showModal({
|
title: "注销确认",
|
content: `确认注销加油卡「${item.cardNumber || ""}」吗?注销后该卡不能用于新增加油记录,余额将保留。`,
|
success: res => {
|
if (!res.confirm) return;
|
uni.showLoading({ title: "处理中...", mask: true });
|
updateFuelCard({ id: item.id, status: "CANCELLED" })
|
.then(() => {
|
uni.showToast({ title: "注销成功", icon: "success" });
|
getList();
|
})
|
.catch(() => {
|
uni.showToast({ title: "注销失败", icon: "none" });
|
})
|
.finally(() => {
|
uni.hideLoading();
|
});
|
},
|
});
|
};
|
|
const handleDelete = item => {
|
if (!item?.id) return;
|
uni.showModal({
|
title: "删除确认",
|
content: `确认删除加油卡「${item.cardNumber || ""}」吗?`,
|
success: res => {
|
if (!res.confirm) return;
|
uni.showLoading({ title: "处理中...", mask: true });
|
delFuelCard(item.id)
|
.then(() => {
|
uni.showToast({ title: "删除成功", icon: "success" });
|
getList();
|
})
|
.catch(() => {
|
uni.showToast({ title: "删除失败", icon: "none" });
|
})
|
.finally(() => {
|
uni.hideLoading();
|
});
|
},
|
});
|
};
|
|
let deptsLoaded = false;
|
|
const loadDepts = () => {
|
if (deptsLoaded) return;
|
deptsLoaded = true;
|
getDept()
|
.then(res => {
|
deptOptions.value = (res?.data || []).map(item => ({
|
name: item.deptName,
|
value: item.deptId,
|
}));
|
})
|
.catch(() => {
|
deptsLoaded = false;
|
});
|
};
|
|
onShow(() => {
|
getList();
|
loadDepts();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "@/styles/sales-common.scss";
|
|
.detail-value {
|
max-width: 70%;
|
word-break: break-all;
|
}
|
</style>
|