提交 1aed5868 作者: zhongye-dev

feat: 角色与用户管理对齐新角色体系

- 角色列表按7类角色重排,更新数据权限与角色描述
- 菜单权限树与左侧导航保持一致
- 用户管理用户类型/角色下拉同步为7项,修正角色名称
上级 a5110a84
...@@ -129,6 +129,9 @@ ...@@ -129,6 +129,9 @@
<el-option label="全部数据" value="全部数据" /> <el-option label="全部数据" value="全部数据" />
<el-option label="本部门数据" value="本部门数据" /> <el-option label="本部门数据" value="本部门数据" />
<el-option label="本部门及下级" value="本部门及下级" /> <el-option label="本部门及下级" value="本部门及下级" />
<el-option label="管辖区业务数据" value="管辖区业务数据" />
<el-option label="全国各隔离中心业务数据" value="全国各隔离中心业务数据" />
<el-option label="本省全域业务数据" value="本省全域业务数据" />
<el-option label="仅本人数据" value="仅本人数据" /> <el-option label="仅本人数据" value="仅本人数据" />
<el-option label="自定义" value="自定义" /> <el-option label="自定义" value="自定义" />
</el-select> </el-select>
...@@ -193,14 +196,16 @@ ...@@ -193,14 +196,16 @@
import { ref, computed, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
const STORAGE_KEY = "settings_roles"; const STORAGE_KEY = "settings_roles_v3";
const defaultRoles = [ const defaultRoles = [
{ id: 1, name: "植保站管理人员", code: "ROLE_ZBZ_ADMIN", dataScope: "全部数据", desc: "负责甘肃省植保植检站业务管理与流程审批", userCount: 1, createTime: "2026-01-01 09:00:00", status: "启用", perms: ["home", "entrust", "sample", "lab", "field", "disposal", "isolation", "analysis", "report", "settings"] }, { id: 1, name: "检疫员", code: "ROLE_QUARANTINE", dataScope: "本部门及下级", desc: "委托受理、样本收发登记、试种观测、检疫处置实施、放行证书申请、报告查阅;统计驾驶舱只读查看", userCount: 2, createTime: "2026-02-15 14:20:00", status: "启用", perms: ["home", "entrust", "sample", "isolation", "disposal", "release-cert", "report", "stats"] },
{ id: 2, name: "隔离中心管理人员", code: "ROLE_GZ_ADMIN", dataScope: "本部门数据", desc: "负责甘州区农业技术推广中心日常业务管理", userCount: 1, createTime: "2026-01-02 10:00:00", status: "启用", perms: ["home", "sample", "field", "isolation", "report"] }, { id: 2, name: "实验员", code: "ROLE_LAB", dataScope: "本部门数据", desc: "样本领用归还、实验室初检与检验、录入检测结果、提交检测鉴定报告;业务统计大屏只读", userCount: 2, createTime: "2026-03-08 16:45:00", status: "启用", perms: ["home", "sample", "lab", "report", "stats"] },
{ id: 3, name: "检疫员", code: "ROLE_QUARANTINE", dataScope: "本部门及下级", desc: "负责样品抽检、田间调查与除害处理等检疫操作", userCount: 2, createTime: "2026-02-15 14:20:00", status: "启用", perms: ["home", "sample", "field", "disposal"] }, { id: 3, name: "区域隔离中心管理员", code: "ROLE_GZ_ADMIN", dataScope: "管辖区业务数据", desc: "本中心全业务办理(委托书、样本、检测、试种、检疫处理、监测、证书报告),维护本中心人员信息,查看本中心统计与研判大屏;不可修改全局系统参数", userCount: 1, createTime: "2026-01-02 10:00:00", status: "启用", perms: ["home", "entrust", "sample", "lab", "isolation", "disposal", "isolation-monitor", "release-cert", "report", "base", "stats"] },
{ id: 4, name: "实验员", code: "ROLE_LAB", dataScope: "本部门数据", desc: "负责实验室检测、检测记录与数据上报", userCount: 2, createTime: "2026-03-08 16:45:00", status: "启用", perms: ["home", "lab"] }, { id: 4, name: "国家隔离中心管理员", code: "ROLE_GJ_ADMIN", dataScope: "全国各隔离中心业务数据", desc: "全国隔离业务统筹管理,查看全域业务数据、风险研判大屏,维护全国隔离中心人员;无系统底层配置权限", userCount: 0, createTime: "2026-01-03 09:00:00", status: "启用", perms: ["home", "entrust", "sample", "lab", "isolation", "disposal", "isolation-monitor", "release-cert", "report", "base", "stats"] },
{ id: 5, name: "系统管理员", code: "ROLE_SYS_ADMIN", dataScope: "全部数据", desc: "负责平台运维、用户与角色管理、数据字典维护及系统配置", userCount: 1, createTime: "2026-01-01 08:30:00", status: "启用", perms: ["home", "settings", "settings-users", "settings-roles", "settings-dict", "settings-log", "entrust", "sample", "lab", "field", "disposal", "isolation", "analysis", "report"] } { id: 5, name: "省级植物检疫机构(省植保植检站)", code: "ROLE_ZBZ_ADMIN", dataScope: "本省全域业务数据", desc: "全省检疫业务统筹管理,承担两级审批省级审批、检疫单证审批盖章;委托书归属本省主管单位,支持全省业务数据复核、补录、向上上报;维护本省省级补充检疫性有害生物名单,可访问全省范围全业务模块,为本省检疫业务责任主体", userCount: 1, createTime: "2026-01-01 09:00:00", status: "启用", perms: ["home", "entrust", "sample", "lab", "isolation", "disposal", "isolation-monitor", "stats", "release-cert", "report", "base"] },
{ id: 6, name: "上级监管(风险分析处)", code: "ROLE_RISK_ANALYSIS", dataScope: "全部数据", desc: "全量业务统计、风险分析、专题研判大屏、各类报告查阅;仅只读查询,不可编辑业务单据", userCount: 0, createTime: "2026-03-20 09:00:00", status: "启用", perms: ["home", "stats", "report"] },
{ id: 7, name: "系统管理员", code: "ROLE_SYS_ADMIN", dataScope: "全部数据", desc: "全模块访问,账号角色管理、数据字典维护、操作日志审计、系统参数配置;不参与检疫业务单据办理", userCount: 1, createTime: "2026-01-01 08:30:00", status: "启用", perms: ["home", "entrust", "sample", "lab", "isolation", "disposal", "isolation-monitor", "stats", "release-cert", "report", "base", "settings", "settings-users", "settings-roles", "settings-dict", "settings-log"] }
]; ];
const menuTree = [ const menuTree = [
...@@ -210,12 +215,7 @@ const menuTree = [ ...@@ -210,12 +215,7 @@ const menuTree = [
}, },
{ {
id: "entrust", name: "委托书管理", id: "entrust", name: "委托书管理",
children: [ children: []
{ id: "entrust-reg", name: "委托书登记" },
{ id: "entrust-list", name: "委托书管理" },
{ id: "entrust-audit", name: "委托书审核" },
{ id: "entrust-archive", name: "委托书归档" }
]
}, },
{ {
id: "sample", name: "样本管理", id: "sample", name: "样本管理",
...@@ -227,24 +227,20 @@ const menuTree = [ ...@@ -227,24 +227,20 @@ const menuTree = [
{ {
id: "lab", name: "实验室检测", id: "lab", name: "实验室检测",
children: [ children: [
{ id: "lab-sample-test", name: "样本抽检" }, { id: "lab-sample-test", name: "样本初检" },
{ id: "lab-experiment-test", name: "实验检验" } { id: "lab-experiment-test", name: "实验检验" }
] ]
}, },
{ {
id: "field", name: "田间调查", id: "isolation", name: "试种观察",
children: [ children: []
{ id: "field-survey", name: "田间调查" }
]
}, },
{ {
id: "disposal", name: "除害处理", id: "disposal", name: "检疫处理",
children: [ children: []
{ id: "disposal-list", name: "除害处理" }
]
}, },
{ {
id: "isolation", name: "隔离监测", id: "isolation-monitor", name: "隔离监测",
children: [ children: [
{ id: "isolation-device", name: "设备总览" }, { id: "isolation-device", name: "设备总览" },
{ id: "isolation-data", name: "监测数据" } { id: "isolation-data", name: "监测数据" }
...@@ -252,6 +248,14 @@ const menuTree = [ ...@@ -252,6 +248,14 @@ const menuTree = [
}, },
{ {
id: "stats", name: "统计分析", id: "stats", name: "统计分析",
children: [
{ id: "stats-business", name: "业务统计" },
{ id: "stats-analysis", name: "风险分析" },
{ id: "stats-dashboard", name: "驾驶舱" }
]
},
{
id: "release-cert", name: "放行证书管理",
children: [] children: []
}, },
{ {
...@@ -259,6 +263,13 @@ const menuTree = [ ...@@ -259,6 +263,13 @@ const menuTree = [
children: [] children: []
}, },
{ {
id: "base", name: "基础信息管理",
children: [
{ id: "base-quarantine", name: "检疫员管理" },
{ id: "base-experimenter", name: "实验员管理" }
]
},
{
id: "settings", name: "系统设置", id: "settings", name: "系统设置",
children: [ children: [
{ id: "settings-users", name: "用户管理" }, { id: "settings-users", name: "用户管理" },
...@@ -272,7 +283,19 @@ const menuTree = [ ...@@ -272,7 +283,19 @@ const menuTree = [
const loadRoles = () => { const loadRoles = () => {
try { try {
const raw = localStorage.getItem(STORAGE_KEY); const raw = localStorage.getItem(STORAGE_KEY);
if (raw) return JSON.parse(raw); if (raw) {
const cached = JSON.parse(raw);
const defaults = JSON.parse(JSON.stringify(defaultRoles));
// 同步默认角色的名称/编码/描述/数据权限,并补全新增角色(保留各角色已自定义的菜单权限)
const merged = cached.map((c) => {
const d = defaults.find((x) => x.id === c.id);
return d ? { ...c, name: d.name, code: d.code, desc: d.desc, dataScope: d.dataScope } : c;
});
defaults.forEach((d) => {
if (!merged.some((c) => c.id === d.id)) merged.push(d);
});
return merged;
}
} catch (e) { /* ignore */ } } catch (e) { /* ignore */ }
return JSON.parse(JSON.stringify(defaultRoles)); return JSON.parse(JSON.stringify(defaultRoles));
}; };
......
...@@ -13,10 +13,13 @@ ...@@ -13,10 +13,13 @@
<div class="filter-item"> <div class="filter-item">
<span class="filter-label">用户类型</span> <span class="filter-label">用户类型</span>
<el-select v-model="filterForm.userType" placeholder="请选择用户类型" clearable size="default"> <el-select v-model="filterForm.userType" placeholder="请选择用户类型" clearable size="default">
<el-option label="甘肃省植保植检站用户" value="甘肃省植保植检站用户" />
<el-option label="甘州区农业技术推广中心用户" value="甘州区农业技术推广中心用户" />
<el-option label="检疫员" value="检疫员" /> <el-option label="检疫员" value="检疫员" />
<el-option label="实验检验员" value="实验检验员" /> <el-option label="实验员" value="实验员" />
<el-option label="区域隔离中心管理员" value="区域隔离中心管理员" />
<el-option label="国家隔离中心管理员" value="国家隔离中心管理员" />
<el-option label="省级植物检疫机构(省植保植检站)" value="省级植物检疫机构(省植保植检站)" />
<el-option label="上级监管(风险分析处)" value="上级监管(风险分析处)" />
<el-option label="系统管理员" value="系统管理员" />
</el-select> </el-select>
</div> </div>
</div> </div>
...@@ -24,10 +27,13 @@ ...@@ -24,10 +27,13 @@
<div class="filter-item"> <div class="filter-item">
<span class="filter-label">角色名称</span> <span class="filter-label">角色名称</span>
<el-select v-model="filterForm.roleName" placeholder="请选择角色" clearable size="default"> <el-select v-model="filterForm.roleName" placeholder="请选择角色" clearable size="default">
<el-option label="植保站管理人员" value="植保站管理人员" />
<el-option label="隔离中心管理人员" value="隔离中心管理人员" />
<el-option label="检疫员" value="检疫员" /> <el-option label="检疫员" value="检疫员" />
<el-option label="实验员" value="实验员" /> <el-option label="实验员" value="实验员" />
<el-option label="区域隔离中心管理员" value="区域隔离中心管理员" />
<el-option label="国家隔离中心管理员" value="国家隔离中心管理员" />
<el-option label="省级植物检疫机构(省植保植检站)" value="省级植物检疫机构(省植保植检站)" />
<el-option label="上级监管(风险分析处)" value="上级监管(风险分析处)" />
<el-option label="系统管理员" value="系统管理员" />
</el-select> </el-select>
</div> </div>
<div class="filter-actions-left"> <div class="filter-actions-left">
...@@ -146,19 +152,25 @@ ...@@ -146,19 +152,25 @@
<div class="form-item"> <div class="form-item">
<label class="form-label required">用户类型</label> <label class="form-label required">用户类型</label>
<el-select v-model="form.userType" :disabled="mode === 'view'" placeholder="请选择用户类型" style="width:100%"> <el-select v-model="form.userType" :disabled="mode === 'view'" placeholder="请选择用户类型" style="width:100%">
<el-option label="甘肃省植保植检站用户" value="甘肃省植保植检站用户" />
<el-option label="甘州区农业技术推广中心用户" value="甘州区农业技术推广中心用户" />
<el-option label="检疫员" value="检疫员" /> <el-option label="检疫员" value="检疫员" />
<el-option label="实验检验员" value="实验检验员" /> <el-option label="实验员" value="实验员" />
<el-option label="区域隔离中心管理员" value="区域隔离中心管理员" />
<el-option label="国家隔离中心管理员" value="国家隔离中心管理员" />
<el-option label="省级植物检疫机构(省植保植检站)" value="省级植物检疫机构(省植保植检站)" />
<el-option label="上级监管(风险分析处)" value="上级监管(风险分析处)" />
<el-option label="系统管理员" value="系统管理员" />
</el-select> </el-select>
</div> </div>
<div class="form-item"> <div class="form-item">
<label class="form-label required">角色名称</label> <label class="form-label required">角色名称</label>
<el-select v-model="form.roleName" :disabled="mode === 'view'" placeholder="请选择角色" style="width:100%"> <el-select v-model="form.roleName" :disabled="mode === 'view'" placeholder="请选择角色" style="width:100%">
<el-option label="植保站管理人员" value="植保站管理人员" />
<el-option label="隔离中心管理人员" value="隔离中心管理人员" />
<el-option label="检疫员" value="检疫员" /> <el-option label="检疫员" value="检疫员" />
<el-option label="实验员" value="实验员" /> <el-option label="实验员" value="实验员" />
<el-option label="区域隔离中心管理员" value="区域隔离中心管理员" />
<el-option label="国家隔离中心管理员" value="国家隔离中心管理员" />
<el-option label="省级植物检疫机构(省植保植检站)" value="省级植物检疫机构(省植保植检站)" />
<el-option label="上级监管(风险分析处)" value="上级监管(风险分析处)" />
<el-option label="系统管理员" value="系统管理员" />
</el-select> </el-select>
</div> </div>
<div class="form-item"> <div class="form-item">
...@@ -200,8 +212,8 @@ import { ElMessage, ElMessageBox } from "element-plus"; ...@@ -200,8 +212,8 @@ import { ElMessage, ElMessageBox } from "element-plus";
const STORAGE_KEY = "settings_users"; const STORAGE_KEY = "settings_users";
const defaultUsers = [ const defaultUsers = [
{ id: 1, account: "gs_admin", name: "张文博", userType: "甘肃省植保植检站用户", roleName: "植保站管理人员", phone: "13919000001", email: "zhangwb@gszbzjz.cn", locked: false, status: "启用", creator: "系统初始化", createTime: "2026-01-01 09:00:00" }, { id: 1, account: "gs_admin", name: "张文博", userType: "甘肃省植保植检站用户", roleName: "省级植物检疫机构", phone: "13919000001", email: "zhangwb@gszbzjz.cn", locked: false, status: "启用", creator: "系统初始化", createTime: "2026-01-01 09:00:00" },
{ id: 2, account: "gz_admin", name: "王俊凯", userType: "甘州区农业技术推广中心用户", roleName: "隔离中心管理人员", phone: "13919000002", email: "wangk@gznyzx.cn", locked: false, status: "启用", creator: "系统初始化", createTime: "2026-01-02 10:00:00" }, { id: 2, account: "gz_admin", name: "王俊凯", userType: "甘州区农业技术推广中心用户", roleName: "区域隔离中心管理员", phone: "13919000002", email: "wangk@gznyzx.cn", locked: false, status: "启用", creator: "系统初始化", createTime: "2026-01-02 10:00:00" },
{ id: 3, account: "quar_001", name: "李建华", userType: "检疫员", roleName: "检疫员", phone: "13919000003", email: "lijh@gszbzjz.cn", locked: false, status: "启用", creator: "张文博", createTime: "2026-02-15 14:20:00" }, { id: 3, account: "quar_001", name: "李建华", userType: "检疫员", roleName: "检疫员", phone: "13919000003", email: "lijh@gszbzjz.cn", locked: false, status: "启用", creator: "张文博", createTime: "2026-02-15 14:20:00" },
{ id: 4, account: "quar_002", name: "赵晓萌", userType: "检疫员", roleName: "检疫员", phone: "13919000004", email: "zhaoxm@gszbzjz.cn", locked: true, status: "禁用", creator: "张文博", createTime: "2026-02-20 11:30:00" }, { id: 4, account: "quar_002", name: "赵晓萌", userType: "检疫员", roleName: "检疫员", phone: "13919000004", email: "zhaoxm@gszbzjz.cn", locked: true, status: "禁用", creator: "张文博", createTime: "2026-02-20 11:30:00" },
{ id: 5, account: "lab_001", name: "孙亚萍", userType: "实验检验员", roleName: "实验员", phone: "13919000005", email: "sunyp@gszbzjz.cn", locked: false, status: "启用", creator: "王俊凯", createTime: "2026-03-08 16:45:00" }, { id: 5, account: "lab_001", name: "孙亚萍", userType: "实验检验员", roleName: "实验员", phone: "13919000005", email: "sunyp@gszbzjz.cn", locked: false, status: "启用", creator: "王俊凯", createTime: "2026-03-08 16:45:00" },
...@@ -211,7 +223,19 @@ const defaultUsers = [ ...@@ -211,7 +223,19 @@ const defaultUsers = [
const loadUsers = () => { const loadUsers = () => {
try { try {
const raw = localStorage.getItem(STORAGE_KEY); const raw = localStorage.getItem(STORAGE_KEY);
if (raw) return JSON.parse(raw); if (raw) {
const cached = JSON.parse(raw);
const defaults = JSON.parse(JSON.stringify(defaultUsers));
// 同步默认用户的角色名称,并补全新增用户(保留其他字段的已有改动)
const merged = cached.map((c) => {
const d = defaults.find((x) => x.id === c.id);
return d ? { ...c, roleName: d.roleName } : c;
});
defaults.forEach((d) => {
if (!merged.some((c) => c.id === d.id)) merged.push(d);
});
return merged;
}
} catch (e) { /* ignore */ } } catch (e) { /* ignore */ }
return JSON.parse(JSON.stringify(defaultUsers)); return JSON.parse(JSON.stringify(defaultUsers));
}; };
......
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论