如何开发一个JavaWeb项目
1、确定需求
需求是本人自己想的,不必深究合理性,只是为了让开发过程尽量完整,如果需求不明确影响代码编写的话再补充描述。主要需求如下
- 定制目标,目标分为愿景目标(终身目标)、长期目标(5~10年)、近期目标(3年)
- 根据目标拆解为年度计划或者专项计划
- 根据年度计划拆解制定季度、月度、每周计划
- 根据每周计划制定每日任务
- 番茄时钟(目前无具体业务,先做埋点,用于统计)
- 数据统计,统计目标进度、计划进度、任务完成情况等
- 每周或者每月进行一次复盘
2、界面设计
计划开发以下几个页面,每个页面里面具体功能
- 仪表盘:总览今日待办任务、本周进度、目标完成情况、快速操作(新增目标、计划、任务)、工作效率统计。
- 目标中心:所有目标的列表和看板视图,新增目标。
- 计划日历:以日历形式展示任务的月视图、周视图、日视图以及计划列表,新增计划。
- 每日待办:极简的每日任务执行界面,包括今日待办,今日已完成任务,今日统计,番茄钟计时器,新增任务。
- 数据统计:图表化展示任务完成率、投入时间、计划进度等统计数据。
- 复盘:查看历史复盘报告,新增复盘。
3、技术栈选型
- 后端:SpringBoot3 + JDK 17
- 前端:NodeJS22 + Vue3 + Vite7 + ElementPlus
- 数据库: MySQL8、Redis
- 部署:Docker
4、数据库设计
数据库设计要点
- 根据业务情况选择主键类型,数字递增,UUID,雪花主键等等,一般选择UUID即可
- 业务字段选择合理的长度、精确度
- 一般业务表都应包含创建时间、修改时间、创建人、修改人,逻辑删除之类
- 字段加上注释,列出枚举值,设定默认值
- 表加上注释
- 一般设计表初期也会考虑添加索引,这里暂且都不考虑,后续尝试性能调优再加
- 一般情况下不建议使用外键,不建议使用存储过程、函数
数据表结构
数据库设计如下,具体需求也可从数据表结构分析出一二。
-
目标表
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='目标'; -
计划表
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='计划表'; -
任务表
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='任务表'; -
复盘记录表
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='复盘记录表'; -
番茄钟记录表
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>
前端代码编写
主要依赖说明
- vue:渐进式JavaScript 框架(Vue.js - 渐进式 JavaScript 框架 | Vue.js)
- vue-router:Vue.js 的官方路由(Vue Router | Vue.js 的官方路由)
- pinia:Vue.js 状态管理库(Pinia | The intuitive store for Vue.js)
- axios:一个基于 promise 的网络请求库,可以用于浏览器和 node.js(Axios中文文档 | Axios中文网)
- element-plus:基于 Vue 3,面向设计师和开发者的组件库(一个 Vue 3 UI 框架 | Element Plus)
- echarts:一个基于 JavaScript 的开源可视化图表库(Apache ECharts)
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"
}
}
仓库地址
-
拉取代码
-
创建数据库,添加数据表结构
-
启动后端服务
-
启动前端服务
-
完成,后面开始写业务代码
后续
- 之后每一篇会对应一个分支
- 每一篇都会保证是可运行的服务,尽量是一个MVP,最小可行产品
- 欢迎各位指正