support consume point

This commit is contained in:
Timi
2026-08-18 16:46:13 +08:00
parent eaee1ae49b
commit eb6b8beb6b
14 changed files with 281 additions and 99 deletions
+9 -2
View File
@@ -9,8 +9,8 @@
<t-cell-group v-if="record" title="登记信息" theme="card">
<t-cell title="登记事件" :note="record.event?.name || '未知事件'" />
<t-cell v-if="record.numberValue !== undefined && record.numberValue !== null" title="事件数值" :note="getNumberValueText(record)" />
<t-cell v-if="record.pointValue !== undefined && record.pointValue !== null" title="提交积分值" :note="`${record.pointValue} 分`" />
<t-cell v-if="record.earnedPointValue !== undefined && record.earnedPointValue !== null" title="本次获得积分" :note="`${record.earnedPointValue} 分`" />
<t-cell v-if="record.pointValue !== undefined && record.pointValue !== null" title="提交积分值" :note="getPointValueText(record.pointValue)" />
<t-cell v-if="record.earnedPointValue !== undefined && record.earnedPointValue !== null" title="本次积分变化" :note="getPointValueText(record.earnedPointValue)" />
<t-cell title="登记时间" :note="record.registeredAt ? Time.toPassedDateTime(record.registeredAt) : '-'" />
<t-cell title="登记人" :note="Text.display(record.operator?.nick || record.operator?.name)" />
<t-cell title="客户编码" :note="Text.display(record.customer?.code)" />
@@ -63,6 +63,13 @@ function getNumberValueText(value: EventRecord): string {
return formatEventNumberValue(value.event, value.numberValue);
}
function getPointValueText(value?: number | null): string {
if (value === undefined || value === null) {
return "-";
}
return `${0 < value ? "获得" : "消耗"} ${Math.abs(value)} 分`;
}
// ---------- 页面数据 ----------
async function loadRecord(): Promise<void> {
+23 -13
View File
@@ -68,7 +68,10 @@
</t-form-item>
</div>
<div v-if="isEditMode" class="edit-point-tip">已产生积分的登记记录不会因修改客户、事件或时间而重算;如需修改这些事实,请删除后重新创建。</div>
<t-form-item v-if="showSourceValueInput" label="自定义积分" required-mark>
<t-form-item v-if="showSourceValueInput" label="积分动作">
<span class="picker-text" v-text="getPointActionText(sourceValueAction)" />
</t-form-item>
<t-form-item v-if="showSourceValueInput" label="积分数量" required-mark>
<t-input
v-model.trim="pointValueText"
type="number"
@@ -198,10 +201,11 @@ import { useSettingStore } from "@/store/settingStore";
import type { Customer } from "@/types/Customer";
import type { EventItem } from "@/types/EventItem";
import type { EventRecord } from "@/types/EventRecord";
import type { PointAction } from "@/types/Point";
import { getEventRecordPhotoURL } from "@/utils/eventRecord";
import { getEventNumberValuePlaceholder, resolveEventNumberValue } from "@/utils/eventValue";
import { permissionCodes } from "@/utils/permission";
import { loadSourceValueRange } from "@/utils/point";
import { loadSourceValueConfig, type SourceValueConfig } from "@/utils/point";
import { compressUploadImageList } from "@/utils/imageCompression";
defineOptions({
@@ -456,40 +460,46 @@ function validateNumberValueList(): boolean {
// ---------- 积分规则联动 ----------
const pointValueText = ref("");
const sourceValueRange = ref<[number, number]>();
const sourceValueConfig = ref<SourceValueConfig>();
const sourceValueAction = ref<PointAction>("EARN");
let sourceValueLoadToken = 0;
const showSourceValueInput = computed(() => (
!isEditMode.value
&& userStore.hasPermissions(permissionCodes.point.sourceValue)
&& !!sourceValueRange.value
&& !!sourceValueConfig.value
));
const sourceValuePlaceholder = computed(() => {
const range = sourceValueRange.value;
return range ? `请输入 ${range[0]}-${range[1]} 的正整数` : "请输入积分";
const range = sourceValueConfig.value?.range;
return range ? `请输入 ${range[0]}-${range[1]} 的数量` : "请输入数量";
});
async function loadSourceValueRule(): Promise<void> {
const token = sourceValueLoadToken + 1;
sourceValueLoadToken = token;
sourceValueRange.value = undefined;
sourceValueConfig.value = undefined;
if (isEditMode.value || !userStore.hasPermissions(permissionCodes.point.sourceValue) || !selectedEventIdList.value.length) {
return;
}
try {
sourceValueRange.value = await loadSourceValueRange(selectedEventIdList.value);
sourceValueConfig.value = await loadSourceValueConfig(selectedEventIdList.value);
sourceValueAction.value = sourceValueConfig.value?.action || "EARN";
if (token !== sourceValueLoadToken) {
return;
}
} catch {
sourceValueRange.value = undefined;
sourceValueConfig.value = undefined;
}
}
function resolveSourceValue(): number | undefined {
const value = Number(pointValueText.value);
return Number.isSafeInteger(value) && 0 < value ? value : undefined;
return Number.isSafeInteger(value) && 0 < value ? sourceValueAction.value === "CONSUME" ? -value : value : undefined;
}
function getPointActionText(action: PointAction): string {
return action === "CONSUME" ? "消耗积分" : "发放积分";
}
// ---------- 照片 ----------
@@ -641,9 +651,9 @@ function validateForm(): boolean {
}
if (showSourceValueInput.value) {
const pointValue = resolveSourceValue();
const range = sourceValueRange.value;
if (!pointValue || !range || pointValue < range[0] || range[1] < pointValue) {
Toast.warning(`自定义积分必须是 ${range?.[0] || 1}-${range?.[1] || 0} 的正整数`);
const range = sourceValueConfig.value?.range;
if (!pointValue || !range || Math.abs(pointValue) < range[0] || range[1] < Math.abs(pointValue)) {
Toast.warning(`积分数量必须是 ${range?.[0] || 1}-${range?.[1] || 0} 的正整数`);
return false;
}
}