news 2026/10/13 21:39:15

ThinkPHP新闻发布系统实战:MVC架构与UEditor后台开发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ThinkPHP新闻发布系统实战:MVC架构与UEditor后台开发

简介:基于ThinkPHP框架构建的新闻发布系统完整源码,同时覆盖前台展示与后台管理双端,面向初学PHP的开发者,也适合需要快速搭建内容型网站的项目参考。压缩包内共1117个文件,以414个PHP业务文件、503个GIF图形素材为主体,另有JS、CSS、HTML前端资源、SQL数据库脚本及框架配置文件,整体体积仅6.43MB,目录结构清晰,便于按功能模块浏览和二次开发。其中PHP文件覆盖控制器、模型与配置逻辑,前端资源用于页面渲染和交互,SQL脚本提供文章表、分类表等初始结构。内容完整涵盖文章发布、分类管理、UEditor富文本集成、图片上传、数据安全过滤等核心环节,并包含数据库设计表和基础模板,可帮助读者直观理解MVC模式下控制器、模型与视图的协作方式,也能从中学习ThinkPHP的路由配置、自动验证与缓存优化等实践技巧。已有4729人学习下载,适合作为PHP框架入门到实战的参考案例。

1. 一套 ThinkPHP 新闻发布系统:前台加后台,UEditor 富文本,半天就能改完

ThinkPHP 新闻发布系统,前台加后台,自带 UEditor 富文本编辑器,单看功能会以为只是又一个课程设计。真拿到手里会发现,它的价值恰恰在“结构清楚”:前台列表、详情、搜索,后台登录、栏目、发布、上传,全部按 MVC 拆好,改起来不用在十几份 PHP 文件里乱翻。适合三种人:刚学完 ThinkPHP 想找一个完整项目对照的人、要快速交付中小内容站的一线开发者、以及想弄明白前后台权限和富文本上传怎么串起来的人。与其自己从零搭,不如先把它跑起来再改。下面按我实际拆过的顺序,从结构、跑通、改后台到排坑,一条线讲完。

2. ThinkPHP + MVC 为什么适合做新闻站:功能闭环、目录结构与选型边界

2.1 新闻系统的最小功能闭环:从后台录入到前台展示要拆成哪几块

新闻系统的业务模型就两条线:内容生产和内容消费。内容生产是后台管理员登录、维护栏目、发布/编辑/上下线新闻;内容消费是前台用户打开列表页、详情页、搜索和分类页。一个完整的新闻发布系统,本质上是在这两条线之间管好“新闻”这个数据对象。

为什么要用 MVC 而不是直接写 PHP 页面?因为闭环里至少有三种角色在变:数据库表结构、后台操作流程、前台展示样式。用原生 PHP 把 SQL、HTML 写在一个文件里,第一次改很爽,第二次加需求就开始乱。ThinkPHP 的模块化 MVC 把这三件事分开:模型描述新闻和栏目的数据规则,控制器处理请求和跳转,模板只负责输出。后台的 NewsController 和前台 Home 模块里的 News 控制器分工,正好对应内容生产和消费两条线。

这套资源里最值得先看的是三张表:news 表存标题、正文、分类、缩略图、点击量、时间、状态;category 表存栏目名、父级 id 和排序;user 表存后台登录账号。只要把这三张表的关系看懂,整个系统的功能边界就清楚了。UEditor 只负责把新闻的富文本内容存进 content 字段,真正决定“存成什么样、展示成什么样”的,还是 MVC 三层各自的处理逻辑。

从选型上说,ThinkPHP 做这个体量的项目算“刚刚好”。它自带数据库操作封装、模板引擎、URL 路由和上传类,不用额外引入 composer 包就能用。如果换成纯框架骨架,需要自己装扩展;如果上更重的框架,对一个新闻站来说又显得杀鸡用牛刀。选型边界也在这:这套资源适合做中小内容站、企业展示站、课程设计,不适合做前后端完全分离的接口服务,也不适合做高并发资讯平台。

2.2 这套资源的目录分层:Home 模块、Admin 模块、Public 资源与 Runtime 缓存

拿到压缩包后,不要急着双击运行,先看目录结构。这套资源沿用 ThinkPHP 的标准模块化布局,Application 下通常分两个模块:Home 对应前台,Admin 对应后台。两个模块各自有 Controller、Model、View 三层目录,后台模板和前台模板互不干扰,这是后期好改的根本原因。

