fix registration event style

This commit is contained in:
Timi
2026-08-03 16:19:43 +08:00
parent b30d0d1769
commit e3be14b0cc
3 changed files with 70 additions and 52 deletions
+37 -9
View File
@@ -56,7 +56,13 @@
<div class="picker-text" v-text="getLimitText(formModel.limitType)" /> <div class="picker-text" v-text="getLimitText(formModel.limitType)" />
</t-form-item> </t-form-item>
<t-form-item v-if="isValueLimitType(formModel.limitType)" label="约束数值"> <t-form-item v-if="isValueLimitType(formModel.limitType)" label="约束数值">
<t-input v-model.trim="formModel.limitValueText" type="number" :placeholder="limitValuePlaceholder" borderless /> <t-input
v-model.trim="formModel.limitValueText"
type="number"
:placeholder="limitValuePlaceholder"
borderless
align="right"
/>
</t-form-item> </t-form-item>
<t-form-item label="需要拍照" content-align="right"> <t-form-item label="需要拍照" content-align="right">
<t-switch v-model="formModel.requirePhoto" /> <t-switch v-model="formModel.requirePhoto" />
@@ -107,7 +113,7 @@
</t-button> </t-button>
</div> </div>
</div> </div>
<t-popup v-model="colorPickerVisible" placement="bottom"> <t-popup v-model="colorPickerVisible" placement="bottom" @opened="handleColorPickerOpened">
<div class="color-popup"> <div class="color-popup">
<div class="header"> <div class="header">
<t-button variant="text" size="small" @click="cancelColorPicker">取消</t-button> <t-button variant="text" size="small" @click="cancelColorPicker">取消</t-button>
@@ -115,10 +121,13 @@
<t-button theme="primary" variant="text" size="small" @click="confirmColorPicker">确定</t-button> <t-button theme="primary" variant="text" size="small" @click="confirmColorPicker">确定</t-button>
</div> </div>
<t-color-picker <t-color-picker
v-if="colorPickerVisible"
:key="colorPickerRenderKey"
v-model="colorDraft" v-model="colorDraft"
format="HEX8" format="HEX8"
type="multiple" type="multiple"
:swatch-colors="colorSwatchList" :swatch-colors="colorSwatchList"
@palette-bar-change="updateColorDraftFromPalette"
/> />
</div> </div>
</t-popup> </t-popup>
@@ -143,8 +152,9 @@
<t-popup v-model="beginAtPickerVisible" placement="bottom"> <t-popup v-model="beginAtPickerVisible" placement="bottom">
<div class="picker-popup"> <div class="picker-popup">
<t-date-time-picker <t-date-time-picker
v-if="beginAtPickerVisible"
v-model="beginAtDraftText" v-model="beginAtDraftText"
:default-value="beginAtDraftText || nowDateTimeText" :start="minimumDateTimeText"
:mode="['date', 'minute']" :mode="['date', 'minute']"
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
title="起始时间" title="起始时间"
@@ -156,8 +166,9 @@
<t-popup v-model="endAtPickerVisible" placement="bottom"> <t-popup v-model="endAtPickerVisible" placement="bottom">
<div class="picker-popup"> <div class="picker-popup">
<t-date-time-picker <t-date-time-picker
v-if="endAtPickerVisible"
v-model="endAtDraftText" v-model="endAtDraftText"
:default-value="endAtDraftText || nowDateTimeText" :start="endAtMinimumDateTimeText"
:mode="['date', 'minute']" :mode="['date', 'minute']"
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
title="终止时间" title="终止时间"
@@ -171,6 +182,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { Time } from "timi-web"; import { Time } from "timi-web";
import { DialogPlugin, Toast } from "tdesign-mobile-vue"; import { DialogPlugin, Toast } from "tdesign-mobile-vue";
import type { ColorObject } from "tdesign-mobile-vue";
import type { Role } from "timi-web"; import type { Role } from "timi-web";
import RegistrationEventAPI from "@/api/RegistrationEventAPI"; import RegistrationEventAPI from "@/api/RegistrationEventAPI";
import GaoUserAPI from "@/api/GaoUserAPI"; import GaoUserAPI from "@/api/GaoUserAPI";
@@ -198,6 +210,7 @@ const pageAccess = computed(() => ({
})); }));
const roleOptions = ref<Role[]>([]); const roleOptions = ref<Role[]>([]);
const colorPickerVisible = ref(false); const colorPickerVisible = ref(false);
const colorPickerRenderKey = ref(0);
const colorDraft = ref("#2f88ff"); const colorDraft = ref("#2f88ff");
const beginAtPickerVisible = ref(false); const beginAtPickerVisible = ref(false);
const endAtPickerVisible = ref(false); const endAtPickerVisible = ref(false);
@@ -250,7 +263,14 @@ const limitPickerVisible = ref(false);
const limitPickerDraft = ref<string[]>([formModel.limitType]); const limitPickerDraft = ref<string[]>([formModel.limitType]);
const statusPickerVisible = ref(false); const statusPickerVisible = ref(false);
const statusPickerDraft = ref<RegistrationEventStatus[]>([formModel.status]); const statusPickerDraft = ref<RegistrationEventStatus[]>([formModel.status]);
const minimumDateTimeText = "1970-01-01 00:00";
const nowDateTimeText = computed(() => Time.formatDateTime(new Date())); const nowDateTimeText = computed(() => Time.formatDateTime(new Date()));
const endAtMinimumDateTimeText = computed(() => formModel.beginAtText || minimumDateTimeText);
const defaultEndAtText = computed(() => {
const date = new Date();
date.setDate(date.getDate() + 7);
return Time.formatDateTime(date);
});
const limitValuePlaceholder = computed(() => { const limitValuePlaceholder = computed(() => {
if (formModel.limitType === "INTERVAL_HOUR") { if (formModel.limitType === "INTERVAL_HOUR") {
return "请输入间隔小时数"; return "请输入间隔小时数";
@@ -266,6 +286,10 @@ function openColorPicker(): void {
colorPickerVisible.value = true; colorPickerVisible.value = true;
} }
function handleColorPickerOpened(): void {
colorPickerRenderKey.value += 1;
}
function cancelColorPicker(): void { function cancelColorPicker(): void {
colorPickerVisible.value = false; colorPickerVisible.value = false;
colorDraft.value = formModel.color; colorDraft.value = formModel.color;
@@ -276,6 +300,10 @@ function confirmColorPicker(): void {
colorPickerVisible.value = false; colorPickerVisible.value = false;
} }
function updateColorDraftFromPalette(context: { color: ColorObject }): void {
colorDraft.value = context.color.hex8;
}
function getLimitText(value: RegistrationLimitType): string { function getLimitText(value: RegistrationLimitType): string {
return limitOptions.find(option => option.value === value)?.label || "不限"; return limitOptions.find(option => option.value === value)?.label || "不限";
} }
@@ -377,17 +405,17 @@ function openBeginAtPicker(): void {
} }
function openEndAtPicker(): void { function openEndAtPicker(): void {
endAtDraftText.value = formModel.endAtText || nowDateTimeText.value; endAtDraftText.value = formModel.endAtText || defaultEndAtText.value;
endAtPickerVisible.value = true; endAtPickerVisible.value = true;
} }
function confirmBeginAt(): void { function confirmBeginAt(value: string | number): void {
formModel.beginAtText = beginAtDraftText.value; formModel.beginAtText = String(value);
beginAtPickerVisible.value = false; beginAtPickerVisible.value = false;
} }
function confirmEndAt(): void { function confirmEndAt(value: string | number): void {
formModel.endAtText = endAtDraftText.value; formModel.endAtText = String(value);
endAtPickerVisible.value = false; endAtPickerVisible.value = false;
} }
+29 -35
View File
@@ -15,9 +15,9 @@
<div class="title" v-text="item.name || '未命名事件'" /> <div class="title" v-text="item.name || '未命名事件'" />
<t-tag <t-tag
class="status" class="status"
:theme="isRegistrationEventActive(item) ? 'primary' : 'default'" :theme="getStatusTag(item).theme"
variant="outline" variant="outline"
:content="getStatusText(item)" :content="getStatusTag(item).text"
/> />
<t-tag v-if="item.requirePhoto" theme="warning" variant="outline">需拍照</t-tag> <t-tag v-if="item.requirePhoto" theme="warning" variant="outline">需拍照</t-tag>
</div> </div>
@@ -36,7 +36,6 @@
<span v-if="!(item.roleCodeList || []).length" class="muted" v-text="'未配置'" /> <span v-if="!(item.roleCodeList || []).length" class="muted" v-text="'未配置'" />
</div> </div>
<div class="line" v-text="getLimitText(item)" /> <div class="line" v-text="getLimitText(item)" />
<div class="line" v-text="getPeriodText(item)" />
</div> </div>
</template> </template>
</t-cell> </t-cell>
@@ -53,11 +52,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { Toast } from "tdesign-mobile-vue"; import { Toast } from "tdesign-mobile-vue";
import { Time, useUserStore, type Role } from "timi-web"; import { useUserStore, type Role } from "timi-web";
import RegistrationEventAPI from "@/api/RegistrationEventAPI"; import RegistrationEventAPI from "@/api/RegistrationEventAPI";
import GaoUserAPI from "@/api/GaoUserAPI"; import GaoUserAPI from "@/api/GaoUserAPI";
import { useNavBarStore } from "@/store/navBarStore"; import { useNavBarStore } from "@/store/navBarStore";
import type { RegistrationEvent, RegistrationLimitType } from "@/types/RegistrationEvent"; import type { RegistrationEvent, RegistrationEventStatus, RegistrationLimitType } from "@/types/RegistrationEvent";
import { gaoPermissionCodes } from "@/utils/gaoPermission"; import { gaoPermissionCodes } from "@/utils/gaoPermission";
defineOptions({ defineOptions({
@@ -72,6 +71,20 @@ const registrationEventList = ref<RegistrationEvent[]>([]);
const roleOptions = ref<Role[]>([]); const roleOptions = ref<Role[]>([]);
const canUpdateRegistrationEvent = computed(() => userStore.hasPermissions(gaoPermissionCodes.registrationEvent.update)); const canUpdateRegistrationEvent = computed(() => userStore.hasPermissions(gaoPermissionCodes.registrationEvent.update));
type StatusTag = {
text: string;
theme: "default" | "primary" | "danger";
};
const fixedStatusTagMap: Partial<Record<RegistrationEventStatus, StatusTag>> = {
DRAFT: { text: "草稿", theme: "default" },
INACTIVE: { text: "不可登记", theme: "default" },
DELETED: { text: "已删除", theme: "default" }
};
const activeStatusTag: StatusTag = { text: "可登记", theme: "primary" };
const notEffectiveStatusTag: StatusTag = { text: "未生效", theme: "default" };
const expiredStatusTag: StatusTag = { text: "已过期", theme: "danger" };
function createRegistrationEvent(): void { function createRegistrationEvent(): void {
router.push("/management/registration-events/create"); router.push("/management/registration-events/create");
} }
@@ -96,21 +109,20 @@ function handleRegistrationEventClick(item: RegistrationEvent): void {
editRegistrationEvent(item); editRegistrationEvent(item);
} }
function isRegistrationEventActive(item: RegistrationEvent): boolean { function getStatusTag(item: RegistrationEvent): StatusTag {
return (item.status || "ACTIVE") === "ACTIVE"; const status = item.status || "ACTIVE";
const fixedStatusTag = fixedStatusTagMap[status];
if (fixedStatusTag) {
return fixedStatusTag;
} }
const now = Date.now();
function getStatusText(item: RegistrationEvent): string { if (item.beginAt !== undefined && now < item.beginAt) {
if (item.status === "DRAFT") { return notEffectiveStatusTag;
return "草稿";
} }
if (item.status === "INACTIVE") { if (item.endAt !== undefined && item.endAt < now) {
return "不可登记"; return expiredStatusTag;
} }
if (item.status === "DELETED") { return activeStatusTag;
return "已删除";
}
return "可登记";
} }
function getLimitText(item: RegistrationEvent): string { function getLimitText(item: RegistrationEvent): string {
@@ -126,24 +138,6 @@ function getLimitText(item: RegistrationEvent): string {
return limitTextMap[item.limitType || "NONE"]; return limitTextMap[item.limitType || "NONE"];
} }
function getPeriodText(item: RegistrationEvent): string {
const beginText = formatTime(item.beginAt);
const endText = formatTime(item.endAt);
if (!beginText && !endText) {
return "有效期:不限";
}
return `有效期:${beginText || "不限"} 至 ${endText || "不限"}`;
}
function formatTime(value?: number): string {
if (!value) {
return "";
}
const date = new Date(value);
return Number.isNaN(date.getTime()) ? "" : Time.formatDateTime(date);
}
function getRoleName(code: string): string { function getRoleName(code: string): string {
const role = roleOptions.value.find(item => item.code === code); const role = roleOptions.value.find(item => item.code === code);
return role?.name || code; return role?.name || code;
@@ -4,9 +4,9 @@
<t-cell-group v-if="record" title="登记信息" theme="card"> <t-cell-group v-if="record" title="登记信息" theme="card">
<t-cell title="登记事件" :note="record.registrationEvent?.name || '未知事件'" /> <t-cell title="登记事件" :note="record.registrationEvent?.name || '未知事件'" />
<t-cell title="登记时间" :note="formatTime(record.registeredAt)" /> <t-cell title="登记时间" :note="formatTime(record.registeredAt)" />
<t-cell title="登记人" :note="getOperatorName(record)" /> <t-cell title="登记人" :note="Text.display(record.operator?.nick || record.operator?.name)" />
<t-cell title="客户编码" :note="record.customer?.code || record.customerId || '未知'" /> <t-cell title="客户编码" :note="Text.display(record.customer?.code)" />
<t-cell title="备注" :note="record.remark || '无'" /> <t-cell title="备注" :note="Text.display(record.remark)" />
</t-cell-group> </t-cell-group>
<section v-if="record" class="photo-panel"> <section v-if="record" class="photo-panel">
<photo-scroller <photo-scroller
@@ -21,7 +21,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Time, useUserStore } from "timi-web"; import { Text, Time, useUserStore } from "timi-web";
import RegistrationEventRecordAPI from "@/api/RegistrationEventRecordAPI"; import RegistrationEventRecordAPI from "@/api/RegistrationEventRecordAPI";
import CustomerProfileCard from "@/components/CustomerProfileCard.vue"; import CustomerProfileCard from "@/components/CustomerProfileCard.vue";
import PhotoScroller from "@/components/PhotoScroller.vue"; import PhotoScroller from "@/components/PhotoScroller.vue";
@@ -85,10 +85,6 @@ function formatTime(value?: number): string {
return Time.formatDateTime(date); return Time.formatDateTime(date);
} }
function getOperatorName(item: RegistrationEventRecord): string {
return item.operator?.nick || item.operator?.name || "未知";
}
watch(() => route.params.id, async () => { watch(() => route.params.id, async () => {
await loadRecord(); await loadRecord();
}, { immediate: true }); }, { immediate: true });