signal event selector
This commit is contained in:
@@ -1,26 +1,25 @@
|
||||
<template>
|
||||
<div v-can="permissionCodes.eventRecord.create" class="quick-sign-in-page">
|
||||
<space class="content-margin" direction="vertical" v-entrance-transition>
|
||||
<div class="event-panel">
|
||||
<event-selector
|
||||
v-if="!isEventLoading && !eventLoadFailed"
|
||||
:model-value="selectedEventIdList"
|
||||
:event-list="eventList"
|
||||
required-mark
|
||||
@update:model-value="handleEventSelectionChange"
|
||||
/>
|
||||
<div v-else-if="isEventLoading" class="empty-block">正在加载登记事件</div>
|
||||
<div v-else class="event-load-error">
|
||||
<span>登记事件加载失败</span>
|
||||
<t-button size="small" theme="primary" variant="text" @click="loadActions">重试</t-button>
|
||||
</div>
|
||||
<div class="tips red">事件可多选,请注意勾选的登记事件</div>
|
||||
</div>
|
||||
<event-option-selector
|
||||
v-model="selectedOptionSelectionMap"
|
||||
:event-list="eventList"
|
||||
:selected-event-id-list="selectedEventIdList"
|
||||
/>
|
||||
<t-cell-group v-if="!isEventLoading && !eventLoadFailed" theme="card">
|
||||
<t-cell
|
||||
title="登记事件"
|
||||
:note="selectedEventName"
|
||||
arrow
|
||||
@click="eventPopupVisible = true"
|
||||
>
|
||||
<template #left-icon>
|
||||
<t-icon name="task-setting" />
|
||||
</template>
|
||||
</t-cell>
|
||||
</t-cell-group>
|
||||
<div v-else-if="isEventLoading" class="center-tips">正在加载登记事件</div>
|
||||
<div v-else class="center-tips">登记事件加载失败</div>
|
||||
<event-option-selector
|
||||
v-model="selectedOptionSelectionMap"
|
||||
:event-list="eventList"
|
||||
:selected-event-id-list="selectedEventIdList"
|
||||
/>
|
||||
<div class="content-margin">
|
||||
<code-scanner
|
||||
visible
|
||||
:session-key="scannerSessionKey"
|
||||
@@ -29,7 +28,7 @@
|
||||
@decode="handleDecodedText"
|
||||
@status-change="handleScanStatusChange"
|
||||
/>
|
||||
</space>
|
||||
</div>
|
||||
<t-cell-group class="auto-register-setting" theme="card" v-entrance-transition="55">
|
||||
<t-cell title="识别成功自动登记">
|
||||
<template #right-icon>
|
||||
@@ -46,7 +45,7 @@
|
||||
:disabled="!canSubmitRegister"
|
||||
:loading="submitting"
|
||||
v-entrance-transition="70"
|
||||
@click="doSubmit"
|
||||
@click="doSubmit()"
|
||||
>登记</t-button>
|
||||
<customer-profile-card
|
||||
v-if="matchedCustomer"
|
||||
@@ -120,6 +119,29 @@
|
||||
@change="handleRecordPhotoSelected"
|
||||
>
|
||||
</div>
|
||||
<bottom-popup
|
||||
v-model="eventPopupVisible"
|
||||
title="选择登记事件"
|
||||
left-button-text="关闭"
|
||||
right-button-text=""
|
||||
@left-button-click="eventPopupVisible = false"
|
||||
>
|
||||
<div class="event-popup">
|
||||
<event-selector
|
||||
v-if="!isEventLoading && !eventLoadFailed"
|
||||
:model-value="selectedEventIdList"
|
||||
:event-list="eventList"
|
||||
selection-mode="single"
|
||||
label=""
|
||||
@update:model-value="handleEventSelectionChange"
|
||||
/>
|
||||
<div v-else-if="isEventLoading" class="empty-block">正在加载登记事件</div>
|
||||
<div v-else class="event-load-error">
|
||||
<span>登记事件加载失败</span>
|
||||
<t-button size="small" theme="primary" variant="text" @click="loadActions">重试</t-button>
|
||||
</div>
|
||||
</div>
|
||||
</bottom-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -145,7 +167,7 @@ import { compressUploadImageList } from "@/utils/imageCompression";
|
||||
import { Storage, Time } from "timi-web";
|
||||
import { AttachmentAPI, type Attachment } from "timi-web-api";
|
||||
import EventSelector from "@/components/EventSelector.vue";
|
||||
import { Space } from "timi-tdesign-mobile";
|
||||
import { BottomPopup, Space } from "timi-tdesign-mobile";
|
||||
|
||||
defineOptions({
|
||||
name: "QuickSignInPage"
|
||||
@@ -164,9 +186,11 @@ const eventList = ref<EventItem[]>([]);
|
||||
const selectedOptionSelectionMap = reactive<EventOptionSelectionMap>({});
|
||||
const isEventLoading = ref(false);
|
||||
const eventLoadFailed = ref(false);
|
||||
const eventPopupVisible = ref(false);
|
||||
const selectedEventList = computed(() => selectedEventIdList.value
|
||||
.map(eventId => eventList.value.find(item => normalizeEventId(item) === eventId))
|
||||
.filter((item): item is EventItem => !!item));
|
||||
const selectedEventName = computed(() => selectedEventList.value[0]?.name || "请选择登记事件");
|
||||
const selectedNumberEventList = computed(() => selectedEventList.value.filter(item => item.valueType === "NUMBER"));
|
||||
const selectedRequiredPhotoEventList = computed(() => selectedEventList.value.filter(item => item.requirePhoto === true));
|
||||
|
||||
@@ -212,12 +236,13 @@ function buildInitialSelectedEventIdList(): string[] {
|
||||
|
||||
function normalizeSelectedEventIdList(eventIdList: string[]): string[] {
|
||||
const validEventIdSet = new Set(eventList.value.map(normalizeEventId).filter(Boolean));
|
||||
return [...new Set(eventIdList.map(String))].filter(eventId => validEventIdSet.has(eventId));
|
||||
return [...new Set(eventIdList.map(String))].filter(eventId => validEventIdSet.has(eventId)).slice(0, 1);
|
||||
}
|
||||
|
||||
async function handleEventSelectionChange(eventIdList: string[]): Promise<void> {
|
||||
selectedEventIdList.value = normalizeSelectedEventIdList(eventIdList);
|
||||
syncStoredEventId();
|
||||
eventPopupVisible.value = false;
|
||||
}
|
||||
|
||||
function resolveRecordOptionGroupList(eventId: string) {
|
||||
@@ -279,7 +304,7 @@ async function handleDecodedText(rawText: string): Promise<void> {
|
||||
}
|
||||
scanStatus.value = `已识别 ${normalizedText},可直接登记`;
|
||||
if (autoRegisterEnabled.value) {
|
||||
await doSubmit();
|
||||
await doSubmit(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -424,7 +449,7 @@ function buildPhotoAttachmentList(): Array<Partial<Attachment>> {
|
||||
}));
|
||||
}
|
||||
|
||||
async function doSubmit(): Promise<void> {
|
||||
async function doSubmit(isAutoRegister = false): Promise<void> {
|
||||
const customer = matchedCustomer.value;
|
||||
if (!customer) {
|
||||
return;
|
||||
@@ -465,7 +490,11 @@ async function doSubmit(): Promise<void> {
|
||||
attachmentList: buildPhotoAttachmentList()
|
||||
})));
|
||||
registeredCustomerIdSet.add(customerId);
|
||||
scanStatus.value = `登记成功:${customer.name || customer.code || scanCode.value}。`;
|
||||
const customerText = customer.name || customer.code || scanCode.value || "客户";
|
||||
scanStatus.value = `登记成功:${customerText}。`;
|
||||
if (isAutoRegister) {
|
||||
Message.success(`自动登记成功:${customerText}`);
|
||||
}
|
||||
scanCode.value = "";
|
||||
matchedCustomer.value = undefined;
|
||||
recordPhotoItemList.value = [];
|
||||
@@ -493,18 +522,6 @@ async function doSubmit(): Promise<void> {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.event-panel {
|
||||
padding: .75rem 1rem;
|
||||
background: rgba(255, 255, 255, .94);
|
||||
box-shadow: 0 .75rem 2rem rgba(15, 23, 42, .08);
|
||||
border-radius: .875rem;
|
||||
|
||||
.tips {
|
||||
margin-top: .5rem;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.input-form {
|
||||
padding: .5rem 0;
|
||||
background: rgba(255, 255, 255, .94);
|
||||
@@ -526,24 +543,6 @@ async function doSubmit(): Promise<void> {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.empty-block,
|
||||
.event-load-error {
|
||||
color: #52607a;
|
||||
min-height: 4rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-block {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.event-load-error {
|
||||
gap: .5rem;
|
||||
display: grid;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.code-box {
|
||||
padding: .875rem;
|
||||
background: #f7faff;
|
||||
@@ -581,6 +580,10 @@ async function doSubmit(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
.event-popup {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
:global(html.theme-dark) {
|
||||
.quick-sign-in-page {
|
||||
.panel,
|
||||
|
||||
@@ -208,7 +208,6 @@ onUnmounted(() => {
|
||||
|
||||
.tips {
|
||||
font-size: .875rem;
|
||||
margin-top: 1rem;
|
||||
text-indent: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user