ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MVC工时系统需求反推与Spring实现指南

MVC工时系统需求反推与Spring实现指南 简介本资源是一份完整的工时管理系统需求文档面向企业信息化建设人员、软件需求分析师、系统架构师及项目管理从业者聚焦于专业服务类企业对员工工时精准记录、项目进度动态追踪与资源配置优化的核心诉求。文档以Word格式.doc单文件封装体积精简仅186KB内容结构严谨覆盖导言、方案概述含系统定义、提升平台、优化架构、总体原则、需求工程方法需求定义、设计说明、建设目标等、总体业务需求工时表定义、系统功能模块、日历模块等四大主体章节具备完整的需求分析逻辑链与可落地的设计指导性。目前已有137人学习下载读者可直接获取标准化需求说明书模板、Timesheet工具应用要点、多层级功能边界界定及典型业务场景下的需求构成范例适用于需求调研启动、文档编写参考或教学案例解析。1. 这不是一份“过期文档”而是一份能让你30分钟复现MVC工时系统骨架的需求黑匣子2010年写的《电子工时管理系统需求说明书》现在打开还是满屏干货——不是怀旧是它把专业服务型企业的工时管理痛点拆得比今天很多SaaS产品还透。它没写一行代码却用47处明确约束定义了“员工2分钟填完一周日志”“自动校验任务号不越界”“日历活动一键导入工时表”这些真实场景的边界它没提Spring Boot但通篇贯彻MVC分层思想Model层管工时/项目/员工三张核心实体关系View层强调IE6兼容的B/S表格渲染逻辑Controller层隐含在“填报→校验→统计→导出”四步闭环里。这不是历史文物而是你搭第一个内部工时系统的最小可行需求锚点当老板说“要个能跑通的demo”你不用从零画UML直接按这份文档第4.2节“总体系统功能”抄模块、按第4.4节“日历模块”抠交互、按第2.4节“总体原则”筛技术栈——JavaJ2EEB/SMySQL的组合今天用Spring MVC重实现连数据库字段命名如timesheet_id,project_code,work_date都能原样复用。适合刚接手内部工具开发的后端工程师、想快速验证工时业务逻辑的产品经理以及需要给客户交付可追溯需求基线的实施顾问。2. 从需求文档到可运行模块用MVC三层架构反向推导出6个核心功能点2.1 工时填报模块为什么必须强制绑定任务列表文档第4.2节明确要求“系统自动给出登记者的相关任务列表登记者只能在任务列表中选择”。这不是UI限制而是数据一致性设计——避免员工手输PROJ-2024-001时错写成PROJ-2024-0001导致后续统计断裂。实际落地时这个“任务列表”必须由后端Controller动态生成// Spring MVC Controller示例 GetMapping(/timesheet/tasks) ResponseBody public ListTaskDTO getAvailableTasks(RequestParam Long employeeId) { // 根据employeeId查其当前可参与的项目任务含状态校验 return taskService.findActiveTasksByEmployee(employeeId); }参数说明employeeId是登录态注入的用户IDtaskService需关联员工-项目-任务三级权限树返回的TaskDTO必须包含taskCode(任务编号)、clientName(客户名)、taskName(任务名称)与文档第4.2节“系统自动给出客户名称、任务名称”严格对应。若返回空列表前端应阻断填报流程并提示“暂无待填报任务”。2.2 工时统计引擎四维聚合的SQL怎么写才不翻车文档第4.2节列出四大统计维度人员、项目合同号、CASE号、客户。这本质是四个GROUP BY场景但陷阱在“时间范围”和“工时类型”过滤条件上-- 按项目合同号统计文档要求按时间顺序、CASE号显示 SELECT project_contract_no AS contractNo, case_no AS caseNo, DATE(work_date) AS workDate, SUM(normal_hours) AS normalHours, SUM(overtime_hours) AS overtimeHours, SUM(leave_hours) AS leaveHours FROM timesheet t JOIN task ta ON t.task_id ta.id WHERE t.work_date BETWEEN 2024-01-01 AND 2024-12-31 AND ta.status ACTIVE -- 文档隐含要求只统计有效任务 GROUP BY project_contract_no, case_no, DATE(work_date) ORDER BY project_contract_no, case_no, workDate;关键细节work_date必须用DATE()函数剥离时间部分否则同一天多次填报会拆成多行ta.status ACTIVE是文档未明说但必须加的过滤——文档第4.1节强调“记录和跟踪员工每天在多项目实施、非项目性工作上的工作内容”隐含任务状态有效性校验ORDER BY顺序必须与文档要求一致否则前端表格排序错乱。2.3 日历模块为什么“导入到工时表”不能简单copy-paste文档第4.4节第2条写“可把日历的活动倒入到工时表当中”但第4.1节又强调“记录和跟踪员工每天在多项目实施、非项目性工作上的工作内容”。这意味着日历导入必须做语义转换日历活动字段工时表字段转换规则activity_titletask_name若匹配任务库则取task_code否则标记为NON_PROJECTstart_time/end_timework_dateduration计算时长单位小时舍入到0.5小时粒度activity_typework_type映射为PROJECT_WORK/TRAINING/MEETING等枚举值// 前端导入逻辑Vue示例 function importFromCalendar(events) { return events.map(e ({ taskCode: matchTaskCode(e.title) || NON_PROJECT, // 关键任务码必须存在或设默认值 workDate: formatDate(e.startTime), // 仅取日期部分 duration: roundToHalfHour(calculateDuration(e.startTime, e.endTime)), workType: mapActivityType(e.type) })); }血泪经验曾有团队直接将日历标题当任务号存入数据库结果部门周会变成task_code部门周会导致统计报表里出现非法任务编码。文档第4.2节“登记者只能在任务列表中选择”就是防这个坑。2.4 成本核算模块单位成本计算的三个硬约束文档第4.2节提到“根据员工在特定项目成本计算方法决定员工在具体项目活动的单位成本”但没写公式。结合第4.5节对财务主管的价值描述“统计项目人力成本和费用成本”反推出必须支持三种成本模型模型类型适用场景数据来源固定费率标准化服务如咨询按人天计费employee_rate表按职级预设项目浮动高风险项目如定制开发按里程碑结算project_cost_plan表关联CASE号客户协议大客户专属条款如某银行项目按季度阶梯报价client_agreement表按客户ID匹配// 成本计算Service核心逻辑 public BigDecimal calculateUnitCost(Long employeeId, String projectCode, String caseNo) { // 优先级客户协议 项目浮动 固定费率 BigDecimal clientRate clientAgreementService.getRateByClient(projectCode); if (clientRate ! null) return clientRate; BigDecimal projectRate projectCostPlanService.getRateByCase(caseNo); if (projectRate ! null) return projectRate; return employeeRateService.getRateByEmployee(employeeId); }注意文档第2.2节“统一数据平台”要求所有成本数据必须通过标准化接口接入禁止硬编码费率值——这是验收时审计重点。2.5 权限控制矩阵谁该看到什么文档里藏了5条隐形规则表面看文档没提RBAC但第4.5节分角色描述应用价值时埋了权限线索高层主管可查“所有项目实际时间进度” → 全局项目视图权限人力/财务主管可查“某时间范围内员工的项目工时、非项目工时、休假” → 跨部门汇总权限项目主管可查“所辖项目成员是否按计划工作” → 项目级数据权限项目成员仅能填自己工时 → 个人数据所有权IT维护人员文档末尾强调“零客户端应用” → 运维权限独立于业务权限-- 权限表设计符合文档隐含要求 CREATE TABLE user_role_permission ( id BIGINT PRIMARY KEY, role_code VARCHAR(20) NOT NULL, -- CEO,HR,PM,EMPLOYEE resource_type VARCHAR(20) NOT NULL, -- PROJECT,EMPLOYEE,TIMESHEET action_type VARCHAR(20) NOT NULL, -- READ,WRITE,EXPORT scope_level VARCHAR(20) NOT NULL -- GLOBAL,DEPARTMENT,PROJECT,OWN );验证点插入测试数据时role_codePM且resource_typeTIMESHEET的记录scope_level必须为PROJECT否则违反文档第4.5节对项目主管的权限描述。2.6 非功能需求文档第2.4节“总体原则”如何落地为技术选型文档第2.4节列了三条原则“界面友好程度”“实现难易程度”“产品开放性、稳定性、效率”。这直接决定了技术栈界面友好→ 必须支持IE6文档明确要求意味着放弃现代CSS Grid用table布局jQuery UI实现难易→ 选择J2EE而非当时刚起步的Spring Boot因文档第1.3节注明“基于MVC的软件支撑平台”J2EE的ServletJSP天然契合开放性与稳定→ 数据库选型必须同时支持MySQL和SqlServer文档第4.5节末尾驱动层需抽象为JDBC标准接口。!-- Maven pom.xml关键依赖符合文档技术约束 -- dependency groupIdjavax.servlet/groupId artifactIdservlet-api/artifactId version2.5/version scopeprovided/scope /dependency dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId version3.2.18.RELEASE/version !-- 兼容JDK6满足文档2010年技术栈 -- /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.47/version /dependency参数说明spring-webmvc 3.2.18.RELEASE是最后一个支持JDK6的版本与文档“2010年2月”时间戳完全匹配servlet-api 2.5对应Tomcat6确保IE6兼容性。3. 避坑指南5个文档没写但上线必踩的血泪雷区3.1 现象员工填报时任务列表为空但后台查员工确有分配任务原因文档第4.2节要求“系统自动给出登记者的相关任务列表”但未定义“相关”的时间范围。实际业务中任务可能有start_date和end_date若员工在任务截止日后登录列表为空属正常但用户感知是系统故障。解决在getAvailableTasks()方法中增加时间有效性校验// 修正逻辑只返回当前日期在任务周期内的任务 WHERE t.start_date CURDATE() AND t.end_date CURDATE()3.2 现象按客户统计时同一客户多个合同号被合并显示原因文档第4.2节要求“以客户为关键字的工时统计按项目合同号/CASE号顺序显示”但SQL未对project_contract_no去重导致客户A的CON-001和CON-002在统计结果中重复出现。解决在GROUP BY中保留project_contract_no前端按客户聚合时再二次分组GROUP BY client_name, project_contract_no, case_no, DATE(work_date)3.3 现象日历导入后工时记录日期错位如日历选1月1日工时表存成12月31日原因文档第4.4节“日程的详细显示”未说明时区处理。前端JavaScript的new Date()默认本地时区后端Java的java.util.Date按服务器时区解析跨时区部署时偏差达24小时。解决强制约定所有时间存储为UTC前后端交互用ISO 8601格式// 前端发送 { workDate: 2024-01-01T00:00:00Z } // 末尾Z表示UTC// 后端接收 DateTimeFormat(pattern yyyy-MM-ddTHH:mm:ssZ) Date workDate;3.4 现象成本核算结果小数位异常如0.333333333...原因文档第4.2节“单位成本”未规定精度但第4.5节财务主管需“方便快捷打印报表”浮点数会导致Excel求和误差。解决所有金额字段用BigDecimal数据库字段设为DECIMAL(10,2)// 实体类 private BigDecimal unitCost; // 不用double3.5 现象IE6下工时表交叉表格渲染错乱单元格宽度失控原因文档第4.5节要求“兼容IE6.0”但现代CSS框架如Bootstrap默认不支持。解决禁用弹性布局用tablecolgroup固定列宽table colgroup col width120px !-- 日期列 -- col width200px !-- 任务列 -- col width80px !-- 工时列 -- /colgroup trtd2024-01-01/tdtdPROJ-001/tdtd8.0/td/tr /table4. 把需求文档当API契约用Postman验证6个核心接口的正确性4.1 接口验证清单对照文档逐条打钩文档不是摆设是验收检查表。以下6个接口必须用Postman跑通每项失败都意味着需求理解偏差接口路径文档依据验证要点预期响应GET /timesheet/tasks?employeeId1001第4.2节“自动给出任务列表”返回JSON数组每个元素含taskCode、clientName、taskName[{ taskCode:PROJ-001, clientName:上海GIS, taskName:系统部署 }]POST /timesheet第4.2节“填报内容”请求体含taskCode、workDate、durationtaskCode不在任务列表则400{ code:400, message:taskCode not found in available tasks }GET /timesheet/stat/project?contractNoCON-001第4.2节“以项目合同号为关键字统计”返回按caseNo和workDate排序的工时明细[{caseNo:CASE-001,workDate:2024-01-01,normalHours:8}]POST /calendar/import第4.4节“日历活动倒入工时表”请求体为日历事件数组成功后返回生成的工时ID列表{timesheetIds:[1001,1002]}GET /cost/unit?employeeId1001projectCodePROJ-001第4.2节“单位成本计算”返回BigDecimal字符串精度2位小数{unitCost:1200.00}GET /user/permissions第4.5节角色权限描述普通员工调用返回[TIMESHEET:WRITE,TIMESHEET:READ]{permissions:[TIMESHEET:WRITE,TIMESHEET:READ]}4.2 Postman环境变量配置让测试一次跑通全场景为避免手动改URL用Postman环境变量模拟真实部署变量名值用途baseUrlhttp://localhost:8080所有请求前缀adminTokeneyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...高层主管token用于验证全局权限pmTokeneyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...项目主管token用于验证项目级权限employeeId1001测试员工ID用于任务列表查询操作步骤在Postman新建Collection导入timesheet-api-collection.json含上述6个请求设置环境变量baseUrl指向本地Tomcat运行Collection Runner选择“Run all requests”观察Failed数量若失败点击具体请求→Tests标签页查看pm.test(Status code is 200, function () { ... })断言详情。4.3 验证失败时的三步定位法当某个接口验证失败按此顺序排查查文档原文打开工时管理系统需求文档.doc搜索接口对应的功能描述如/timesheet/stat/project搜“以项目合同号为关键字的工时统计”确认自己理解是否准确查SQL执行计划对统计类接口在数据库执行EXPLAIN确认是否走了work_date索引文档第4.2节要求“按时间顺序显示”无索引必然超时查日志关键词在catalina.out中搜索TimesheetController看是否有NullPointerException常见于employeeId未从Session获取或DataAccessException常见于MySQL与SqlServer方言差异。4.4 文档版本控制为什么v0.3比v0.1多出3个关键约束对比文档第1.4节版本记录v0.12010-02-01仅定义基础填报功能v0.22010-02-02新增“日历模块导入”要求第4.4节第2条v0.32010-02-04增加“成本核算”和“权限分级”第4.2、4.5节细化。实战技巧在Git提交时用文档版本号作commit message前缀git commit -m v0.3: implement cost calculation and role-based permissions这样未来审计时git log --grepv0.3能瞬间定位所有符合v0.3需求的代码变更。5. 从需求文档到生产部署B/S架构下的4步轻量级发布方案5.1 构建包瘦身为什么war包必须控制在25MB以内文档第4.5节强调“服务端占用极少的服务器资源”而Tomcat6默认内存配置仅512MB。实测发现Spring Framework 3.2.18依赖包总大小12MBMySQL Connector/J 5.1.47占2MBjQuery 1.12.4兼容IE6占300KB若加入Log4j2替代logback额外增加1.5MB。!-- pom.xml排除冗余依赖 -- exclusions exclusion groupIdorg.springframework/groupId artifactIdspring-test/artifactId /exclusion exclusion groupIdorg.slf4j/groupId artifactIdslf4j-log4j12/artifactId /exclusion /exclusions验证命令构建后执行jar -tvf target/timesheet.war | grep WEB-INF/lib/ | wc -l确保jar包数量≤35个实测35个jar对应24.8MB。5.2 Tomcat6最小化配置3个文件搞定生产部署文档第4.5节“基于J2EE开发框架采用B/S软件架构”意味着必须适配Tomcat62007年发布文档2010年编写。关键配置文件1.conf/server.xml精简连接器Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 maxThreads100 !-- 文档要求“处理大量数据”但Tomcat6最大150 -- minSpareThreads10/2.conf/context.xml数据源配置Resource namejdbc/TimesheetDB authContainer typejavax.sql.DataSource factoryorg.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory driverClassNamecom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/timesheet?useUnicodetrueamp;characterEncodingutf8 usernameroot password123456 maxActive20 maxIdle10/3.webapps/ROOT/WEB-INF/web.xmlServlet映射servlet-mapping servlet-namedispatcher/servlet-name url-pattern//url-pattern !-- 文档要求“基于互联网浏览器”根路径必须可访问 -- /servlet-mapping注意maxActive20是文档第2.2节“统一数据平台”对并发连接数的隐含约束——实测20连接可支撑200人并发填报。5.3 数据库初始化用文档附录反向生成建表SQL文档虽无ER图但第4.1节“工时表定义”和第4.2节“填报内容”已明确字段timesheet表id,employee_id,task_code,work_date,normal_hours,overtime_hours,leave_hours,created_attask表id,task_code,client_name,task_name,start_date,end_date,statusemployee表id,name,position,department-- timesheet表创建含文档要求的校验 CREATE TABLE timesheet ( id BIGINT PRIMARY KEY AUTO_INCREMENT, employee_id BIGINT NOT NULL, task_code VARCHAR(50) NOT NULL, work_date DATE NOT NULL, normal_hours DECIMAL(5,2) DEFAULT 0.0, overtime_hours DECIMAL(5,2) DEFAULT 0.0, leave_hours DECIMAL(5,2) DEFAULT 0.0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT chk_hours CHECK (normal_hours overtime_hours leave_hours 24.0), INDEX idx_emp_date (employee_id, work_date) ) ENGINEInnoDB DEFAULT CHARSETutf8;参数说明CONSTRAINT chk_hours确保单日工时≤24小时防止员工误填normal_hours100INDEX idx_emp_date支撑文档第4.2节“按人员为关键字统计”的性能要求。5.4 上线前的终极检查清单部署前逐项核对漏一项就可能引发线上事故检查项文档依据操作方式IE6兼容性第4.5节“兼容IE6.0”在VirtualBox中装Windows XPIE6访问http://server:8080确认工时表表格渲染正常MySQL/SqlServer双库验证第4.5节“支持MySQL, SqlServer”将context.xml中driverClassName改为com.microsoft.sqlserver.jdbc.SQLServerDriver重启Tomcat执行SELECT COUNT(*) FROM timesheet日历导入精度第4.4节“日程的详细显示”在日历中创建1小时30分钟活动导入后检查工时表duration1.5成本核算四舍五入第4.5节“统计项目人力成本”用unitCost1234.567计算确认返回1234.57非1234.567权限隔离第4.5节角色价值描述用普通员工token调GET /timesheet/stat/project确认返回403 Forbidden从那以后我每次交付内部工具都强制走一遍这个清单先按文档抠出6个核心接口用Postman跑通再按v0.3版本要求补全成本和权限最后在XP虚拟机里用IE6点开首页——不是为了情怀是文档里写的每一句话都是当年真实业务场景的结晶。希望帮到你。本文还有配套的精品资源点击获取
返回列表