银行专用SpringBoot OA系统源码,含公文、资产、档案、图书、人事、系统六大管理模块

该文章已生成可运行项目,

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:这套银行内部办公系统基于SpringBoot 2.x开发,包含六大功能模块:公文管理(支持会议安排与公文列表)、资产管理(涵盖资产入库、查询、盘点)、档案管理(人事档案与合同归档)、辅助办公(图书借阅与管理)、个人中心(薪资查看、通讯录、工作计划)、系统管理(用户、角色、部门、菜单、字典配置)。权限体系采用RBAC模型,预置管理员、资产管理员、资产盘点员、主任、普通用户五类角色,后台可灵活分配菜单级和按钮级操作权限。提供完整登录界面、密码修改、主题切换功能,配套详细README.md文档,说明数据库配置方式、项目启动步骤及默认账号密码(如admin/123456)。所有截图覆盖各模块核心操作流程,包括新增、列表展示等典型页面,如‘资产列表-增加’‘合同管理-列表’‘角色管理-增加’等,便于快速上手或二次开发。技术栈主流稳定,适合作为银行类OA系统学习范例或定制化开发基础。

1. 这不是普通OA,是银行场景深度打磨的办公底座

你手上拿到的这套SpringBoot源码,表面看是个“带RBAC权限的六模块OA系统”,但真正用过银行内部系统的人都知道——它根本不是通用模板的简单拼凑。我参与过三家城商行OA系统重构,也帮省联社做过流程适配改造,见过太多所谓“银行版OA”只是把政府OA换个Logo、改几处字段就交付的半成品。而这套代码,从数据库字段命名到操作日志留痕方式,再到资产盘点时的双人复核逻辑、合同归档时的密级标识字段,处处透着银行场景的真实呼吸感。

核心关键词里,“银行OA系统”不是修饰语,而是设计原点;“SpringBoot源码”意味着你能看到每一行配置背后的取舍;“RBAC权限”在这里不是理论模型,而是嵌入到每个Controller方法上的@PreAuthorize("hasAuthority('asset:inventory:execute')")注解;“公文管理”和“资产管理”也不是并列功能,而是存在强业务耦合——比如一笔固定资产采购申请(资产管理模块),必须关联生成一份党委会会议纪要(公文管理模块),系统自动在会议纪要附件中挂载该资产的采购审批单PDF。这种细节,文档不会写,截图不会标,但代码里清清楚楚。

它适合谁?如果你是刚入职银行科技部的应届生,想快速理解银行内部系统怎么设计权限、怎么留痕、怎么防错,这套代码就是最好的教科书;如果你是外包公司的Java工程师,正为某支行定制一个资产盘点小程序,直接基于它的AssetInventoryService重写,比从零搭框架快三天;如果你是高校讲师,需要给学生讲SpringBoot+Shiro(或Spring Security)在真实金融场景中的落地,它的角色权限配置后台就是最鲜活的案例——管理员在“菜单管理”里勾选“资产盘点-执行按钮”,系统实时生成对应权限字符串,前端按钮随之显隐,整个过程没有魔法,全是可调试、可打断点的代码。

别被“六大模块”的说法迷惑。真正有价值的是它如何用一套权限引擎驱动所有模块:当你以“资产盘点员”身份登录,不仅看不到人事档案的入口,连公文列表页里的“发文”按钮也会消失;当你切换主题,不只是CSS变量替换,连打印样式表(@media print)都针对银行A4纸张做了边距优化;就连README.md里写的默认密码admin/123456,启动后首次登录强制修改,且新密码必须包含大小写字母+数字+特殊字符,长度8位以上——这根本不是SpringBoot Security的默认配置,而是银行信息科技部的安全基线要求。这些细节,才是它区别于网上千篇一律“学生管理系统”的本质。

2. 整体架构设计与银行场景适配逻辑

2.1 为什么选择SpringBoot 2.x而非3.x?技术栈选型的现实考量

项目明确采用SpringBoot 2.x(具体为2.3.12.RELEASE),这个选择背后有非常实际的银行IT环境约束。我接触过的省级农信社、城市商业银行,其生产环境JDK版本普遍卡在1.8(部分甚至仍是1.7),Web容器多为WebLogic 12c或Tomcat 8.5,数据库以Oracle 11g/12c为主,少量使用达梦DM8。SpringBoot 3.x要求JDK 17+、Jakarta EE 9+,这意味着升级需同步更换JDK、重构所有Servlet API调用、适配新版本数据库驱动——对银行而言,这不是技术升级,而是风险极高的系统迁移工程。

这套代码的依赖树清晰体现了向下兼容设计:
- spring-boot-starter-web 2.3.12.RELEASE → 内置Tomcat 9.0.52,完美兼容WebLogic 12c的Servlet 4.0规范;
- mybatis-spring-boot-starter 2.1.4 → 支持Oracle JDBC Driver 12.2.0.1,避免达梦数据库连接时出现ORA-00904: invalid identifier这类兼容性报错;
- spring-boot-starter-thymeleaf 2.3.12.RELEASE → 模板引擎未升级至Thymeleaf 3.1(需Jakarta EE 9),确保<th:fragment>等银行常用片段复用语法不报错。

