一、如何开发一个JavaWeb项目

22 阅读10分钟

如何开发一个JavaWeb项目

1、确定需求

需求是本人自己想的,不必深究合理性,只是为了让开发过程尽量完整,如果需求不明确影响代码编写的话再补充描述。主要需求如下

  • 定制目标,目标分为愿景目标(终身目标)、长期目标(5~10年)、近期目标(3年)
  • 根据目标拆解为年度计划或者专项计划
  • 根据年度计划拆解制定季度、月度、每周计划
  • 根据每周计划制定每日任务
  • 番茄时钟(目前无具体业务,先做埋点,用于统计)
  • 数据统计,统计目标进度、计划进度、任务完成情况等
  • 每周或者每月进行一次复盘

2、界面设计

计划开发以下几个页面,每个页面里面具体功能

  • 仪表盘:总览今日待办任务、本周进度、目标完成情况、快速操作(新增目标、计划、任务)、工作效率统计。 image-20251217161737797.png
  • 目标中心:所有目标的列表和看板视图,新增目标。 image-20251217161756966.png
  • 计划日历:以日历形式展示任务的月视图、周视图、日视图以及计划列表,新增计划。 image-20251217161813955.png
  • 每日待办:极简的每日任务执行界面,包括今日待办,今日已完成任务,今日统计,番茄钟计时器,新增任务。 image-20251217161824173.png
  • 数据统计:图表化展示任务完成率、投入时间、计划进度等统计数据。 image-20251217161833775.png
  • 复盘:查看历史复盘报告,新增复盘。 image-20251217161842028.png

3、技术栈选型

  • 后端:SpringBoot3 + JDK 17
  • 前端:NodeJS22 + Vue3 + Vite7 + ElementPlus
  • 数据库: MySQL8、Redis
  • 部署:Docker

4、数据库设计

数据库设计要点

  • 根据业务情况选择主键类型,数字递增,UUID,雪花主键等等,一般选择UUID即可
  • 业务字段选择合理的长度、精确度
  • 一般业务表都应包含创建时间、修改时间、创建人、修改人,逻辑删除之类
  • 字段加上注释,列出枚举值,设定默认值
  • 表加上注释
  • 一般设计表初期也会考虑添加索引,这里暂且都不考虑,后续尝试性能调优再加
  • 一般情况下不建议使用外键,不建议使用存储过程、函数

数据表结构

