fix PointLedgerList.vue style
This commit is contained in:
+155
-123
@@ -2,13 +2,14 @@
|
|||||||
<div v-can="permissionCodes.point.ledgerRead" class="point-ledger-list">
|
<div v-can="permissionCodes.point.ledgerRead" class="point-ledger-list">
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
<t-input
|
<t-input
|
||||||
v-model.trim="customerKeyword"
|
v-model="customerKeyword"
|
||||||
class="customer"
|
class="customer"
|
||||||
|
type="search"
|
||||||
borderless
|
borderless
|
||||||
clearable
|
|
||||||
placeholder="输入客户编码或姓名"
|
placeholder="输入客户编码或姓名"
|
||||||
@clear="applyCustomerSearch"
|
@clear="searchCustomer"
|
||||||
@enter="applyCustomerSearch"
|
@enter="searchCustomer"
|
||||||
|
@input="searchCustomer"
|
||||||
>
|
>
|
||||||
<template #suffix-icon>
|
<template #suffix-icon>
|
||||||
<t-button
|
<t-button
|
||||||
@@ -34,32 +35,32 @@
|
|||||||
@change="selectDateFilter"
|
@change="selectDateFilter"
|
||||||
/>
|
/>
|
||||||
</t-dropdown-menu>
|
</t-dropdown-menu>
|
||||||
<div v-if="isCustomDate" class="date-range">
|
|
||||||
<t-button
|
|
||||||
size="small"
|
|
||||||
variant="outline"
|
|
||||||
:content="dateRange[0] || '开始时间'"
|
|
||||||
@click="startDateVisible = true"
|
|
||||||
/>
|
|
||||||
<span>至</span>
|
|
||||||
<t-button
|
|
||||||
size="small"
|
|
||||||
variant="outline"
|
|
||||||
:content="dateRange[1] || '结束时间'"
|
|
||||||
@click="endDateVisible = true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<card-container v-if="customer" class="customer">
|
|
||||||
<customer-profile-card :customer="customer" />
|
|
||||||
</card-container>
|
|
||||||
<t-pull-down-refresh
|
<t-pull-down-refresh
|
||||||
v-model="isRefreshing"
|
v-model="isRefreshing"
|
||||||
:refresh-timeout="30000"
|
:refresh-timeout="30000"
|
||||||
@refresh="reload"
|
@refresh="reload"
|
||||||
@scrolltolower="load"
|
@scrolltolower="load"
|
||||||
>
|
>
|
||||||
<t-cell-group v-if="pageResult.list.length" class="list" theme="card">
|
<div class="list-wrap">
|
||||||
|
<card-container v-if="customer" class="customer">
|
||||||
|
<customer-profile-card :customer="customer" />
|
||||||
|
</card-container>
|
||||||
|
<t-cell-group class="summary" theme="card">
|
||||||
|
<t-cell
|
||||||
|
title="开始时间"
|
||||||
|
:note="dateRange[0] || '-'"
|
||||||
|
arrow
|
||||||
|
@click="openStartDate"
|
||||||
|
/>
|
||||||
|
<t-cell
|
||||||
|
title="结束时间"
|
||||||
|
:note="dateRange[1] || '-'"
|
||||||
|
arrow
|
||||||
|
@click="openEndDate"
|
||||||
|
/>
|
||||||
|
</t-cell-group>
|
||||||
|
<t-cell-group v-if="pageResult.list.length" class="list" theme="card">
|
||||||
<t-cell
|
<t-cell
|
||||||
v-entrance-transition="index * 30"
|
v-entrance-transition="index * 30"
|
||||||
v-for="(item, index) in pageResult.list"
|
v-for="(item, index) in pageResult.list"
|
||||||
@@ -91,7 +92,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #description>
|
<template #description>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<div v-text="`时间:${Time.toPassedDateTime(item.occurredAt)}`" />
|
<div>
|
||||||
|
<span>时间:</span>
|
||||||
|
<pass-time-label :timestamp="item.occurredAt" underline />
|
||||||
|
</div>
|
||||||
<div v-text="`余额:${item.balanceBefore ?? 0} → ${item.balanceAfter ?? 0}`" />
|
<div v-text="`余额:${item.balanceBefore ?? 0} → ${item.balanceAfter ?? 0}`" />
|
||||||
<div v-text="item.remark" />
|
<div v-text="item.remark" />
|
||||||
</div>
|
</div>
|
||||||
@@ -100,51 +104,45 @@
|
|||||||
<div class="delta keep-text" :class="getLedgerTheme(item)" v-text="getLedgerDelta(item)" />
|
<div class="delta keep-text" :class="getLedgerTheme(item)" v-text="getLedgerDelta(item)" />
|
||||||
</template>
|
</template>
|
||||||
</t-cell>
|
</t-cell>
|
||||||
</t-cell-group>
|
</t-cell-group>
|
||||||
<div class="center-tips" v-text="loadStateText" />
|
<div class="center-tips" v-text="loadStateText" />
|
||||||
|
</div>
|
||||||
</t-pull-down-refresh>
|
</t-pull-down-refresh>
|
||||||
|
|
||||||
<section v-if="customer" class="actions">
|
|
||||||
<t-button
|
|
||||||
v-can="permissionCodes.point.adjust"
|
|
||||||
theme="primary"
|
|
||||||
size="small"
|
|
||||||
@click="toAdjust"
|
|
||||||
>
|
|
||||||
人工调整
|
|
||||||
</t-button>
|
|
||||||
</section>
|
|
||||||
<customer-selector
|
|
||||||
v-model="selectedCustomerId"
|
|
||||||
v-model:visible="selectorVisible"
|
|
||||||
@change="handleCustomerChange"
|
|
||||||
/>
|
|
||||||
<t-popup v-model="startDateVisible" placement="bottom">
|
|
||||||
<t-date-time-picker
|
|
||||||
v-model="dateRange[0]"
|
|
||||||
format="YYYY-MM-DD HH:mm"
|
|
||||||
:mode="['date', 'minute']"
|
|
||||||
title="开始时间"
|
|
||||||
@cancel="startDateVisible = false"
|
|
||||||
@confirm="confirmDateRange"
|
|
||||||
/>
|
|
||||||
</t-popup>
|
|
||||||
<t-popup v-model="endDateVisible" placement="bottom">
|
|
||||||
<t-date-time-picker
|
|
||||||
v-model="dateRange[1]"
|
|
||||||
format="YYYY-MM-DD HH:mm"
|
|
||||||
:mode="['date', 'minute']"
|
|
||||||
title="结束时间"
|
|
||||||
@cancel="endDateVisible = false"
|
|
||||||
@confirm="confirmDateRange"
|
|
||||||
/>
|
|
||||||
</t-popup>
|
|
||||||
</div>
|
</div>
|
||||||
|
<customer-selector
|
||||||
|
v-model="selectedCustomerId"
|
||||||
|
v-model:visible="selectorVisible"
|
||||||
|
@change="handleCustomerChange"
|
||||||
|
/>
|
||||||
|
<t-popup v-model="startDateVisible" placement="bottom">
|
||||||
|
<t-date-time-picker
|
||||||
|
v-if="startDateVisible"
|
||||||
|
v-model="startDraft"
|
||||||
|
format="YYYY-MM-DD HH:mm"
|
||||||
|
:mode="['date', 'minute']"
|
||||||
|
title="开始时间"
|
||||||
|
:default-value="dateRange[0]"
|
||||||
|
@cancel="cancelStartDate"
|
||||||
|
@confirm="confirmStartDate"
|
||||||
|
/>
|
||||||
|
</t-popup>
|
||||||
|
<t-popup v-model="endDateVisible" placement="bottom">
|
||||||
|
<t-date-time-picker
|
||||||
|
v-if="endDateVisible"
|
||||||
|
v-model="endDraft"
|
||||||
|
format="YYYY-MM-DD HH:mm"
|
||||||
|
:mode="['date', 'minute']"
|
||||||
|
title="结束时间"
|
||||||
|
:default-value="dateRange[1]"
|
||||||
|
@cancel="cancelEndDate"
|
||||||
|
@confirm="confirmEndDate"
|
||||||
|
/>
|
||||||
|
</t-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { DropdownValue } from "tdesign-mobile-vue";
|
import type { DropdownValue } from "tdesign-mobile-vue";
|
||||||
import { Time } from "timi-web";
|
import { PassTimeLabel, Time, Toolkit } from "timi-web";
|
||||||
import { type PageResult, useUserStore } from "timi-web-api";
|
import { type PageResult, useUserStore } from "timi-web-api";
|
||||||
import CustomerAPI from "@/api/CustomerAPI";
|
import CustomerAPI from "@/api/CustomerAPI";
|
||||||
import PointAPI from "@/api/PointAPI";
|
import PointAPI from "@/api/PointAPI";
|
||||||
@@ -178,14 +176,16 @@ const selectorVisible = ref(false);
|
|||||||
const changeTypeFilter = ref("ALL");
|
const changeTypeFilter = ref("ALL");
|
||||||
const dateFilter = ref<DateFilter>("last30");
|
const dateFilter = ref<DateFilter>("last30");
|
||||||
const dateRange = ref<[string, string]>(buildDateRange(dateFilter.value));
|
const dateRange = ref<[string, string]>(buildDateRange(dateFilter.value));
|
||||||
|
const startDraft = ref("");
|
||||||
|
const endDraft = ref("");
|
||||||
const startDateVisible = ref(false);
|
const startDateVisible = ref(false);
|
||||||
const endDateVisible = ref(false);
|
const endDateVisible = ref(false);
|
||||||
const changeTypeOptions = [
|
const changeTypeOptions = [
|
||||||
{ label: "全部类型", value: "ALL" },
|
{ label: "全部类型", value: "ALL" },
|
||||||
{ label: "获得 EARN", value: "EARN" },
|
{ label: "获得", value: "EARN" },
|
||||||
{ label: "消费 CONSUME", value: "CONSUME" },
|
{ label: "消费", value: "CONSUME" },
|
||||||
{ label: "撤销 REVOKE", value: "REVOKE" },
|
{ label: "撤销", value: "REVOKE" },
|
||||||
{ label: "调整 ADJUST", value: "ADJUST" }
|
{ label: "调整", value: "ADJUST" }
|
||||||
];
|
];
|
||||||
const dateFilterOptions = [
|
const dateFilterOptions = [
|
||||||
{ label: "全部时间", value: "all" },
|
{ label: "全部时间", value: "all" },
|
||||||
@@ -195,7 +195,6 @@ const dateFilterOptions = [
|
|||||||
{ label: "自定义", value: "custom" }
|
{ label: "自定义", value: "custom" }
|
||||||
];
|
];
|
||||||
const dateFilterLabel = computed(() => dateFilterOptions.find(item => item.value === dateFilter.value)?.label || "时间范围");
|
const dateFilterLabel = computed(() => dateFilterOptions.find(item => item.value === dateFilter.value)?.label || "时间范围");
|
||||||
const isCustomDate = computed(() => dateFilter.value === "custom");
|
|
||||||
|
|
||||||
async function handleCustomerChange(value: string | string[]): Promise<void> {
|
async function handleCustomerChange(value: string | string[]): Promise<void> {
|
||||||
selectedCustomerId.value = Array.isArray(value) ? String(value[0] || "") : value;
|
selectedCustomerId.value = Array.isArray(value) ? String(value[0] || "") : value;
|
||||||
@@ -209,7 +208,11 @@ async function handleCustomerChange(value: string | string[]): Promise<void> {
|
|||||||
await reload();
|
await reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function applyCustomerSearch(): Promise<void> {
|
function getCustomerSearchKeyword(value?: Customer): string {
|
||||||
|
return value?.name?.trim() || value?.code?.trim() || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchCustomer = Toolkit.debounce(async () => {
|
||||||
const keyword = customerKeyword.value.trim();
|
const keyword = customerKeyword.value.trim();
|
||||||
if (!keyword) {
|
if (!keyword) {
|
||||||
selectedCustomerId.value = "";
|
selectedCustomerId.value = "";
|
||||||
@@ -220,7 +223,6 @@ async function applyCustomerSearch(): Promise<void> {
|
|||||||
if (keyword === getCustomerSearchKeyword(customer.value)) {
|
if (keyword === getCustomerSearchKeyword(customer.value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const matched = await CustomerAPI.findByCode(keyword, currentStoreStore.currentStoreId || undefined)
|
const matched = await CustomerAPI.findByCode(keyword, currentStoreStore.currentStoreId || undefined)
|
||||||
|| await CustomerAPI.findByName(keyword);
|
|| await CustomerAPI.findByName(keyword);
|
||||||
@@ -235,11 +237,7 @@ async function applyCustomerSearch(): Promise<void> {
|
|||||||
} catch {
|
} catch {
|
||||||
Message.error("客户信息加载失败");
|
Message.error("客户信息加载失败");
|
||||||
}
|
}
|
||||||
}
|
}, false);
|
||||||
|
|
||||||
function getCustomerSearchKeyword(value?: Customer): string {
|
|
||||||
return value?.name?.trim() || value?.code?.trim() || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
async function selectChangeType(value: DropdownValue): Promise<void> {
|
async function selectChangeType(value: DropdownValue): Promise<void> {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
@@ -254,15 +252,48 @@ async function selectDateFilter(value: DropdownValue): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dateFilter.value = String(value) as DateFilter;
|
dateFilter.value = String(value) as DateFilter;
|
||||||
if (!isCustomDate.value) {
|
if (dateFilter.value !== "custom") {
|
||||||
dateRange.value = buildDateRange(dateFilter.value);
|
dateRange.value = buildDateRange(dateFilter.value);
|
||||||
await reload();
|
await reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openStartDate(): void {
|
||||||
|
startDraft.value = dateRange.value[0];
|
||||||
|
startDateVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function openEndDate(): void {
|
||||||
|
endDraft.value = dateRange.value[1];
|
||||||
|
endDateVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelStartDate(): void {
|
||||||
|
startDateVisible.value = false;
|
||||||
|
startDraft.value = dateRange.value[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelEndDate(): void {
|
||||||
|
endDateVisible.value = false;
|
||||||
|
endDraft.value = dateRange.value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmStartDate(value?: string | number): Promise<void> {
|
||||||
|
startDateVisible.value = false;
|
||||||
|
dateRange.value = [String(value || startDraft.value), dateRange.value[1]];
|
||||||
|
await confirmDateRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmEndDate(value?: string | number): Promise<void> {
|
||||||
|
endDateVisible.value = false;
|
||||||
|
dateRange.value = [dateRange.value[0], String(value || endDraft.value)];
|
||||||
|
await confirmDateRange();
|
||||||
|
}
|
||||||
|
|
||||||
async function confirmDateRange(): Promise<void> {
|
async function confirmDateRange(): Promise<void> {
|
||||||
startDateVisible.value = false;
|
startDateVisible.value = false;
|
||||||
endDateVisible.value = false;
|
endDateVisible.value = false;
|
||||||
|
dateFilter.value = "custom";
|
||||||
if (dateRange.value[0] && dateRange.value[1] && dateRange.value[1] < dateRange.value[0]) {
|
if (dateRange.value[0] && dateRange.value[1] && dateRange.value[1] < dateRange.value[0]) {
|
||||||
dateRange.value = [dateRange.value[1], dateRange.value[0]];
|
dateRange.value = [dateRange.value[1], dateRange.value[0]];
|
||||||
}
|
}
|
||||||
@@ -405,15 +436,6 @@ async function toDetail(item: PointLedger): Promise<void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toAdjust(): Promise<void> {
|
|
||||||
await router.push({
|
|
||||||
name: "PointAdjust",
|
|
||||||
query: {
|
|
||||||
customerId: selectedCustomerId.value
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 时间 ----------
|
// ---------- 时间 ----------
|
||||||
|
|
||||||
function buildDateRange(type: DateFilter): [string, string] {
|
function buildDateRange(type: DateFilter): [string, string] {
|
||||||
@@ -471,6 +493,10 @@ onMounted(async () => {
|
|||||||
Message.error("积分流水页面加载失败");
|
Message.error("积分流水页面加载失败");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
searchCustomer.cancel();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@@ -515,57 +541,64 @@ onMounted(async () => {
|
|||||||
padding-top: .8rem;
|
padding-top: .8rem;
|
||||||
border-radius: 0 0 1rem 1rem;
|
border-radius: 0 0 1rem 1rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.date-range {
|
.summary {
|
||||||
gap: .5rem;
|
overflow: hidden;
|
||||||
padding: .5rem 0 .75rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.t-button {
|
:deep(.t-cell__title) {
|
||||||
flex: 1;
|
flex: 0 0 4.5rem;
|
||||||
min-width: 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
:deep(.t-cell__note) {
|
||||||
color: #52607a;
|
flex: 1 1 0;
|
||||||
}
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: right;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.list-wrap {
|
||||||
|
gap: 1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.item {
|
.list {
|
||||||
|
|
||||||
.avatar {
|
.item {
|
||||||
width: 3.5rem;
|
|
||||||
height: 3.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
.avatar {
|
||||||
gap: .5rem;
|
width: 3.5rem;
|
||||||
display: flex;
|
height: 3.5rem;
|
||||||
|
|
||||||
.type-icon {
|
|
||||||
display: flex;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
.title {
|
||||||
font-size: .75rem;
|
gap: .5rem;
|
||||||
line-height: 1.25;
|
display: flex;
|
||||||
}
|
|
||||||
|
|
||||||
.delta {
|
.type-icon {
|
||||||
font-weight: 700;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.increase {
|
.description {
|
||||||
color: #059669;
|
font-size: .75rem;
|
||||||
}
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
.decrease {
|
.delta {
|
||||||
color: #dc2626;
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.increase {
|
||||||
|
color: #059669;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decrease {
|
||||||
|
color: #dc2626;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -599,7 +632,6 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters .date-range span,
|
|
||||||
.customer-id,
|
.customer-id,
|
||||||
.empty {
|
.empty {
|
||||||
color: #94a3b8;
|
color: #94a3b8;
|
||||||
|
|||||||
Reference in New Issue
Block a user