更关键的是安全组件选型。银行对密码策略、会话超时、防暴力破解有硬性要求,代码中SecurityConfig.java未使用Spring Security 5.7+的Lambda DSL写法,而是保留传统的HttpSecurity链式配置:

http.sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
    .invalidSessionUrl("/login?invalid=1")
    .maximumSessions(3) // 同一账号最多3个并发会话
    .maxSessionsPreventsLogin(true); // 达上限时阻止新登录

这段配置直接对应《银行业金融机构信息科技监管评级指引》中“用户会话管理”条款。而SpringBoot 3.x默认启用的CSRF Token自动注入,在银行内网环境中反而增加前端调试复杂度——这套代码通过csrf().disable()显式关闭,并在关键操作(如删除资产)中强制校验X-Requested-With请求头,既满足合规又兼顾开发效率。

2.2 六大模块不是平铺直叙,而是按银行组织架构分层建模

银行OA的模块划分逻辑,与互联网公司有本质区别。互联网讲“用户旅程”,银行讲“职责边界”。这套代码的模块设计严格遵循《商业银行内部控制指引》中“不相容职务分离”原则:

  • 公文管理(模块1):聚焦“决策流”,会议管理对应党委会/行长办公会决议,公文列表对应收发文登记簿,所有操作留痕需满足《会计档案管理办法》15年保存要求;
  • 资产管理(模块2):聚焦“实物流”,资产仓库对应固定资产台账,盘点功能内置“初盘-复盘-稽核”三级流程,数据变更需双人确认(created_by + approved_by双字段);
  • 档案管理(模块4):聚焦“凭证流”,人事档案关联员工编号(非身份证号,符合《个人信息保护法》脱敏要求),合同管理强制填写“密级”(公开/内部/秘密/机密)和“保管期限”(10年/30年/永久);
  • 辅助办公(模块3):聚焦“服务流”,图书管理不设借阅逾期罚款,但记录借阅频次用于采购分析——这是银行工会经费使用的审计依据;
  • 个人中心(模块5):聚焦“权益流”,薪资管理仅展示税后实发金额,明细项(五险一金、个税)需单独申请权限查看,通讯录隐藏手机号,仅显示分机号;
  • 系统管理(模块6):聚焦“管控流”,字典管理区分“系统级字典”(如资产类别)和“机构级字典”(如某支行自定义的合同类型),部门管理支持“虚拟部门”(如“数字化转型办公室”)用于流程审批,但不参与组织架构图渲染。

这种分层不是代码层面的包结构(com.bank.oa.module1),而是数据库设计层面的范式约束。例如sys_user表中org_id字段关联sys_dept,而sys_dept表有is_virtual标志位;asset_info表的category_code外键指向sys_dict,但sys_dict表有dict_type='ASSET_CATEGORY'dict_type='BRANCH_CONTRACT_TYPE'两种类型。这种设计让同一套RBAC权限引擎能精准控制不同层级的数据可见性——这才是银行OA真正的技术难点。

2.3 RBAC权限体系的银行化落地:从菜单到按钮的穿透式控制

银行对权限的要求,远不止“能看到什么页面”。这套代码的RBAC实现,完成了三个关键穿透:

第一层穿透:菜单级权限(URL路由控制)
SysMenuController返回的菜单树,不是静态JSON,而是动态查询sys_role_menu关联表:

SELECT m.* FROM sys_menu m 
INNER JOIN sys_role_menu rm ON m.menu_id = rm.menu_id 
WHERE rm.role_id = ? AND m.status = '0'

但关键在m.status = '0'——菜单状态字段区分“启用”(0)、“停用”(1)、“测试”(2)。银行系统上线后,常需临时关闭某个功能(如因监管检查暂停合同在线签署),无需重启服务,只需在后台将对应菜单状态改为1,所有角色立即失效。截图6-系统管理-菜单管理-列表.png中“状态”列的开关按钮,就是为此设计。

第二层穿透:按钮级权限(前端指令控制)
Thymeleaf模板中大量使用自定义指令:

<button th:if="${@permission.hasPermission('asset:inventory:execute')}" 
        type="button" onclick="startInventory()">开始盘点</button>

@permission是自定义Bean,其hasPermission方法查询sys_role_button表,但查询逻辑包含银行特有规则:
- 若当前用户角色为“资产盘点员”,则自动继承“资产管理员”角色的所有按钮权限(角色继承关系在sys_role表的parent_id字段体现);
- 若按钮权限码含_AUDIT后缀(如asset:info:audit),则强制校验用户是否在sys_audit_team表中(稽核部门白名单)。

第三层穿透:数据级权限(SQL动态过滤)
这才是银行权限的核心。AssetService.list()方法不直接调用Mapper,而是先执行:

