Skip to content

Commit

Permalink
feat(ui): add systemSettingView
Browse files Browse the repository at this point in the history
  • Loading branch information
ShiinaKin committed Nov 30, 2024
1 parent 2d09924 commit 76e2445
Show file tree
Hide file tree
Showing 3 changed files with 335 additions and 5 deletions.
16 changes: 16 additions & 0 deletions ui/src/locales/zh_cn.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -634,3 +634,19 @@ settingView:
failedTitle: "修改失败"
fetch:
failedTitle: "获取站点设置失败"
systemSetting:
title: "系统设置"
form:
defaultGroupId: "默认用户组"
allowSignup: "允许注册"
allowRandomFetch: "允许获取随机图"
verify:
atLeastOneField: "请至少修改一个字段"
submitButton: "保存"
toast:
patch:
successTitle: "修改成功"
failedTitle: "修改失败"
fetch:
failedTitle: "获取站点设置失败"
groupFailedTitle: "获取用户组失败"
13 changes: 8 additions & 5 deletions ui/src/views/structure/adminField/setting/SiteSettingView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,22 @@ function patchSiteSetting(patchRequest: SiteSettingPatchRequest) {
toast.add({
severity: "success",
summary: t("settingView.siteSetting.toast.patch.successTitle"),
detail: resp.message
detail: resp.message,
life: 3000
});
fetchSiteSetting();
} else {
toast.add({
severity: "warn",
summary: t("settingView.siteSetting.toast.patch.failedTitle"),
detail: resp.message
detail: resp.message,
life: 3000
});
}
})
.catch((error) => {
console.error(error);
toast.add({ severity: "error", summary: "Error", detail: error.message });
toast.add({ severity: "error", summary: "Error", detail: error.message, life: 3000 });
});
}
Expand All @@ -127,13 +129,14 @@ function fetchSiteSetting() {
toast.add({
severity: "warn",
summary: t("settingView.siteSetting.toast.fetch.failedTitle"),
detail: resp.message
detail: resp.message,
life: 3000
});
}
})
.catch((error) => {
console.error(error);
toast.add({ severity: "error", summary: "Error", detail: error.message });
toast.add({ severity: "error", summary: "Error", detail: error.message, life: 3000 });
});
}
</script>
Expand Down
311 changes: 311 additions & 0 deletions ui/src/views/structure/adminField/setting/SystemSettingView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { useI18n } from "vue-i18n";
import { useToast } from "primevue/usetoast";
import {
Configuration,
GroupApi,
type GroupApiApiGroupPageGetRequest,
type GroupPageVO,
SettingApi,
type SystemSettingPatchRequest
} from "api-client";
import { useForm } from "vee-validate";
import * as yup from "yup";
import { debounce } from "lodash-es";
import Toolbar from "primevue/toolbar";
import IftaLabel from "primevue/iftalabel";
import Message from "primevue/message";
import Select from "primevue/select";
import Button from "primevue/button";
import type { VirtualScrollerLazyEvent } from "primevue";
import VeeToggleSwitch from "@/components/vee-input/VeeToggleSwitch.vue";
import LoadingDialog from "@/components/LoadingDialog.vue";
const { t } = useI18n();
const token = localStorage.getItem("token");
const toast = useToast();
const configuration = new Configuration({ baseOptions: { headers: { Authorization: `Bearer ${token}` } } });
const settingApi = new SettingApi(configuration);
const groupApi = new GroupApi(configuration);
const systemSetting = ref();
const systemSettingDefaultGroupVO = ref();
const groupPage = ref(1);
const groupPageSize = ref(15);
const groupOrderBy = ref("createTime");
const groupOrder = ref("DESC");
const groupPageRequest = computed<GroupApiApiGroupPageGetRequest>(() => {
return {
page: groupPage.value,
pageSize: groupPageSize.value,
orderBy: groupOrderBy.value === "" ? undefined : groupOrderBy.value,
order: groupOrder.value === "" ? undefined : groupOrder.value
};
});
const groupCurPage = ref(1);
const groupTotalRecord = ref(-1);
const groupPageData = ref<GroupPageVO[]>([]);
const showLoadingDialog = ref(false);
const groupSelectLoading = ref(false);
const debounceHandleGroupSelectLazyLoading = debounce(
(event: VirtualScrollerLazyEvent) => handleGroupSelectLazyLoading(event),
200
);
function handleGroupSelectLazyLoading(event: VirtualScrollerLazyEvent) {
if (groupPageData.value.length === 0) {
pageGroup(groupPageRequest.value)
.then((data) => {
if (data instanceof Array) groupPageData.value = data;
})
.then(() => (groupSelectLoading.value = false));
return;
}
const { last } = event;
if (groupTotalRecord.value === last) return;
groupPage.value += 1;
pageGroup(groupPageRequest.value)
.then((data) => {
if (data) groupPageData.value.push(...data);
})
.then(() => (groupSelectLoading.value = false));
}
const systemSettingFormInitValue = {
defaultGroup: undefined,
allowSignup: undefined,
allowRandomFetch: undefined
};
const systemSettingFormSchema = yup.object({
defaultGroup: yup
.object()
.test("at-least-one-field", t("settingView.systemSetting.form.verify.atLeastOneField"), function () {
return (
(this.parent.defaultGroup && this.parent.defaultGroup.id !== systemSettingDefaultGroupVO.value.id) ||
this.parent.allowSignup ||
this.parent.allowRandomFetch
);
}),
allowSignup: yup
.boolean()
.test("at-least-one-field", t("settingView.systemSetting.form.verify.atLeastOneField"), function () {
return (
(this.parent.defaultGroup && this.parent.defaultGroup.id !== systemSettingDefaultGroupVO.value.id) ||
this.parent.allowSignup ||
this.parent.allowRandomFetch
);
}),
allowRandomFetch: yup
.boolean()
.test("at-least-one-field", t("settingView.systemSetting.form.verify.atLeastOneField"), function () {
return (
(this.parent.defaultGroup && this.parent.defaultGroup.id !== systemSettingDefaultGroupVO.value.id) ||
this.parent.allowSignup ||
this.parent.allowRandomFetch
);
})
});
const { handleSubmit, defineField, errors } = useForm({
validationSchema: systemSettingFormSchema
});
const [defaultGroup, defaultGroupAttrs] = defineField("defaultGroup");
const onSystemSettingFormSubmit = handleSubmit((values) => {
const patchRequest: SystemSettingPatchRequest = {
defaultGroupId: values.defaultGroup?.id,
allowSignup: values.allowSignup,
allowRandomFetch: values.allowRandomFetch
};
patchSystemSetting(patchRequest);
});
onMounted(async () => {
await init();
});
async function init() {
showLoadingDialog.value = true;
try {
await fetchSystemSetting();
if (systemSetting.value?.defaultGroupId) {
systemSettingDefaultGroupVO.value = await fetchGroup(systemSetting.value.defaultGroupId);
}
} finally {
showLoadingDialog.value = false;
}
}
async function patchSystemSetting(patchRequest: SystemSettingPatchRequest) {
return settingApi
.apiSettingSystemPatch({ systemSettingPatchRequest: patchRequest })
.then((response) => {
const resp = response.data;
if (resp.isSuccessful) {
toast.add({
severity: "success",
summary: t("settingView.systemSetting.toast.patch.successTitle"),
detail: resp.message,
life: 3000
});
init();
} else {
toast.add({
severity: "warn",
summary: t("settingView.systemSetting.toast.patch.failedTitle"),
detail: resp.message,
life: 3000
});
}
})
.catch((error) => {
console.error(error);
toast.add({ severity: "error", summary: "Error", detail: error.message, life: 3000 });
});
}
async function fetchSystemSetting() {
return settingApi
.apiSettingSettingTypeGet({ settingType: "system" })
.then((response) => {
const resp = response.data;
if (resp.isSuccessful) {
systemSetting.value = resp.data?.config;
} else {
toast.add({
severity: "warn",
summary: t("settingView.systemSetting.toast.fetch.failedTitle"),
detail: resp.message,
life: 3000
});
}
})
.catch((error) => {
console.error(error);
toast.add({ severity: "error", summary: "Error", detail: error.message, life: 3000 });
});
}
async function fetchGroup(groupId: number) {
return groupApi
.apiGroupIdGet({ id: groupId })
.then((response) => {
const resp = response.data;
if (resp.isSuccessful) {
return resp.data;
} else {
toast.add({
severity: "warn",
summary: t("settingView.systemSetting.toast.fetch.groupFailedTitle"),
detail: resp.message,
life: 3000
});
}
})
.catch((error) => {
console.error(error);
toast.add({ severity: "error", summary: "Error", detail: error.message, life: 3000 });
});
}
async function pageGroup(pageRequest: GroupApiApiGroupPageGetRequest): Promise<GroupPageVO[] | void> {
return groupApi
.apiGroupPageGet(pageRequest)
.then((response) => {
const resp = response.data;
if (resp.isSuccessful) {
const pageResult = resp.data!;
groupCurPage.value = pageResult.page;
groupTotalRecord.value = pageResult.total;
return pageResult.data;
} else {
toast.add({
severity: "warn",
summary: t("settingView.systemSetting.toast.fetch.groupFailedTitle"),
detail: resp.message,
life: 3000
});
}
})
.catch((error) => {
console.error(error);
toast.add({ severity: "error", summary: "Error", detail: error.message, life: 3000 });
});
}
</script>

