perf: 支持设置网安备案号

pull/409/head
xiaojunnuo 2025-05-10 21:31:32 +08:00
parent 0a147d2db7
commit d18e431e2f
8 changed files with 41 additions and 26 deletions

View File

@ -25,6 +25,7 @@ export class SysPublicSettings extends BaseSettings {
limitUserPipelineCount = 0;
managerOtherUserPipeline = false;
icpNo?: string;
mpsNo?: string;
robots?: boolean = true;
}

View File

@ -15,8 +15,13 @@
<template v-if="sysPublic.icpNo">
<span>
<a href="https://beian.miit.gov.cn/" target="_blank">{{ sysPublic.icpNo }}</a>
<a-divider type="vertical" />
</span>
</template>
<span v-if="sysPublic.mpsNo">
<a href="http://www.beian.gov.cn/portal/registerSystemInfo" target="_blank">{{ sysPublic.mpsNo }}</a>
</span>
</div>
<div class="ml-5">v{{ version }}</div>
</div>
@ -26,7 +31,7 @@ import { computed, onMounted, ref } from "vue";
import { useSettingStore } from "/@/store/settings";
defineOptions({
name: "PageFooter"
name: "PageFooter",
});
const version = ref(import.meta.env.VITE_APP_VERSION);

View File

@ -20,8 +20,8 @@ const menus = computed(() => [
router.push("/certd/mine/user-profile");
},
icon: "fa-solid:book",
text: "账号信息"
}
text: "账号信息",
},
]);
const avatar = computed(() => {
@ -42,7 +42,7 @@ const siteInfo = computed(() => {
return settingStore.siteInfo;
});
onErrorCaptured((e) => {
onErrorCaptured(e => {
console.error("ErrorCaptured:", e);
// notification.error({ message: e.message });
//

View File

@ -133,7 +133,7 @@ const asideCollapsed = ref(false);
function asideCollapsedToggle() {
asideCollapsed.value = !asideCollapsed.value;
}
onErrorCaptured((e) => {
onErrorCaptured(e => {
console.error("ErrorCaptured:", e);
// notification.error({ message: e.message });
//

View File

@ -31,6 +31,10 @@
<a-divider type="vertical" />
<a href="https://beian.miit.gov.cn/" target="_blank">{{ sysPublic.icpNo }}</a>
</span>
<span v-if="sysPublic.mpsNo">
<a-divider type="vertical" />
<a href="http://www.beian.gov.cn/portal/registerSystemInfo" target="_blank">{{ sysPublic.mpsNo }}</a>
</span>
</div>
</div>
</div>

View File

@ -39,6 +39,7 @@ export type SysPublicSetting = {
limitUserPipelineCount?: number;
managerOtherUserPipeline?: boolean;
icpNo?: string;
mpsNo?: string;
robots?: boolean;
};
export type SuiteSetting = {

View File

@ -18,7 +18,7 @@ import { useLayout } from "./hooks/use-layout";
interface Props extends VbenLayoutProps {}
defineOptions({
name: "VbenLayout"
name: "VbenLayout",
});
const props = withDefaults(defineProps<Props>(), {
@ -48,7 +48,7 @@ const props = withDefaults(defineProps<Props>(), {
sideCollapseWidth: 60,
tabbarEnable: true,
tabbarHeight: 40,
zIndex: 200
zIndex: 200,
});
const emit = defineEmits<{ sideMouseLeave: []; toggleSidebar: [] }>();
@ -193,7 +193,7 @@ const mainStyle = computed(() => {
}
return {
sidebarAndExtraWidth,
width
width,
};
});
@ -221,7 +221,7 @@ const tabbarStyle = computed((): CSSProperties => {
return {
marginLeft: `${marginLeft}px`,
width
width,
};
});
@ -231,7 +231,7 @@ const contentStyle = computed((): CSSProperties => {
const { footerEnable, footerFixed, footerHeight } = props;
return {
marginTop: fixed && !isFullContent.value && !headerIsHidden.value && (!isHeaderAutoMode.value || scrollY.value < headerWrapperHeight.value) ? `${headerWrapperHeight.value}px` : 0,
paddingBottom: `${footerEnable && footerFixed ? footerHeight : 0}px`
paddingBottom: `${footerEnable && footerFixed ? footerHeight : 0}px`,
};
});
@ -249,7 +249,7 @@ const headerWrapperStyle = computed((): CSSProperties => {
position: fixed ? "fixed" : "static",
top: headerIsHidden.value || isFullContent.value ? `-${headerWrapperHeight.value}px` : 0,
width: mainStyle.value.width,
"z-index": headerZIndex.value
"z-index": headerZIndex.value,
};
});
@ -289,13 +289,13 @@ const showHeaderLogo = computed(() => {
watch(
() => props.isMobile,
(val) => {
val => {
if (val) {
sidebarCollapse.value = true;
}
},
{
immediate: true
immediate: true,
}
);
@ -305,7 +305,7 @@ watch(
setLayoutHeaderHeight(isFullContent.value ? 0 : height);
},
{
immediate: true
immediate: true,
}
);
@ -315,7 +315,7 @@ watch(
setLayoutFooterHeight(height);
},
{
immediate: true
immediate: true,
}
);
@ -336,7 +336,7 @@ watch(
mouseMove();
},
{
immediate: true
immediate: true,
}
);
}
@ -433,9 +433,9 @@ const idMainContent = ELEMENT_ID_MAIN_CONTENT;
<div
:class="[
{
'shadow-[0_16px_24px_hsl(var(--background))]': scrollY > 20
'shadow-[0_16px_24px_hsl(var(--background))]': scrollY > 20,
},
SCROLL_FIXED_CLASS
SCROLL_FIXED_CLASS,
]"
:style="headerWrapperStyle"
class="overflow-hidden transition-all duration-200"

View File

@ -4,6 +4,9 @@
<a-form-item label="ICP备案号" :name="['public', 'icpNo']">
<a-input v-model:value="formState.public.icpNo" placeholder="粤ICP备xxxxxxx号" />
</a-form-item>
<a-form-item label="网安备案号" :name="['public', 'mpsNo']">
<a-input v-model:value="formState.public.mpsNo" placeholder="京公网安备xxxxxxx号" />
</a-form-item>
<a-form-item label="允许爬虫" :name="['public', 'robots']">
<a-switch v-model:checked="formState.public.robots" />
@ -53,19 +56,20 @@ import { notification } from "ant-design-vue";
import { util } from "/@/utils";
defineOptions({
name: "SettingBase"
name: "SettingBase",
});
const formState = reactive<Partial<SysSettings>>({
public: {
icpNo: ""
icpNo: "",
mpsNo: "",
},
private: {}
private: {},
});
const urlRules = ref({
type: "url",
message: "请输入正确的URL"
message: "请输入正确的URL",
});
async function loadSysSettings() {
@ -82,7 +86,7 @@ const onFinish = async (form: any) => {
await api.SysSettingsSave(form);
await settingsStore.loadSysSettings();
notification.success({
message: "保存成功"
message: "保存成功",
});
} finally {
saveLoading.value = false;
@ -96,7 +100,7 @@ const onFinishFailed = (errorInfo: any) => {
async function stopOtherUserTimer() {
await api.stopOtherUserTimer();
notification.success({
message: "停止成功"
message: "停止成功",
});
}
@ -120,13 +124,13 @@ async function testProxy() {
if (!success) {
notification.error({
message: "测试失败",
description: content
description: content,
});
return;
}
notification.success({
message: "测试完成",
description: content
description: content,
});
} finally {
testProxyLoading.value = false;