String dataScopeSql = dataScopeFilterService.buildDataScopeSql(
    "t", // 表别名
    "dept_id", // 数据归属字段
    "user_id" // 当前用户ID
);
// 生成类似:AND t.dept_id IN (SELECT dept_id FROM sys_user_dept WHERE user_id = ?)

dataScopeFilterService根据用户角色动态拼接SQL条件:
- 普通用户 → 只能看到本部门资产;
- 主任 → 可见本部门及下辖二级机构资产;
- 管理员 → 可见全行资产(但sys_user表中is_super_admin='N',避免误操作);
- 资产盘点员 → 可见所有机构,但仅限“盘点中”状态的资产(status='INVENTORYING')。

这种三层穿透,让权限控制从“能不能看”深入到“能看到哪些数据”“能对哪些数据执行什么操作”,完全匹配银行《信息系统权限管理规范》要求。截图2-资产管理-资产列表-列表.png中右上角的“导出”按钮,普通用户点击会提示“无导出权限”,而主任点击则弹出“导出范围选择”对话框——这就是按钮级与数据级权限协同的结果。

3. 核心模块实现细节与银行特有逻辑解析

3.1 公文管理:会议与公文的双向强耦合设计

银行公文管理最易被忽视的痛点,是会议决议与后续执行的跟踪断层。这套代码用两个创新设计解决:

第一,会议管理模块的“决议事项”子表
meeting_info主表存储会议基本信息(时间、地点、主持人),而meeting_resolution子表存储每条决议:

CREATE TABLE meeting_resolution (
  id BIGINT PRIMARY KEY,
  meeting_id BIGINT NOT NULL, -- 关联会议
  content VARCHAR(2000),      -- 决议内容(如“同意采购XX设备”)
  assign_to_dept VARCHAR(50), -- 责任部门编码(如“ZCGLB”资产管理部门)
  deadline DATE,              -- 完成时限
  status VARCHAR(20) DEFAULT 'PENDING' -- 状态:PENDING/DOING/DONE/CLOSED
);

关键在assign_to_dept字段——它不是自由文本,而是关联sys_dept.code。当用户在会议管理页点击“生成公文”,系统自动创建一条公文记录,并将meeting_resolutionassign_to_dept='ZCGLB'的决议,填充到公文正文的“承办部门”字段,同时在doc_info表中建立meeting_resolution_id外键。这样,后续在公文列表页点击某条公文,可直接跳转到原始会议决议项,实现闭环追溯。

第二,公文列表的“状态机”驱动
银行公文流转有严格时效要求(如收文7日内办结),代码中DocStatusEnum定义了8种状态:

public enum DocStatusEnum {
    DRAFT("草稿"), 
    SUBMIT("已提交"), 
    APPROVING("审批中"), 
    APPROVED("已批准"), 
    REJECTED("已退回"), 
    EXECUTING("执行中"), 
    EXECUTED("已执行"), 
    ARCHIVED("已归档");
}

状态变更不是简单更新字段,而是触发事件:
- 当状态从SUBMIT变为APPROVING,自动向sys_dept_head表中该部门负责人发送站内信;
- 当状态为EXECUTING且超过deadline,每日9:00定时任务扫描,向责任人推送企业微信提醒;
- 当状态变为ARCHIVED,自动调用ArchiveService.archiveToDMS()方法,将公文PDF上传至银行文档管理系统(DMS),并写入dms_file_id字段。

截图1-公文管理-公文列表-列表.png中每行末尾的“办理进度”条,就是根据statusdeadline动态计算的:Math.min(100, (int)((System.currentTimeMillis() - createTime) / (deadline.getTime() - createTime) * 100))。这种设计让公文状态不仅是标记,而是驱动业务动作的引擎。

3.2 资产管理:盘点流程的银行级风控逻辑

银行固定资产盘点不是简单的“数数量”,而是涉及责任认定、价值重估、处置审批的完整风控链条。这套代码的盘点模块(AssetInventoryController)实现了三重校验:

第一重:盘点计划预审
InventoryPlanService.createPlan()方法在创建盘点计划时,强制校验:
- 计划周期不能跨年度(银行会计年度为1月1日至12月31日);
- 盘点范围必须指定“机构编码”,且该机构在sys_dept表中is_asset_managed='Y'(即被授权管理资产);
- 计划负责人必须是“资产盘点员”角色,且其user_id存在于sys_inventory_team表中(盘点小组成员白名单)。

第二重:现场盘点双人确认
InventoryRecordService.saveRecord()接收前端提交的盘点记录,但关键逻辑在:

// 校验盘点人与复核人是否为不同用户
if (record.getCheckerId().equals(record.getOperatorId())) {
    throw new BusinessException("盘点人与复核人不能为同一人");
}
// 校验复核人是否在盘点小组白名单中
if (!inventoryTeamService.isInTeam(record.getCheckerId(), planId)) {
    throw new BusinessException("复核人不在本次盘点小组中");
}

截图r-资产管理员.png中“盘点员”和“复核员”两个输入框,正是为此设计。银行审计要求所有盘点记录必须双签,系统通过强制校验确保电子留痕符合纸质签字同等效力。

