refactor(@vben/web-antd): remove store code field from store drawer
This commit is contained in:
@@ -8,21 +8,34 @@ import type { SelectOptionItem } from '../types';
|
||||
|
||||
import type { ServiceType, StoreBusinessStatus } from '#/api/store';
|
||||
|
||||
import { Button, Drawer, Form, FormItem, Input, Select } from 'ant-design-vue';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Drawer,
|
||||
Form,
|
||||
FormItem,
|
||||
Input,
|
||||
message,
|
||||
Select,
|
||||
Upload,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
interface Props {
|
||||
address: string;
|
||||
businessStatus: StoreBusinessStatus;
|
||||
businessStatusOptions: SelectOptionItem<StoreBusinessStatus>[];
|
||||
code: string;
|
||||
contactPhone: string;
|
||||
coverImage?: string;
|
||||
isSubmitting: boolean;
|
||||
managerName: string;
|
||||
name: string;
|
||||
onSetAddress: (value: string) => void;
|
||||
onSetBusinessStatus: (value: StoreBusinessStatus) => void;
|
||||
onSetCode: (value: string) => void;
|
||||
onSetContactPhone: (value: string) => void;
|
||||
onSetCoverImage?: (value: string) => void;
|
||||
onSetManagerName: (value: string) => void;
|
||||
onSetName: (value: string) => void;
|
||||
onSetServiceTypes: (value: ServiceType[]) => void;
|
||||
@@ -51,16 +64,6 @@ function readEnumValue<T extends number>(value: unknown): T | undefined {
|
||||
return Number.isFinite(numericValue) ? (numericValue as T) : undefined;
|
||||
}
|
||||
|
||||
/** 解析服务方式多选结果。 */
|
||||
function readServiceTypeList(value: unknown): ServiceType[] {
|
||||
if (!Array.isArray(value)) return [];
|
||||
|
||||
return value
|
||||
.map(Number)
|
||||
.filter((item) => Number.isFinite(item))
|
||||
.map((item) => item as ServiceType);
|
||||
}
|
||||
|
||||
/** 同步营业状态。 */
|
||||
function handleBusinessStatusChange(value: unknown) {
|
||||
const nextStatus = readEnumValue<StoreBusinessStatus>(value);
|
||||
@@ -68,9 +71,41 @@ function handleBusinessStatusChange(value: unknown) {
|
||||
props.onSetBusinessStatus(nextStatus);
|
||||
}
|
||||
|
||||
/** 同步服务方式。 */
|
||||
function handleServiceTypesChange(value: unknown) {
|
||||
props.onSetServiceTypes(readServiceTypeList(value));
|
||||
/** 切换服务方式。 */
|
||||
function toggleServiceType(value: ServiceType) {
|
||||
const current = [...props.serviceTypes];
|
||||
const index = current.indexOf(value);
|
||||
if (index === -1) {
|
||||
current.push(value);
|
||||
} else {
|
||||
current.splice(index, 1);
|
||||
}
|
||||
props.onSetServiceTypes(current);
|
||||
}
|
||||
|
||||
/** 处理图片上传。 */
|
||||
async function handleUpload(options: any) {
|
||||
const { file, onSuccess, onError } = options;
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
// 假设后端上传接口为 /upload,返回 { url: string }
|
||||
const res = await requestClient.post<{ url: string }>('/upload', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
|
||||
const url = res?.url || (typeof res === 'string' ? res : '');
|
||||
if (url) {
|
||||
props.onSetCoverImage?.(url);
|
||||
onSuccess(res, file);
|
||||
message.success('上传成功');
|
||||
} else {
|
||||
throw new Error('Upload response missing url');
|
||||
}
|
||||
} catch (error) {
|
||||
onError(error);
|
||||
message.error('上传失败');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -92,13 +127,6 @@ function handleServiceTypesChange(value: unknown) {
|
||||
@update:value="(value) => props.onSetName(readTextValue(value))"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="门店编码" required>
|
||||
<Input
|
||||
:value="props.code"
|
||||
placeholder="如:ST20250006"
|
||||
@update:value="(value) => props.onSetCode(readTextValue(value))"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="联系电话" required>
|
||||
<Input
|
||||
:value="props.contactPhone"
|
||||
@@ -125,6 +153,33 @@ function handleServiceTypesChange(value: unknown) {
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="门店图片">
|
||||
<Upload
|
||||
name="file"
|
||||
list-type="picture-card"
|
||||
class="avatar-uploader"
|
||||
:show-upload-list="false"
|
||||
:custom-request="handleUpload"
|
||||
>
|
||||
<img
|
||||
v-if="props.coverImage"
|
||||
:src="props.coverImage"
|
||||
alt="avatar"
|
||||
class="h-full w-full rounded-lg object-cover"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-col items-center justify-center text-gray-400"
|
||||
>
|
||||
<IconifyIcon
|
||||
icon="ant-design:plus-outlined"
|
||||
class="mb-2 text-2xl"
|
||||
/>
|
||||
<div class="text-xs">点击上传门店图片</div>
|
||||
</div>
|
||||
</Upload>
|
||||
</FormItem>
|
||||
|
||||
<div class="store-drawer-section-title">营业设置</div>
|
||||
<FormItem label="营业状态">
|
||||
<Select
|
||||
@@ -133,14 +188,22 @@ function handleServiceTypesChange(value: unknown) {
|
||||
@update:value="handleBusinessStatusChange"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="服务方式">
|
||||
<Select
|
||||
:value="props.serviceTypes"
|
||||
mode="multiple"
|
||||
placeholder="请选择服务方式"
|
||||
:options="props.serviceTypeOptions"
|
||||
@update:value="handleServiceTypesChange"
|
||||
/>
|
||||
<FormItem label="配送方式">
|
||||
<div class="flex gap-3">
|
||||
<div
|
||||
v-for="option in props.serviceTypeOptions"
|
||||
:key="option.value"
|
||||
class="cursor-pointer select-none rounded-full border px-4 py-1.5 text-sm transition-all"
|
||||
:class="
|
||||
props.serviceTypes.includes(option.value)
|
||||
? 'border-primary bg-primary/5 font-medium text-primary'
|
||||
: 'border-gray-200 text-gray-500 hover:border-primary/50 hover:text-primary/80'
|
||||
"
|
||||
@click="toggleServiceType(option.value)"
|
||||
>
|
||||
{{ option.label }}
|
||||
</div>
|
||||
</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ export const DEFAULT_FILTERS: StoreFilterState = {
|
||||
export const DEFAULT_FORM_STATE: StoreFormState = {
|
||||
address: '',
|
||||
businessStatus: StoreBusinessStatusEnum.Operating,
|
||||
code: '',
|
||||
contactPhone: '',
|
||||
coverImage: '',
|
||||
id: '',
|
||||
|
||||
@@ -40,7 +40,6 @@ export function applyRecordToForm(
|
||||
Object.assign(formState, {
|
||||
address: store.address,
|
||||
businessStatus: store.businessStatus,
|
||||
code: store.code,
|
||||
contactPhone: store.contactPhone,
|
||||
coverImage: store.coverImage || '',
|
||||
id: store.id,
|
||||
@@ -55,7 +54,6 @@ export function toSavePayload(formState: StoreFormState): SaveStoreDto {
|
||||
return {
|
||||
address: formState.address.trim(),
|
||||
businessStatus: formState.businessStatus,
|
||||
code: formState.code.trim(),
|
||||
contactPhone: formState.contactPhone.trim(),
|
||||
coverImage: formState.coverImage.trim(),
|
||||
id: formState.id || undefined,
|
||||
|
||||
@@ -143,10 +143,6 @@ export function useStoreListPage() {
|
||||
formState.name = value;
|
||||
}
|
||||
|
||||
function setFormCode(value: string) {
|
||||
formState.code = value;
|
||||
}
|
||||
|
||||
function setFormContactPhone(value: string) {
|
||||
formState.contactPhone = value;
|
||||
}
|
||||
@@ -159,6 +155,10 @@ export function useStoreListPage() {
|
||||
formState.address = value;
|
||||
}
|
||||
|
||||
function setFormCoverImage(value: string) {
|
||||
formState.coverImage = value;
|
||||
}
|
||||
|
||||
function setFormBusinessStatus(value: StoreBusinessStatus) {
|
||||
formState.businessStatus = value;
|
||||
}
|
||||
@@ -210,8 +210,8 @@ export function useStoreListPage() {
|
||||
setDrawerVisible,
|
||||
setFormAddress,
|
||||
setFormBusinessStatus,
|
||||
setFormCode,
|
||||
setFormContactPhone,
|
||||
setFormCoverImage,
|
||||
setFormManagerName,
|
||||
setFormName,
|
||||
setFormServiceTypes,
|
||||
|
||||
@@ -41,8 +41,8 @@ const {
|
||||
setDrawerVisible,
|
||||
setFormAddress,
|
||||
setFormBusinessStatus,
|
||||
setFormCode,
|
||||
setFormContactPhone,
|
||||
setFormCoverImage,
|
||||
setFormManagerName,
|
||||
setFormName,
|
||||
setFormServiceTypes,
|
||||
@@ -105,7 +105,7 @@ function handleExport() {
|
||||
:title="drawerTitle"
|
||||
:is-submitting="isSubmitting"
|
||||
:name="formState.name"
|
||||
:code="formState.code"
|
||||
:cover-image="formState.coverImage"
|
||||
:contact-phone="formState.contactPhone"
|
||||
:manager-name="formState.managerName"
|
||||
:address="formState.address"
|
||||
@@ -114,7 +114,7 @@ function handleExport() {
|
||||
:business-status-options="businessStatusOptions"
|
||||
:service-type-options="serviceTypeOptions"
|
||||
:on-set-name="setFormName"
|
||||
:on-set-code="setFormCode"
|
||||
:on-set-cover-image="setFormCoverImage"
|
||||
:on-set-contact-phone="setFormContactPhone"
|
||||
:on-set-manager-name="setFormManagerName"
|
||||
:on-set-address="setFormAddress"
|
||||
|
||||
@@ -40,7 +40,6 @@ export interface StoreFilterState {
|
||||
export interface StoreFormState {
|
||||
address: string;
|
||||
businessStatus: StoreBusinessStatus;
|
||||
code: string;
|
||||
contactPhone: string;
|
||||
coverImage: string;
|
||||
id: string;
|
||||
|
||||
Reference in New Issue
Block a user