Application/ ├── Common/ │ └── Conf/ │ └── config.php # 全局数据库、URL 配置 ├── Home/ │ ├── Controller/ │ │ ├── IndexController.class.php │ │ └── NewsController.class.php │ └── View/ │ ├── Index/ │ └── News/ ├── Admin/ │ ├── Controller/ │ │ ├── LoginController.class.php │ │ ├── NewsController.class.php │ │ └── CategoryController.class.php │ └── View/ │ ├── Login/ │ └── News/ └── Runtime/ ├── Cache/ ├── Logs/ └── Temp/

这个目录至少说明三件事:第一,Common/Conf/config.php 是全局配置,数据库连接、URL 模式、默认模块都在这改,千万不要在每个控制器里单独写连接信息;第二,Home 和 Admin 是两个平行模块,前后台控制器可以存在同名类,因为命名空间和模块前缀把它们隔开了;第三,Runtime 目录是缓存和日志,权限不对会直接导致白屏或 500,部署时第一个检查它。

我一般在拿到任何 ThinkPHP 资源后,第一步不是改代码,而是先把 Runtime 目录清空、把缓存目录权限设成可写,再打开首页。很多所谓“项目跑不起来”的问题,八成是旧服务器的缓存目录残留和新环境不兼容。这套系统里前台模板编译缓存就存在 Runtime/Temp,后台的日志写在 Runtime/Logs,不清理干净,改模板半天没反应都不奇怪。

2.3 用 30 分钟确认项目能不能跑:环境检查与入口验证

这一步要动手做。先确认运行环境满足基础要求。这类新闻系统通常要求 PHP 5.4 以上、MySQL 5.5 以上,Apache 或 Nginx 都行。关键是几个扩展必须启用:pdo_mysql、mbstring、gd、curl。在项目根目录放一个临时检查文件,或者直接在命令行执行:

php -m | grep -E "pdo_mysql|mbstring|gd|curl"

如果四行都输出,扩展没问题。缺哪一个,就去 php.ini 里打开对应的 extension 并重启服务。gd 关系到缩略图和水印,curl 关系到可能用到的远程图片抓取功能,缺了可能某些页面不报错,但后台传图时表现怪异。

确认完环境,再确认入口。ThinkPHP 的入口文件一般是根目录的 index.php,它定义应用目录并启动框架。Apache 环境下可以直接访问首页看是否跳转到前台;如果出现“无法加载模块”之类的错误,先检查防伪静态配置。常见做法是在入口同级放 .htaccess 或使用 Nginx 的 try_files 规则,让所有请求都经过 index.php。URL_MODEL 设为 2 时依赖伪静态,本地能打开页面但链接带 index.php 反而是没配好。

打开前台首页,正常应该看到栏目导航和新闻列表,点进详情页 URL 形如 /index.php/News/detail/id/1.html。如果首页是空白,看 Runtime/Logs 下的日志;如果报控制器不存在,说明 Home/Controller 文件名或类名不一致。这套资源里类文件名是 XxxController.class.php,类名是 XxxController,大小写必须与引用一致,Linux 部署对这里尤其敏感。

3. 把系统跑起来:环境匹配、配置三处必改与前后台联调验证

3.1 环境版本与扩展要求:PHP 5.4+、MySQL 5.5+ 与常见扩展检查

上一章做过快速检查,这里再说几个容易忽略的版本细节。PHP 版本太新时,一些老写法会触发 Deprecated 提示,比如 mysql 相关函数在 PHP 7 以后被移除,但只要这套系统不走原生 mysql_ 连接,一般不受影响。真正常见的是 PHP 7.4 之后对“未定义数组索引”的提示变严,模板里直接读取空字段会打印警告,前台页面顶部多出一行报错文字。遇到这种,先把 PHP 的 display_errors 关掉,再打开 ThinkPHP 调试模式看日志,定位到具体模板行。

MySQL 版本方面,5.5 到 5.7 都能跑,但 8.0 上如果使用旧版驱动,可能报 caching_sha2_password 认证问题。解决方法是把数据库用户改成 mysql_native_password 认证,或者在连接配置里指定驱动。这块属于环境玄学,踩过一次后,我每次部署都会先查数据库版本,而不是上来就导数据。

扩展检查除了命令行的 php -m,还可以写一个临时探针页面:

<?php phpinfo();

页面里搜 pdo_mysql、mbstring、gd、curl 四个关键字,确认 enabled。服务器是虚拟主机时,看不到 php.ini 就找控制面板的“PHP 扩展管理”入口。还有一点:不要漏了 fileinfo 扩展,有些旧版本 ThinkPHP 的上传类依赖它做 MIME 检测,缺了会在上传时莫名报错,而且错误信息不直观。

