add point

This commit is contained in:
Timi
2026-08-11 22:25:30 +08:00
parent e612cfd382
commit 9f60a36c6c
21 changed files with 2928 additions and 36 deletions
+74 -2
View File
@@ -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);