资讯动态

SpringBoot+Vue获奖作家信息管理系统:数据库设计与前后端分离实战解析

发布时间:2026/10/22 4:16:52 来源:尧图企业网站定制
1. 项目由来与整体定位这个系统是从一个很实际的需求出发的出版社要做一个内部使用的当代获奖作家信息库便于编辑约稿时快速查作者、看获奖记录、理清作品脉络。但市面上的图书管理系统、作者百科都是面向读者的展示型产品对编辑工作来说一是太杂二是没有获奖维度没法一眼看出某位作家的奖励层级和履历全貌。所以就有了这个“当代中国获奖知名作家信息管理系统”——本质上是一个垂直领域的内容管理后台把获奖作家、获奖记录、代表作品这三块核心数据统一管起来。技术栈选择上SpringBoot负责后端接口与业务逻辑Vue负责前端页面交互MySQL存数据MyBatis管数据访问。这套组合在中小型管理系统里非常成熟能快速落地、便于二次开发。我见过太多项目用更重的框架结果人力和维护成本全耗在框架本身业务逻辑反而没时间打磨。这个项目把技术锁定在Java生态最常用的一套组合上目的就是让代码易读、易改、易交接尤其适合毕设展示或者作为企业内部工具快速上线。系统解决的核心问题有三块一是作家基础档案的数字化管理二是个性化获奖记录的维护与查询三是作品信息与作家、获奖记录之间的关联检索。配合后台登录、权限控制、数据统计等功能算是把一个信息管理系统的完整闭环做出来了。适合参考这份设计的人我认为有三类正在做管理类毕设的同学尤其SpringBootVue方向的、想搭建内部作者库或内容库的团队、以及想看看经典SSH式项目如何在SpringBoot时代重新组织代码结构的开发者。下面我把每个关键环节的设计思路和踩坑点都摊开讲。2. 整体架构设计为什么是前后端分离以及模块怎么拆2.1 前后端分离的决策逻辑很多人在做管理系统时会犹豫到底用JSP模板一把梭还是前后端分离这个项目选择了后者核心原因是系统里有大量动态交互需求——筛选作家、联动查询获奖记录、实时展示统计数据。如果按传统方式在服务端渲染页面每次筛选都要刷新整页体验差代码也会随着页面增多变得很难维护。前后端分离以后后端只暴露RESTful接口前端用Vue通过Axios请求数据各管各的。后端不需要关心页面长什么样前端也不需要碰Java代码。这样一来想给系统换皮肤、加页面、改交互都只动前端就行想换数据库、调接口逻辑也只动后端即可。开发阶段甚至可以前后端并行开工效率差距很明显。架构上还要考虑的一个问题是这个系统未来会不会被外部系统对接答案是很有可能的。出版社内部往往有OA、编务系统作者库如果做成纯JSP页面第三方要拿数据只能靠爬虫。改成前后端分离后后端接口天然就是一套API对接成本从“想办法抓页面解析”降为“直接调接口”。这是一个很容易被忽略、但对长期价值影响很大的架构红利。2.2 功能模块划分系统整体按业务领域拆成几个独立模块每个模块对应一组接口和一组前端页面。我整理一下实际落地的模块清单作家档案管理作家基本信息姓名、笔名、性别、籍贯、出生日期、文学流派、简介等的增删改查。获奖记录管理记录作家获得的文学奖项名称、获奖年份、颁奖机构、奖项级别等信息一个作家对应多条获奖记录。代表作品管理作家代表作品的名称、类型、出版年份、出版社等与作家关联。系统登录与用户管理登录认证、用户增删改查、角色权限控制把管理员和普通编辑的权限分开。数据统计看板按获奖级别、文学流派、地域等维度统计作家数量前端用图表方式展示。模块划分遵循的原则是每个模块高内聚模块之间通过作家ID这一外键关联尽量少做跨表复杂耦合。比如获奖记录和作品都属于作家的从属数据操作入口放在作家详情页内既符合编辑的工作习惯也让代码分层更清晰。2.3 技术选型的细节账单框架选型看起来是常识但每一项背后都有实际理由这里补一个细节账SpringBoot 2.x系列稳定、资料多、兼容性好。能用内嵌Tomcat把应用打成单JAR包直接跑不需要额外装Tomcat。对部署环境极其友好。MyBatis MySQLSQL由开发者控制适合这个系统里中等复杂度的关联查询。MySQL选择5.7以上版本注意字符集用utf8mb4不然存生僻字或特殊符号会出乱码问题。Vue全家桶Vue 2 Vue Router Vuex Element UI页面组件化表格、表单、弹窗都是现成组件开发效率很高。管理系统这个场景用Element UI几乎是最省力的选择。Maven多模块管理按common、domain、mapper、service、controller分层让依赖关系清晰不会出现互相引用的混乱。这套选型的核心思想就是“用最短路径解决业务问题”。框架只是工具把编辑从Excel表格里解放出来才是目的所以在选型上一切以务实为主。3. 数据库设计信息管理系统的地基怎么打3.1 核心表结构与字段设计数据库设计是整个系统最不该省时间的部分。一个信息管理系统如果表设计得烂后面写多少代码都是在打补丁。我常用的思路是先理清实体关系再定字段最后考虑索引和扩展字段。这个系统的核心实体是“作家”。围绕它设计了四张主表作家表writer主键id、姓名、笔名、性别、出生日期、籍贯、文学流派、个人简介、头像URL、创建时间、更新时间。获奖记录表award_record主键id、作家id、奖项名称、颁奖机构、获奖年份、奖项等级、备注。作品表work主键id、作家id、作品名称、作品类型、出版年份、出版社、作品简介。用户表sys_user主键id、用户名、密码加密存储、真实姓名、角色、状态。从字段设计里能看到几个关键决策第一性别、文学流派这类字段不要直接存中文。比如流派用字典值“novel”“poetry”“prose”页面显示时再转中文。原因是后续做统计时需要按流派分组存英文编码更便于查询和维护。第二获奖等级字段设计成可排序的类型。如果奖项等级有国家级、省部级、其他等层级建议用整数存储3代表国家级2代表省部级1代表其他这样按奖项重要性筛选时就只需要一个范围查询。第三所有表都加创建时间和更新时间这是管理系统的基本素养。出问题排查时能知道数据是何时写入的责任人是谁。下面是作家表和获奖记录表的建表SQL可以直接参考CREATE TABLE writer ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID, name varchar(50) NOT NULL DEFAULT COMMENT 姓名, pen_name varchar(50) DEFAULT NULL COMMENT 笔名, gender tinyint(1) DEFAULT 0 COMMENT 性别 0未知 1男 2女, birth_date date DEFAULT NULL COMMENT 出生日期, native_place varchar(100) DEFAULT NULL COMMENT 籍贯, genre varchar(20) DEFAULT NULL COMMENT 文学流派编码, intro text COMMENT 个人简介, avatar_url varchar(255) DEFAULT NULL COMMENT 头像地址, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_genre (genre), KEY idx_name (name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT作家信息表; CREATE TABLE award_record ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID, writer_id int(11) NOT NULL COMMENT 作家ID, award_name varchar(100) NOT NULL DEFAULT COMMENT 奖项名称, award_org varchar(100) DEFAULT NULL COMMENT 颁奖机构, award_year year DEFAULT NULL COMMENT 获奖年份, award_level tinyint(1) DEFAULT 1 COMMENT 奖项等级 1其他 2省部级 3国家级, remark varchar(255) DEFAULT NULL COMMENT 备注, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_writer_id (writer_id), KEY idx_award_year (award_year) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT获奖记录表;3.2 为什么给外键字段建立单独索引这里有一个新手容易忽略的细节外键字段一定要手动加索引。就拿获奖记录表来说最频繁的操作是按作家ID查询获奖列表也就是执行select * from award_record where writer_id ?。如果没有 idx_writer_id 这个索引MySQL会做全表扫描数据量小的时候没感觉数据到了几十万条之后查询速度会明显变慢。实战中我还遇到过一种情况某个作家有上百条获奖记录在后台编辑页面加载作家列表时需要统计每个作家的获奖数量。子查询里用count(*)配合索引响应时间可以控制在几十毫秒以内这个体验差异从用户端是很容易感知的。所以建表阶段就把索引规划好比上线后到处找慢查询再去补索引成本完全不是一个量级。3.3 扩展字段与冗余设计信息管理系统有个通病需求总是会变。今天加一个“微信读书作者主页链接”明天加一个“获奖证书扫描件”。这类字段如果业务刚开始就频繁改表一是麻烦二是容易影响已在运行的功能。我在这套系统里加了一个通用扩展思路在作家表上预置一个JSON扩展字段用来存放一些暂时没转正的自定义信息。MySQL从5.7版本开始支持JSON类型查询时可以用函数直接提取内容相当方便。比如当前只存了“创作领域”“创作风格”两个临时扩展条目后续要转正成正式字段时只需要写一次数据迁移脚本把JSON里的值抽到新列里就行了。这里强调一下JSON扩展字段是“桥”不是“家”。真正重要的、需要频繁按条件筛选的数据还是必须正经建列并加索引。JSON字段只应该用来过渡那些还看不清楚需求的数据免得每次需求一变就改表延误迭代节奏。4. 后端核心实现分层架构与关键接口4.1 分层架构与请求流转路径后端代码按经典四层结构组织每一层各司其职Controller层负责接收HTTP请求参数校验调用Service返回统一结构。Service层处理业务逻辑事务控制组合Mapper调用。Mapper层Dao层基于MyBatis定义数据访问接口和SQL映射。Domain层实体类、DTO、查询参数对象。一个典型请求的流转路径是页面发起请求 - Controller接收参数 - Service执行业务逻辑 - Mapper执行SQL - 结果逐级返回 - Controller包装成统一JSON - 前端渲染。这套分层设计的好处非常直接每一层的职责单一出了问题能迅速定位。比如查询作家列表发现SQL报错只需要打开Mapper文件检查XML语法发现统计逻辑不对只需要检查Service层。对于后续接手这个项目的人来说结构越规整上手成本就越低。4.2 统一返回结构与全局异常处理前后端分离项目中接口返回格式统一是基本素养。我在这套系统里定义了一个Result对象包含三个核心字段code状态码、message提示信息、data业务数据。所有接口都返回这个结构前端Axios拦截器统一判断code省去了每个页面的重复错误处理。public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(String message) { ResultT result new Result(); result.setCode(500); result.setMessage(message); return result; } }全局异常处理用RestControllerAdvice把参数校验异常、业务异常、系统异常统一拦截。这样Controller里只管正常流程出现异常时用户看到的是“参数格式不正确”“该作家已被删除”这类业务化提示而不会看到一堆英文堆栈信息。4.3 作家分页查询接口与MyBatis动态SQL作家列表是这个系统的核心页面接口必须支持多条件组合筛选和分页。常见的筛选条件包括姓名关键词、文学流派、获奖级别、性别。如果对每个条件都写一个独立的查询方法代码会非常臃肿。这里用MyBatis的动态SQL来组装查询条件是最实用的方案。Mapper接口定义如下public interface WriterMapper { ListWriterDO selectWriterPage(Param(query) WriterQuery query); Long countWriter(Param(query) WriterQuery query); }对应的XML映射核心片段select idselectWriterPage resultTypecom.example.domain.WriterDO SELECT w.id, w.name, w.pen_name, w.gender, w.birth_date, w.native_place, w.genre, w.intro, w.avatar_url FROM writer w where if testquery.name ! null and query.name ! AND (w.name LIKE CONCAT(%, #{query.name}, %) OR w.pen_name LIKE CONCAT(%, #{query.name}, %)) /if if testquery.genre ! null and query.genre ! AND w.genre #{query.genre} /if if testquery.awardLevel ! null AND EXISTS ( SELECT 1 FROM award_record a WHERE a.writer_id w.id AND a.award_level #{query.awardLevel} ) /if /where ORDER BY w.update_time DESC LIMIT #{query.offset}, #{query.limit} /select这里有三个细节特别注意第一每页大小用 limit不要允许前端随意传一个万级的分页参数需要做最大值限制。很多接口被恶意刷就是因为参数没有约束。第二时间排序用 update_time 而不是 create_time这样编辑过信息的作家会排在前面编辑体验更合理。第三用模糊查询时注意使用CONCAT(%, #{query.name}, %)而不是在Java代码里拼好再传参这样是为了防止SQL注入MyBatis预编译参数才会生效。4.4 获奖记录主从联动的事务处理作家详情页有一个常见功能修改作家信息的同时批量更新获奖记录。比如新增两条获奖记录、修改一条、删除一条一次接口完成提交。这种场景必须用事务保证数据一致性。我在Service层加上Transactional(rollbackFor Exception.class)然后按“先删后插”的策略处理接收一个获奖记录列表先把该作家的旧记录全部删除再批量插入新列表。这样做的好处是逻辑简单不容易出现逐条对账的遗漏和错位。有人可能会问先删后插如果删除成功但插入失败怎么办这正是事务发挥作用的地方。任何一个步骤抛异常数据库都会回滚到操作前的状态不会出现数据半新半旧的情况。批量插入用MyBatis的foreach标签一次SQL插入多条记录减少数据库连接往返次数。数据量在几十条以内时性能非常好。4.5 登录认证与密码加密用户登录模块不能存明文密码这是底线。项目采用BCrypt加密算法存储用户密码。BCrypt的优点是每次生成哈希时自动加盐相同的密码加密出的结果都不同即使数据库泄露也不能通过撞库逆推出用户明文密码。登录时流程为根据用户名查出用户记录用BCrypt校验密码校验通过后生成一个UUID作为会话标识存到Redis或内存Map里。考虑到管理系统并发量不高这里直接使用内存Session方式配合Spring Boot自带的Session管理简单可控。对于权限控制我用拦截器检查请求头中的Token信息。未登录时统一返回提示前端路由器配合拦截响应跳回登录页。4.6 数据统计看板的SQL思路统计看板包含几个维度的数据获奖级别分布、流派分布、地域分布、每年获奖数量趋势。这些统计查询本质上是同一类“分组计数”问题。例如按流派统计作家数量SQL如下SELECT genre, COUNT(*) AS cnt FROM writer GROUP BY genre ORDER BY cnt DESC;获奖数量按年份趋势的SQL则是SELECT award_year, COUNT(*) AS cnt FROM award_record WHERE award_year IS NOT NULL GROUP BY award_year ORDER BY award_year ASC;这类统计不要在Java内存里做直接交给MySQL的GROUP BY性能最优。前端拿到标准的结构化数组后用ECharts渲染成饼图和折线图即可。图表库的选型也可以换但ECharts在中文文档、社区案例方面优势明显几乎不用怎么学就能做出规整的看板。5. 前端核心实现Vue页面与交互细节5.1 前端目录结构与路由划分前端采用Vue CLI创建标准工程目录按模块分开管理src/api/所有接口定义统一封装Axios实例。src/router/路由配置带登录鉴权守卫。src/store/Vuex状态管理保存用户信息和菜单状态。src/views/页面组件按功能模块分成子目录。路由设计时/login和/dashboard等页面区分开。在全局前置守卫中检查Token如果访问的不是登录页且没有Token重定向到登录页如果已登录且再次访问登录页重定向到首页。这是非常基础但不可或缺的导航守卫逻辑。5.2 作家列表页与筛选表单的实现思路作家列表页是前端最复杂的页面由三部分组成筛选表单区、数据表格区、分页区。筛选表单用Element UI的Form组件包含姓名输入框、流派下拉框、获奖级别下拉框、查询按钮和重置按钮。点击查询时取表单数据作为参数调用后端分页接口每次查询后重置页码为1。表格区的列配置包括姓名/笔名、性别、出生日期、籍贯、流派、操作编辑和删除按钮。流派的显示用字典翻译函数后端返回的是编码前端映射成中文既方便展示也方便筛选。操作按钮上我加了一条很实用的规则删除操作必须二次确认。用this.$confirm弹窗提示“确认删除该作家吗删除后不可恢复”用户点击确认后才发送删除请求。这是管理系统里防止误操作的基本防护绝对不能省。另外一个容易踩的坑性别字段返回的是0/1/2数字如果直接绑到表格里就会显示成数字。正确做法是在表格列上用formatter函数把数字转成中文。我见过不少新手在这里卡很久才发现是忘记写翻译函数。5.3 作家详情编辑页的主从表联动作家编辑页是另一个复杂页面需要同时维护作家基本信息、获奖记录列表、作品列表三块数据。页面上方是基础表单下方是两个Tab选项卡获奖记录和代表作品。每次编辑获奖记录时都用对话框模式新增或修改一条记录保存整个页面时把作家信息、获奖记录列表、作品列表三组数据一起提交到后端。这个联动方案的代码实现其实不难核心是用Vue的reactive数据对象维护两个数组再在同一套提交逻辑里打包给后端。但交互逻辑要想清楚获奖记录的改动不能直接写库等用户点了整页保存才统一提交。这才符合编辑的使用预期——在一个页面里把作家的所有资料一次改完。5.4 上传头像与文件静态资源处理作家头像上传在管理系统中属于常见需求。实现时要注意前端通过el-upload组件选择图片上传接口写在后端保存到本地磁盘的某个上传目录并把访问URL返回给前端随后写入作家记录。这里有一个默认的坑Spring Boot的静态资源默认只映射classpath:/static/如果图片传到本地磁盘的某个非classpath路径直接通过URL访问会404。我处理的方式是在配置类里注册一个资源映射器Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceHandler(file: uploadDir); } }这样img src/upload/xxx.jpg就能正常访问了。另外要注意上传文件的命名规则我是用UUID 原始文件名后缀来重命名避免中文文件名和重名问题。5.5 权限控制在前端的配合后端做了权限校验前端也要做菜单和按钮级别的权限控制。登录成功后后端返回当前用户的角色信息前端根据角色判断显示哪些菜单。这个系统只有管理员和普通编辑两种角色逻辑相对简单管理员可以删除作家和重置用户密码编辑只能录入资料和查看信息。按钮的显隐用一个简单的指令判断当前角色即可比如立一个v-has-roleadmin的自定义指令。这样前端做了第一层过滤后端接口再兜底校验双保险。6. 部署与运行从源码到可用系统的完整过程6.1 本地开发环境准备要完整跑起这套系统环境清单如下JDK 1.8以上推荐8或11。Maven 3.6以上。MySQL 5.7以上。Node.js 12以上。IDE推荐IDEA前端页面用VS Code也可以但一个IDEA搞定前后端问题不大。数据库初始化方面提供一份完整的SQL脚本包含建库、建表、插入初始化用户admin/123456和演示数据。拿到后端源码后只需要修改application.yml中的数据库连接账号密码和上传目录路径就可以启动后端服务。6.2 前后端联调与最后配置前端开发环境通过Vue CLI的代理服务器解决跨域问题。配置vue.config.js中的 devServer.proxy把/api前缀的请求转发到后端服务地址。正式部署时则让Nginx把前端静态资源目录当作站点根目录并把/api反向代理到后端服务端口。这样要求前端所有接口请求统一带/api前缀后端Controller通过server.servlet.context-path/api来匹配。联调阶段最容易被忽视的是接口字段名不一致。后端返回updateTime前端用的却是update_time结果页面死活不显示更新时间。我在项目里统一用了驼峰命名规范同时设置MyBatis的map-underscore-to-camel-case: true让数据库的下划线字段自动映射成驼峰属性从源头避免这类问题。6.3 打包部署的两种姿势后端部署用Maven执行clean package生成一个可执行JAR包直接跑java -jar xxx.jar启动。如果想要正式一点用 systemd 注册成服务实现开机自启和崩溃重启。前端部署npm run build生成dist静态目录把这整个目录放到Nginx站点根目录下。这里有一个关键点前端路由如果使用了history模式需要在Nginx配置文件里加一段try_files规则否则刷新页面时会出现404。config配置片段location / { root /var/www/dist; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }加了这个配置之后无论用户从哪个路径进入页面Nginx都会回退到入口HTML前端路由再接管跳到对应页面404的问题就解决了。7. 常见问题与排查技巧实录7.1 数据库连接失败怎么定位启动后端报Access denied for user优先检查三处数据库用户名密码是否正确、该用户是否有权限访问目标数据库、MySQL服务是否真的在运行。我用systemctl status mysql查服务状态用mysql -u root -p测登录。如果密码对但权限不足执行授权SQLGRANT ALL PRIVILEGES ON writer_db.* TO rootlocalhost IDENTIFIED BY 你的密码; FLUSH PRIVILEGES;7.2 MyBatis查询结果全是null值SQL能查到数据但接口返回的JSON里全是null十有八九是实体类的属性名和数据库字段名对不上。最常见的情况就是数据库字段是birth_date实体属性是birthDate中间没有启用驼峰映射。解决办法有两个一是在application.yml里设置mybatis.configuration.map-underscore-to-camel-casetrue二是在SQL里给字段起别名。优先用第一种一劳永逸。7.3 前端Axios请求报错404或跨域前端请求接口报404先看网络请求的URL到底是什么。常见原因是后端context-path没设置、Nginx反向代理路径不对、或者代理转发时没去掉/api前缀。跨域时报错信息会有提示本地开发大多数人容易漏掉vue.config.js的代理配置直接在前端文件里写http://localhost:8080也是可以但不建议这么做——上线后改地址会特别麻烦用代理加环境变量方式更规范化。7.4 静态资源上传了但图片不显示这个问题我接手过很多次几乎都是资源映射器没配置到位或者配置路径和实际存储路径不一致。排查方法很简单先看看浏览器控制台里图片URL返回的是404还是403。如果是404确认磁盘目录是否存在、路径与配置的addResourceHandler是否匹配如果是403一般是目录权限问题给运行用户加读写权限即可。7.5 保存数据时出现乱码MySQL表和数据连接都建议用utf8mb4字符集。如果库里数据是中文但页面显示乱码检查连接串里是否带了characterEncodingutf8。另外数据库本身要确认是utf8mb4因为个别情况下库是utf8、表是latin1数据写入时就会变成问号。一旦数据本身写坏了改连接串是无济于事的只能后续重建表导入数据。8. 优化迭代思路与经验收尾这套系统做完之后我后续又做了一些体验层面的优化这些点比功能本身更能体现设计质量。第一加载状态必须有。列表查询、保存、删除这些耗时操作前端都要有loading状态。没有loading反馈用户双击提交就会产生重复数据这是我在实际使用中踩过的坑。我所有操作按钮都绑定了loading变量在请求期间置为true。第二列表的排序功能要实用。当前实现是默认按更新时间倒序但编辑场景下想要按获奖年份倒序查看谁最近获了奖也应该支持。我给后端列表查询接口补了一个可选的排序字段和排序方向参数前端表格列头加了排序触发事件。一个可配置排序的列表比固定顺序的列表有用得多。第三数据备份意识要强。系统每天都在录入数据数据库如果没做定时备份一个误操作可能全盘皆输。我给项目补了一个简单的mysqldump定时备份脚本每天凌晨跑一次保留最近7天的备份文件这个成本几乎为零但价值是不可估量的。第四注意在删除作家时同步级联处理。如果直接在数据库里删掉某个作家ID但他的获奖记录和作品还在列表里前端就会出现“空壳数据”显示作家信息为空。现在做法是在删除作家时同时删除该作家的获奖记录和作品记录。虽然数据库外键ON DELETE CASCADE也能实现但由Service层显式控制逻辑更清晰也便于打印日志审计。这个项目本身不算大但它把“信息管理系统”最核心的套路都走了一遍需求分析、表设计、接口开发、前端联调、部署上线、运维排错。我个人体会最深的一点是一个项目能不能稳定运行取决于最不起眼的基础工作——字段设计是否规范、索引是否建对、错误处理是否安全、资源路径是否统一。把这些基本功做好项目就成功了大半。后续如果想继续扩展方向也很明确加入作家作品排名展示、按时间线展示获奖历程、甚至接一个公开的文学奖项数据源做自动更新都是在这个架构上很容易延展的玩法。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