3.2 数据库导入与 config.php:三处必改与一套检查 SQL

资源包一般带一份 .sql 文件,比如 news.sql。先用命令行或客户端导入,再改配置。命令行导入对大批量数据更稳,不容易出现“导入到一半客户端卡死”的问题。

mysql -uroot -p newsdb < news.sql

导入完成后,改 Application/Common/Conf/config.php:

return array( 'DB_TYPE' => 'mysql', 'DB_HOST' => '127.0.0.1', 'DB_NAME' => 'newsdb', 'DB_USER' => 'root', 'DB_PWD' => 'your_password', 'DB_PREFIX' => 'tp_', 'URL_MODEL' => 2, );

三处必改:DB_NAME、DB_USER、DB_PWD。DB_PREFIX 要和导入的 SQL 里表名前缀一致,默认是 tp_,如果导入时改成了其他前缀,这里必须同步。如果打开前台首页发现“表不存在”,先看报错里是哪个表名,再反推前缀是否一致。URL_MODEL 是 URL 模式,2 代表 PATHINFO 伪静态模式,如果本地没配伪静态,可以先设为 0 的兼容模式,保证项目先跑起来,等部署到线上再改回 2。

这里补一个检查 SQL,专门验证导入完整性:

USE newsdb; SHOW TABLES; DESC tp_news; SELECT COUNT(*) FROM tp_news;

如果 tp_news 字段和控制器引用对不上,说明导入不完整。很多“系统运行报错”其实在导入环节就已经埋下,尤其是客户端导入遇到外键或特殊字符中断,表结构残缺但报错提示不直接。

提示:改完 config.php 之后,务必清空 Runtime 下所有缓存文件,否则配置不会立即生效,这是最容易被忽略的一步。

3.3 前台路由与模板联动:列表页、详情页和搜索页怎么接上

运行起来后,前台首页会读取 news 表和 category 表。工作流程是:URL 进入入口 → 路由解析到 Home 模块的 Index/News 控制器 → 控制器调用模型查数据库 → assign 给模板 → 模板引擎输出。看到的是 HTML,但背后是完整的 MVC 数据流。

想要验证模板联动,直接在后台插入一条带富文本内容的新闻,然后看前台详情页。模板里典型的代码是这样:

<volist name="newsList" id="vo"> <li> <a href="{:U('News/detail', array('id'=>$vo['id']))}">{$vo.title}</a> <span>{$vo.add_time|date='Y-m-d',###}</span> </li> </volist>

这里 name="newsList" 对应控制器里$this->assign('newsList', $list)的键名;U 函数生成详情页 URL,array('id'=>$vo['id']) 是参数;{$vo.add_time|date='Y-m-d',###}是模板引擎的日期格式化写法,### 代表变量本身。如果不记得键名,模板什么都不会输出但也不报错,这是新手最困惑的地方,排查时先回头看控制器里 assign 的变量名。

搜索页的原理更简单:表单提交 keyword 到控制器,控制器用where("title LIKE '%$keyword%'")查库,列表模板不变,只多一个搜索入口。注意搜索词一定要经过 I('get.keyword') 过滤,否则 SQL 注入风险很大,ThinkPHP 的查询条件也建议用数组方式拼接,不要直接拼字符串。

3.4 后台操作全流程验证:登录、分类、发布、上传到上线

后台路径一般对应 Admin 模块的登录页。打开后输入 user 表里的账号密码,登录成功后进入管理界面。这里的一整套验证流程很有用:先新建一个栏目,再在该栏目下发布新闻,上传一张缩略图,保存后在详情页看缩略图和正文是否正常。

点发布时后台控制器会执行 insert 操作,字段通过 create() 过滤,add_time 通常由模型自动填充,或者控制器里手动 time()。这个过程可以验证三件事:数据库连接是否正常、上传目录是否可写、模板输出转义是否正常。如果后台发布成功但前台正文是空白,多半是 UEditor 内容被转义,详情页模板里对 content 字段做了 htmlspecialchars 处理,需要改成原样输出或使用专门的过滤函数。

后台跑通后,顺手把伪静态规则也配了。Nginx 下常见配置是:

location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; break; } }

这段规则的意思是:当请求的文件或目录不存在时,把整个请求交给 index.php,并把它作为 PATHINFO 参数处理。Apache 则用 .htaccess 里的 RewriteRule 实现同样效果。配置完记得重启 Nginx,并清空 Runtime 缓存,然后重新访问前台页面,看链接是否已经去掉 index.php。

