refactor file tree
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<div v-can="savePermissionCode" class="store-edit">
|
||||
<t-form class="form" label-align="left">
|
||||
<t-form-item v-if="!isStoreManagerScope" label="编码">
|
||||
<t-input v-model.trim="formModel.code" placeholder="门店编码" borderless />
|
||||
</t-form-item>
|
||||
<t-form-item label="名称">
|
||||
<t-input v-model.trim="formModel.name" placeholder="门店名称" borderless />
|
||||
</t-form-item>
|
||||
<t-form-item v-if="!isStoreManagerScope" label="启用" content-align="right">
|
||||
<t-switch v-model="formModel.status" :custom-value="['ACTIVE', 'INACTIVE']" />
|
||||
</t-form-item>
|
||||
<t-form-item label="电话">
|
||||
<t-input v-model.trim="formModel.telephone" type="tel" placeholder="联系电话" borderless />
|
||||
</t-form-item>
|
||||
<t-form-item label="地址">
|
||||
<t-input v-model.trim="formModel.address" placeholder="门店地址" borderless />
|
||||
</t-form-item>
|
||||
<t-form-item label="备注">
|
||||
<t-textarea v-model.trim="formModel.remark" class="textarea" placeholder="备注" autosize borderless />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
<t-cell-group v-if="!isCreateMode" theme="card">
|
||||
<t-cell title="营业日管理" note="配置营业或休息日期" arrow hover @click="router.push(`/management/stores/${routeId}/business-days`)" />
|
||||
</t-cell-group>
|
||||
<div class="actions">
|
||||
<t-button
|
||||
v-if="!isCreateMode && !isStoreManagerScope"
|
||||
v-can="permissionCodes.store.delete"
|
||||
class="action"
|
||||
theme="danger"
|
||||
:loading="isRemoving"
|
||||
@click="confirmRemoveStore"
|
||||
>删除</t-button>
|
||||
<t-button
|
||||
class="action"
|
||||
theme="primary"
|
||||
:loading="isSaving"
|
||||
@click="saveStore"
|
||||
>保存</t-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DialogPlugin, Toast } from "tdesign-mobile-vue";
|
||||
import { useUserStore } from "timi-web";
|
||||
import StoreAPI from "@/api/StoreAPI";
|
||||
import type { Store, StoreStatus } from "@/types/Store";
|
||||
import { gaoRoleCodes, permissionCodes } from "@/utils/permission";
|
||||
|
||||
defineOptions({
|
||||
name: "StoreEdit"
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const userStore = useUserStore();
|
||||
const routeId = computed(() => String(route.params.id || ""));
|
||||
const isStoreManagerScope = computed(() => userStore.hasRoles(gaoRoleCodes.storeManager) && !userStore.hasRoles(gaoRoleCodes.globalManager));
|
||||
|
||||
// ---------- 路由权限 ----------
|
||||
|
||||
const isCreateMode = computed(() => !routeId.value);
|
||||
const savePermissionCode = computed(() => isCreateMode.value ? permissionCodes.store.create : permissionCodes.store.update);
|
||||
|
||||
// ---------- 表单 ----------
|
||||
|
||||
const isSaving = ref(false);
|
||||
const isRemoving = ref(false);
|
||||
const formModel = reactive({
|
||||
id: "",
|
||||
code: "",
|
||||
name: "",
|
||||
status: "ACTIVE" as StoreStatus,
|
||||
telephone: "",
|
||||
address: "",
|
||||
remark: ""
|
||||
});
|
||||
const sortValue = ref(0);
|
||||
|
||||
// ---------- 页面数据 ----------
|
||||
|
||||
async function fillForm(): Promise<void> {
|
||||
if (!routeId.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const current = await StoreAPI.detail(routeId.value);
|
||||
Object.assign(formModel, {
|
||||
id: current.id || "",
|
||||
code: current.code || "",
|
||||
name: current.name || "",
|
||||
status: current.status || "ACTIVE",
|
||||
telephone: current.telephone || "",
|
||||
address: current.address || "",
|
||||
remark: current.remark || ""
|
||||
});
|
||||
sortValue.value = current.sort ?? 0;
|
||||
}
|
||||
|
||||
// ---------- 保存 ----------
|
||||
|
||||
async function saveStore(): Promise<void> {
|
||||
if (!validateForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isSaving.value = true;
|
||||
try {
|
||||
const store = buildStorePayload();
|
||||
if (isCreateMode.value) {
|
||||
await StoreAPI.create(store);
|
||||
} else {
|
||||
await StoreAPI.update(store);
|
||||
}
|
||||
Toast.success("门店已保存");
|
||||
if (isStoreManagerScope.value) {
|
||||
return;
|
||||
}
|
||||
await router.replace("/management/stores");
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function buildStorePayload(): Store {
|
||||
if (isStoreManagerScope.value) {
|
||||
return {
|
||||
id: formModel.id || undefined,
|
||||
name: formModel.name,
|
||||
telephone: formModel.telephone || undefined,
|
||||
address: formModel.address || undefined,
|
||||
remark: formModel.remark || undefined
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
id: formModel.id || undefined,
|
||||
code: formModel.code,
|
||||
name: formModel.name,
|
||||
status: formModel.status,
|
||||
telephone: formModel.telephone || undefined,
|
||||
address: formModel.address || undefined,
|
||||
remark: formModel.remark || undefined,
|
||||
sort: sortValue.value
|
||||
};
|
||||
}
|
||||
|
||||
function validateForm(): boolean {
|
||||
if (!isStoreManagerScope.value && !formModel.code) {
|
||||
Toast.warning("请填写门店编码");
|
||||
return false;
|
||||
}
|
||||
if (!formModel.name) {
|
||||
Toast.warning("请填写门店名称");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function confirmRemoveStore(): Promise<void> {
|
||||
if (!formModel.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dialog = DialogPlugin.confirm({
|
||||
title: "删除门店",
|
||||
content: `确定删除 ${formModel.name} 吗?删除后无法恢复。`,
|
||||
cancelBtn: "取消",
|
||||
confirmBtn: "删除",
|
||||
onCancel() {
|
||||
dialog.destroy();
|
||||
},
|
||||
async onConfirm() {
|
||||
dialog.destroy();
|
||||
await removeStore();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function removeStore(): Promise<void> {
|
||||
if (isRemoving.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
isRemoving.value = true;
|
||||
try {
|
||||
await StoreAPI.remove(formModel.id);
|
||||
Toast.success("门店已删除");
|
||||
await router.replace("/management/stores");
|
||||
} finally {
|
||||
isRemoving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
await fillForm();
|
||||
} catch {
|
||||
Toast.error("门店数据加载失败");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.store-edit {
|
||||
gap: 1rem;
|
||||
padding: calc(var(--app-nav-height) + 1rem) 0 6rem 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.form {
|
||||
border-radius: .75rem;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.links {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.actions {
|
||||
gap: .75rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
bottom: calc(.75rem + env(safe-area-inset-bottom, 0));
|
||||
display: flex;
|
||||
position: fixed;
|
||||
|
||||
.action {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user