数据库设计如下,具体需求也可从数据表结构分析出一二。

  1. 目标表

     CREATE TABLE `goal` (
       `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键',
       `parent_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父目标ID',
       `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '目标标题',
       `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '目标详细描述',
       `goal_type` enum('VISION','LONG_TERM','SHORT_TERM') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '目标类型:LONG_TERM(长期)/SHORT_TERM(短期)',
       `priority` enum('HIGH','MEDIUM','LOW') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '优先级:HIGH(高)/MEDIUM(中)/LOW(低)',
       `goal_status` enum('PLANNED','ACTIVE','COMPLETED','ABANDONED') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '目标状态:PLANNED(计划中)/ACTIVE(进行中)/COMPLETED(已完成)/ABANDONED(已放弃)',
       `progress` int DEFAULT '0' COMMENT '进度百分比(0-100)',
       `start_date` date NOT NULL COMMENT '开始日期',
       `end_date` date NOT NULL COMMENT '结束日期',
       `is_focused` tinyint(1) DEFAULT '0' COMMENT '是否重点关注',
       `estimated_hours` int DEFAULT NULL COMMENT '预估需要小时数',
       `actual_hours` decimal(5,2) DEFAULT '0.00' COMMENT '实际投入小时数',
       `sort_order` int DEFAULT '0' COMMENT '排序顺序',
       `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
       `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
       PRIMARY KEY (`id`) USING BTREE
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='目标';
    
  2. 计划表

     CREATE TABLE `plan` (
       `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键',
       `goal_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '目标ID',
       `parent_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父计划ID',
       `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '计划标题',
       `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '计划详细描述',
       `plan_type` enum('YEARLY','QUARTERLY','MONTHLY','WEEKLY','DAILY','SPECIAL') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '计划类型:YEARLY(年度)/QUARTERLY(季度)/MONTHLY(月度)/WEEKLY(周度)/DAILY(每日)/SPECIAL(其他)',
       `priority` enum('HIGH','MEDIUM','LOW') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '优先级:HIGH(高)/MEDIUM(中)/LOW(低)',
       `plan_status` enum('PENDING','IN_PROGRESS','COMPLETED','CANCELLED') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '计划状态:PENDING(待开始)/IN_PROGRESS(进行中)/COMPLETED(已完成)/CANCELLED(已取消)',
       `progress` int DEFAULT '0' COMMENT '进度百分比(0-100)',
       `start_date` date NOT NULL COMMENT '开始日期',
       `end_date` date NOT NULL COMMENT '结束日期',
       `sort_order` int DEFAULT '0' COMMENT '排序顺序',
       `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
       `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
       PRIMARY KEY (`id`) USING BTREE
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='计划表';
    
  3. 任务表

     CREATE TABLE `task` (
       `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键',
       `goal_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '目标ID',
       `plan_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '计划ID',
       `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务标题',
       `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '任务描述',
       `priority` enum('HIGH','MEDIUM','LOW') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '优先级:HIGH(高)/MEDIUM(中)/LOW(低)',
       `task_status` enum('PENDING','IN_PROGRESS','COMPLETED','CANCELLED') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务状态:PENDING(待开始)/IN_PROGRESS(进行中)/COMPLETED(已完成)/CANCELLED(已取消)',
       `task_time` datetime NOT NULL COMMENT '任务时间',
       `complete_at` datetime DEFAULT NULL COMMENT '完成时间',
       `estimated_minutes` int NOT NULL COMMENT '预估分钟数',
       `actual_minutes` int DEFAULT '0' COMMENT '实际分钟数',
       `estimated_tomatoes` int DEFAULT NULL COMMENT '预估番茄数',
       `completed_tomatoes` int DEFAULT '0' COMMENT '完成番茄数',
       `is_repeat` tinyint(1) DEFAULT '0' COMMENT '是否重复任务',
       `repeat_rule` json DEFAULT NULL COMMENT '重复规则',
       `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
       `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
       PRIMARY KEY (`id`) USING BTREE
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='任务表';
    
  4. 复盘记录表

     CREATE TABLE `review` (
       `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键',
       `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '复盘标题',
       `review_type` enum('WEEKLY','MONTHLY','QUARTERLY','YEARLY') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '复盘类型:WEEKLY(周度)/MONTHLY(月度)/QUARTERLY(季度)/YEARLY(年度)',
       `start_date` date NOT NULL COMMENT '复盘开始日期',
       `end_date` date NOT NULL COMMENT '复盘结束日期',
       `total_focus_time` int DEFAULT NULL COMMENT '总专注时间(分钟)',
       `total_task` int DEFAULT NULL COMMENT '总任务数',
       `completed_task_count` int DEFAULT NULL COMMENT '完成任务数',
       `efficiency_score` int DEFAULT NULL COMMENT '效率评分(1-100)',
       `achievement` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '成就回顾(JSON数组)',
       `good_reflection` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '做得好的方面(JSON数组)',
       `improve_reflection` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '待改进方面(JSON数组)',
       `insight` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '复盘洞察(JSON数组)',
       `action_plan` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '下一步行动计划(JSON数组)',
       `is_template` tinyint(1) DEFAULT '0' COMMENT '是否为模板',
       `template_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '模板名称',
       `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
       `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
       PRIMARY KEY (`id`) USING BTREE
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='复盘记录表';
    
  5. 番茄钟记录表

     CREATE TABLE `tomato_record` (
       `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键',
       `task_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '任务ID',
       `start_time` datetime NOT NULL COMMENT '开始时间',
       `end_time` datetime DEFAULT NULL COMMENT '结束时间',
       `duration_seconds` int DEFAULT NULL COMMENT '持续秒数',
       `planned_duration_seconds` int DEFAULT NULL COMMENT '计划持续秒数',
       `interruption_reason` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '中断原因',
       `focus_score` int DEFAULT NULL COMMENT '专注度评分(1-5)',
       `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
       `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
       PRIMARY KEY (`id`) USING BTREE
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='番茄钟专注记录表';
    

5、代码编写

正常企业开发一个项目,很少从0开始,一般都是以一个老项目为模板,在上面修改。就算更新技术栈,也会在旧项目中先升级,维护一套基本企业框架代码,里面包含用户体系、登录、日志、常用工具类等等。以此为蓝本开发一个个项目。到代码编写这步纠结,到底是给一个基本框架然后开始写业务代码的增删改查,还是从创建项目开始一步步逐步实现。为了让读者范围广一点,还是一步步逐步实现,但也不真的从创建项目开始,我会提供一个gitee地址,会有基本的依赖。

后端代码编写

主要依赖说明
  • spring-boot-starter-web:web应用必备依赖
  • spring-boot-starter-data-jpa:数据库增删改查依赖
  • mysql-connector-j:数据库连接依赖,配合spring-boot-starter-data-jpa使用
  • spring-boot-starter-data-redis:redis增删改查依赖
  • forest-spring-boot3-starter:用于对接第三方接口,声明式HTTP 请求(Forest
  • hutool-all:hutool工具依赖,内置各种工具类(入门和安装
  • lombok:用注解的方式代替get、set、construct,减少代码量
pom.xml
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>3.5.7</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>com.dong</groupId>
     <artifactId>personal-plan-server</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>personal-plan-server</name>
     <description>personal-plan-server</description>
 ​
     <properties>
         <java.version>17</java.version>
     </properties>
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
         <dependency>
             <groupId>com.mysql</groupId>
             <artifactId>mysql-connector-j</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>com.dtflys.forest</groupId>
             <artifactId>forest-spring-boot3-starter</artifactId>
             <version>1.8.0</version>
         </dependency>
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
             <version>5.8.41</version>
         </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <optional>true</optional>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-configuration-processor</artifactId>
             <optional>true</optional>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
 ​
     <build>
         <finalName>personal-plan-server</finalName>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <annotationProcessorPaths>
                         <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                             <version>1.18.42</version>
                         </path>
                         <path>
                             <groupId>org.springframework.boot</groupId>
                             <artifactId>spring-boot-configuration-processor</artifactId>
                         </path>
                     </annotationProcessorPaths>
                 </configuration>
             </plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
 ​
 </project>

前端代码编写

主要依赖说明
package.json
 {
   "name": "personal-plan-web",
   "private": true,
   "version": "0.0.0",
   "type": "module",
   "scripts": {
     "dev": "vite",
     "build": "vite build",
     "preview": "vite preview"
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.2",
     "axios": "^1.13.2",
     "echarts": "^6.0.0",
     "element-plus": "^2.11.7",
     "lodash-es": "^4.17.21",
     "moment": "^2.30.1",
     "pinia": "^3.0.4",
     "sortablejs": "^1.15.6",
     "vue": "^3.5.24",
     "vue-router": "^4.6.3"
   },
   "devDependencies": {
     "@types/node": "^24.10.0",
     "@vitejs/plugin-vue": "^6.0.1",
     "sass": "^1.94.0",
     "vite": "^7.2.2"
   }
 }

仓库地址

gitee.com/meet-ui/xxx…

  1. 拉取代码

  2. 创建数据库,添加数据表结构

  3. 启动后端服务 image-20251217160344783.png

  4. 启动前端服务 image-20251217160403854.png

  5. 完成,后面开始写业务代码

后续

  • 之后每一篇会对应一个分支
  • 每一篇都会保证是可运行的服务,尽量是一个MVP,最小可行产品
  • 欢迎各位指正