feat(project): wire quick business status toggle in store list
This commit is contained in:
@@ -76,6 +76,14 @@ export interface SaveStoreDto {
|
||||
serviceTypes?: ServiceType[];
|
||||
}
|
||||
|
||||
/** 快速切换门店营业状态参数 */
|
||||
export interface ToggleStoreBusinessStatusDto {
|
||||
storeId: string;
|
||||
businessStatus: StoreBusinessStatus;
|
||||
closureReason?: number;
|
||||
closureReasonText?: string;
|
||||
}
|
||||
|
||||
/** 获取门店列表 */
|
||||
export async function getStoreListApi(params: StoreListQuery) {
|
||||
return requestClient.get<PaginatedResult<StoreListItemDto>>('/store/list', {
|
||||
@@ -102,3 +110,10 @@ export async function updateStoreApi(data: SaveStoreDto) {
|
||||
export async function deleteStoreApi(id: string) {
|
||||
return requestClient.post('/store/delete', { id });
|
||||
}
|
||||
|
||||
/** 快速切换门店营业状态 */
|
||||
export async function toggleStoreBusinessStatusApi(
|
||||
data: ToggleStoreBusinessStatusDto,
|
||||
) {
|
||||
return requestClient.post('/store/toggle-business-status', data);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@ import type { StoreListItemDto } from '#/api/store';
|
||||
|
||||
import { Button, Card, Popconfirm, Table, Tag } from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
StoreAuditStatus as StoreAuditStatusEnum,
|
||||
StoreBusinessStatus as StoreBusinessStatusEnum,
|
||||
} from '#/api/store';
|
||||
|
||||
interface Props {
|
||||
auditStatusMap: Record<number, StatusTagMeta>;
|
||||
businessStatusMap: Record<number, StatusTagMeta>;
|
||||
@@ -30,6 +35,7 @@ const props = defineProps<Props>();
|
||||
const emit = defineEmits<{
|
||||
(event: 'delete', record: StoreListItemDto): void;
|
||||
(event: 'edit', record: StoreListItemDto): void;
|
||||
(event: 'toggleBusinessStatus', record: StoreListItemDto): void;
|
||||
(event: 'tableChange', pagination: TablePagination): void;
|
||||
}>();
|
||||
|
||||
@@ -56,6 +62,51 @@ function emitDelete(record: unknown) {
|
||||
if (!isStoreRecord(record)) return;
|
||||
emit('delete', record);
|
||||
}
|
||||
|
||||
/** 当前门店是否允许快速切换营业状态。 */
|
||||
function canQuickToggleBusinessStatus(record: unknown) {
|
||||
if (!isStoreRecord(record)) return false;
|
||||
return (
|
||||
record.auditStatus === StoreAuditStatusEnum.Approved &&
|
||||
record.businessStatus !== StoreBusinessStatusEnum.ForceClosed
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取快速切换按钮文案。 */
|
||||
function getToggleBusinessStatusText(record: unknown) {
|
||||
if (!isStoreRecord(record)) return '不可切换';
|
||||
const status = record.businessStatus;
|
||||
if (status === StoreBusinessStatusEnum.Operating) {
|
||||
return '设为休息';
|
||||
}
|
||||
if (status === StoreBusinessStatusEnum.Resting) {
|
||||
return '恢复营业';
|
||||
}
|
||||
return '不可切换';
|
||||
}
|
||||
|
||||
/** 安全触发营业状态切换事件。 */
|
||||
function emitToggleBusinessStatus(record: unknown) {
|
||||
if (!isStoreRecord(record)) return;
|
||||
emit('toggleBusinessStatus', record);
|
||||
}
|
||||
|
||||
/** 创建时间格式化为 yyyy-MM-dd。 */
|
||||
function formatCreatedDate(value: string) {
|
||||
if (!value) return '--';
|
||||
const isoDateMatch = /^(\d{4}-\d{2}-\d{2})/.exec(value.trim());
|
||||
if (isoDateMatch) {
|
||||
return isoDateMatch[1] ?? '--';
|
||||
}
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return value.slice(0, 10) || '--';
|
||||
}
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -129,11 +180,23 @@ function emitDelete(record: unknown) {
|
||||
</Tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'createdAt'">
|
||||
<span>{{ formatCreatedDate(record.createdAt) }}</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<div class="store-action-row">
|
||||
<Button type="link" size="small" @click="emitEdit(record)">
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
:disabled="!canQuickToggleBusinessStatus(record)"
|
||||
@click="emitToggleBusinessStatus(record)"
|
||||
>
|
||||
{{ getToggleBusinessStatusText(record) }}
|
||||
</Button>
|
||||
<Popconfirm
|
||||
title="确定要删除该门店吗?"
|
||||
ok-text="确定"
|
||||
|
||||
@@ -8,11 +8,17 @@ import type { Ref } from 'vue';
|
||||
|
||||
import type { DrawerMode, StoreFormState } from '../../types';
|
||||
|
||||
import type { StoreListItemDto } from '#/api/store';
|
||||
import type { StoreBusinessStatus, StoreListItemDto } from '#/api/store';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { createStoreApi, deleteStoreApi, updateStoreApi } from '#/api/store';
|
||||
import {
|
||||
createStoreApi,
|
||||
deleteStoreApi,
|
||||
StoreBusinessStatus as StoreBusinessStatusEnum,
|
||||
toggleStoreBusinessStatusApi,
|
||||
updateStoreApi,
|
||||
} from '#/api/store';
|
||||
|
||||
import { applyRecordToForm, resetStoreForm, toSavePayload } from './helpers';
|
||||
|
||||
@@ -81,9 +87,40 @@ export function createDrawerActions(options: CreateDrawerActionsOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
/** 快速切换门店营业状态。 */
|
||||
async function handleToggleBusinessStatus(record: StoreListItemDto) {
|
||||
try {
|
||||
const nextStatus: StoreBusinessStatus =
|
||||
record.businessStatus === StoreBusinessStatusEnum.Operating
|
||||
? StoreBusinessStatusEnum.Resting
|
||||
: StoreBusinessStatusEnum.Operating;
|
||||
|
||||
await toggleStoreBusinessStatusApi({
|
||||
storeId: record.id,
|
||||
businessStatus: nextStatus,
|
||||
...(nextStatus === StoreBusinessStatusEnum.Resting
|
||||
? {
|
||||
closureReason: 99,
|
||||
closureReasonText: '门店手动切换为休息中',
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
message.success(
|
||||
nextStatus === StoreBusinessStatusEnum.Operating
|
||||
? '已恢复营业'
|
||||
: '已切换为休息中',
|
||||
);
|
||||
await Promise.all([options.loadList(), options.loadStats()]);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
handleDelete,
|
||||
handleSubmit,
|
||||
handleToggleBusinessStatus,
|
||||
openDrawer,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -108,14 +108,15 @@ export function useStoreListPage() {
|
||||
});
|
||||
|
||||
// 6. 组装抽屉与删除动作。
|
||||
const { handleDelete, handleSubmit, openDrawer } = createDrawerActions({
|
||||
drawerMode,
|
||||
formState,
|
||||
isDrawerVisible,
|
||||
isSubmitting,
|
||||
loadList,
|
||||
loadStats,
|
||||
});
|
||||
const { handleDelete, handleSubmit, handleToggleBusinessStatus, openDrawer } =
|
||||
createDrawerActions({
|
||||
drawerMode,
|
||||
formState,
|
||||
isDrawerVisible,
|
||||
isSubmitting,
|
||||
loadList,
|
||||
loadStats,
|
||||
});
|
||||
|
||||
// 7. 筛选字段更新方法。
|
||||
function setKeyword(value: string) {
|
||||
@@ -185,6 +186,7 @@ export function useStoreListPage() {
|
||||
formState,
|
||||
getAvatarColor,
|
||||
handleDeleteStore: handleDelete,
|
||||
handleToggleStoreBusinessStatus: handleToggleBusinessStatus,
|
||||
handleReset,
|
||||
handleSearch,
|
||||
handleSubmitStore: handleSubmit,
|
||||
|
||||
@@ -25,6 +25,7 @@ const {
|
||||
formState,
|
||||
getAvatarColor,
|
||||
handleDeleteStore,
|
||||
handleToggleStoreBusinessStatus,
|
||||
handleReset,
|
||||
handleSearch,
|
||||
handleSubmitStore,
|
||||
@@ -96,6 +97,7 @@ function handleExport() {
|
||||
@table-change="handleTableChange"
|
||||
@edit="openEditDrawer"
|
||||
@delete="handleDeleteStore"
|
||||
@toggle-business-status="handleToggleStoreBusinessStatus"
|
||||
/>
|
||||
|
||||
<StoreEditorDrawer
|
||||
|
||||
Reference in New Issue
Block a user