add entrance transition

This commit is contained in:
Timi
2026-08-24 16:16:43 +08:00
parent 2efce6de11
commit 05aad89706
54 changed files with 874 additions and 694 deletions
+47 -51
View File
@@ -3,59 +3,55 @@
v-can="permissionCodes.event.read"
class="registration-event-detail"
>
<section v-if="event" class="event-header">
<div class="color" :style="{ background: event.color || defaultColor }" />
<div class="header-content">
<div class="title-row">
<h2 v-text="event.name || '未命名事件'" />
<t-tag :theme="getStatusTheme(event.status)" variant="light-outline" :content="getStatusText(event.status)" />
<div v-entrance-transition v-if="event" class="event-header">
<div class="color" :style="{ background: event.color || defaultColor }" />
<div class="header-content">
<div class="title-row">
<h2 v-text="event.name || '未命名事件'" />
<t-tag :theme="getStatusTheme(event.status)" variant="light-outline" :content="getStatusText(event.status)" />
</div>
<div class="description" v-text="Text.display(event.description)" />
</div>
<div class="description" v-text="Text.display(event.description)" />
</div>
</section>
<t-cell-group v-if="event" title="基本信息" theme="card">
<t-cell title="所属门店" :note="storeName" />
<t-cell title="事件颜色">
<template #note>
<div class="color-note">
<span class="color-dot" :style="{ background: event.color || defaultColor }" />
<span v-text="(event.color || defaultColor).toLowerCase()" />
</div>
</template>
</t-cell>
<t-cell title="说明" :note="Text.display(event.description)" />
<t-cell title="可登记角色">
<template #note>
<div v-if="event.roleCodeList?.length" class="tag-list">
<t-tag
v-for="roleCode in event.roleCodeList"
:key="roleCode"
theme="primary"
variant="light-outline"
:content="getRoleName(roleCode)"
/>
</div>
<span v-else>未配置</span>
</template>
</t-cell>
</t-cell-group>
<t-cell-group v-if="event" title="登记配置" theme="card">
<t-cell title="数值类型" :note="getValueTypeText(event.valueType)" />
<t-cell v-if="event.valueType === 'NUMBER'" title="数值单位" :note="getValueUnitText(event.valueUnit)" />
<t-cell v-if="event.valueType === 'NUMBER'" title="登记必填数值" :note="event.requireValue ? '是' : '否'" />
<t-cell title="需要拍照" :note="event.requirePhoto ? '是' : '否'" />
<t-cell title="次数约束" :note="getLimitText(event)" />
</t-cell-group>
<t-cell-group v-if="event" title="生效时间" theme="card">
<t-cell title="起始时间" :note="formatDate(event.beginAt)" />
<t-cell title="终止时间" :note="formatDate(event.endAt)" />
<t-cell title="创建时间" :note="formatDate(event.createdAt, '未知时间')" />
<t-cell title="更新时间" :note="formatDate(event.updatedAt, '未知时间')" />
</t-cell-group>
<t-cell-group v-entrance-transition="70" v-if="event" title="基本信息" theme="card">
<t-cell title="所属门店" :note="storeName" />
<t-cell title="事件颜色">
<template #note>
<div class="color-note">
<span class="color-dot" :style="{ background: event.color || defaultColor }" />
<span v-text="(event.color || defaultColor).toLowerCase()" />
</div>
</template>
</t-cell>
<t-cell title="说明" :note="Text.display(event.description)" />
<t-cell title="可登记角色">
<template #note>
<div v-if="event.roleCodeList?.length" class="tag-list">
<t-tag
v-for="roleCode in event.roleCodeList"
:key="roleCode"
theme="primary"
variant="light-outline"
:content="getRoleName(roleCode)"
/>
</div>
<span v-else>未配置</span>
</template>
</t-cell>
</t-cell-group>
<t-cell-group v-entrance-transition="140" v-if="event" title="登记配置" theme="card">
<t-cell title="数值类型" :note="getValueTypeText(event.valueType)" />
<t-cell v-if="event.valueType === 'NUMBER'" title="数值单位" :note="getValueUnitText(event.valueUnit)" />
<t-cell v-if="event.valueType === 'NUMBER'" title="登记必填数值" :note="event.requireValue ? '是' : '否'" />
<t-cell title="需要拍照" :note="event.requirePhoto ? '是' : '否'" />
<t-cell title="次数约束" :note="getLimitText(event)" />
</t-cell-group>
<t-cell-group v-entrance-transition="210" v-if="event" title="生效时间" theme="card">
<t-cell title="起始时间" :note="formatDate(event.beginAt)" />
<t-cell title="终止时间" :note="formatDate(event.endAt)" />
<t-cell title="创建时间" :note="formatDate(event.createdAt, '未知时间')" />
<t-cell title="更新时间" :note="formatDate(event.updatedAt, '未知时间')" />
</t-cell-group>
<t-empty v-else :description="isLoading ? '正在加载登记事件' : '登记事件不存在'" />
</div>
</template>
+2 -2
View File
@@ -1,6 +1,6 @@
<template>
<div v-can="pageAccess" class="registration-event-edit">
<t-form class="form" label-align="left" label-width="7rem">
<t-form class="form" label-align="left" label-width="7rem" v-entrance-transition>
<t-form-item label="颜色">
<t-button
size="extra-small"
@@ -83,7 +83,7 @@
<div class="picker-text" v-text="getStatusText(formModel.status)" />
</t-form-item>
</t-form>
<section class="roles">
<section class="roles" v-entrance-transition="70">
<div class="title">
<span>可登记角色</span>
<span class="hint">必须至少选择一个角色,上级角色拥有子级角色可登记事件的登记权限</span>
+37 -36
View File
@@ -10,45 +10,46 @@
@scrolltolower="fetch"
>
<t-cell-group theme="card">
<t-cell
class="item"
v-for="item in visibleEventList"
:key="item.id"
:arrow="!!item.id"
:hover="!!item.id"
@click="toEventItem(item)"
>
<template #title>
<div class="header">
<div class="color" :style="{ background: item.color || defaultColor }" />
<div class="title" v-text="item.name || '未命名事件'" />
<t-tag
class="status"
:theme="getStatusTag(item).theme"
variant="outline"
:content="getStatusTag(item).text"
/>
<t-tag v-if="item.requirePhoto" theme="warning" variant="outline">需拍照</t-tag>
</div>
</template>
<template #description>
<div class="description">
<div class="line">
<span>可登记角色</span>
<t-cell
v-entrance-transition="index * 30"
v-for="(item, index) in visibleEventList"
:key="item.id"
class="item"
:arrow="!!item.id"
:hover="!!item.id"
@click="toEventItem(item)"
>
<template #title>
<div class="header">
<div class="color" :style="{ background: item.color || defaultColor }" />
<div class="title" v-text="item.name || '未命名事件'" />
<t-tag
v-for="roleCode in item.roleCodeList"
:key="roleCode"
theme="primary"
variant="light-outline"
:content="getRoleName(roleCode)"
class="status"
:theme="getStatusTag(item).theme"
variant="outline"
:content="getStatusTag(item).text"
/>
<span v-if="!(item.roleCodeList || []).length" class="muted" v-text="'未配置'" />
<t-tag v-if="item.requirePhoto" theme="warning" variant="outline">需拍照</t-tag>
</div>
<div class="line" v-text="getLimitText(item)" />
<div class="line" v-text="getValueDefinitionText(item)" />
</div>
</template>
</t-cell>
</template>
<template #description>
<div class="description">
<div class="line">
<span>可登记角色</span>
<t-tag
v-for="roleCode in item.roleCodeList"
:key="roleCode"
theme="primary"
variant="light-outline"
:content="getRoleName(roleCode)"
/>
<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>
</template>
</t-cell>
</t-cell-group>
<div v-if="!visibleEventList.length" class="empty-block" v-text="emptyText" />
<div v-if="visibleEventList.length" class="load-state" v-text="isNoMore ? '已经到底了' : '上拉加载更多'" />
+14 -11
View File
@@ -1,12 +1,13 @@
<template>
<div v-can="permissionCodes.eventRecord.read" class="registration-record-detail">
<customer-profile-card
v-entrance-transition
v-if="record?.customer"
class="customer-profile"
:customer="record.customer"
@click="toCustomerDetail"
/>
<t-cell-group v-if="record" title="登记信息" theme="card">
<t-cell-group v-entrance-transition="70" v-if="record" title="登记信息" theme="card">
<t-cell title="登记事件" :note="record.event?.name || '未知事件'" />
<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)" />
@@ -16,15 +17,16 @@
<t-cell title="客户编码" :note="Text.display(record.customer?.code)" />
<t-cell title="备注" :note="Text.display(record.remark)" />
</t-cell-group>
<section v-if="record" class="photo-panel">
<photo-scroller
:model-value="recordPhotoList"
:photo-items="recordPhotoItemList"
:show-add="false"
:show-remove="false"
title="登记照片"
/>
</section>
<photo-scroller
v-entrance-transition="140"
v-if="record"
class="photo-panel"
:model-value="recordPhotoList"
:photo-items="recordPhotoItemList"
:show-add="false"
:show-remove="false"
title="登记照片"
/>
<t-empty v-else :description="isLoading ? '正在加载登记事件记录' : '登记事件记录不存在'" />
</div>
</template>
@@ -141,8 +143,9 @@ onUnmounted(() => {
}
.photo-panel {
padding: 1rem;
width: calc(100% - 2rem);
margin: 0 1rem;
padding: 1rem;
background: rgba(255, 255, 255, .92);
box-shadow: var(--td-shadow-1);
border-radius: 1.4rem;
+4 -3
View File
@@ -1,6 +1,6 @@
<template>
<div v-can="pageAccess" class="registration-record-edit">
<t-form class="form" label-align="left">
<t-form class="form" label-align="left" v-entrance-transition>
<t-form-item label="客户" required-mark>
<t-input
:model-value="customerDisplayText"
@@ -42,10 +42,11 @@
v-if="showSelectedCustomerProfile"
class="customer-profile"
:customer="selectedCustomer"
v-entrance-transition
/>
<event-selector
v-model="selectedEventIdList"
class="registration-event-selector"
class="event-selector"
:event-list="eventList"
:disabled="isEditMode"
required-mark
@@ -804,7 +805,7 @@ watch(customerCode, async (value) => {
margin: 1rem;
}
.registration-event-selector {
.event-selector {
padding: 0 1rem;
margin-top: 1rem;
}
+52 -51
View File
@@ -33,64 +33,65 @@
@scrolltolower="loadRecords"
>
<div class="list-wrapper">
<t-cell-group class="summary" theme="card">
<t-cell
title="开始时间"
:note="dateRange[0] || '-'"
arrow
@click="startVisible = true"
/>
<t-cell
title="结束时间"
:note="dateRange[1] || '-'"
arrow
@click="endVisible = true"
/>
<t-cell title="事件" :note="eventFilterLabel" />
<t-cell title="数据量" :note="summaryTotalText" />
<t-cell v-if="summaryNumberValueText" title="数值合计" :note="summaryNumberValueText" />
</t-cell-group>
<t-cell-group v-entrance-transition class="summary" theme="card">
<t-cell
title="开始时间"
:note="dateRange[0] || '-'"
arrow
@click="startVisible = true"
/>
<t-cell
title="结束时间"
:note="dateRange[1] || '-'"
arrow
@click="endVisible = true"
/>
<t-cell title="事件" :note="eventFilterLabel" />
<t-cell title="数据量" :note="summaryTotalText" />
<t-cell v-if="summaryNumberValueText" title="数值合计" :note="summaryNumberValueText" />
</t-cell-group>
<t-cell-group
v-if="pageResult.list.length"
class="record-list"
theme="card"
>
<t-swipe-cell
v-for="item in pageResult.list"
:key="item.id"
class="item"
>
<t-cell
class="cell"
:title="getRecordEventName(item)"
:description="getRecordCustomerName(item)"
:note="getRecordRegisteredAt(item)"
arrow
hover
@click="toDetail(item.id || '')"
<t-swipe-cell
v-entrance-transition="index * 30"
v-for="(item, index) in pageResult.list"
:key="item.id"
class="item"
>
<template #leftIcon>
<t-image
v-if="getRecordPhotoURL(item)"
:src="getRecordPhotoURL(item)"
:alt="getRecordEventName(item)"
fit="cover"
class="avatar"
/>
<div v-else class="avatar fallback" v-text="getRecordCustomerInitial(item)" />
</template>
</t-cell>
<template v-if="canDeleteRecord" #right>
<t-button
class="delete"
theme="danger"
:loading="isDeleting && deletingId === item.id"
@click.stop="confirmRemoveRecord(item)"
<t-cell
class="cell"
:title="getRecordEventName(item)"
:description="getRecordCustomerName(item)"
:note="getRecordRegisteredAt(item)"
arrow
hover
@click="toDetail(item.id || '')"
>
删除
</t-button>
</template>
</t-swipe-cell>
<template #leftIcon>
<t-image
v-if="getRecordPhotoURL(item)"
:src="getRecordPhotoURL(item)"
:alt="getRecordEventName(item)"
fit="cover"
class="avatar"
/>
<div v-else class="avatar fallback" v-text="getRecordCustomerInitial(item)" />
</template>
</t-cell>
<template v-if="canDeleteRecord" #right>
<t-button
class="delete"
theme="danger"
:loading="isDeleting && deletingId === item.id"
@click.stop="confirmRemoveRecord(item)"
>
删除
</t-button>
</template>
</t-swipe-cell>
</t-cell-group>
<div v-else class="load-state" v-text="isLoading ? '正在加载登记事件记录' : '暂无登记事件记录'" />
<div v-if="pageResult.list.length" class="load-state" v-text="loadStateText" />
+45 -44
View File
@@ -47,55 +47,56 @@
class="list"
theme="card"
>
<customer-cell
class="item"
:class="{ 'in-top3': index < 3}"
v-for="(item, index) in pageResult.list"
:key="item.customerId"
arrow
@click="toCustomerDetail(item.customerId || '')"
:customer="item.customer"
>
<template #note>
<div
class="rank"
:class="{
<customer-cell
v-entrance-transition="index * 30"
v-for="(item, index) in pageResult.list"
:key="item.customerId"
class="item"
:class="{ 'in-top3': index < 3}"
arrow
@click="toCustomerDetail(item.customerId || '')"
:customer="item.customer"
>
<template #note>
<div
class="rank"
:class="{
top1: index === 0,
top2: index === 1,
top3: index === 2,
}"
v-text="index + 1"
/>
</template>
<template #description>
<div class="description">
<t-tag
v-if="rankType === 'TOTAL_DAYS'"
size="small"
variant="outline"
:content="`累计天数 ${item.totalEventDays || 0}`"
v-text="index + 1"
/>
<t-tag
v-else-if="rankType === 'TOTAL_COUNT'"
size="small"
variant="outline"
:content="`累计次数 ${item.totalEventCount || 0}`"
/>
<t-tag
v-else-if="rankType === 'CONTINUOUS_DAYS'"
size="small"
variant="outline"
:content="`连续天数 ${item.recentContinuousEventDays || 0}`"
/>
<t-tag
v-else
size="small"
variant="outline"
:content="`登记数值 ${getTotalNumberValueText(item)}`"
/>
</div>
</template>
</customer-cell>
</template>
<template #description>
<div class="description">
<t-tag
v-if="rankType === 'TOTAL_DAYS'"
size="small"
variant="outline"
:content="`累计天数 ${item.totalEventDays || 0}`"
/>
<t-tag
v-else-if="rankType === 'TOTAL_COUNT'"
size="small"
variant="outline"
:content="`累计次数 ${item.totalEventCount || 0}`"
/>
<t-tag
v-else-if="rankType === 'CONTINUOUS_DAYS'"
size="small"
variant="outline"
:content="`连续天数 ${item.recentContinuousEventDays || 0}`"
/>
<t-tag
v-else
size="small"
variant="outline"
:content="`登记数值 ${getTotalNumberValueText(item)}`"
/>
</div>
</template>
</customer-cell>
</t-cell-group>
<div v-else class="load-state" v-text="emptyStateText" />
<div v-if="pageResult.list.length" class="load-state" v-text="loadStateText" />
+3 -2
View File
@@ -1,6 +1,6 @@
<template>
<div v-can="permissionCodes.event.update" class="registration-event-sort">
<div class="tip" v-text="'按住右侧拖动手柄调整事件顺序,保存后生效'" />
<div class="tip" v-text="'按住右侧拖动手柄调整事件顺序,保存后生效'" v-entrance-transition />
<div class="items">
<t-cell-group v-if="eventList.length" theme="card">
<vue-draggable-next
@@ -16,10 +16,11 @@
@change="handleSortChange"
>
<t-cell
v-for="element in eventList"
v-for="(element, index) in eventList"
:key="element.id"
class="cell"
:title="element.name || '未命名事件'"
v-entrance-transition="index * 30"
>
<template #leftIcon>
<div class="color" :style="{ background: element.color || defaultColor }" />