update registration event editor
This commit is contained in:
@@ -8,10 +8,17 @@
|
||||
<t-textarea v-model.trim="formModel.description" class="textarea" placeholder="事件说明" autosize borderless />
|
||||
</t-form-item>
|
||||
<t-form-item label="颜色">
|
||||
<label class="color-picker">
|
||||
<input v-model="formModel.color" type="color">
|
||||
<span v-text="formModel.color" />
|
||||
</label>
|
||||
<t-button
|
||||
size="extra-small"
|
||||
variant="outline"
|
||||
class="color-trigger"
|
||||
@click="openColorPicker"
|
||||
>
|
||||
<div class="content">
|
||||
<span class="swatch" :style="{ background: formModel.color }" />
|
||||
<span v-text="formModel.color" />
|
||||
</div>
|
||||
</t-button>
|
||||
</t-form-item>
|
||||
<t-form-item label="状态">
|
||||
<t-radio-group v-model="formModel.status" class="inline-options" variant="default-filled">
|
||||
@@ -19,10 +26,10 @@
|
||||
<t-radio :block="false" borderless value="INACTIVE">无效</t-radio>
|
||||
</t-radio-group>
|
||||
</t-form-item>
|
||||
<t-form-item label="启用">
|
||||
<t-form-item label="启用" content-align="right">
|
||||
<t-switch v-model="formModel.enabled" />
|
||||
</t-form-item>
|
||||
<t-form-item label="拍照">
|
||||
<t-form-item label="需要拍照" content-align="right">
|
||||
<t-switch v-model="formModel.requirePhoto" />
|
||||
</t-form-item>
|
||||
<t-form-item label="排序">
|
||||
@@ -62,12 +69,50 @@
|
||||
</t-checkbox>
|
||||
</t-checkbox-group>
|
||||
</section>
|
||||
<t-button v-can="savePermissionCode" class="save" theme="primary" @click="saveRegistrationEvent">保存</t-button>
|
||||
<div class="bottom-actions">
|
||||
<t-button
|
||||
v-if="!isCreateMode"
|
||||
v-can="deletePermissionCode"
|
||||
class="delete bg-white"
|
||||
theme="danger"
|
||||
variant="outline"
|
||||
:loading="removing"
|
||||
:disabled="saving || removing"
|
||||
@click="confirmRemoveRegistrationEvent"
|
||||
>
|
||||
删除事件
|
||||
</t-button>
|
||||
<t-button
|
||||
v-can="savePermissionCode"
|
||||
class="save"
|
||||
theme="primary"
|
||||
:loading="saving"
|
||||
:disabled="removing"
|
||||
@click="saveRegistrationEvent"
|
||||
>
|
||||
保存
|
||||
</t-button>
|
||||
</div>
|
||||
</div>
|
||||
<t-popup v-model="colorPickerVisible" placement="bottom">
|
||||
<div class="color-popup">
|
||||
<div class="header">
|
||||
<t-button variant="text" size="small" @click="cancelColorPicker">取消</t-button>
|
||||
<span class="title" v-text="'颜色选择'" />
|
||||
<t-button theme="primary" variant="text" size="small" @click="confirmColorPicker">确定</t-button>
|
||||
</div>
|
||||
<t-color-picker
|
||||
v-model="colorDraft"
|
||||
format="HEX8"
|
||||
type="multiple"
|
||||
:swatch-colors="colorSwatchList"
|
||||
/>
|
||||
</div>
|
||||
</t-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Toast } from "tdesign-mobile-vue";
|
||||
import { DialogPlugin, Toast } from "tdesign-mobile-vue";
|
||||
import type { Role } from "timi-web";
|
||||
import RegistrationEventAPI from "@/api/RegistrationEventAPI";
|
||||
import GaoUserAPI from "@/api/GaoUserAPI";
|
||||
@@ -88,11 +133,30 @@ const router = useRouter();
|
||||
const routeId = computed(() => String(route.params.id || ""));
|
||||
const isCreateMode = computed(() => !routeId.value);
|
||||
const savePermissionCode = computed(() => isCreateMode.value ? gaoPermissionCodes.registrationEvent.create : gaoPermissionCodes.registrationEvent.update);
|
||||
const deletePermissionCode = gaoPermissionCodes.registrationEvent.delete;
|
||||
const pageAccess = computed(() => ({
|
||||
value: [gaoPermissionCodes.registrationEvent.read, gaoPermissionCodes.user.read, savePermissionCode.value],
|
||||
value: isCreateMode.value
|
||||
? [gaoPermissionCodes.registrationEvent.read, gaoPermissionCodes.user.read, savePermissionCode.value]
|
||||
: [gaoPermissionCodes.registrationEvent.read, gaoPermissionCodes.user.read, { value: [savePermissionCode.value, deletePermissionCode], mode: "or" as const }],
|
||||
mode: "and" as const
|
||||
}));
|
||||
const roleOptions = ref<Role[]>([]);
|
||||
const colorPickerVisible = ref(false);
|
||||
const colorDraft = ref("#2f88ff");
|
||||
const saving = ref(false);
|
||||
const removing = ref(false);
|
||||
const colorSwatchList = [
|
||||
"#2f88ff",
|
||||
"#0ea5e9",
|
||||
"#10b981",
|
||||
"#22c55e",
|
||||
"#f59e0b",
|
||||
"#f97316",
|
||||
"#ef4444",
|
||||
"#ec4899",
|
||||
"#8b5cf6",
|
||||
"#64748b"
|
||||
];
|
||||
const limitOptions: LimitOption[] = [
|
||||
{ label: "不限", value: "NONE" },
|
||||
{ label: "上午/下午各一次", value: "DAILY_HALF_DAY" },
|
||||
@@ -116,6 +180,21 @@ const formModel = reactive({
|
||||
});
|
||||
const limitValuePlaceholder = computed(() => formModel.limitType === "INTERVAL_HOUR" ? "请输入间隔小时数" : "请输入累计上限次数");
|
||||
|
||||
function openColorPicker(): void {
|
||||
colorDraft.value = formModel.color;
|
||||
colorPickerVisible.value = true;
|
||||
}
|
||||
|
||||
function cancelColorPicker(): void {
|
||||
colorPickerVisible.value = false;
|
||||
colorDraft.value = formModel.color;
|
||||
}
|
||||
|
||||
function confirmColorPicker(): void {
|
||||
formModel.color = colorDraft.value;
|
||||
colorPickerVisible.value = false;
|
||||
}
|
||||
|
||||
function isValueLimitType(value: RegistrationLimitType): boolean {
|
||||
return value === "INTERVAL_HOUR" || value === "TOTAL_LIMIT";
|
||||
}
|
||||
@@ -162,6 +241,7 @@ async function saveRegistrationEvent(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
saving.value = true;
|
||||
try {
|
||||
const payload = buildPayload();
|
||||
if (isCreateMode.value) {
|
||||
@@ -173,6 +253,47 @@ async function saveRegistrationEvent(): Promise<void> {
|
||||
await router.replace("/management/registration-events");
|
||||
} catch {
|
||||
showToast("登记事件保存失败", "error");
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmRemoveRegistrationEvent(): Promise<void> {
|
||||
const id = formModel.id || routeId.value;
|
||||
if (!id || removing.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eventName = formModel.name.trim() || "未命名事件";
|
||||
const dialog = DialogPlugin.confirm({
|
||||
title: "删除登记事件",
|
||||
content: `确定删除登记事件 ${eventName} 吗?删除后无法恢复。`,
|
||||
cancelBtn: "取消",
|
||||
confirmBtn: "删除",
|
||||
onCancel() {
|
||||
dialog.destroy();
|
||||
},
|
||||
async onConfirm() {
|
||||
dialog.destroy();
|
||||
await removeRegistrationEvent(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function removeRegistrationEvent(id: string): Promise<void> {
|
||||
if (removing.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
removing.value = true;
|
||||
try {
|
||||
await RegistrationEventAPI.remove(id);
|
||||
showToast("登记事件已删除");
|
||||
await router.replace("/management/registration-events");
|
||||
} catch {
|
||||
showToast("登记事件删除失败", "error");
|
||||
} finally {
|
||||
removing.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +325,7 @@ async function fillForm(): Promise<void> {
|
||||
sortText: String(current.sort ?? 0),
|
||||
roleCodeList: [...(current.roleCodeList || [])]
|
||||
});
|
||||
colorDraft.value = formModel.color;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -227,22 +349,30 @@ onMounted(async () => {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.color-picker {
|
||||
.color-trigger {
|
||||
--td-button-extra-small-padding-horizontal: 2px;
|
||||
|
||||
gap: .75rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: .875rem;
|
||||
justify-content: flex-start;
|
||||
|
||||
input {
|
||||
padding: 0;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.content {
|
||||
gap: .5rem;
|
||||
display: flex;
|
||||
|
||||
span {
|
||||
color: #52607a;
|
||||
font-size: .875rem;
|
||||
.swatch {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
display: block;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #52607a;
|
||||
font-size: .875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,21 +419,57 @@ onMounted(async () => {
|
||||
}
|
||||
}
|
||||
|
||||
.save {
|
||||
.bottom-actions {
|
||||
gap: .75rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
display: flex;
|
||||
bottom: calc(.75rem + env(safe-area-inset-bottom, 0));
|
||||
position: fixed;
|
||||
|
||||
.delete {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.save {
|
||||
flex: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.color-popup {
|
||||
padding: .75rem 0 1.25rem;
|
||||
background: #fff;
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
padding: 0 1rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
span {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global(html.theme-dark) {
|
||||
.registration-event-edit {
|
||||
.color-picker span,
|
||||
.color-trigger span,
|
||||
.roles .title .hint {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.color-trigger .swatch {
|
||||
box-shadow: inset 0 0 0 1px rgba(148, 163, 184, .24);
|
||||
}
|
||||
|
||||
.color-popup {
|
||||
background: #0f172a;
|
||||
}
|
||||
|
||||
.roles .group .item {
|
||||
color: #e2e8f0;
|
||||
background: rgba(15, 23, 42, .72);
|
||||
|
||||
Reference in New Issue
Block a user