系统配置静态页面部分

This commit is contained in:
2026-08-25 17:13:29 +08:00
parent a5de29a3de
commit 250cf6b22e
7 changed files with 351 additions and 1 deletions
+2 -1
View File
@@ -253,7 +253,8 @@ const local: App.I18n.Schema = {
home_closeconfirm: '关闭确认',
report: '统计报表',
signstatistics: '质量会签统计',
factoryoverview: '全工厂统计概览'
factoryoverview: '全工厂统计概览',
systemmanage_setting: '系统配置'
},
form: {
required: '不能为空',
+1
View File
@@ -43,6 +43,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
riskstatistics: () => import("@/views/riskStatistics/index.vue"),
signstatistics: () => import("@/views/signStatistics/index.vue"),
systemmanage_role: () => import("@/views/systemManage/role/index.vue"),
systemmanage_setting: () => import("@/views/systemManage/setting/index.vue"),
systemmanage_template: () => import("@/views/systemManage/template/index.vue"),
systemmanage_user: () => import("@/views/systemManage/user/index.vue"),
};
+11
View File
@@ -363,6 +363,17 @@ export const generatedRoutes: GeneratedRoute[] = [
order: 2
}
},
{
name: 'systemmanage_setting',
path: '/systemmanage/setting',
component: 'view.systemmanage_setting',
meta: {
title: 'systemmanage_setting',
i18nKey: 'route.systemmanage_setting',
icon: '',
order: 4
}
},
{
name: 'systemmanage_template',
path: '/systemmanage/template',
+1
View File
@@ -195,6 +195,7 @@ const routeMap: RouteMap = {
"signstatistics": "/signstatistics",
"systemmanage": "/systemmanage",
"systemmanage_role": "/systemmanage/role",
"systemmanage_setting": "/systemmanage/setting",
"systemmanage_template": "/systemmanage/template",
"systemmanage_user": "/systemmanage/user"
};
+2
View File
@@ -75,6 +75,7 @@ declare module 'vue' {
NSwitch: typeof import('naive-ui')['NSwitch']
NTab: typeof import('naive-ui')['NTab']
NTable: typeof import('naive-ui')['NTable']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag']
NTooltip: typeof import('naive-ui')['NTooltip']
@@ -161,6 +162,7 @@ declare global {
const NSwitch: typeof import('naive-ui')['NSwitch']
const NTab: typeof import('naive-ui')['NTab']
const NTable: typeof import('naive-ui')['NTable']
const NTabPane: typeof import('naive-ui')['NTabPane']
const NTabs: typeof import('naive-ui')['NTabs']
const NTag: typeof import('naive-ui')['NTag']
const NTooltip: typeof import('naive-ui')['NTooltip']
+2
View File
@@ -49,6 +49,7 @@ declare module "@elegant-router/types" {
"signstatistics": "/signstatistics";
"systemmanage": "/systemmanage";
"systemmanage_role": "/systemmanage/role";
"systemmanage_setting": "/systemmanage/setting";
"systemmanage_template": "/systemmanage/template";
"systemmanage_user": "/systemmanage/user";
};
@@ -139,6 +140,7 @@ declare module "@elegant-router/types" {
| "riskstatistics"
| "signstatistics"
| "systemmanage_role"
| "systemmanage_setting"
| "systemmanage_template"
| "systemmanage_user"
>;
+332
View File
@@ -0,0 +1,332 @@
<script setup lang="ts">
import { ref, computed } from 'vue';
import { useAppStore } from '@/store/modules/app';
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme';
import { getColorWithOpacity } from '@/utils/common';
const appStore = useAppStore();
const themeStore = useThemeStore();
const gap = computed(() => (appStore.isMobile ? 0 : 16));
const aiEnabled = ref<boolean>(true);
// AI 辅助功能配置
const aiConfig = ref<{address:string, mode:number|null, key:string,timeout:null|number}>({
address:'',
mode:null,
key:'',
timeout:null,
})
const modeOptions = ref<{label:string, value:number}[]>([
{label:'kimi-k2(企业私有化部署)',value:1}
])
// 变更类型
const typeList = ref<{id:number, name:string, desc?:string}[]>([
{id:1,name:'工艺', desc:'工艺参数、配方、操作条件、操作规程等工艺技术类变更'},
{id:2,name:'设备', desc:'设备本体、附件、材质、规格、备件等硬件类变更'},
{id:3,name:'管理', desc:'制度、职责、程序、组织与人员等管理类变更'},
])
// 变更等级
const levelList = ref<{id:number, name:string, way:string,tools:{id:number, name:string}[]}[]>([
{id:1,name:'一般', way:'等级评分< 20 分',tools:[{id:1,name:'AI预分析'},{id:2,name:'检查表法'}]},
{id:2,name:'重要', way:'等级评分 > 20 分',tools:[{id:1,name:'AI预分析'},{id:2,name:'HAZOP'},{id:3,name:'JSA'},{id:4,name:'SCL'}]},
])
// 变更编号规则
const ruleInfo = ref<{prefix:string, year:null|string, code:number|null, digit:number|null, rule:number|null}>({
prefix:'MOC',
year:null,
code: null,
digit: null,
rule: null,
})
const yearOptions = ref<{label:string, value:string}[]>([
{label:'四位年份(yyyy',value:'yyyy'}
])
const codeOptions = ref<{label:string, value:number}[]>([
{label:'申请部门装置代码',value:1}
])
const ruleOptions = ref<{label:string, value:number}[]>([
{label:'按年度+装置代码重置',value:1}
])
const toggle = (v: boolean) => {
window.$message?.success(v ? "AI 辅助功能已启用" : "AI 辅助功能已关闭");
aiEnabled.value = v;
}
</script>
<template>
<NSpace vertical :size="16">
<NGrid :x-gap="gap" :y-gap="16" responsive="screen" item-responsive>
<!-- AI 辅助功能 -->
<NGi span="24 s:24 m:24 l:12">
<NCard :bordered="true" size="small" :content-style="{padding: 0}"
:style="{
borderRadius: themeStore.themeRadius + 'px',
height: '100%',
'--success-color': themeStore.otherColor.success,
'--warning-color': themeStore.otherColor.warning,
'--success-bg': getColorWithOpacity(themeStore.otherColor.success, 0.1),
'--warning-bg': getColorWithOpacity(themeStore.otherColor.warning, 0.1),
}"
>
<p class=" text-base font-semibold border-b border-slate-100 p-3 flex items-center">
<Icon icon="lucide:sparkles" class="size-14px text-violet-500 mr-1" />AI 辅助功能
</p>
<div class="py-3 px-4">
<div class="rounded-lg border p-4">
<div class="flex items-center justify-between">
<div class="text-sm font-medium">启用 AI 辅助</div>
<NSwitch size="small" :value="aiEnabled" @update:value="toggle" />
</div>
<div class="mt-1 text-xs text-slate-500">
开启后变更申请界面显示变更识别按钮AI 自动完成变更前后比较生成变更申请表均支持手动修改关闭后全部内容手动填写
</div>
</div>
<div class="mt-3 flex items-center gap-2 rounded-lg px-3 py-2 text-xs"
:class="aiEnabled ? 'bg-[var(--success-bg)] text-[var(--success-color)]' : 'bg-[var(--warning-bg)] text-[var(--warning-color)]'">
<Icon v-if="aiEnabled" icon="material-symbols:check-circle-outline" class="size-16px" />
<Icon v-else icon="proicons:alert-triangle" class="size-16px" />
当前状态{{ aiEnabled ? "已启用 —— 变更申请界面提供 AI 变更识别与申请表生成" : "已关闭 —— 变更申请界面为纯手动模式" }}
</div>
<div class="space-y-2 border rounded-md p-3 mt-3">
<div class="flex items-center">
<p class="w-100px text-left">接口地址</p>
<div class="flex-1">
<NInput v-model:value="aiConfig.address" placeholder="请输入接口地址" />
</div>
</div>
<div class="flex items-center">
<p class="w-100px text-left">模型</p>
<div class="flex-1">
<NSelect v-model:value="aiConfig.mode" :options="modeOptions" placeholder="请选择模型" />
</div>
</div>
<div class="flex items-center">
<p class="w-100px text-left">API Key</p>
<div class="flex-1">
<NInput v-model:value="aiConfig.key" placeholder="请输入API Key" />
</div>
</div>
<div class="flex items-center">
<p class="w-100px text-left">超时</p>
<div class="flex-1">
<NInputNumber v-model:value="aiConfig.timeout" :min="1" :show-button="false" :precision="0" placeholder="请输入超时时间" />
</div>
</div>
<div class="flex items-center gap-3">
<NButton size="small" type="primary" class="text-xs">测试连接</NButton>
<NButton size="small" class="text-xs">保存配置</NButton>
<NButton size="small" class="text-xs">
<Icon icon="akar-icons:file" class="size-14px mr-1" />
调用记录查询
</NButton>
</div>
</div>
</div>
</NCard>
</NGi>
<!-- 变更类型设置支持自定义 -->
<NGi span="24 s:24 m:24 l:12">
<NCard :bordered="true" size="small" :content-style="{padding: 0}" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
<div class="flex items-center justify-between text-base font-semibold border-b border-slate-100 p-3">
<div class="flex items-center">
<Icon icon="ep:setting" class="size-16px mr-1" />
变更类型设置支持自定义
</div>
<NButton size="small" type="primary" class="text-xs">
<Icon icon="ic:round-plus" class="size-16px" />新增类型
</NButton>
</div>
<div class="py-3 px-4">
<div v-if="typeList.length" class="border rounded-md">
<template v-for="(item,index) in typeList" :key="item.id">
<div class="p-3 flex items-center gap-2" :class="{'border-t':index !== 0}">
<div class="flex-1 flex gap-2">
<NTag size="small" type="success">{{item.name}}</NTag>
<p class="flex-1">{{item.desc}}</p>
</div>
<div class="flex items-center gap-2">
<NButton text type="primary" class="text-xs">
<Icon icon="akar-icons:edit" class="size-14px" />编辑
</NButton>
<NButton text type="error" class="text-xs">
<Icon icon="ep:delete" class="size-12px" />删除
</NButton>
</div>
</div>
</template>
</div>
<div v-else>
<NEmpty description="暂无变更类型"></NEmpty>
</div>
<p class="mt-3 text-xs text-slate-400">每个类型可关联默认审批流程模板材料清单模板和 PSSR 检查模板;历史变更单保留原类型快照不受修改/删除影响</p>
</div>
</NCard>
</NGi>
</NGrid>
<NGrid :x-gap="gap" :y-gap="16" responsive="screen" item-responsive>
<!-- 变更等级设定支持自定义 -->
<NGi span="24 s:24 m:24 l:12">
<NCard :bordered="true" size="small" :content-style="{padding: 0}"
:style="{
borderRadius: themeStore.themeRadius + 'px',
height: '100%',
'--theme-color': themeStore.themeColor,
'--warning-color': themeStore.otherColor.warning,
'--error-color': themeStore.otherColor.error,
}"
>
<div class="flex items-center justify-between text-base font-semibold border-b border-slate-100 p-3">
<div class="flex items-center">
<Icon icon="ep:setting" class="size-16px mr-1" />
变更等级设定支持自定义
</div>
<NButton size="small" type="primary" class="text-xs">
<Icon icon="ic:round-plus" class="size-16px" />新增等级
</NButton>
</div>
<div class="py-3 px-4">
<div v-if="levelList.length" class="space-y-2">
<div v-for="item in levelList" :key="item.id" class="border rounded-md p-3">
<div class="flex items-center">
<div class="flex-1 flex items-center gap-2">
<NTag v-if="item.name==='一般'" size="small">{{item.name}}</NTag>
<NTag v-else-if="item.name==='重要'" size="small" type="error">{{item.name}}</NTag>
<p class="flex-1">判定方式<b>{{item.way}}</b></p>
</div>
<div class="flex items-center gap-2">
<NButton text type="primary" class="text-xs">
<Icon icon="akar-icons:edit" class="size-14px" />编辑
</NButton>
<NButton text type="error" class="text-xs">
<Icon icon="ep:delete" class="size-12px" />删除
</NButton>
</div>
</div>
<div class="flex flex-wrap mt-2">
<p>对应分析工具</p>
<div class="flex items-center flex-wrap gap-2">
<NTag v-for="tool in item.tools" :key="tool.id" size="small" type="info">{{tool.name}}</NTag>
</div>
</div>
</div>
</div>
<div v-else>
<NEmpty description="暂无变更等级"></NEmpty>
</div>
<p class="mt-3 text-xs text-slate-400">等级决定审批流程风险分析深度与会签范围;申请时系统按判定方式自动定级并推荐对应分析工具支持人工改判留痕勾选 HAZOP/JSA/SCL的风险定级规则见下方风险矩阵设置</p>
</div>
</NCard>
</NGi>
<!-- 变更编号规则 -->
<NGi span="24 s:24 m:24 l:12">
<NCard :bordered="true" size="small" :content-style="{padding: 0}"
:style="{
borderRadius: themeStore.themeRadius + 'px',
height: '100%',
'--theme-color': themeStore.themeColor,
'--warning-color': themeStore.otherColor.warning,
'--error-color': themeStore.otherColor.error,
}"
>
<div class="flex items-center justify-between text-base font-semibold border-b border-slate-100 p-3">
<div class="flex items-center">
<Icon icon="ep:setting" class="size-16px mr-1" />
变更编号规则
</div>
</div>
<div class="py-3 px-4">
<div class="space-y-2">
<div class="flex items-center">
<p class="w-100px text-left">编号前缀</p>
<div class="flex-1">
<NInput v-model:value="ruleInfo.prefix" placeholder="请输入编号前缀" />
</div>
</div>
<div class="flex items-center">
<p class="w-100px text-left">年份格式</p>
<div class="flex-1">
<NSelect v-model:value="ruleInfo.year" :options="yearOptions" placeholder="请选择年份格式" />
</div>
</div>
<div class="flex items-center">
<p class="w-100px text-left">装置代码段</p>
<div class="flex-1">
<NSelect v-model:value="ruleInfo.code" :options="codeOptions" placeholder="请选择装置代码段" />
</div>
</div>
<div class="flex items-center">
<p class="w-100px text-left">流水号位数</p>
<div class="flex-1">
<NInputNumber v-model:value="ruleInfo.digit" :min="1" :show-button="false" :precision="0" placeholder="请输入流水号位数" />
</div>
</div>
<div class="flex items-center">
<p class="w-100px text-left">流水重置规则</p>
<div class="flex-1">
<NSelect v-model:value="ruleInfo.rule" :options="ruleOptions" placeholder="请选择流水重置规则" />
</div>
</div>
<div class="flex items-center p-3 bg-[#f8fafc] rounded-md">
<span>编号示例预览</span>
<span class="text-[var(--theme-color)]">MOC-2026-R01-0001</span>
<NButton size="small" type="primary" class="text-xs ml-auto">保存规则</NButton>
</div>
</div>
<p class="mt-3 text-xs text-slate-400">保存草稿即预占编号提交后正式生效;规则修改不影响历史单据编号</p>
</div>
</NCard>
</NGi>
</NGrid>
<!-- 风险矩阵设置按分析方法 -->
<NGrid :x-gap="gap" :y-gap="16" responsive="screen" item-responsive>
<NGi span="24 s:24 m:24 l:24">
<NCard :bordered="true" size="small" :content-style="{padding: 0}"
:style="{
borderRadius: themeStore.themeRadius + 'px',
height: '100%',
'--theme-color': themeStore.themeColor,
'--warning-color': themeStore.otherColor.warning,
'--error-color': themeStore.otherColor.error,
}"
>
<div class="flex items-center justify-between text-base font-semibold border-b border-slate-100 p-3">
<div class="flex items-center">
<Icon icon="icon-park-outline:all-application" class="size-16px mr-1" />
风险矩阵设置按分析方法
</div>
<NButton size="small" class="text-xs">
<Icon icon="akar-icons:edit" class="size-14px mr-1" />
维度分级定义
</NButton>
<NButton size="small" type="primary" class="text-xs">
保存矩阵
</NButton>
</div>
<div class="py-3 px-4">
<NTabs type="segment" animated>
<NTabPane name="chap1" tab="HAZOP分析矩阵">
</NTabPane>
<NTabPane name="chap2" tab="JSA分析矩阵">
</NTabPane>
<NTabPane name="chap3" tab="SCL分析矩阵">
</NTabPane>
</NTabs>
</div>
</NCard>
</NGi>
</NGrid>
</NSpace>
</template>
<style scoped></style>