refactor(@vben/web-antd): remove store code field from store drawer
This commit is contained in:
@@ -68,7 +68,6 @@ export interface PaginatedResult<T> {
|
|||||||
export interface SaveStoreDto {
|
export interface SaveStoreDto {
|
||||||
id?: string;
|
id?: string;
|
||||||
name: string;
|
name: string;
|
||||||
code: string;
|
|
||||||
contactPhone: string;
|
contactPhone: string;
|
||||||
managerName: string;
|
managerName: string;
|
||||||
address: string;
|
address: string;
|
||||||
|
|||||||
@@ -8,21 +8,34 @@ import type { SelectOptionItem } from '../types';
|
|||||||
|
|
||||||
import type { ServiceType, StoreBusinessStatus } from '#/api/store';
|
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 {
|
interface Props {
|
||||||
address: string;
|
address: string;
|
||||||
businessStatus: StoreBusinessStatus;
|
businessStatus: StoreBusinessStatus;
|
||||||
businessStatusOptions: SelectOptionItem<StoreBusinessStatus>[];
|
businessStatusOptions: SelectOptionItem<StoreBusinessStatus>[];
|
||||||
code: string;
|
|
||||||
contactPhone: string;
|
contactPhone: string;
|
||||||
|
coverImage?: string;
|
||||||
isSubmitting: boolean;
|
isSubmitting: boolean;
|
||||||
managerName: string;
|
managerName: string;
|
||||||
name: string;
|
name: string;
|
||||||
onSetAddress: (value: string) => void;
|
onSetAddress: (value: string) => void;
|
||||||
onSetBusinessStatus: (value: StoreBusinessStatus) => void;
|
onSetBusinessStatus: (value: StoreBusinessStatus) => void;
|
||||||
onSetCode: (value: string) => void;
|
|
||||||
onSetContactPhone: (value: string) => void;
|
onSetContactPhone: (value: string) => void;
|
||||||
|
onSetCoverImage?: (value: string) => void;
|
||||||
onSetManagerName: (value: string) => void;
|
onSetManagerName: (value: string) => void;
|
||||||
onSetName: (value: string) => void;
|
onSetName: (value: string) => void;
|
||||||
onSetServiceTypes: (value: ServiceType[]) => 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;
|
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) {
|
function handleBusinessStatusChange(value: unknown) {
|
||||||
const nextStatus = readEnumValue<StoreBusinessStatus>(value);
|
const nextStatus = readEnumValue<StoreBusinessStatus>(value);
|
||||||
@@ -68,9 +71,41 @@ function handleBusinessStatusChange(value: unknown) {
|
|||||||
props.onSetBusinessStatus(nextStatus);
|
props.onSetBusinessStatus(nextStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 同步服务方式。 */
|
/** 切换服务方式。 */
|
||||||
function handleServiceTypesChange(value: unknown) {
|
function toggleServiceType(value: ServiceType) {
|
||||||
props.onSetServiceTypes(readServiceTypeList(value));
|
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>
|
</script>
|
||||||
|
|
||||||
@@ -92,13 +127,6 @@ function handleServiceTypesChange(value: unknown) {
|
|||||||
@update:value="(value) => props.onSetName(readTextValue(value))"
|
@update:value="(value) => props.onSetName(readTextValue(value))"
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="门店编码" required>
|
|
||||||
<Input
|
|
||||||
:value="props.code"
|
|
||||||
placeholder="如:ST20250006"
|
|
||||||
@update:value="(value) => props.onSetCode(readTextValue(value))"
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem label="联系电话" required>
|
<FormItem label="联系电话" required>
|
||||||
<Input
|
<Input
|
||||||
:value="props.contactPhone"
|
:value="props.contactPhone"
|
||||||
@@ -125,6 +153,33 @@ function handleServiceTypesChange(value: unknown) {
|
|||||||
/>
|
/>
|
||||||
</FormItem>
|
</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>
|
<div class="store-drawer-section-title">营业设置</div>
|
||||||
<FormItem label="营业状态">
|
<FormItem label="营业状态">
|
||||||
<Select
|
<Select
|
||||||
@@ -133,14 +188,22 @@ function handleServiceTypesChange(value: unknown) {
|
|||||||
@update:value="handleBusinessStatusChange"
|
@update:value="handleBusinessStatusChange"
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="服务方式">
|
<FormItem label="配送方式">
|
||||||
<Select
|
<div class="flex gap-3">
|
||||||
:value="props.serviceTypes"
|
<div
|
||||||
mode="multiple"
|
v-for="option in props.serviceTypeOptions"
|
||||||
placeholder="请选择服务方式"
|
:key="option.value"
|
||||||
:options="props.serviceTypeOptions"
|
class="cursor-pointer select-none rounded-full border px-4 py-1.5 text-sm transition-all"
|
||||||
@update:value="handleServiceTypesChange"
|
: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>
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ export const DEFAULT_FILTERS: StoreFilterState = {
|
|||||||
export const DEFAULT_FORM_STATE: StoreFormState = {
|
export const DEFAULT_FORM_STATE: StoreFormState = {
|
||||||
address: '',
|
address: '',
|
||||||
businessStatus: StoreBusinessStatusEnum.Operating,
|
businessStatus: StoreBusinessStatusEnum.Operating,
|
||||||
code: '',
|
|
||||||
contactPhone: '',
|
contactPhone: '',
|
||||||
coverImage: '',
|
coverImage: '',
|
||||||
id: '',
|
id: '',
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ export function applyRecordToForm(
|
|||||||
Object.assign(formState, {
|
Object.assign(formState, {
|
||||||
address: store.address,
|
address: store.address,
|
||||||
businessStatus: store.businessStatus,
|
businessStatus: store.businessStatus,
|
||||||
code: store.code,
|
|
||||||
contactPhone: store.contactPhone,
|
contactPhone: store.contactPhone,
|
||||||
coverImage: store.coverImage || '',
|
coverImage: store.coverImage || '',
|
||||||
id: store.id,
|
id: store.id,
|
||||||
@@ -55,7 +54,6 @@ export function toSavePayload(formState: StoreFormState): SaveStoreDto {
|
|||||||
return {
|
return {
|
||||||
address: formState.address.trim(),
|
address: formState.address.trim(),
|
||||||
businessStatus: formState.businessStatus,
|
businessStatus: formState.businessStatus,
|
||||||
code: formState.code.trim(),
|
|
||||||
contactPhone: formState.contactPhone.trim(),
|
contactPhone: formState.contactPhone.trim(),
|
||||||
coverImage: formState.coverImage.trim(),
|
coverImage: formState.coverImage.trim(),
|
||||||
id: formState.id || undefined,
|
id: formState.id || undefined,
|
||||||
|
|||||||
@@ -143,10 +143,6 @@ export function useStoreListPage() {
|
|||||||
formState.name = value;
|
formState.name = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFormCode(value: string) {
|
|
||||||
formState.code = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setFormContactPhone(value: string) {
|
function setFormContactPhone(value: string) {
|
||||||
formState.contactPhone = value;
|
formState.contactPhone = value;
|
||||||
}
|
}
|
||||||
@@ -159,6 +155,10 @@ export function useStoreListPage() {
|
|||||||
formState.address = value;
|
formState.address = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setFormCoverImage(value: string) {
|
||||||
|
formState.coverImage = value;
|
||||||
|
}
|
||||||
|
|
||||||
function setFormBusinessStatus(value: StoreBusinessStatus) {
|
function setFormBusinessStatus(value: StoreBusinessStatus) {
|
||||||
formState.businessStatus = value;
|
formState.businessStatus = value;
|
||||||
}
|
}
|
||||||
@@ -210,8 +210,8 @@ export function useStoreListPage() {
|
|||||||
setDrawerVisible,
|
setDrawerVisible,
|
||||||
setFormAddress,
|
setFormAddress,
|
||||||
setFormBusinessStatus,
|
setFormBusinessStatus,
|
||||||
setFormCode,
|
|
||||||
setFormContactPhone,
|
setFormContactPhone,
|
||||||
|
setFormCoverImage,
|
||||||
setFormManagerName,
|
setFormManagerName,
|
||||||
setFormName,
|
setFormName,
|
||||||
setFormServiceTypes,
|
setFormServiceTypes,
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ const {
|
|||||||
setDrawerVisible,
|
setDrawerVisible,
|
||||||
setFormAddress,
|
setFormAddress,
|
||||||
setFormBusinessStatus,
|
setFormBusinessStatus,
|
||||||
setFormCode,
|
|
||||||
setFormContactPhone,
|
setFormContactPhone,
|
||||||
|
setFormCoverImage,
|
||||||
setFormManagerName,
|
setFormManagerName,
|
||||||
setFormName,
|
setFormName,
|
||||||
setFormServiceTypes,
|
setFormServiceTypes,
|
||||||
@@ -105,7 +105,7 @@ function handleExport() {
|
|||||||
:title="drawerTitle"
|
:title="drawerTitle"
|
||||||
:is-submitting="isSubmitting"
|
:is-submitting="isSubmitting"
|
||||||
:name="formState.name"
|
:name="formState.name"
|
||||||
:code="formState.code"
|
:cover-image="formState.coverImage"
|
||||||
:contact-phone="formState.contactPhone"
|
:contact-phone="formState.contactPhone"
|
||||||
:manager-name="formState.managerName"
|
:manager-name="formState.managerName"
|
||||||
:address="formState.address"
|
:address="formState.address"
|
||||||
@@ -114,7 +114,7 @@ function handleExport() {
|
|||||||
:business-status-options="businessStatusOptions"
|
:business-status-options="businessStatusOptions"
|
||||||
:service-type-options="serviceTypeOptions"
|
:service-type-options="serviceTypeOptions"
|
||||||
:on-set-name="setFormName"
|
:on-set-name="setFormName"
|
||||||
:on-set-code="setFormCode"
|
:on-set-cover-image="setFormCoverImage"
|
||||||
:on-set-contact-phone="setFormContactPhone"
|
:on-set-contact-phone="setFormContactPhone"
|
||||||
:on-set-manager-name="setFormManagerName"
|
:on-set-manager-name="setFormManagerName"
|
||||||
:on-set-address="setFormAddress"
|
:on-set-address="setFormAddress"
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ export interface StoreFilterState {
|
|||||||
export interface StoreFormState {
|
export interface StoreFormState {
|
||||||
address: string;
|
address: string;
|
||||||
businessStatus: StoreBusinessStatus;
|
businessStatus: StoreBusinessStatus;
|
||||||
code: string;
|
|
||||||
contactPhone: string;
|
contactPhone: string;
|
||||||
coverImage: string;
|
coverImage: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user