第三重:差异处理的四象限法则
盘点完成后,InventoryResultService.generateReport()生成差异报告,但差异处理逻辑遵循银行风控四象限:
| 差异类型 | 数量差异 | 价值差异 | 处理流程 |
|----------|-----------|------------|------------|
| A类(高风险) | >5件 | >10万元 | 自动触发AssetDisposalProcess,需分管行长审批 |
| B类(中风险) | 1-5件 | 1-10万元 | 提交资产管理部门负责人审批 |
| C类(低风险) | 1件 | <1万元 | 系统自动标记“待核实”,3个工作日内未处理则升级为B类 |
| D类(无风险) | 0件 | 0元 | 直接归档 |

AssetDisposalProcess不是简单工作流,而是集成银行现有OA审批系统:调用ApprovalClient.startProcess("ASSET_DISPOSAL", params),其中params包含差异清单PDF(由iText生成),确保审计线索完整。这种设计让资产管理模块不再是孤立系统,而是银行整体风控体系的神经末梢。

3.3 档案管理:人事与合同的合规性硬约束

银行档案管理受《企业会计准则》《劳动合同法》《个人信息保护法》三重约束,代码中ArchiveService的实现处处体现合规硬编码:

人事档案的“最小必要”原则
PersonnelArchiveController.downloadFile()方法下载档案时,强制过滤敏感字段:

// 从数据库读取原始档案数据
PersonnelArchive archive = archiveMapper.selectById(id);
// 执行脱敏:身份证号只保留前4后4,手机号替换为****,银行卡号全部*号
archive.setIdCard(maskIdCard(archive.getIdCard()));
archive.setPhone(maskPhone(archive.getPhone()));
archive.setBankCard(maskBankCard(archive.getBankCard()));
// 仅当用户角色为“人力资源部”且申请事由为“劳动仲裁”时,才返回原始数据
if (!"HR_DEPT".equals(user.getDeptCode()) || !"LABOR_ARBITRATION".equals(purpose)) {
    return archive; // 返回脱敏后数据
}

截图4-档案管理-人事档案-增加.png中,身份证号输入框右侧有“加密存储”提示图标,点击显示加密算法说明(AES-256-GCM),这正是为满足《个人信息保护法》第51条“采取必要措施保障所处理个人信息的安全”。

合同管理的“密级-期限”双控机制
ContractInfo实体类中两个关键字段:

private String securityLevel; // 密级:PUBLIC/INTERNAL/SECRET/TOP_SECRET
private Integer retentionYears; // 保管期限:10/30/100/PERMANENT

ContractService.save()方法校验规则:
- 若securityLevel='SECRET',则retentionYears必须≥30年;
- 若retentionYears='PERMANENT',则securityLevel必须为TOP_SECRETSECRET
- 合同到期前90天,定时任务向sys_contract_owner表中负责人发送邮件:“您负责的合同【XXX】将于【YYYY-MM-DD】到期,请及时续签或归档”。

更关键的是归档逻辑:ContractArchiveService.archive()方法调用时,自动根据securityLevel选择存储位置:
- PUBLIC → 存入公共NAS目录 /archive/public/
- INTERNAL → 存入部门NAS目录 /archive/internal/{deptCode}/
- SECRET/TOP_SECRET → 加密后存入专用加密存储服务(代码中预留EncryptionService.encrypt(fileBytes)接口)。

这种设计让档案管理模块天然具备合规审计能力——任何监管检查,只需导出sys_contract表中securityLevelretentionYears字段,即可生成符合《金融行业网络安全等级保护基本要求》的自查报告。

4. 实操部署与二次开发关键路径

4.1 数据库配置的银行环境适配要点

README.md中“修改数据库”截图(0-99-修改数据库.png)看似简单,实则暗藏银行特有配置。以Oracle为例,application-oracle.yml关键配置:

spring:
  datasource:
    url: jdbc:oracle:thin:@//10.10.1.100:1521/ORCL # 银行内网IP,禁用主机名(DNS故障风险)
    username: OA_USER # 必须使用独立数据库用户,禁止用SYSTEM
    password: ${DB_PASSWORD:changeme} # 密码从环境变量读取,禁止明文
    hikari:
      connection-timeout: 30000
      validation-timeout: 3000
      idle-timeout: 600000
      max-lifetime: 1800000
      maximum-pool-size: 20 # 银行应用池大小通常≤20,避免连接耗尽
      minimum-idle: 5
      pool-name: HikariCP-OA
      # 银行关键配置:连接泄漏检测
      leak-detection-threshold: 60000 # 60秒未归还连接视为泄漏
  jpa:
    hibernate:
      ddl-auto: none # 绝对禁止update/create,银行数据库变更必须走DBA工单
    show-sql: false # 生产环境禁用SQL日志(性能+安全)
    properties:
      hibernate:
        format_sql: false
        dialect: org.hibernate.dialect.Oracle12cDialect

