update customer profile card
This commit is contained in:
@@ -1,19 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="customer" class="customer-profile-card">
|
<div v-if="customer" class="customer-profile-card">
|
||||||
<button v-if="photoURL" type="button" class="avatar-trigger" @click="handlePhotoClick">
|
<div v-if="photoURL" class="avatar-trigger" @click="handlePhotoClick">
|
||||||
<t-image :src="photoURL" :alt="customerName" fit="cover" class="avatar" />
|
<t-image :src="photoURL" :alt="customerName" fit="cover" class="avatar" />
|
||||||
</button>
|
|
||||||
<div v-else class="avatar fallback" v-text="avatarText" />
|
|
||||||
<div class="content">
|
|
||||||
<div class="header">
|
|
||||||
<div class="name">
|
|
||||||
<span v-text="customerName"></span>
|
|
||||||
<gender-icon v-if="customer.gender" :value="customer.gender" size="1rem" />
|
|
||||||
</div>
|
|
||||||
<span class="gray" v-text="customerCode" />
|
|
||||||
</div>
|
|
||||||
<telephone-link class="telephone gray" :value="customerTelephone" />
|
|
||||||
</div>
|
|
||||||
<div @click.stop>
|
<div @click.stop>
|
||||||
<t-image-viewer
|
<t-image-viewer
|
||||||
v-model:visible="photoViewerVisible"
|
v-model:visible="photoViewerVisible"
|
||||||
@@ -22,6 +10,23 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="avatar fallback" v-text="avatarText" />
|
||||||
|
<div class="content">
|
||||||
|
<div class="header">
|
||||||
|
<div class="name white">
|
||||||
|
<span v-text="customerName"></span>
|
||||||
|
<gender-icon v-if="customer.gender" :value="customer.gender" size="1rem" />
|
||||||
|
</div>
|
||||||
|
<t-tag
|
||||||
|
class="code"
|
||||||
|
variant="outline"
|
||||||
|
shape="round"
|
||||||
|
:content="customerCode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<telephone-link class="telephone white" :value="customerTelephone" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -65,17 +70,12 @@ function openPhotoViewer(): void {
|
|||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
box-shadow: var(--td-shadow-1);
|
box-shadow: var(--td-shadow-1);
|
||||||
background: #e6eeff;
|
background: linear-gradient(135deg, #43cea2, var(--td-brand-color));
|
||||||
border-radius: 1.125rem;
|
border-radius: 1.125rem;
|
||||||
|
|
||||||
.avatar-trigger {
|
.avatar-trigger {
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
display: block;
|
|
||||||
cursor: pointer;
|
|
||||||
background: transparent;
|
|
||||||
border-radius: .875rem;
|
border-radius: .875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,11 @@ function openPhotoViewer(): void {
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
padding-bottom: .25rem;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -97,8 +101,14 @@ function openPhotoViewer(): void {
|
|||||||
.name {
|
.name {
|
||||||
gap: .5rem;
|
gap: .5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
font-size: 1.25rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
color: #FFF;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.telephone {
|
.telephone {
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<component
|
<contact-number :value="value" @click="handleClick" underline>
|
||||||
:is="href ? 'a' : 'span'"
|
<template #icon>
|
||||||
v-if="displayText"
|
|
||||||
:href="href || undefined"
|
|
||||||
class="telephone-link"
|
|
||||||
:class="{ clickable: !!href }"
|
|
||||||
@click="handleClick"
|
|
||||||
>
|
|
||||||
<t-icon v-if="value" name="call" />
|
<t-icon v-if="value" name="call" />
|
||||||
<span v-text="displayText" />
|
</template>
|
||||||
</component>
|
</contact-number>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { buildTelephoneURL, canDialTelephone } from "@/utils/telephone";
|
import { ContactNumber } from "timi-web";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "TelephoneLink"
|
name: "TelephoneLink"
|
||||||
@@ -27,8 +21,6 @@ const props = withDefaults(defineProps<{
|
|||||||
});
|
});
|
||||||
|
|
||||||
const textValue = computed(() => props.value?.trim() || "");
|
const textValue = computed(() => props.value?.trim() || "");
|
||||||
const displayText = computed(() => textValue.value || props.placeholder);
|
|
||||||
const href = computed(() => canDialTelephone(textValue.value) ? buildTelephoneURL(textValue.value) : "");
|
|
||||||
|
|
||||||
function handleClick(event: MouseEvent): void {
|
function handleClick(event: MouseEvent): void {
|
||||||
if (textValue.value) {
|
if (textValue.value) {
|
||||||
@@ -42,10 +34,5 @@ function handleClick(event: MouseEvent): void {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
&.clickable {
|
|
||||||
text-decoration: underline;
|
|
||||||
text-underline-offset: .16rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -21,7 +21,11 @@
|
|||||||
<t-cell title="病症" :note="Text.display(customer.disease)" />
|
<t-cell title="病症" :note="Text.display(customer.disease)" />
|
||||||
<t-cell title="备注" :note="Text.display(customer.remark)" />
|
<t-cell title="备注" :note="Text.display(customer.remark)" />
|
||||||
<t-cell title="录入用户" :note="Text.display(customer.creatorUser?.nick || customer.creatorUser?.name)" />
|
<t-cell title="录入用户" :note="Text.display(customer.creatorUser?.nick || customer.creatorUser?.name)" />
|
||||||
<t-cell title="录入时间" :note="Time.toPassedDateTime(customer.createdAt)" />
|
<t-cell title="录入时间">
|
||||||
|
<template #note>
|
||||||
|
<pass-time-label :timestamp="customer.createdAt" underline />
|
||||||
|
</template>
|
||||||
|
</t-cell>
|
||||||
</t-cell-group>
|
</t-cell-group>
|
||||||
<customer-tag-card
|
<customer-tag-card
|
||||||
v-if="customer && canReadTag"
|
v-if="customer && canReadTag"
|
||||||
@@ -167,7 +171,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { DialogPlugin, Toast } from "tdesign-mobile-vue";
|
import { DialogPlugin, Toast } from "tdesign-mobile-vue";
|
||||||
import { Text, Time, useUserStore } from "timi-web";
|
import { PassTimeLabel, Text, Time, useUserStore } from "timi-web";
|
||||||
import CustomerAPI from "@/api/CustomerAPI";
|
import CustomerAPI from "@/api/CustomerAPI";
|
||||||
import PointAPI from "@/api/PointAPI";
|
import PointAPI from "@/api/PointAPI";
|
||||||
import TagAPI from "@/api/TagAPI";
|
import TagAPI from "@/api/TagAPI";
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
/>
|
/>
|
||||||
<div class="name" v-text="getCustomerName(item)" />
|
<div class="name" v-text="getCustomerName(item)" />
|
||||||
</div>
|
</div>
|
||||||
<t-tag size="small" :content="item.customer?.code" />
|
<t-tag size="small" variant="light-outline" :content="item.customer?.code" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #description>
|
<template #description>
|
||||||
|
|||||||
@@ -86,11 +86,6 @@ import type { PointLedger, PointRule, PointRuleMode, PointRuleStatus, PointRuleT
|
|||||||
import { formatEventNumberValue, getEventValueUnitText } from "@/utils/eventValue";
|
import { formatEventNumberValue, getEventValueUnitText } from "@/utils/eventValue";
|
||||||
import { permissionCodes } from "@/utils/permission";
|
import { permissionCodes } from "@/utils/permission";
|
||||||
|
|
||||||
type SourcePayloadItem = {
|
|
||||||
key: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "PointLedgerDetail"
|
name: "PointLedgerDetail"
|
||||||
});
|
});
|
||||||
@@ -119,16 +114,6 @@ const isLoading = ref(false);
|
|||||||
const hasEventNumberValue = computed(() => eventRecord.value?.numberValue !== undefined && eventRecord.value?.numberValue !== null);
|
const hasEventNumberValue = computed(() => eventRecord.value?.numberValue !== undefined && eventRecord.value?.numberValue !== null);
|
||||||
const hasSubmittedPointValue = computed(() => eventRecord.value?.pointValue !== undefined && eventRecord.value?.pointValue !== null);
|
const hasSubmittedPointValue = computed(() => eventRecord.value?.pointValue !== undefined && eventRecord.value?.pointValue !== null);
|
||||||
const hasEarnedPointValue = computed(() => eventRecord.value?.earnedPointValue !== undefined && eventRecord.value?.earnedPointValue !== null);
|
const hasEarnedPointValue = computed(() => eventRecord.value?.earnedPointValue !== undefined && eventRecord.value?.earnedPointValue !== null);
|
||||||
const sourcePayloadList = computed<SourcePayloadItem[]>(() => {
|
|
||||||
const payload = ledger.value?.sourcePayload;
|
|
||||||
if (!payload) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return Object.entries(payload).map(([key, value]) => ({
|
|
||||||
key,
|
|
||||||
value: formatSourceValue(value)
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
function getQueryText(key: string): string {
|
function getQueryText(key: string): string {
|
||||||
const value = route.query[key];
|
const value = route.query[key];
|
||||||
@@ -328,17 +313,6 @@ function getRuleEmptyText(): string {
|
|||||||
return canReadRule.value ? "未找到命中规则" : "暂无命中规则查看权限";
|
return canReadRule.value ? "未找到命中规则" : "暂无命中规则查看权限";
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatSourceValue(value: unknown): string {
|
|
||||||
if (value === null || value === undefined) {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
if (typeof value === "string") {
|
|
||||||
return value || "-";
|
|
||||||
}
|
|
||||||
const text = JSON.stringify(value);
|
|
||||||
return text === undefined ? String(value) : text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 导航 ----------
|
// ---------- 导航 ----------
|
||||||
|
|
||||||
async function toCustomerDetail(): Promise<void> {
|
async function toCustomerDetail(): Promise<void> {
|
||||||
|
|||||||
@@ -47,9 +47,12 @@ html.theme-dark body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.t-cell__title {
|
.t-cell__title {
|
||||||
|
|
||||||
|
.t-cell__title-text {
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: unset;
|
text-overflow: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-state {
|
.load-state {
|
||||||
|
|||||||
Reference in New Issue
Block a user