<template>
<div class="w-full m-8 flex flex-col items-center gap-4">
<Toolbar class="w-full">
<template #start>
<h1 class="text-2xl font-bold">{{ t("settingView.systemSetting.title") }}</h1>
</template>
</Toolbar>
<div class="w-full bg-white rounded flex-grow flex flex-col justify-center items-center">
<form
:initial-values="systemSettingFormInitValue"
@submit="onSystemSettingFormSubmit"
class="flex flex-col gap-4 w-1/3"
>
<div class="flex flex-col gap-2.5 w-full">
<div class="flex flex-col gap-1">
<IftaLabel>
<Select
id="systemSettingFormDefaultGroup"
name="defaultGroup"
:options="groupPageData"
optionLabel="name"
:placeholder="systemSettingDefaultGroupVO?.name"
v-model="defaultGroup"
v-bind="defaultGroupAttrs"
:virtualScrollerOptions="{
lazy: true,
showLoader: true,
loading: groupSelectLoading,
onLazyLoad: debounceHandleGroupSelectLazyLoading
}"
fluid
/>
<label for="systemSettingFormDefaultGroup">
{{ t("settingView.systemSetting.form.defaultGroupId") }}
</label>
</IftaLabel>
<Message v-if="errors.defaultGroup" severity="error" size="small" variant="simple">
{{ errors.defaultGroup }}
</Message>
</div>
<div class="flex flex-col gap-1">
<VeeToggleSwitch
id="systemSettingFormAllowSignup"
name="allowSignup"
:label="t('settingView.systemSetting.form.allowSignup')"
:defaultValue="systemSetting?.allowSignup as boolean"
/>
</div>
<div class="flex flex-col gap-1">
<VeeToggleSwitch
id="systemSettingFormAllowRandomFetch"
name="allowRandomFetch"
:label="t('settingView.systemSetting.form.allowRandomFetch')"
:defaultValue="systemSetting?.allowRandomFetch as boolean"
/>
</div>
</div>
<div class="flex justify-end gap-2">
<Button type="submit" :label="t('settingView.systemSetting.form.submitButton')" />
</div>
</form>
</div>

<LoadingDialog v-model:visible="showLoadingDialog" />
</div>
</template>

<style scoped></style>

0 comments on commit 76e2445

Please sign in to comment.