update point tier rule
This commit is contained in:
@@ -65,6 +65,23 @@
|
||||
:event-list="eventList"
|
||||
/>
|
||||
</t-form-item>
|
||||
<div v-if="selectedNumberEventList.length" class="event-value-list">
|
||||
<t-form-item
|
||||
v-for="item in selectedNumberEventList"
|
||||
:key="item.id"
|
||||
:label="`${item.name || '未命名事件'}数值`"
|
||||
:required-mark="item.requireValue === true"
|
||||
label-align="top"
|
||||
>
|
||||
<t-input
|
||||
v-model.trim="numberValueTextMap[item.id || '']"
|
||||
type="number"
|
||||
align="right"
|
||||
borderless
|
||||
:placeholder="getNumberValuePlaceholder(item)"
|
||||
/>
|
||||
</t-form-item>
|
||||
</div>
|
||||
<div v-if="showSourceValueInput" class="source-value-panel">
|
||||
<div class="source-value-title">自定义积分</div>
|
||||
<t-input
|
||||
@@ -130,6 +147,7 @@ import { useSettingStore } from "@/store/settingStore";
|
||||
import type { Customer } from "@/types/Customer";
|
||||
import type { EventItem } from "@/types/EventItem";
|
||||
import { getCustomerPhotoURL } from "@/utils/customer";
|
||||
import { getEventNumberValuePlaceholder, resolveEventNumberValue } from "@/utils/eventValue";
|
||||
import { permissionCodes } from "@/utils/permission";
|
||||
import { loadSourceValueRange } from "@/utils/point";
|
||||
import { compressUploadImage, compressUploadImageList } from "@/utils/imageCompression";
|
||||
@@ -148,6 +166,10 @@ const userStore = useUserStore();
|
||||
const eventList = ref<EventItem[]>([]);
|
||||
|
||||
const selectedEventIdList = ref<string[]>([]);
|
||||
const numberValueTextMap = reactive<Record<string, string>>({});
|
||||
const selectedNumberEventList = computed(() => selectedEventIdList.value
|
||||
.map(eventId => eventList.value.find(item => item.id === eventId))
|
||||
.filter((item): item is EventItem => item?.valueType === "NUMBER"));
|
||||
const pointValueText = ref("");
|
||||
const sourceValueRange = ref<[number, number]>();
|
||||
const showSourceValueInput = computed(() => (
|
||||
@@ -176,6 +198,46 @@ function resolveSourceValue(): number | undefined {
|
||||
return Number.isSafeInteger(value) && 0 < value ? value : undefined;
|
||||
}
|
||||
|
||||
function getNumberValuePlaceholder(event: EventItem): string {
|
||||
return getEventNumberValuePlaceholder(event);
|
||||
}
|
||||
|
||||
function resolveNumberValue(eventId: string): number | undefined {
|
||||
const valueText = numberValueTextMap[eventId] || "";
|
||||
if (!valueText.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
const event = eventList.value.find(item => item.id === eventId);
|
||||
return event ? resolveEventNumberValue(event, valueText) : undefined;
|
||||
}
|
||||
|
||||
function validateNumberValueList(): boolean {
|
||||
for (const eventId of selectedEventIdList.value) {
|
||||
const event = eventList.value.find(item => item.id === eventId);
|
||||
if (!event) {
|
||||
continue;
|
||||
}
|
||||
const valueText = numberValueTextMap[eventId] || "";
|
||||
if (event.valueType !== "NUMBER") {
|
||||
if (valueText.trim()) {
|
||||
showToast(`${event.name || "当前事件"}不能提交数值`, "warning");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const numberValue = resolveNumberValue(eventId);
|
||||
if (valueText.trim() && numberValue === undefined) {
|
||||
showToast(`${event.name || "当前事件"}数值格式不正确,请检查单位和小数位`, "warning");
|
||||
return false;
|
||||
}
|
||||
if (event.requireValue && numberValue === undefined) {
|
||||
showToast(`请填写${event.name || "当前事件"}数值`, "warning");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const note = ref("");
|
||||
const saving = ref(false);
|
||||
const canSubmit = computed(() => !!inputCode.value && !!customerName.value.trim() && !customerPhotoUploading.value && !recordPhotoUploading.value);
|
||||
@@ -508,6 +570,7 @@ async function saveRecord(): Promise<void> {
|
||||
name: customerName.value.trim(),
|
||||
eventRecordList: selectedEventIdList.value.map(eventId => ({
|
||||
eventId,
|
||||
numberValue: resolveNumberValue(eventId),
|
||||
pointValue: showSourceValueInput.value ? resolveSourceValue() : undefined,
|
||||
remark: note.value || "快速补录登记"
|
||||
}))
|
||||
@@ -556,6 +619,9 @@ function resetFormAfterSubmit(): void {
|
||||
customerPhotoTempFileId.value = "";
|
||||
recordPhotoItemList.value = [];
|
||||
pointValueText.value = "";
|
||||
for (const eventId of Object.keys(numberValueTextMap)) {
|
||||
delete numberValueTextMap[eventId];
|
||||
}
|
||||
refreshInputTips();
|
||||
}
|
||||
|
||||
@@ -569,6 +635,9 @@ function validateForm(): string {
|
||||
showToast("请填写客户姓名", "warning");
|
||||
return "";
|
||||
}
|
||||
if (!validateNumberValueList()) {
|
||||
return "";
|
||||
}
|
||||
if (showSourceValueInput.value) {
|
||||
const pointValue = resolveSourceValue();
|
||||
const range = sourceValueRange.value;
|
||||
@@ -628,6 +697,10 @@ watch(scanCode, (value) => {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.event-value-list {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.source-value-panel {
|
||||
padding: .75rem 1rem 1rem;
|
||||
|
||||
|
||||
@@ -17,6 +17,16 @@
|
||||
v-if="matchedCustomer"
|
||||
:customer="matchedCustomer"
|
||||
/>
|
||||
<div v-if="showNumberValueInput" class="number-value-panel">
|
||||
<div class="number-value-title" v-text="`${selectedEvent?.name || '事件'}数值`" />
|
||||
<t-input
|
||||
v-model.trim="numberValueText"
|
||||
type="number"
|
||||
align="right"
|
||||
borderless
|
||||
:placeholder="numberValuePlaceholder"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="showSourceValueInput" class="source-value-panel">
|
||||
<div class="source-value-title">自定义积分</div>
|
||||
<t-input
|
||||
@@ -89,6 +99,7 @@ import { useSettingStore } from "@/store/settingStore";
|
||||
import type { Customer } from "@/types/Customer";
|
||||
import type { EventItem } from "@/types/EventItem";
|
||||
import type { EventRecord } from "@/types/EventRecord";
|
||||
import { getEventNumberValuePlaceholder, resolveEventNumberValue } from "@/utils/eventValue";
|
||||
import { permissionCodes } from "@/utils/permission";
|
||||
import { getEventRecordPhotoURL } from "@/utils/eventRecord";
|
||||
import { Storage, Time, useUserStore } from "timi-web";
|
||||
@@ -108,6 +119,7 @@ const EventItemStorageKey = "quick-scan-event-id";
|
||||
const eventSelectorVisible = ref(false);
|
||||
const selectedEventId = ref("");
|
||||
const eventList = ref<EventItem[]>([]);
|
||||
const selectedEvent = computed(() => eventList.value.find(item => item.id === selectedEventId.value));
|
||||
const selectedEventName = computed(() => eventList.value.find(item => item.id === selectedEventId.value)?.name || "请选择登记事件");
|
||||
|
||||
async function loadActions(): Promise<void> {
|
||||
@@ -126,6 +138,7 @@ async function selectEvent(eventId?: string): Promise<void> {
|
||||
return;
|
||||
}
|
||||
selectedEventId.value = eventId;
|
||||
numberValueText.value = "";
|
||||
Storage.setString(EventItemStorageKey, selectedEventId);
|
||||
eventSelectorVisible.value = false;
|
||||
await loadSourceValueRule();
|
||||
@@ -192,8 +205,11 @@ async function toRecordDetail(id: string): Promise<void> {
|
||||
|
||||
const submitting = ref(false);
|
||||
const pointValueText = ref("");
|
||||
const numberValueText = ref("");
|
||||
const sourceValueRange = ref<[number, number]>();
|
||||
const canSubmitRegister = computed(() => !!matchedCustomer.value && !!selectedEventId.value);
|
||||
const showNumberValueInput = computed(() => selectedEvent.value?.valueType === "NUMBER");
|
||||
const numberValuePlaceholder = computed(() => selectedEvent.value ? getEventNumberValuePlaceholder(selectedEvent.value) : "请输入事件数值");
|
||||
const showSourceValueInput = computed(() => (
|
||||
userStore.hasPermissions(permissionCodes.point.sourceValue)
|
||||
&& !!sourceValueRange.value
|
||||
@@ -220,12 +236,25 @@ function resolveSourceValue(): number | undefined {
|
||||
return Number.isSafeInteger(value) && 0 < value ? value : undefined;
|
||||
}
|
||||
|
||||
function resolveNumberValue(): number | undefined {
|
||||
return selectedEvent.value ? resolveEventNumberValue(selectedEvent.value, numberValueText.value) : undefined;
|
||||
}
|
||||
|
||||
async function doSubmit(): Promise<void> {
|
||||
const customer = matchedCustomer.value;
|
||||
if (!customer) {
|
||||
return;
|
||||
}
|
||||
const pointValue = resolveSourceValue();
|
||||
const numberValue = resolveNumberValue();
|
||||
if (showNumberValueInput.value && numberValueText.value.trim() && numberValue === undefined) {
|
||||
Toast.warning("事件数值格式不正确,请检查单位和小数位");
|
||||
return;
|
||||
}
|
||||
if (selectedEvent.value?.requireValue && numberValue === undefined) {
|
||||
Toast.warning("请填写事件数值");
|
||||
return;
|
||||
}
|
||||
const range = sourceValueRange.value;
|
||||
if (showSourceValueInput.value && (!pointValue || !range || pointValue < range[0] || range[1] < pointValue)) {
|
||||
Toast.warning(`自定义积分必须是 ${range?.[0] || 1}-${range?.[1] || 0} 的正整数`);
|
||||
@@ -237,12 +266,14 @@ async function doSubmit(): Promise<void> {
|
||||
customerId: customer.id,
|
||||
eventId: selectedEventId.value,
|
||||
pointValue: showSourceValueInput.value ? pointValue : undefined,
|
||||
numberValue,
|
||||
remark: "客户快速扫码登记"
|
||||
});
|
||||
scanStatus.value = `登记成功:${customer.name || customer.code || scanCode.value}。`;
|
||||
scanCode.value = "";
|
||||
matchedCustomer.value = undefined;
|
||||
pointValueText.value = "";
|
||||
numberValueText.value = "";
|
||||
recentRecordList.value = [];
|
||||
latestDecodedText = "";
|
||||
scannerSessionKey.value += 1;
|
||||
@@ -300,12 +331,14 @@ async function doSubmit(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
.number-value-panel,
|
||||
.source-value-panel {
|
||||
padding: .75rem 1rem;
|
||||
background: rgba(255, 255, 255, .94);
|
||||
box-shadow: 0 .75rem 2rem rgba(15, 23, 42, .08);
|
||||
border-radius: .875rem;
|
||||
|
||||
.number-value-title,
|
||||
.source-value-title {
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -405,6 +438,7 @@ async function doSubmit(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
.number-value-panel,
|
||||
.source-value-panel {
|
||||
background: rgba(15, 23, 42, .88);
|
||||
box-shadow: 0 .75rem 2rem rgba(2, 6, 23, .32);
|
||||
|
||||
Reference in New Issue
Block a user