add package

This commit is contained in:
Timi
2026-09-01 01:14:54 +08:00
parent 100d4c4c44
commit 2d94abfb32
39 changed files with 4425 additions and 59 deletions
+30 -3
View File
@@ -15,6 +15,15 @@
</div>
<t-cell-group v-entrance-transition="70" v-if="event" title="基本信息" theme="card">
<t-cell title="所属门店" :note="storeName" />
<t-cell title="业务类型" :note="getEventBizTypeText(event.bizType)" />
<t-cell v-if="isPackagePurchaseEvent(event)" title="绑定套餐">
<template #note>
<div class="package-note">
<strong v-text="event.packageConfig?.name || '未返回套餐配置'" />
<span v-if="event.packageConfig" v-text="`${formatPackageAmount(event.packageConfig.standardAmount)}|${getPackageConfigStatusText(event.packageConfig.status)}`" />
</div>
</template>
</t-cell>
<t-cell title="事件颜色">
<template #note>
<div class="color-note">
@@ -39,13 +48,18 @@
</template>
</t-cell>
<t-cell
v-if="canReadEventRecord"
v-if="canReadEventRecord && event.bizType !== 'PACKAGE_PURCHASE'"
title="登记记录"
note="查看该事件登记记录"
arrow
:hover="true"
@click="toEventRecordList"
/>
<t-cell
v-else-if="event.bizType === 'PACKAGE_PURCHASE'"
title="购买记录"
note="请在客户套餐详情中查看"
/>
</t-cell-group>
<t-cell-group v-entrance-transition="140" v-if="event" title="登记配置" theme="card">
<t-cell title="数值类型" :note="getValueTypeText(event.valueType)" />
@@ -116,6 +130,8 @@ import EventRemoveDialog from "@/pages/event/component/EventRemoveDialog.vue";
import { useCurrentStoreStore } from "@/store/currentStoreStore";
import { useNavBarStore } from "@/store/navBarStore";
import type { EventItem, EventLimitType, EventOptionSelectionMap, EventStatus, EventValueType, EventValueUnit } from "@/types/EventItem";
import { getEventBizTypeText, isPackagePurchaseEvent } from "@/utils/event";
import { formatPackageAmount, getPackageConfigStatusText } from "@/utils/package";
import { gaoRoleCodes, permissionCodes } from "@/utils/permission";
import { Message } from "@/utils/message";
@@ -309,7 +325,7 @@ async function removeEvent(eventItem: EventItem): Promise<void> {
async function toEventRecordList(): Promise<void> {
const eventId = event.value?.id || String(route.params.id || "");
if (!eventId || !canReadEventRecord.value) {
if (!eventId || !canReadEventRecord.value || isPackagePurchaseEvent(event.value)) {
return;
}
await router.push({
@@ -417,7 +433,8 @@ onUnmounted(() => {
}
.color-note,
.tag-list {
.tag-list,
.package-note {
gap: .4rem;
display: flex;
align-items: center;
@@ -425,6 +442,16 @@ onUnmounted(() => {
flex-wrap: wrap;
}
.package-note {
flex-direction: column;
align-items: flex-end;
span {
color: var(--td-text-color-secondary);
font-size: .8125rem;
}
}
.color-dot {
width: 1rem;
height: 1rem;
+152 -3
View File
@@ -25,6 +25,15 @@
<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()">
<div class="picker-text" v-text="getBizTypeText(formModel.bizType)" />
</t-form-item>
<div v-if="formModel.bizType === 'PACKAGE_PURCHASE'" class="biz-type-tip">
套餐购买事件必须绑定一个套餐配置。实际购买时只能使用此处绑定的套餐,不能临时更换。
</div>
<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="说明">
<t-textarea
class="description"
@@ -80,7 +89,7 @@
<t-switch v-model="formModel.requirePhoto" />
</t-form-item>
<t-form-item label="需要核销" content-align="right">
<t-switch v-model="formModel.requireVerification" />
<t-switch v-model="formModel.requireVerification" :disabled="formModel.bizType === 'PACKAGE_PURCHASE'" />
</t-form-item>
<t-form-item label="状态" arrow @click="openStatusPicker">
<div class="picker-text" v-text="getStatusText(formModel.status)" />
@@ -157,6 +166,24 @@
@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"
@@ -219,12 +246,16 @@ 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 { EventItem, EventLimitType, EventOptionGroup, EventStatus, EventValueType, EventValueUnit } from "@/types/EventItem";
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";
@@ -263,6 +294,8 @@ const optionGroupList = ref<EventOptionGroup[]>([]);
const formModel = reactive({
id: "",
storeId: "",
bizType: "GENERAL" as EventBizType,
packageConfigId: "",
name: "",
description: "",
color: "#0f766e",
@@ -279,6 +312,93 @@ const formModel = reactive({
roleCodeList: [] as string[]
});
// ---------- 业务类型 ----------
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);
@@ -309,13 +429,16 @@ function openStorePicker(): void {
storePickerVisible.value = true;
}
function confirmStorePicker(): void {
async function confirmStorePicker(): Promise<void> {
const storeId = String(storePickerDraft.value[0] || "");
if (!storeId) {
return;
}
formModel.storeId = storeId;
if (formModel.bizType === "PACKAGE_PURCHASE") {
await loadPackageConfigList();
}
storePickerVisible.value = false;
}
@@ -573,6 +696,10 @@ 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);
@@ -582,6 +709,10 @@ 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) {
@@ -636,6 +767,8 @@ async function saveEventItem(): Promise<void> {
const payload: EventItem = {
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,
@@ -698,6 +831,8 @@ async function fillForm(): Promise<void> {
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",
@@ -712,6 +847,12 @@ 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;
@@ -762,6 +903,14 @@ onUnmounted(() => navBarStore.clearRight());
font-size: .875rem;
flex-direction: column;
}
.biz-type-tip {
padding: .75rem 1rem;
color: var(--td-text-color-secondary);
font-size: .8125rem;
line-height: 1.5;
background: var(--td-bg-color-secondarycontainer);
}
}
.picker-text {
+4 -1
View File
@@ -34,6 +34,7 @@
/>
<t-tag v-if="item.requirePhoto" theme="warning" variant="outline">需拍照</t-tag>
<t-tag v-if="item.requireVerification" theme="warning" variant="outline">需核销</t-tag>
<t-tag v-if="item.bizType === 'PACKAGE_PURCHASE'" theme="primary" variant="outline">套餐购买</t-tag>
</div>
</template>
<template #description>
@@ -50,7 +51,8 @@
<span v-if="!(item.roleCodeList || []).length" class="muted" v-text="'未配置'" />
</div>
<div class="line" v-text="getLimitText(item)" />
<div class="line" v-text="getValueDefinitionText(item)" />
<div class="line" v-text="`${getEventBizTypeText(item.bizType)}|${getValueDefinitionText(item)}`" />
<div v-if="item.bizType === 'PACKAGE_PURCHASE'" class="line" v-text="`绑定套餐:${item.packageConfig?.name || '未配置'}`" />
</div>
</template>
</t-cell>
@@ -89,6 +91,7 @@ import { useCurrentStoreStore } from "@/store/currentStoreStore";
import { useNavBarStore } from "@/store/navBarStore";
import type { EventItem, EventLimitType, EventStatus } from "@/types/EventItem";
import type { NavBarAction } from "@/types/NavBarAction";
import { getEventBizTypeText } from "@/utils/event";
import { getEventValueUnitText } from "@/utils/eventValue";
import { gaoRoleCodes, permissionCodes } from "@/utils/permission";
+14 -9
View File
@@ -15,6 +15,7 @@
:hover="canReadEvent && !!(record.event?.id || record.eventId)"
@click="toEventDetail"
/>
<t-cell title="业务类型" :note="getEventBizTypeText(record.event?.bizType)" />
<t-cell v-if="record.numberValue !== undefined && record.numberValue !== null" title="事件数值" :note="getNumberValueText(record)" />
<t-cell v-if="record.pointValue !== undefined && record.pointValue !== null" title="提交积分值" :note="getPointValueText(record.pointValue, pointLedgerChangeType)" />
<t-cell v-if="record.earnedPointValue !== undefined && record.earnedPointValue !== null" title="本次积分变化" :note="getPointValueText(record.earnedPointValue, pointLedgerChangeType)" />
@@ -111,6 +112,7 @@ import type { PhotoItem } from "@/types/Photo";
import type { PointLedgerChangeType } from "@/types/Point";
import { getAttachmentReadURL } from "@/utils/attachment";
import { buildEventOptionSelectionMap } from "@/utils/eventOption";
import { getEventBizTypeText, isPackagePurchaseEvent } from "@/utils/event";
import { getErrorMessage } from "@/utils/error";
import { formatEventNumberValue } from "@/utils/eventValue";
import { Message } from "@/utils/message";
@@ -133,9 +135,10 @@ const isVerifying = ref(false);
const isDeleting = ref(false);
const verifyDialogVisible = ref(false);
const canUpdateRecord = computed(() => userStore.hasPermissions(permissionCodes.eventRecord.update));
const canVerifyRecord = computed(() => userStore.hasPermissions(permissionCodes.eventRecord.verify));
const canDeleteRecord = computed(() => userStore.hasPermissions(permissionCodes.eventRecord.delete));
const isPackagePurchaseRecord = computed(() => isPackagePurchaseEvent(record.value?.event));
const canUpdateRecord = computed(() => !!record.value && !isPackagePurchaseRecord.value && userStore.hasPermissions(permissionCodes.eventRecord.update));
const canVerifyRecord = computed(() => !!record.value && !isPackagePurchaseRecord.value && userStore.hasPermissions(permissionCodes.eventRecord.verify));
const canDeleteRecord = computed(() => !!record.value && !isPackagePurchaseRecord.value && userStore.hasPermissions(permissionCodes.eventRecord.delete));
const canReadEvent = computed(() => userStore.hasPermissions(permissionCodes.event.read));
const recordPhotoItemList = computed(() => (record.value?.attachmentList || [])
.filter(item => !!item.id)
@@ -149,7 +152,7 @@ const recordPhotoList = computed(() => recordPhotoItemList.value.map(item => ite
async function submitPhotoItems(photoItems: PhotoItem[]): Promise<void> {
const currentRecord = record.value;
if (!currentRecord?.id) {
if (!currentRecord?.id || isPackagePurchaseRecord.value) {
throw new Error("登记记录不存在");
}
@@ -260,7 +263,7 @@ async function confirmVerifyRecord(): Promise<void> {
async function submitVerifyRecord(record: EventRecord, attachmentList: Attachment[]): Promise<void> {
const id = record.id;
if (!id) {
if (!id || isPackagePurchaseRecord.value) {
throw new Error("登记事件记录不存在");
}
@@ -313,7 +316,7 @@ function confirmRemoveRecord(): void {
}
async function removeRecord(id: string): Promise<void> {
if (isDeleting.value) {
if (isDeleting.value || isPackagePurchaseRecord.value) {
return;
}
@@ -338,7 +341,7 @@ async function removeRecord(id: string): Promise<void> {
async function toEdit(): Promise<void> {
const recordId = String(route.params.id || "");
if (!recordId) {
if (!recordId || !canUpdateRecord.value) {
return;
}
await router.push(`/management/registration-event-records/${recordId}/edit`);
@@ -380,12 +383,14 @@ watch(() => route.params.id, async () => {
await loadRecord();
}, { immediate: true });
onMounted(() => {
function updateNavBarAction(): void {
navBarStore.clearRight();
if (canUpdateRecord.value) {
navBarStore.setRightText("编辑", "var(--td-brand-color)", toEdit);
}
});
}
watch(canUpdateRecord, updateNavBarAction, { immediate: true });
onUnmounted(() => {
navBarStore.clearRight();
+35 -2
View File
@@ -46,11 +46,12 @@
/>
<div v-if="isEditMode" class="edit-point-tip red">涉及积分变动的数据不能修改,已产生积分流水的登记记录不会因修改客户、事件或时间而重算;如需修改这些事实,请删除后重新创建,删除会自动回流积分。</div>
<event-selector
v-model="selectedEventIdList"
:model-value="selectedEventIdList"
class="event-selector"
:event-list="eventList"
:disabled="isEditMode"
required-mark
@update:model-value="handleEventSelectionChange"
/>
<event-option-selector
class="option-selector"
@@ -219,6 +220,7 @@ import type { EventItem, EventOptionSelectionMap } from "@/types/EventItem";
import type { EventRecord } from "@/types/EventRecord";
import type { PointAction } from "@/types/Point";
import { getAttachmentReadURL } from "@/utils/attachment";
import { isPackagePurchaseEvent } from "@/utils/event";
import { buildEventOptionSelectionMap, resolveSelectedOptionGroupList, validateEventOptionSelection } from "@/utils/eventOption";
import { getEventRecordPhotoURL, hasPhotoAttachment } from "@/utils/eventRecord";
import { getEventNumberValuePlaceholder, resolveEventNumberValue } from "@/utils/eventValue";
@@ -434,6 +436,27 @@ const eventNameMap = computed(() => {
return map;
});
async function handleEventSelectionChange(eventIdList: string[]): Promise<void> {
const packageEvent = eventIdList
.map(eventId => eventList.value.find(item => item.id === eventId))
.find(item => isPackagePurchaseEvent(item));
if (!isEditMode.value && packageEvent?.id) {
if (!userStore.hasPermissions(permissionCodes.customerPackage.create)) {
Message.warning("当前账号没有套餐购买权限");
return;
}
await router.push({
name: "CustomerPackagePurchase",
query: {
eventId: packageEvent.id,
...(selectedCustomer.value?.id ? { customerId: selectedCustomer.value.id } : {})
}
});
return;
}
selectedEventIdList.value = eventIdList;
}
function appendRecordEvent(record: EventRecord): void {
if (!record.event?.id || eventList.value.some(item => item.id === record.event?.id)) {
return;
@@ -683,6 +706,10 @@ function validateForm(): boolean {
Message.warning("请至少选择一个登记事件");
return false;
}
if (selectedEventIdList.value.some(eventId => isPackagePurchaseEvent(eventList.value.find(item => item.id === eventId)))) {
Message.warning("套餐购买事件必须通过客户套餐购买页面登记");
return false;
}
for (const eventId of selectedEventIdList.value) {
const event = eventList.value.find(item => item.id === eventId);
if (!event) {
@@ -769,11 +796,17 @@ async function loadPageData(): Promise<void> {
return;
}
selectedEventIdList.value = eventList.value.slice(0, 1).map(item => item.id).filter((item): item is string => Boolean(item));
const defaultEvent = eventList.value.find(item => !isPackagePurchaseEvent(item));
selectedEventIdList.value = defaultEvent?.id ? [defaultEvent.id] : [];
}
async function loadRecordForEdit(): Promise<void> {
const record = await EventRecordAPI.detail(routeId.value);
if (isPackagePurchaseEvent(record.event)) {
Message.warning("套餐购买记录不能通过普通登记页编辑,请在客户套餐详情中查看");
await router.replace({ name: "EventRecordDetail", params: { id: routeId.value } });
return;
}
editingRecord.value = record;
appendRecordEvent(record);
selectedCustomerList.value = record.customer ? [record.customer] : [];
+10 -3
View File
@@ -128,6 +128,7 @@ import { useNavBarStore } from "@/store/navBarStore";
import type { EventItem, EventStatus } from "@/types/EventItem";
import type { EventOptionStat, EventRecordPage, EventRecordPageResult, VerificationStatus } from "@/types/EventRecord";
import type { NavBarAction } from "@/types/NavBarAction";
import { isPackagePurchaseEvent } from "@/utils/event";
import { formatEventNumberValue } from "@/utils/eventValue";
import { permissionCodes } from "@/utils/permission";
import { Message } from "@/utils/message.ts";
@@ -367,6 +368,10 @@ async function loadRecords(): Promise<void> {
if (isLoading.value || isNoMore.value) {
return;
}
if (!eventList.value.length) {
isNoMore.value = true;
return;
}
const token = loadToken + 1;
loadToken = token;
isLoading.value = true;
@@ -398,7 +403,7 @@ async function loadActions(): Promise<void> {
const result = canCreateEvent.value
? await EventAPI.listHistory()
: await EventAPI.list({ index: 0, size: 1000 });
eventList.value = result.list || [];
eventList.value = (result.list || []).filter(item => !isPackagePurchaseEvent(item));
const eventIdList = eventList.value.map(item => item.id).filter((item): item is string => Boolean(item));
const eventIdSet = new Set(eventIdList);
const selectedEventIdList = parseEventIdList(route.query.eventIds).filter(eventId => eventIdSet.has(eventId));
@@ -529,13 +534,15 @@ async function toCreate(): Promise<void> {
function buildRangeReq(): Omit<EventRecordPage, "index" | "size"> {
const [beginAt, endAt] = buildUnixRange();
const selectedAllEvent = !actionFilter.value.length || actionFilter.value.length === eventList.value.length;
const eventIdList = actionFilter.value.length
? actionFilter.value
: eventList.value.map(item => item.id).filter((item): item is string => Boolean(item));
return {
beginAt,
endAt,
customerId: customerId.value || undefined,
keyword: keyword.value.trim() || undefined,
eventIdList: actionFilter.value.length === 1 ? actionFilter.value : selectedAllEvent ? undefined : actionFilter.value,
eventIdList,
optionIdList: optionFilter.value.length ? optionFilter.value : undefined,
verificationStatus: verificationFilter.value === "ALL" ? undefined : verificationFilter.value
};
@@ -74,6 +74,7 @@ import EventRecordAPI from "@/api/EventRecordAPI";
import EventRecordVerifyDialog from "@/components/EventRecordVerifyDialog.vue";
import type { EventRecord, EventRecordListItemView } from "@/types/EventRecord";
import { getCustomerPhotoURL } from "@/utils/customer";
import { isPackagePurchaseEvent } from "@/utils/event";
import { getErrorMessage } from "@/utils/error";
import { permissionCodes } from "@/utils/permission";
import { Message } from "@/utils/message";
@@ -100,9 +101,10 @@ const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const canUpdateRecord = computed(() => userStore.hasPermissions(permissionCodes.eventRecord.update));
const canVerifyRecord = computed(() => userStore.hasPermissions(permissionCodes.eventRecord.verify));
const canDeleteRecord = computed(() => userStore.hasPermissions(permissionCodes.eventRecord.delete));
const isPackagePurchaseRecord = computed(() => isPackagePurchaseEvent(props.record.event));
const canUpdateRecord = computed(() => !isPackagePurchaseRecord.value && userStore.hasPermissions(permissionCodes.eventRecord.update));
const canVerifyRecord = computed(() => !isPackagePurchaseRecord.value && userStore.hasPermissions(permissionCodes.eventRecord.verify));
const canDeleteRecord = computed(() => !isPackagePurchaseRecord.value && userStore.hasPermissions(permissionCodes.eventRecord.delete));
const isDeleting = ref(false);
const isVerifying = ref(false);
const isLoadingVerifyRecord = ref(false);