必须修改的三项银行专属配置:
1. 连接串中的SID/Service Name:银行Oracle实例多为RAC集群,urlORCL需替换为实际服务名(如OA_SERV),可通过tnsping OA_SERV验证;
2. 数据库用户权限OA_USER需被授予SELECT ANY DICTIONARY(用于动态字典查询)和EXECUTE ON DBMS_CRYPTO(用于密码加密),但禁止DROP ANY TABLE
3. 密码加密密钥application.ymlcrypto.key字段必须替换为32位随机字符串(如openssl rand -base64 32生成),该密钥用于加密sys_user.password字段,银行审计要求密钥不得与代码共存,应存于运维密钥管理系统。

提示:若使用达梦数据库(DM8),需额外修改pom.xmldm.jdbc.driver.DmDriver依赖版本为8.1.2.117,并在application-dm.yml中添加hibernate.dialect: org.hibernate.dialect.DmDialect,否则sys_dict表的dict_type字段会出现乱码。

4.2 启动与默认账号的银行安全加固步骤

README.md提供的默认账号admin/123456仅用于首次启动验证,正式使用前必须执行以下加固

第一步:重置管理员密码
访问http://localhost:8080/login,用admin/123456登录后,立即进入“个人中心→密码修改”,新密码需满足:
- 长度8-20位;
- 包含大写字母、小写字母、数字、特殊字符(!@#$%^&*)各至少1个;
- 不能与前5次密码重复(sys_user_history_password表记录);
- 修改后,旧密码立即失效,且sys_login_log表记录login_status='PASSWORD_CHANGED'

第二步:禁用默认账号
在系统管理→用户管理中,找到username='admin'的用户,将其status字段更新为DISABLED(数据库直接执行UPDATE sys_user SET status='DISABLED' WHERE username='admin'),并分配新管理员账号(如oa_admin)。银行安全基线要求:禁止使用默认账号,所有账号必须实名制绑定工号。

第三步:配置会话超时与锁屏
application.yml中调整:

# 银行标准:操作超时15分钟,锁屏5分钟
server:
  servlet:
    context-path: /oa
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
spring:
  session:
    timeout: 900 # 15分钟,单位秒
  thymeleaf:
    cache: true
  resources:
    add-mappings: true
# 前端锁屏配置(src/main/resources/static/js/common.js)
const LOCK_TIMEOUT = 300000; // 5分钟毫秒值

截图0-4-切换主题.png中右上角的“锁屏”按钮,点击后调用/api/v1/auth/lock接口,该接口生成一次性锁屏令牌存入Redis(LOCK:{userId}),解锁时需输入当前用户密码进行二次认证。

4.3 二次开发黄金路径:从“增删改查”到“银行流程嵌入”

作为银行OA二次开发基础,这套代码提供了清晰的扩展接口。我以“为某支行增加‘普惠金融贷款台账’模块”为例,说明高效开发路径:

路径一:复用现有模块骨架(推荐新手)
1. 复制module2-asset包为module7-loan
2. 修改LoanInfo实体类,字段参考银行《普惠金融统计制度》:
java private String loanNo; // 贷款编号(按银行规则:YYMMDD+6位流水) private BigDecimal amount; // 贷款金额(精度18,2) private Date disburseDate; // 发放日期(必须≤今日) private String customerType; // 客户类型(小微企业/个体工商户/农户) private String guaranteeType; // 担保方式(信用/抵押/质押/保证)
3. 在SysMenu表中插入新菜单,perms字段设为loan:info:list
4. 在SysDict表中新增字典类型LOAN_CUSTOMER_TYPE,录入值MICRO_ENTERPRISE,INDIVIDUAL_BUSINESS,FARMER
5. 启动后,管理员在“菜单管理”中为“支行行长”角色分配该菜单,即完成上线。

路径二:嵌入银行现有流程(推荐进阶)
若需对接银行信贷管理系统(CMS),在LoanService.submit()中调用外部接口:

// 调用CMS校验客户征信
CmsResponse cmsResp = cmsClient.verifyCredit(customerId);
if (!"SUCCESS".equals(cmsResp.getCode())) {
    throw new BusinessException("征信校验失败:" + cmsResp.getMsg());
}
// 同步贷款信息至CMS
cmsClient.syncLoanInfo(loanInfo);
// 更新本地状态为“已同步”
loanMapper.updateStatus(loanId, "SYNCED");

此时需在application.yml中配置CMS地址与密钥,并在SysDict中新增CMS_ENVIRONMENT字典(DEV/UAT/PROD),不同环境调用不同CMS地址。这种开发方式,让新模块天然融入银行现有IT生态,避免形成数据孤岛。

5. 常见问题与银行环境排查技巧实录

5.1 启动失败高频问题与根因定位

银行环境启动失败,80%源于环境配置与安全策略冲突。以下是真实排查记录:

现象错误日志关键词根因分析解决方案
启动卡在Starting Servlet web serverCaused by: java.net.UnknownHostException: hostname银行内网DNS未配置,application.ymlserver.address使用了主机名而非IPserver.address改为内网IP(如10.10.1.100),或在/etc/hosts添加10.10.1.100 hostname
登录页空白,F12显示Failed to load resource: net::ERR_CONNECTION_REFUSEDAccess to XMLHttpRequest at 'http://localhost:8080/api/v1/auth/login' from origin 'http://localhost:8080' has been blocked by CORS policy银行Chrome浏览器启用了严格CSP策略,禁止localhost跨域application.yml中配置cors.allowed-origins: ["http://localhost:8080"],或使用银行统一的前端域名(如oa.bank.com
登录成功但菜单为空SELECT * FROM sys_role_menu WHERE role_id = ?返回空结果默认角色ROLE_ADMIN未在sys_role_menu中分配菜单,银行DBA执行了TRUNCATE sys_role_menu清理脚本执行init-menu.sql脚本(资源包中提供),或在后台“角色管理→分配菜单”中为管理员勾选全部菜单
切换主题后样式错乱Refused to apply inline style because it violates the following Content Security Policy directive银行安全组在Web服务器层启用了CSP头,禁止style-src 'unsafe-inline'修改WebMvcConfigurer.addResourceHandlers(),将主题CSS改为外部文件引用,或联系安全组临时放宽CSP策略

注意:银行环境严禁使用mvn spring-boot:run直接启动。必须打包为jar后,用java -Dfile.encoding=UTF-8 -Xms512m -Xmx1024m -jar oa-system.jar命令启动,并通过nohup守护进程。截图0-99-启动项目.png中终端窗口的-Xmx1024m参数,正是为避免内存溢出导致的JVM崩溃。

5.2 权限配置典型失误与修复指南

银行权限配置失误往往导致重大合规风险。以下是五个血泪教训:

失误一:角色继承关系断裂
现象:新创建的“支行行长”角色无法看到下属网点资产。
根因:sys_role.parent_id字段为空,未设置其父角色为“分行行长”。
修复:执行SQL UPDATE sys_role SET parent_id = (SELECT role_id FROM sys_role WHERE role_code = 'BRANCH_MANAGER') WHERE role_code = 'SUB_BRANCH_MANAGER';

失误二:按钮权限未同步更新
现象:在菜单管理中为“资产管理员”增加了“资产报废”菜单,但列表页无“报废”按钮。
根因:按钮权限码asset:info:scrap未在sys_role_button表中为该角色插入记录。
修复:在后台“系统管理→按钮权限分配”中,为“资产管理员”角色勾选asset:info:scrap,或执行SQL INSERT INTO sys_role_button(role_id, button_code) VALUES (?, 'asset:info:scrap');

失误三:数据权限范围过大
现象:某支行员工能看到全省资产数据。
根因:sys_user.dept_id字段错误关联到省级部门(dept_code='PROVINCE'),而非支行部门(dept_code='SUB_BRANCH_001')。
修复:核对sys_user表中该用户dept_id,更新为正确支行部门ID,并检查sys_dept表中该部门的parent_id是否逐级指向正确上级。

失误四:字典缓存未刷新
现象:新增了合同类型字典,但前端下拉框不显示。
根因:SysDictService使用@Cacheable注解缓存字典,但未配置缓存失效策略。
修复:在后台“系统管理→字典管理”中点击“刷新缓存”按钮,或执行redis-cli DEL "sys:dict:*"清除Redis缓存。

失误五:会话超时后未跳转登录页
现象:用户离开电脑15分钟后返回,点击按钮报错401 Unauthorized,未自动跳转登录页。
根因:前端axios.interceptors.response.use()未捕获401状态码并重定向。
修复:修改src/main/resources/static/js/common.js,在响应拦截器中添加:

if (error.response.status === 401) {
    window.location.href = '/login?timeout=1';
}

5.3 银行特色功能调试技巧

主题切换的灰度发布验证
银行系统升级需灰度验证。截图0-4-切换主题.png中的主题切换,实际通过Cookie控制:

// ThemeController.setTheme()
Cookie themeCookie = new Cookie("oa_theme", themeName);
themeCookie.setPath("/");
themeCookie.setMaxAge(3600); // 1小时
response.addCookie(themeCookie);

调试时,在Chrome开发者工具Application→Cookies中,手动修改oa_theme值为darkblue,刷新页面即可验证主题效果,无需重启服务。

密码强度校验的监管合规测试
银行要求密码必须包含特殊字符。测试时用Postman发送:

curl -X POST http://localhost:8080/api/v1/auth/change-password \
  -H "Content-Type: application/json" \
  -d '{"oldPassword":"Abc12345!","newPassword":"Abc12345@"}'

若返回{"code":400,"msg":"新密码必须包含!@#$%^&*中的至少一个"},说明校验生效。注意:@符号在URL中需编码为%40,否则会被Tomcat截断。

打印功能的银行A4适配验证
银行所有打印必须符合A4纸张(210×297mm)。在Chrome中按Ctrl+P,选择“另存为PDF”,检查PDF属性:
- 页面大小:A4(210 × 297 毫米);
- 页边距:上2.5cm、下2cm、左2.5cm、右2cm(@page { margin: 2.5cm 2cm; });
- 字体:中文用“微软雅黑”,英文用“Arial”,字号≥10.5pt(符合《银行业务凭证印刷规范》)。

这些细节,正是银行OA系统区别于通用OA的核心价值——它不是功能的堆砌,而是将监管要求、风控逻辑、操作习惯,一行行代码刻进系统骨髓。当你真正理解sys_role_button表中那几百条权限码的业务含义,当你在AssetInventoryService里看到双人复核的强制校验,当你发现PersonnelArchive实体类中每一个字段都在回应一部法律条文,你就触摸到了银行数字化转型最真实的脉搏。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:这套银行内部办公系统基于SpringBoot 2.x开发,包含六大功能模块:公文管理(支持会议安排与公文列表)、资产管理(涵盖资产入库、查询、盘点)、档案管理(人事档案与合同归档)、辅助办公(图书借阅与管理)、个人中心(薪资查看、通讯录、工作计划)、系统管理(用户、角色、部门、菜单、字典配置)。权限体系采用RBAC模型,预置管理员、资产管理员、资产盘点员、主任、普通用户五类角色,后台可灵活分配菜单级和按钮级操作权限。提供完整登录界面、密码修改、主题切换功能,配套详细README.md文档,说明数据库配置方式、项目启动步骤及默认账号密码(如admin/123456)。所有截图覆盖各模块核心操作流程,包括新增、列表展示等典型页面,如‘资产列表-增加’‘合同管理-列表’‘角色管理-增加’等,便于快速上手或二次开发。技术栈主流稳定,适合作为银行类OA系统学习范例或定制化开发基础。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

本文章已经生成可运行项目
源码链接: https://pan.quark.cn/s/1889b1ebf6bc ### Linux环境下Vivado借助VCS进行仿真的操作指南 #### 一、前言 在数字电路系统设计领域中,FPGA(Field Programmable Gate Array,即现场可编程门阵列)的设计与验证占据着核心地位。伴随着设计复杂程度的增加,高效的仿真验证成为了保障设计正确性的关键环节之一。在Linux操作系统环境中运用Vivado来调用VCS执行仿真操作,不仅能够提升仿真的执行速度,同时也便于进行波形监测,从而大幅度增强设计验证的整体效率。本指南将详尽阐述如何在Linux系统平台上完成这一流程的操作。 #### 二、准备工作阶段 1. **软件部署**: - 验证Vivado软件是否已经正确安装。Vivado是由Xilinx公司开发的一款集成开发环境,专门用于FPGA的设计工作。 - 进行VCS软件的安装。VCS是一款性能卓越的仿真工具,广泛应用于Verilog和SystemVerilog语言代码的仿真测试。为了更好地支持混合语言环境下的仿真,建议采用VCS-MX版本。 2. **权限配置**: - Linux系统权限管理机制较为严格,尤其是针对普通用户的权限限制较为严格。因此,在启动Vivado调用VCS仿真之前,必须确保所有必要的权限都已经正确配置。 3. **环境变量设定**: - 配置个人用户目录下的`.bashrc`文件,以便在终端操作时能够顺利加载所需的环境变量。 #### 三、调整个人用户下的.bashrc文件 1. **编辑.bashrc文件**: - 使用`cd`指令进入到个人用户的主目录,通过`ll -la`指令查看当前目录中的所有文件,...
下载代码方式:https://pan.quark.cn/s/a4b39357ea24 标题中所指的"RS485转USB驱动"是一种硬件接口转换技术,其功能在于将传统的RS485通信协议转换为USB接口形式,从而使得现代计算机或设备能够便捷地与采用RS485协议的设备展开通信。RS485作为一种在工业控制、远程通信及多点系统中得到普遍应用的串行通信标准,具备传输距离长、抗干扰性能优异等显著优势。文中提及的型号(CH340、CH341、FT232RL、PL2303、Y-105)是几种常见的USB至UART(通用异步接收发送器)桥接芯片,它们在USB接口与RS485网络之间充当转换媒介的角色。这些芯片赋予USB通信能力,使得计算机可以通过USB接口与RS485网络中的设备执行数据交换。 1. CH340/CH341:这些由韦东山科技研制的USB转串口芯片,常被用于构建低成本的USB转串口适配器。它们提供从USB到UART的转换功能,支持多种波特率的设定,并且在Windows操作系统环境下通常需要安装相应的驱动程序方可正常运作。 2. FT232RL:FTDI公司推出的一款高性能且低功耗的USB到UART桥接器。FT232RL配备全速USB 1.1接口,支持多种串行接口模式,在数据通信、工业控制等领域能够得到广泛应用。同样地,采用FT232RL的设备在连接至电脑时也需要安装对应的驱动程序。 3. PL2303:硅光电子(Prolific)公司所生产的产品,亦是一种常用的USB到UART桥接芯片。它展现出良好的兼容性以及广泛的驱动程序支持,适用于各类USB至串口的应用场景。 4. Y-105:这可能是一款特定的RS485转USB转换模块,或许集成了上述其中一种或多种转换...
已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 ### 基本栈和队列操作实验报告 一、实验目标 1、熟练掌握栈和队列的基本操作在数组与链表两种存储结构上的具体实现。 2、学会运用栈和队列来处理简单的实际应用场景。 二、实验内容 任务:设计一个算法,用以检测一个以`@`作为终止标志的字符序列是否构成回文。所谓“回文”是指正向与反向读取均无差异的字符串,例如`"321123"`或`"ableelba"`。 ### 栈和队列的基本操作及其应用实验报告 #### 实验目标 1. **熟练掌握栈和队列的基本操作**:在数组和链表两种存储结构上完成栈和队列的基本操作的具体实现。 2. **应用栈和队列解决实际问题**:通过具体的编程实践,学习如何利用栈和队列来处理简单的实际问题。 #### 实验内容 本实验的核心是通过编写一个算法来判断一个以`@`为结束标志的字符序列是否为回文。回文是指一个字符串不论正向还是反向读都保持相同的情况,比如`"321123"`或`"ableelba"`。 ### 数据结构及核心算法设计 #### 常量及结构体定义 ```cpp #define STACK_INIT_SIZE 100 #define STACK_INCREMENT 10 #define OK 1 #define ERROR 0 struct SqStack { // 定义栈结构体 char *base; // 底部指针 char *top; // 顶部指针 }; struct Queue { // 定义队列结构体 char *front; // 队首指针 char *rear; // 队尾指针 }; ``` #### 栈的操作实现 - `i...
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在编程领域,特别是GUI应用程序开发中,Qt框架是一个非常流行的选择。 Qt库提供了一套丰富的控件和功能,使得开发者可以构建美观且功能强大的用户界面。 "Qt动态添加控件demo"这个主题聚焦于如何在运行时根据需求动态地向用户界面添加控件,而不是在设计阶段就预设好所有控件。 这种技术在处理数据量不确定、需要用户自定义布局或者创建可扩展的界面时尤其有用。 让我们理解Qt中的控件。 控件(Widgets)是构成Qt界面的基本元素,如按钮(QPushButton)、文本框(QLineEdit)、标签(QLabel)等。 这些控件可以通过Qt Designer图形化工具预先设计,也可以在C++或Python代码中动态创建。 动态添加控件通常涉及以下步骤: 1. **创建控件对象**:你需要实例化相应的控件类,例如`QPushButton *button = new QPushButton("点击我");`。 2. **设置控件属性**:你可以通过调用控件对象的成员函数来改变其属性,如大小、位置、文本等。 例如,`button->setGeometry(x, y, width, height);`来设定按钮的位置和大小。 3. **将控件添加到布局**:在Qt中,布局(Layouts)管理着控件的排列方式和大小调整。 你可以使用各种布局,如水平布局(QHBoxLayout)、垂直布局(QVBoxLayout)或网格布局(QGridLayout)。 创建布局后,使用`addWidget()`方法将控件添加到布局中。 例如,`QHBoxLayout *layout = new QHBoxLayout(); l...
内容概要:本文围绕“基于粒子群优化算法的非最小相位系统的最小化欠阻尼研究”,结合Matlab代码实现,深入探讨了在带有优化的连续死区控制策略下,如何利用粒子群优化(PSO)算法对具有反向响应、延迟等复杂动态特性的非最小相位系统进行动态性能优化,重点解决系统因固有特性导致的欠阻尼、超调大、响应慢等问题。研究通过建立精确的系统数学模型,设计融合PSO算法的优化控制律,对控制器参数进行全局寻优,从而有效提升系统的稳定性、快速性与鲁棒性,并通过大量仿真实验验证了所提方法在抑制振荡、缩短调节时间方面的优越性能。该技术为存在非线性与不稳定零点的工业控制系统提供了有效的优化设计思路。; 适合人群:具备扎实自动控制理论基础、熟悉系统建模与仿真分析,并掌握Matlab/Simulink编程技能的科研人员、高校研究生及从事先进控制算法开发、系统优化设计的工程技术人员。; 使用场景及目标:①应用于飞行器姿态控制、倒立摆系统、热工过程控制等典型的非最小相位系统的高性能控制器设计;②利用智能优化算法(如PSO)自动整定PID或高级控制器参数,克服传统试凑法的局限性;③为解决工业现场中由死区、间隙等非线性环节引发的系统性能下降问题提供仿真验证平台与技术方案。; 阅读建议:建议读者在深入理解非最小相位系统特性的基础上,结合提供的Matlab代码进行仿真复现,重点分析PSO算法中惯性权重、学习因子等关键参数对寻优过程及最终控制效果的影响,并可进一步尝试将该优化框架迁移至灰狼优化器(GWO)、鲸鱼优化算法(WOA)等其他智能算法,以对比不同元启发式算法的性能差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值