4. 后台实战:UEditor、模型关联与栏目管理的可复用写法

4.1 控制器里的增删改查:I() 过滤、U() 跳转与状态上下线

后台开发最频繁的是增删改查。ThinkPHP 里D('News')和M('News')有区别:M 是基础模型,D 会加载 NewsModel 并执行里面定义的自动验证。这个资源里如果只是简单改数据,用 M 就够;要接自动验证就改成 D。实际操作中大多数情况下用 D 更稳:

public function update() { $model = D('News'); $data = $model->create(); if (!$data) { $this->error($model->getError()); } $data['update_time'] = time(); $result = $model->save($data); if ($result !== false) { $this->success('更新成功', U('News/index')); } else { $this->error('更新失败'); } }

create() 会按模型里定义的字段和验证规则处理 POST 数据,比直接M('News')->save(I('post.'))安全。save 返回的是受影响行数,如果内容完全没改动,返回 0,所以判断要用!== false而不是> 0。U('News/index') 生成后台列表 URL,success 方法会输出提示并跳转。

这里有个安全习惯值得养成:后台列表的控制方法开头要校验登录态,通常是在 Common 控制器里写一个_initialize()判断 session,后台控制器继承它。不要在每个方法里重复写验证代码,那样漏掉一个就等于漏了一个入口。状态上下线也简单,一个 update 把 status 字段改成 0 或 1 就行,别直接删除数据,运营时后悔药很重要。

4.2 UEditor 富文本接入:serverUrl、上传目录与输出时的转义边界

UEditor 是这套系统里最影响体验的部分。官方默认的编辑器有很多配置项,但直接引入多半有上传问题。核心配置是 serverUrl,它指向后端上传处理接口:

var ue = UE.getEditor('container', { serverUrl: "/index.php?s=/Admin/Ueditor/upload", initialFrameHeight: 400, initialFrameWidth: '100%' });

正常情况下,上传图片时编辑器会把 multipart 表单 POST 到 serverUrl,后端返回 JSON 格式的 url/error 信息,编辑器再根据返回值插入图片。后端接口要处理上传目录、命名和类型过滤。常见做法是把图片存到 Public/uploads/ueditor/ 下,并按日期分目录。

这里有个很隐蔽的点:UEditor 返回的图片地址如果是相对路径,前台模板输出时要拼上域名或站点根目录;如果是绝对路径,迁移服务器后图片会 404。我一般会在后端把 url 返回成以 / 开头的根相对地址,这样换域名不用改数据库。正文输出时,不要把 content 直接 htmlspecialchars 转义,那样会把<img>和<p>显示成源码;但也不能完全裸输出,如果系统开放了投稿权限,必须在保存时做白名单过滤,把 script、iframe、onerror 属性全去掉。

4.3 栏目无限级分类:pid 递归成树与面包屑数组

栏目表里的 pid 字段就是无限级分类的核心。后台添加子栏目时选择父级,存储 pid;前台按 pid 分组展示。如果想做二级或多级栏目,可以写一个递归函数:

function buildTree($list, $pid = 0, $level = 0) { $result = array(); foreach ($list as $item) { if ($item['pid'] == $pid) { $item['level'] = $level; $result[] = $item; $result = array_merge($result, buildTree($list, $item['id'], $level + 1)); } } return $result; }

这个函数的核心是“在剩余节点里找当前节点的子节点”。level 用来做后台下拉的缩进,也可以顺便生成面包屑。数据量只有几十个栏目时,递归性能完全没问题;如果栏目到几千个,再考虑用预排序树算法,那另当别论。

后台栏目管理常见还有一个排序字段 sort,查询时 ORDER BY sort ASC, id ASC,排序数字越小越靠前。别把 sort 只当成摆设,改排序比改标题更容易出小问题。前台导航的栏目顺序、首页的栏目块顺序,基本都靠这个字段控制。

4.4 把站点信息做成可配置项:首页条数、轮播开关、标题后缀

开发后台时会遇到一个需求:首页显示多少条、后台的轮播开关、每个页面的 title 后缀,不想每次进代码里改。这套资源最常见的做法是写在 Common/Conf/config.php 或额外建一张配置表。我建议用配置表,因为这样可以在后台界面改,不用碰代码。

config.php 里可以加:

'NEWS_LIST_NUM' => 10, 'SITE_TITLE' => '某某新闻站', 'SWITCH_CAROUSEL' => true,

