update permission and product

This commit is contained in:
Timi
2026-09-04 23:07:59 +08:00
parent 1df5748f54
commit fc9e6a5023
48 changed files with 1670 additions and 2475 deletions
+6 -131
View File
@@ -25,17 +25,9 @@
<t-form-item v-if="isGlobalManager" label="门店" :arrow="isCreateMode" @click="openStorePicker">
<div class="picker-text" v-text="selectedStoreName" />
</t-form-item>
<t-form-item label="业务类型" :arrow="isCreateMode" @click="isCreateMode && openBizTypePicker()">
<t-form-item label="业务类型" :arrow="false">
<div class="picker-text" v-text="getBizTypeText(formModel.bizType)" />
</t-form-item>
<t-form-item v-if="formModel.bizType === 'PACKAGE_PURCHASE'" label="绑定套餐" required-mark arrow @click="openPackageConfigPicker">
<div class="picker-text" v-text="selectedPackageConfig?.name || '请选择套餐配置'" />
</t-form-item>
<t-form-item
label-width="0"
v-if="formModel.bizType === 'PACKAGE_PURCHASE'"
class="form-tips bg-white"
>套餐购买事件必须绑定一个套餐配置。登记该事件即视为购买</t-form-item>
<t-form-item label="说明">
<t-textarea
class="description"
@@ -188,24 +180,6 @@
@confirm="confirmStorePicker"
/>
</t-popup>
<t-popup v-model="bizTypePickerVisible" placement="bottom">
<t-picker
v-model="bizTypePickerDraft"
:columns="bizTypePickerColumns"
title="业务类型"
@cancel="bizTypePickerVisible = false"
@confirm="confirmBizTypePicker"
/>
</t-popup>
<t-popup v-model="packageConfigPickerVisible" placement="bottom">
<t-picker
v-model="packageConfigPickerDraft"
:columns="packageConfigPickerColumns"
title="绑定套餐"
@cancel="packageConfigPickerVisible = false"
@confirm="confirmPackageConfigPicker"
/>
</t-popup>
<t-popup v-model="statusPickerVisible" placement="bottom">
<t-picker
v-model="statusPickerDraft"
@@ -268,16 +242,13 @@ import { Time } from "timi-web";
import { type ModuleCode, type Role, RoleAPI, useUserStore } from "timi-web-api";
import type { ColorObject } from "tdesign-mobile-vue";
import EventAPI from "@/api/EventAPI";
import PackageAPI from "@/api/PackageAPI";
import EventOptionEditor from "@/pages/event/component/EventOptionEditor.vue";
import { useCurrentStoreStore } from "@/store/currentStoreStore";
import { useNavBarStore } from "@/store/navBarStore";
import type { EventBizType, EventItem, EventLimitType, EventOptionGroup, EventStatus, EventValueType, EventValueUnit } from "@/types/EventItem";
import type { GaoPackageConfig } from "@/types/Package";
import { getErrorMessage } from "@/utils/error";
import { normalizeEventOptionGroupList, prepareEventOptionGroupList, validateEventOptionGroupList } from "@/utils/eventOption";
import { getEventBizTypeText } from "@/utils/event";
import { getPackageConfigStatusText } from "@/utils/package";
import { gaoRoleCodes, permissionCodes } from "@/utils/permission";
import { Message } from "@/utils/message";
@@ -317,7 +288,6 @@ const formModel = reactive({
id: "",
storeId: "",
bizType: "GENERAL" as EventBizType,
packageConfigId: "",
name: "",
description: "",
color: "#0f766e",
@@ -337,91 +307,10 @@ const isPackagePurchase = computed(() => formModel.bizType === "PACKAGE_PURCHASE
// ---------- 业务类型 ----------
const bizTypeOptions: Array<{ label: string; value: EventBizType }> = [
{ label: "普通登记", value: "GENERAL" },
{ label: "套餐购买", value: "PACKAGE_PURCHASE" }
];
const bizTypePickerVisible = ref(false);
const bizTypePickerDraft = ref<PickerValue[]>([formModel.bizType]);
const bizTypePickerColumns = [bizTypeOptions];
function getBizTypeText(value: EventBizType): string {
return getEventBizTypeText(value);
}
function openBizTypePicker(): void {
if (!isCreateMode.value) {
return;
}
bizTypePickerDraft.value = [formModel.bizType];
bizTypePickerVisible.value = true;
}
async function confirmBizTypePicker(value: Array<string | number>): Promise<void> {
const bizType = value[0];
if (bizType !== "GENERAL" && bizType !== "PACKAGE_PURCHASE") {
return;
}
formModel.bizType = bizType;
if (bizType === "PACKAGE_PURCHASE") {
formModel.requireVerification = false;
await loadPackageConfigList();
} else {
formModel.packageConfigId = "";
}
bizTypePickerVisible.value = false;
}
// ---------- 套餐绑定 ----------
const packageConfigList = ref<GaoPackageConfig[]>([]);
const packageConfigPickerVisible = ref(false);
const packageConfigPickerDraft = ref<PickerValue[]>([]);
const packageConfigPickerColumns = computed(() => [[...packageConfigList.value].map(item => ({
label: `${item.name || "未命名套餐"}(${getPackageConfigStatusText(item.status)})`,
value: item.id || ""
}))]);
const selectedPackageConfig = computed(() => packageConfigList.value.find(item => item.id === formModel.packageConfigId));
async function loadPackageConfigList(): Promise<void> {
if (formModel.bizType !== "PACKAGE_PURCHASE" || !formModel.storeId) {
packageConfigList.value = [];
return;
}
try {
const result = await PackageAPI.configList({
storeId: formModel.storeId,
index: 0,
size: 1000
});
packageConfigList.value = result.list || [];
} catch (error) {
packageConfigList.value = [];
Message.error(getErrorMessage(error, "套餐配置加载失败"));
}
}
function openPackageConfigPicker(): void {
if (formModel.bizType !== "PACKAGE_PURCHASE") {
return;
}
if (!packageConfigList.value.length) {
Message.warning("当前门店没有可绑定的套餐配置");
return;
}
packageConfigPickerDraft.value = [formModel.packageConfigId];
packageConfigPickerVisible.value = true;
}
function confirmPackageConfigPicker(value: Array<string | number>): void {
const packageConfigId = String(value[0] || "");
if (!packageConfigList.value.some(item => item.id === packageConfigId)) {
return;
}
formModel.packageConfigId = packageConfigId;
packageConfigPickerVisible.value = false;
}
// ---------- 门店选择 ----------
const storePickerVisible = ref(false);
@@ -459,9 +348,6 @@ async function confirmStorePicker(): Promise<void> {
}
formModel.storeId = storeId;
if (formModel.bizType === "PACKAGE_PURCHASE") {
await loadPackageConfigList();
}
storePickerVisible.value = false;
}
@@ -725,10 +611,6 @@ function validateForm(): boolean {
Message.warning("请至少选择一个可登记角色");
return false;
}
if (formModel.bizType === "PACKAGE_PURCHASE" && (!formModel.packageConfigId || !selectedPackageConfig.value)) {
Message.warning("请选择绑定套餐配置");
return false;
}
const optionError = validateEventOptionGroupList(optionGroupList.value);
if (optionError) {
Message.warning(optionError);
@@ -738,10 +620,6 @@ function validateForm(): boolean {
Message.warning("请输入有效的约束数值");
return false;
}
if (formModel.bizType === "PACKAGE_PURCHASE" && formModel.requireVerification) {
Message.warning("套餐购买事件不能要求核销");
return false;
}
const beginAt = resolveTimestamp(formModel.beginAtText);
const endAt = resolveTimestamp(formModel.endAtText);
if (beginAt !== undefined && endAt !== undefined && endAt < beginAt) {
@@ -815,7 +693,6 @@ async function saveEventItem(): Promise<void> {
id: formModel.id || undefined,
storeId: formModel.storeId,
bizType: formModel.bizType,
packageConfigId: formModel.bizType === "PACKAGE_PURCHASE" ? formModel.packageConfigId : undefined,
name: formModel.name.trim(),
description: formModel.description,
color: formModel.color,
@@ -875,11 +752,15 @@ async function fillForm(): Promise<void> {
await router.replace({ name: "EventDetail", params: { id: routeId.value } });
return;
}
if (current.bizType === "PACKAGE_PURCHASE" || current.bizType === "LEGACY_CONSUMPTION") {
Message.warning("退役事件仅支持历史查看,不能编辑");
await router.replace({ name: "EventDetail", params: { id: routeId.value } });
return;
}
Object.assign(formModel, {
id: current.id || "",
storeId: current.storeId || formModel.storeId,
bizType: current.bizType || "GENERAL",
packageConfigId: current.packageConfigId || "",
name: current.name || "",
description: current.description || "",
color: current.color || "#2f88ff",
@@ -894,12 +775,6 @@ async function fillForm(): Promise<void> {
endAtText: current.endAt ? Time.toDateTime(current.endAt) : "",
roleCodeList: [...(current.roleCodeList || [])]
});
if (formModel.bizType === "PACKAGE_PURCHASE") {
await loadPackageConfigList();
if (current.packageConfig && !packageConfigList.value.some(item => item.id === current.packageConfig?.id)) {
packageConfigList.value.unshift(current.packageConfig);
}
}
optionGroupList.value = normalizeEventOptionGroupList(current.optionGroupList);
formModel.limitValueText = resolveLimitValueText(current.limitValue);
colorDraft.value = formModel.color;