add package

This commit is contained in:
Timi
2026-09-01 01:14:54 +08:00
parent 100d4c4c44
commit 2d94abfb32
39 changed files with 4425 additions and 59 deletions
+12 -1
View File
@@ -43,10 +43,12 @@ interface Props {
modelValue: string | string[];
visible: boolean;
selectionMode?: SelectionMode;
storeId?: string;
}
const props = withDefaults(defineProps<Props>(), {
selectionMode: "single"
selectionMode: "single",
storeId: ""
});
const emit = defineEmits<{
@@ -100,6 +102,7 @@ async function loadCustomers(): Promise<void> {
const result = await CustomerAPI.list({
index: pageIndex.value,
size: pageSize,
storeId: props.storeId || undefined,
likesExample: {
code: keyword.value || undefined,
name: keyword.value || undefined,
@@ -195,6 +198,14 @@ watch(() => props.visible, async (value) => {
await bindScrollListener();
});
watch(() => props.storeId, async () => {
if (!props.visible) {
return;
}
await reloadCustomers();
await bindScrollListener();
});
watch(keyword, async () => {
if (!props.visible) {
return;
+89
View File
@@ -0,0 +1,89 @@
<template>
<div class="package-photo-field">
<photo-scroller
v-model="photoUrlList"
v-model:photo-items="photoItems"
:title="title"
:required="required"
:loading="isUploading"
:edit-mode="true"
@add="openFilePicker"
/>
<input ref="fileInput" class="file-input" type="file" accept="image/*" multiple @change="handleFileChange" />
</div>
</template>
<script setup lang="ts">
import { AttachmentAPI } from "timi-web-api";
import PhotoScroller from "@/components/PhotoScroller.vue";
import type { PhotoItem } from "@/types/Photo";
import { compressUploadImageList } from "@/utils/imageCompression";
import { Message } from "@/utils/message";
interface Props {
required?: boolean;
title?: string;
}
withDefaults(defineProps<Props>(), {
required: false,
title: "业务照片"
});
defineOptions({
name: "PackagePhotoField"
});
const photoItems = defineModel<PhotoItem[]>({ required: true });
const fileInput = ref<HTMLInputElement>();
const isUploading = ref(false);
const photoUrlList = computed<string[]>({
get: () => photoItems.value.map(item => item.url),
set: value => {
const urlSet = new Set(value);
photoItems.value = photoItems.value.filter(item => urlSet.has(item.url));
}
});
function openFilePicker(): void {
fileInput.value?.click();
}
async function handleFileChange(event: Event): Promise<void> {
const input = event.target as HTMLInputElement;
const fileList = Array.from(input.files || []);
if (!fileList.length) {
return;
}
isUploading.value = true;
try {
const tempFileList = await AttachmentAPI.upload(await compressUploadImageList(fileList));
for (const tempFile of tempFileList) {
if (!tempFile.id) {
continue;
}
photoItems.value.push({
tempFileId: tempFile.id,
attachType: "PHOTO",
url: AttachmentAPI.getTempReadURL(tempFile.id)
});
}
} catch {
Message.error("照片上传失败");
} finally {
isUploading.value = false;
input.value = "";
}
}
</script>
<style scoped lang="less">
.package-photo-field {
width: 100%;
.file-input {
display: none;
}
}
</style>
+18 -5
View File
@@ -126,14 +126,27 @@ function getUserAgentMajorVersion(userAgent: string, pattern: RegExp): number {
// ---------- 导航返回 ----------
function doBack(): void {
if (navBarStore.backTo) {
router.push(navBarStore.backTo);
navBarStore.setBackTo(undefined);
let isBacking = false;
async function doBack(): Promise<void> {
if (isBacking) {
return;
}
router.back();
isBacking = true;
const backTo = navBarStore.backTo;
navBarStore.setBackTo(undefined);
navBarStore.clearRight();
try {
if (backTo) {
await router.push(backTo);
return;
}
await router.back();
} finally {
isBacking = false;
}
}
// ---------- 右侧操作 ----------