控制器里读取 C('NEWS_LIST_NUM'),模板里可以直接用 C 函数或 assign 到变量。把配置放在一个地方的价值是交付时很好交接:对方不用懂代码,改首页条数和站点标题只动一处。这个点看似简单,但很多新手会把数量写死在模板里,导致每个列表页的条数要单独改,后面删起来很痛苦。

5. 常见问题排查:四组真实报错与修复顺序

5.1 后台登录跳转后是空白页:Runtime 与 SESSION 的双重夹击

现象:后台输入账号密码后提示成功,跳转到管理首页却是完全空白,前台反而正常。 原因:后台控制器依赖 session,而 Runtime 目录不可写,或 PHP 会话目录权限不对。ThinkPHP 的 session 默认写到服务器临时目录,某些虚拟主机临时目录权限受限;同时 Runtime/Cache 不可写也会让模板编译失败,默认错误页被吞掉后就是白屏。 解决:先把 Application/Runtime 整个目录权限设为 775 或 777,再在 config.php 里检查 session 配置。如果还没好,打开调试模式或看 Runtime/Logs 下的日志,定位到具体提示。不要一上来就重装系统,这类问题九成是目录权限。

5.2 UEditor 上传图片返回 404:serverUrl、伪静态与上传目录权限

现象:点击上传图片,编辑器里没有插入图片,Network 面板看到请求失败,有时直接 404。 原因:多半是 serverUrl 写错,指向了不存在的控制器方法;或者伪静态规则没覆盖到上传接口;或上传目录不可写导致后端返回错误。 解决:先用浏览器直接访问 serverUrl,看是否能正常返回 JSON。不能返回就检查 URL 规则和控制器方法名;能返回再检查 uploads 目录权限。把上传目录和 Runtime 目录一起设为可写,就可以排除权限问题。上传接口返回的 JSON 格式也要盯一眼,UEditor 2.x 要求返回{"state":"SUCCESS","url":"..."},state 字段拼错,编辑器一样不认账。

5.3 样式和图片全部丢失:模板路径写法和入口 URL 的配合

现象:本地用 /index.php 访问正常,部署后用伪静态访问页面,CSS 和图片路径全部 404;或者页面 HTML 出来了,但静态资源带的是绝对路径不匹配。 原因:模板里如果写死了 /Public/xxx 或用了相对路径,在伪静态 URL 下相对路径会被解析到当前控制器路径,导致找不到资源。Nginx/Apache 的 rewrite 只重写伪静态请求,静态文件请求没被正确交给对应目录。 解决:模板里尽量用ROOT或 PUBLIC 常量拼资源地址,例如__ROOT__/Public/css/style.css。部署时检查 .htaccess 或 Nginx 的 location 规则,确保 /Public/ 物理目录直接访问,不经过 rewrite。这个坑经常出现在“本地一切正常,一上服务器就裸奔”的场景里,排查顺序先看页面源码里的 CSS 地址,再顺手点进去看 404 还是 403。

5.4 数据库导入报错或字段对不上:MySQL 版本与 sql_mode 适配

现象:导入 .sql 文件时报“字段长度”或“默认值”错误,或者导入成功,但后台保存时间字段全是 0000-00-00 导致详情页格式化出错。 原因:MySQL 5.7+ 默认启用 strict 模式,对零日期和空字符串校验更严格。旧项目导出的 SQL 里时间字段可能用了 0000-00-00 这样的默认值,新库直接拒绝。 解决:临时把当前会话的 sql_mode 调整为兼容模式,然后重新导入:

SET sql_mode = '';

导入完再恢复服务商的默认配置。如果控制不了数据库全局配置,就把 SQL 文件里的时间默认值改成合法的 NULL 或当前时间戳,再导入。这类问题表面上是“数据库导入错误”,实际上大多是版本差异引起的,排查时先看 sql_mode 再找别的原因。

6. 再进一步:换模板时的高亮、分页与 URL 重写三件事

6.1 导航高亮:当前操作名与菜单标识对比

把默认模板换成自己的模板后,最容易出现导航高亮不对。传统做法是在公共头部模板里比较当前控制器名:

<a href="{:U('Index/index')}" class="{:CONTROLLER_NAME=='Index'?'active':''}">首页</a> <a href="{:U('News/lists')}" class="{:CONTROLLER_NAME=='News'?'active':''}">资讯</a>

这样首页、资讯页分别高亮。如果导航是从数据库栏目循环出来的,就需要在控制器里把当前栏目 id 传进去,在循环里做判断。

