add point
This commit is contained in:
@@ -65,6 +65,16 @@
|
||||
:event-list="eventList"
|
||||
/>
|
||||
</t-form-item>
|
||||
<div v-if="showSourceValueInput" class="source-value-panel">
|
||||
<div class="source-value-title">自定义积分</div>
|
||||
<t-input
|
||||
v-model.trim="pointValueText"
|
||||
type="number"
|
||||
align="right"
|
||||
borderless
|
||||
:placeholder="sourceValuePlaceholder"
|
||||
/>
|
||||
</div>
|
||||
<t-form-item label="登记备注">
|
||||
<t-textarea
|
||||
v-model.trim="note"
|
||||
@@ -107,7 +117,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { AttachmentAPI, Toolkit } from "timi-web";
|
||||
import { AttachmentAPI, Toolkit, useUserStore } from "timi-web";
|
||||
import type { TdInputProps } from "tdesign-mobile-vue";
|
||||
import { Toast } from "tdesign-mobile-vue";
|
||||
import CustomerAPI from "@/api/CustomerAPI";
|
||||
@@ -121,6 +131,7 @@ import type { Customer } from "@/types/Customer";
|
||||
import type { EventItem } from "@/types/EventItem";
|
||||
import { getCustomerPhotoURL } from "@/utils/customer";
|
||||
import { permissionCodes } from "@/utils/permission";
|
||||
import { loadSourceValueRange } from "@/utils/point";
|
||||
import { compressUploadImage, compressUploadImageList } from "@/utils/imageCompression";
|
||||
import EventSelector from "@/components/EventSelector.vue";
|
||||
import EventRecordAPI from "@/api/EventRecordAPI.ts";
|
||||
@@ -131,11 +142,39 @@ defineOptions({
|
||||
|
||||
const settingStore = useSettingStore();
|
||||
const router = useRouter();
|
||||
const userStore = useUserStore();
|
||||
|
||||
|
||||
const eventList = ref<EventItem[]>([]);
|
||||
|
||||
const selectedEventIdList = ref<string[]>([]);
|
||||
const pointValueText = ref("");
|
||||
const sourceValueRange = ref<[number, number]>();
|
||||
const showSourceValueInput = computed(() => (
|
||||
userStore.hasPermissions(permissionCodes.point.sourceValue)
|
||||
&& !!sourceValueRange.value
|
||||
));
|
||||
const sourceValuePlaceholder = computed(() => {
|
||||
const range = sourceValueRange.value;
|
||||
return range ? `请输入 ${range[0]}-${range[1]} 的正整数` : "请输入积分";
|
||||
});
|
||||
|
||||
async function loadSourceValueRule(): Promise<void> {
|
||||
if (!selectedEventIdList.value.length || !userStore.hasPermissions(permissionCodes.point.sourceValue)) {
|
||||
sourceValueRange.value = undefined;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sourceValueRange.value = await loadSourceValueRange(selectedEventIdList.value);
|
||||
} catch {
|
||||
sourceValueRange.value = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function resolveSourceValue(): number | undefined {
|
||||
const value = Number(pointValueText.value);
|
||||
return Number.isSafeInteger(value) && 0 < value ? value : undefined;
|
||||
}
|
||||
|
||||
const note = ref("");
|
||||
const saving = ref(false);
|
||||
@@ -469,6 +508,7 @@ async function saveRecord(): Promise<void> {
|
||||
name: customerName.value.trim(),
|
||||
eventRecordList: selectedEventIdList.value.map(eventId => ({
|
||||
eventId,
|
||||
pointValue: showSourceValueInput.value ? resolveSourceValue() : undefined,
|
||||
remark: note.value || "快速补录登记"
|
||||
}))
|
||||
};
|
||||
@@ -514,7 +554,8 @@ function resetFormAfterSubmit(): void {
|
||||
boundCodeCustomer.value = undefined;
|
||||
customerPhoto.value = "";
|
||||
customerPhotoTempFileId.value = "";
|
||||
recordPhotoItemList.value = [];
|
||||
recordPhotoItemList.value = [];
|
||||
pointValueText.value = "";
|
||||
refreshInputTips();
|
||||
}
|
||||
|
||||
@@ -528,6 +569,14 @@ function validateForm(): string {
|
||||
showToast("请填写客户姓名", "warning");
|
||||
return "";
|
||||
}
|
||||
if (showSourceValueInput.value) {
|
||||
const pointValue = resolveSourceValue();
|
||||
const range = sourceValueRange.value;
|
||||
if (!pointValue || !range || pointValue < range[0] || range[1] < pointValue) {
|
||||
showToast(`自定义积分必须是 ${range?.[0] || 1}-${range?.[1] || 0} 的正整数`, "warning");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return customerCode;
|
||||
}
|
||||
|
||||
@@ -545,6 +594,10 @@ onMounted(async () => {
|
||||
eventList.value = await EventAPI.listValid();
|
||||
});
|
||||
|
||||
watch(selectedEventIdList, async () => {
|
||||
await loadSourceValueRule();
|
||||
}, { deep: true });
|
||||
|
||||
watch(scanCode, (value) => {
|
||||
const normalizedCode = value.trim();
|
||||
currentCode.value = normalizedCode;
|
||||
@@ -574,6 +627,20 @@ watch(scanCode, (value) => {
|
||||
.textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.source-value-panel {
|
||||
padding: .75rem 1rem 1rem;
|
||||
|
||||
.source-value-title {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.t-input {
|
||||
margin-top: .5rem;
|
||||
border: 1px solid var(--td-component-border);
|
||||
border-radius: .75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-input {
|
||||
@@ -618,6 +685,11 @@ watch(scanCode, (value) => {
|
||||
}
|
||||
}
|
||||
|
||||
.source-value-panel .t-input {
|
||||
background: rgba(15, 23, 42, .72);
|
||||
border-color: rgba(148, 163, 184, .16);
|
||||
}
|
||||
|
||||
:deep(.textarea .t-textarea__inner) {
|
||||
color: #e2e8f0;
|
||||
background: rgba(15, 23, 42, .72);
|
||||
|
||||
@@ -17,6 +17,16 @@
|
||||
v-if="matchedCustomer"
|
||||
:customer="matchedCustomer"
|
||||
/>
|
||||
<div v-if="showSourceValueInput" class="source-value-panel">
|
||||
<div class="source-value-title">自定义积分</div>
|
||||
<t-input
|
||||
v-model.trim="pointValueText"
|
||||
type="number"
|
||||
align="right"
|
||||
borderless
|
||||
:placeholder="sourceValuePlaceholder"
|
||||
/>
|
||||
</div>
|
||||
<t-cell-group
|
||||
v-if="recentRecordList.length"
|
||||
title="最近登记记录"
|
||||
@@ -81,13 +91,15 @@ import type { EventItem } from "@/types/EventItem";
|
||||
import type { EventRecord } from "@/types/EventRecord";
|
||||
import { permissionCodes } from "@/utils/permission";
|
||||
import { getEventRecordPhotoURL } from "@/utils/eventRecord";
|
||||
import { Storage, Time } from "timi-web";
|
||||
import { Storage, Time, useUserStore } from "timi-web";
|
||||
import { loadSourceValueRange } from "@/utils/point";
|
||||
|
||||
defineOptions({
|
||||
name: "QuickSignInPage"
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
const userStore = useUserStore();
|
||||
const settingStore = useSettingStore();
|
||||
|
||||
// ---------- 登记事件 ----------
|
||||
@@ -106,15 +118,17 @@ async function loadActions(): Promise<void> {
|
||||
if (selectedEventId.value) {
|
||||
Storage.setString(EventItemStorageKey, selectedEventId);
|
||||
}
|
||||
await loadSourceValueRule();
|
||||
}
|
||||
|
||||
function selectEvent(eventId?: string): void {
|
||||
async function selectEvent(eventId?: string): Promise<void> {
|
||||
if (!eventId) {
|
||||
return;
|
||||
}
|
||||
selectedEventId.value = eventId;
|
||||
Storage.setString(EventItemStorageKey, selectedEventId);
|
||||
eventSelectorVisible.value = false;
|
||||
await loadSourceValueRule();
|
||||
Toast.success("登记事件已切换");
|
||||
}
|
||||
|
||||
@@ -177,23 +191,58 @@ async function toRecordDetail(id: string): Promise<void> {
|
||||
// ---------- 表单 ----------
|
||||
|
||||
const submitting = ref(false);
|
||||
const pointValueText = ref("");
|
||||
const sourceValueRange = ref<[number, number]>();
|
||||
const canSubmitRegister = computed(() => !!matchedCustomer.value && !!selectedEventId.value);
|
||||
const showSourceValueInput = computed(() => (
|
||||
userStore.hasPermissions(permissionCodes.point.sourceValue)
|
||||
&& !!sourceValueRange.value
|
||||
));
|
||||
const sourceValuePlaceholder = computed(() => {
|
||||
const range = sourceValueRange.value;
|
||||
return range ? `请输入 ${range[0]}-${range[1]} 的正整数` : "请输入积分";
|
||||
});
|
||||
|
||||
async function loadSourceValueRule(): Promise<void> {
|
||||
if (!selectedEventId.value || !userStore.hasPermissions(permissionCodes.point.sourceValue)) {
|
||||
sourceValueRange.value = undefined;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sourceValueRange.value = await loadSourceValueRange([selectedEventId.value]);
|
||||
} catch {
|
||||
sourceValueRange.value = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function resolveSourceValue(): number | undefined {
|
||||
const value = Number(pointValueText.value);
|
||||
return Number.isSafeInteger(value) && 0 < value ? value : undefined;
|
||||
}
|
||||
|
||||
async function doSubmit(): Promise<void> {
|
||||
const customer = matchedCustomer.value;
|
||||
if (!customer) {
|
||||
return;
|
||||
}
|
||||
const pointValue = resolveSourceValue();
|
||||
const range = sourceValueRange.value;
|
||||
if (showSourceValueInput.value && (!pointValue || !range || pointValue < range[0] || range[1] < pointValue)) {
|
||||
Toast.warning(`自定义积分必须是 ${range?.[0] || 1}-${range?.[1] || 0} 的正整数`);
|
||||
return;
|
||||
}
|
||||
submitting.value = true;
|
||||
try {
|
||||
await EventRecordAPI.create({
|
||||
customerId: customer.id,
|
||||
eventId: selectedEventId.value,
|
||||
pointValue: showSourceValueInput.value ? pointValue : undefined,
|
||||
remark: "客户快速扫码登记"
|
||||
});
|
||||
scanStatus.value = `登记成功:${customer.name || customer.code || scanCode.value}。`;
|
||||
scanCode.value = "";
|
||||
matchedCustomer.value = undefined;
|
||||
pointValueText.value = "";
|
||||
recentRecordList.value = [];
|
||||
latestDecodedText = "";
|
||||
scannerSessionKey.value += 1;
|
||||
@@ -251,6 +300,23 @@ async function doSubmit(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
|
||||
.source-value-title {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.t-input {
|
||||
margin-top: .5rem;
|
||||
border: 1px solid var(--td-component-border);
|
||||
border-radius: .75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.code-box {
|
||||
padding: .875rem;
|
||||
background: #f7faff;
|
||||
@@ -339,6 +405,11 @@ async function doSubmit(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
.source-value-panel {
|
||||
background: rgba(15, 23, 42, .88);
|
||||
box-shadow: 0 .75rem 2rem rgba(2, 6, 23, .32);
|
||||
}
|
||||
|
||||
.code-box {
|
||||
background: rgba(30, 41, 59, .9);
|
||||
border-color: rgba(148, 163, 184, .16);
|
||||
|
||||
Reference in New Issue
Block a user