6.2 分页参数:Page 类与翻页 URL 的固定写法

换模板时,分页样式也会丢。ThinkPHP 的分页一般是控制器里查总数、实例化分页类、limit 查询,然后把 page 变量 assign 给模板。注意翻页 URL 里的参数名默认为 p,如果伪静态规则里有冲突,需要显式指定参数名。最容易翻车的点是:列表页第一页正常,点击第二页 404,基本是 rewrite 规则没有把 p 参数传给 index.php,在 Nginx 里要注意 rewrite 的尾参处理。

6.3 伪静态与路由规则:让链接既短又能被收藏

最后说一下 URL 重写。这一套系统默认用 PATHINFO 模式,链接形如 /index.php/News/detail/id/1。上线时去掉 index.php 后,Apache 下面放 .htaccess 即可,Nginx 用前面给过的 rewrite 规则。如果后续要 SEO 友好的 .html 后缀,把 URL_ROUTE_RULES 配置一下,把 /News/detail/id/1 映射成 /news/1.html。规则是一次性的,配完要清 Runtime 缓存,否则旧路由缓存一直生效,看似改了实则没改。

我之前交付模拟项目X时,换模板只改了头部和 CSS,忘了分页参数与伪静态,结果页面样式全对但翻页全 404,最后花了一晚上把三处问题排查完。从那以后每次更换模板,我都强制自己走一遍“高亮—分页—伪静态”三件套,先把这三处确认完再调样式,折腾成本低很多。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 21:37:34

C++ Primer Plus第11章编程练习答案:运算符重载、友元与类型转换全解

如果你正在啃《C Primer Plus》&#xff0c;第11章编程练习绝对是你遇到的第一道真正需要“憋一口气”才能写完的关卡。这一章的主线非常集中&#xff1a;运算符重载、友元函数、类的自动类型转换。练习数量不算多&#xff0c;但几乎每一道题都在逼你把“类”当成一种自带行为的…

作者头像 李华
网站建设 2026/10/13 21:36:59

车机CarPlay插件集成指南:四通道架构、调参与量产避坑

简介&#xff1a;面向iOS车载开发者的CarPlay通信插件源码包&#xff0c;内含Apple CarPlay Communications Plugin的轻微修改版&#xff0c;聚焦iPhone与车载多媒体系统之间的数据互通&#xff0c;覆盖音频流、导航指令、电话、短信等关键链路&#xff0c;既适合初学CarPlay架…

作者头像 李华
网站建设 2026/10/13 21:36:38

从CRUD到领域拆分:后端模块化架构演进之路

做后端开发这几年&#xff0c;我最大的感触是&#xff1a;大部分项目并不是被业务复杂本身压垮的&#xff0c;而是被没有跟着业务一起演进的结构拖垮的。CRUD 写起来很爽&#xff0c;一个控制器、一个服务、一个数据访问接口&#xff0c;数据库表一映射&#xff0c;接口一铺开&…

作者头像 李华
网站建设 2026/10/13 21:35:58

SSM+Java社团管理系统:2026毕设选题与全流程解析

每年到了三、四月份&#xff0c;我都会被一批又一批做毕业设计的同学问到同一个问题&#xff1a;毕设题目选什么&#xff1f;在我这几年看到的题目里&#xff0c;SSM Java 社团管理系统几乎是出现频率最高的一个。为什么大家都选它&#xff1f;因为这类系统技术上不冷门、业务…

作者头像 李华
网站建设 2026/10/13 21:33:26

自制桌面收纳系统aa---(10):需求、选材与实测全解析

这套作品被我在工作文件夹里记成aa---(10)&#xff0c;起因比较随意。当时连续做了九个版本的桌面整理系统&#xff0c;每个版本都只是在原结构上加加减减&#xff0c;命名一直用 AA 做主键再加版本号&#xff0c;做到第十版的时候&#xff0c;改动范围明显超过了小修的界限&am…

作者头像 李华
网站建设 2026/10/13 21:30:49

用官方能力把PS5打造成家庭媒体中心:AnyPS5完整折腾指南

“AnyPS5”这个项目名&#xff0c;说白了就是让手里那台PS5不再只当游戏机用。很多玩家买回来就只玩几个大作&#xff0c;时间一长积灰吃灰&#xff0c;完全没意识到这台机器本身就是一台性能不错的家庭娱乐主机。这个项目就是把它的闲置能力盘活&#xff1a;本地视频随便放、各…

作者头像 李华