From aa485e340570b7e0fad11bd37223bd450ed3e359 Mon Sep 17 00:00:00 2001 From: lizhengwei Date: Fri, 14 Nov 2025 11:29:14 +0800 Subject: [PATCH] =?UTF-8?q?font=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-site/ruoyi-h5/doc/h5_fonts.sql | 42 +++++ ruoyi-site/ruoyi-h5/doc/http/fonts.http | 80 +++++++++ ruoyi-site/ruoyi-h5/doc/需求.md | 64 +++++++ .../luban/api/controller/FontController.java | 40 +++-- .../main/java/com/luban/api/dao/FontDao.java | 15 ++ .../main/java/com/luban/api/entity/Font.java | 80 +++++++++ .../api/mongo/dao/FontContentRepository.java | 12 ++ .../luban/api/mongo/entity/FontContent.java | 163 ++++++++++++++++++ .../com/luban/api/service/FontService.java | 53 ++++++ .../api/service/impl/FontServiceImpl.java | 121 +++++++++++++ 10 files changed, 658 insertions(+), 12 deletions(-) create mode 100644 ruoyi-site/ruoyi-h5/doc/h5_fonts.sql create mode 100644 ruoyi-site/ruoyi-h5/doc/http/fonts.http create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/FontDao.java create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/Font.java create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/dao/FontContentRepository.java create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/entity/FontContent.java create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/FontService.java create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/FontServiceImpl.java diff --git a/ruoyi-site/ruoyi-h5/doc/h5_fonts.sql b/ruoyi-site/ruoyi-h5/doc/h5_fonts.sql new file mode 100644 index 000000000..8845c141c --- /dev/null +++ b/ruoyi-site/ruoyi-h5/doc/h5_fonts.sql @@ -0,0 +1,42 @@ +/* + Navicat Premium Data Transfer + + Source Server : localhost + Source Server Type : MySQL + Source Server Version : 80023 + Source Host : localhost:3306 + Source Schema : h5 + + Target Server Type : MySQL + Target Server Version : 80023 + File Encoding : 65001 + + Date: 14/11/2025 15:00:00 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for h5_font +-- ---------------------------- +DROP TABLE IF EXISTS `h5_font`; +CREATE TABLE `h5_font` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `source` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '字体来源', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字体名称', + `font_family` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字体族名称(唯一标识)', + `lang` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '字体语言类型:zh-中文,en-英文', + `alias` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '字体别名', + `authorization_id` bigint NULL DEFAULT NULL COMMENT '授权ID', + `user_over_role` int NULL DEFAULT NULL COMMENT '用户角色', + `sale_type` int NULL DEFAULT NULL COMMENT '销售类型', + `create_time` bigint NOT NULL COMMENT '创建时间戳', + `update_time` bigint NOT NULL COMMENT '更新时间戳', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_font_family`(`font_family`) USING BTREE COMMENT '字体族名称唯一索引', + INDEX `idx_lang`(`lang`) USING BTREE COMMENT '语言类型索引', + INDEX `idx_name`(`name`) USING BTREE COMMENT '字体名称索引' +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字体表' ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/doc/http/fonts.http b/ruoyi-site/ruoyi-h5/doc/http/fonts.http new file mode 100644 index 000000000..724b31408 --- /dev/null +++ b/ruoyi-site/ruoyi-h5/doc/http/fonts.http @@ -0,0 +1,80 @@ +### 批量上传字体 +POST http://localhost:19200/h5/font/create +Content-Type: application/json + +[ + { + "id": 1, + "sourceId": "GD", + "name": "OpenSans-Bold", + "preview": { + "url": "https://st0.dancf.com/csc/49/fonts/0/20200809-105104-c105.svg", + "width": 490, + "height": 80, + "partial_video": "", + "video": "", + "hex": "", + "duration": 0 + }, + "price": null, + "items": [], + "content": { + "family": "Open Sans", + "alias": "Open Sans Bold", + "style": "normal", + "weight": 700, + "woff": "https://gd-filems.dancf.com/gaoding/editor/20240116-211715-jaeea.woff", + "ttf": "https://gd-filems.dancf.com/gaoding/editor/20240116-211715-kiige.ttf", + "lang": "en", + "origin_file": { + "size": 104120, + "url": "https://st0.dancf.com/csc/49/fonts/0/20200809-105059-cc06.ttf" + }, + "woff_size": 56092, + "ttf_size": 92500, + "meta_data": { + "ascent": 2189, + "descent": -600, + "emSize": 2048, + "typoAscent": 2189, + "typoDescent": -600, + "typoLineGap": 0, + "winAscent": 2189, + "winDescent": 600, + "capitalHeight": 1462, + "underlinePosition": -154, + "underlineThickness": 102, + "fsType": 0, + "hheadAscent": 2189, + "hheadDescent": -600, + "hheadLineGap": 0, + "xheight": 1118 + } + }, + "content_id": null, + "content_url": "https://gd-filems.dancf.com/xi19e5/xi19e5/0/32d51454-451e-4b80-a8b2-138fa5d185e750.json?auth_key=1763092800-10a7b6d1071b4787b7225660db3f71a1-0-8c6b2cbd6b9aae7a0943fd4190e16094", + "lang": "en", + "alias": "Open Sans Bold", + "authorization_id": 26, + "user_over_role": 0, + "sale_type": 0, + "createTime": 1602230400, + "updateTime": 1602230400 + } +] + +### 分页查询字体 +GET http://localhost:19200/h5/font/page?name=OpenSans&type=en&pageNum=1&pageSize=10 +Accept: application/json + +### 根据字体族名称列表查询字体 +POST http://localhost:19200/h5/font/list +Content-Type: application/json + +[ + "Open Sans" +] + +### 根据ID获取字体详情 +GET http://localhost:19200/h5/font/1 +Accept: application/json \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/doc/需求.md b/ruoyi-site/ruoyi-h5/doc/需求.md index b612e8c12..898d554f0 100644 --- a/ruoyi-site/ruoyi-h5/doc/需求.md +++ b/ruoyi-site/ruoyi-h5/doc/需求.md @@ -69,3 +69,67 @@ - 确保编译无错误,代码符合规范 请按照以上要求生成相应的代码和文档。 + + +## 第二波需求 +工作完成的非常好,继续开发下个需求,完善 字体的实现,目前只有个FontController文件,请继续完善接口,定义好表结构,定义好的表结构记得给我审核一下,字体要提供这些功能。 +1、批量上传字体。 +2、分页查询字体,包含两种类型字体:中文英文。 +3、根据fontFamily字体名称批量查询字体,字体名称唯一属性。 +下面为字体的JSON结构,请设计表和代码,你看看是存在mysql还是mongo比较好 +{ +"id": "33912837", +"source": "GD", +"name": "OpenSans-Bold", +"preview": { +"url": "https://st0.dancf.com/csc/49/fonts/0/20200809-105104-c105.svg", +"width": 490, +"height": 80, +"partial_video": "", +"video": "", +"hex": "", +"duration": 0 +}, +"price": null, +"items": [], +"content": { +"family": "Open Sans", +"alias": "Open Sans Bold", +"style": "normal", +"weight": 700, +"woff": "https://gd-filems.dancf.com/gaoding/editor/20240116-211715-jaeea.woff", +"ttf": "https://gd-filems.dancf.com/gaoding/editor/20240116-211715-kiige.ttf", +"lang": "en", +"origin_file": { +"size": 104120, +"url": "https://st0.dancf.com/csc/49/fonts/0/20200809-105059-cc06.ttf" +}, +"woff_size": 56092, +"ttf_size": 92500, +"meta_data": { +"ascent": 2189, +"descent": -600, +"emSize": 2048, +"typoAscent": 2189, +"typoDescent": -600, +"typoLineGap": 0, +"winAscent": 2189, +"winDescent": 600, +"capitalHeight": 1462, +"underlinePosition": -154, +"underlineThickness": 102, +"fsType": 0, +"hheadAscent": 2189, +"hheadDescent": -600, +"hheadLineGap": 0, +"xheight": 1118 +} +}, +"content_id": null, +"content_url": "https://gd-filems.dancf.com/xi19e5/xi19e5/0/32d51454-451e-4b80-a8b2-138fa5d185e750.json?auth_key=1763092800-10a7b6d1071b4787b7225660db3f71a1-0-8c6b2cbd6b9aae7a0943fd4190e16094", +"lang": "en", +"alias": "Open Sans Bold", +"authorization_id": 26, +"user_over_role": 0, +"sale_type": 0 +} diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/FontController.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/FontController.java index 6a3a937b8..1b5614414 100644 --- a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/FontController.java +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/FontController.java @@ -1,39 +1,55 @@ package com.luban.api.controller; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.luban.api.entity.Font; +import com.luban.api.mongo.entity.FontContent; +import com.luban.api.service.FontService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; - @RestController @RequestMapping("font") @Tag(name = "字体") @Slf4j public class FontController { + @Autowired + private FontService fontService; @Operation(summary = "批量上传字体") @PostMapping("create") - public List create(@RequestBody List list) { - return new ArrayList<>(); + public Boolean create(@RequestBody List fontContents) { + return fontService.batchSaveFonts(fontContents); } - @Operation(summary = "分页查询字体") @GetMapping("page") - public List page(@RequestParam String type//中文、英文 - , @RequestParam String name) { - return new ArrayList<>(); + public IPage page(@RequestParam(required = false) String type, + @RequestParam(required = false) String name, + @RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "10") Integer pageSize) { + return fontService.pageFonts(type, name, pageNum, pageSize); } - @Operation(summary = "查询字体") - @GetMapping("list") - public List list(@RequestParam List nameLike) { - return new ArrayList<>(); + @Operation(summary = "根据字体族名称列表查询字体") + @PostMapping("list") + public List list(@RequestBody List fontFamilyNames) { + List fontContents = fontService.listFontsByFamilyNames(fontFamilyNames); + if (fontContents == null) { + return new ArrayList<>(); + } + return fontContents; } -} + @Operation(summary = "根据ID获取字体详情") + @GetMapping("/{id}") + public FontContent getFontById(@PathVariable Long id) { + return fontService.getFontDetail(id); + } +} \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/FontDao.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/FontDao.java new file mode 100644 index 000000000..5d6b31713 --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/FontDao.java @@ -0,0 +1,15 @@ +package com.luban.api.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.luban.api.entity.Font; + +/** + *

+ * 字体 Mapper 接口 + *

+ * + * @author your-name + */ +public interface FontDao extends BaseMapper { + +} \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/Font.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/Font.java new file mode 100644 index 000000000..b165102e3 --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/Font.java @@ -0,0 +1,80 @@ +package com.luban.api.entity; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * 字体实体类 + * + * @author your-name + */ +@Data +@EqualsAndHashCode +@Accessors(chain = true) +@TableName("h5_font") +@Schema(title = "字体对象") +public class Font implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 字体来源 + */ + private String source; + + /** + * 字体名称 + */ + private String name; + + /** + * 字体族名称(唯一标识) + */ + private String fontFamily; + + /** + * 字体语言类型:zh-中文,en-英文 + */ + private String lang; + + /** + * 字体别名 + */ + private String alias; + + /** + * 授权ID + */ + private Long authorizationId; + + /** + * 用户角色 + */ + private Integer userOverRole; + + /** + * 销售类型 + */ + private Integer saleType; + + /** + * 创建时间戳 + */ + private Long createTime; + + /** + * 更新时间戳 + */ + private Long updateTime; +} \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/dao/FontContentRepository.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/dao/FontContentRepository.java new file mode 100644 index 000000000..5266445e3 --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/dao/FontContentRepository.java @@ -0,0 +1,12 @@ +package com.luban.api.mongo.dao; + +import com.luban.api.mongo.entity.FontContent; +import org.springframework.data.mongodb.repository.MongoRepository; + +/** + * 字体内容 Repository + * + * @author your-name + */ +public interface FontContentRepository extends MongoRepository { +} \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/entity/FontContent.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/entity/FontContent.java new file mode 100644 index 000000000..40975966d --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/mongo/entity/FontContent.java @@ -0,0 +1,163 @@ +package com.luban.api.mongo.entity; + +import lombok.Data; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.List; +import java.util.Map; + +/** + * 字体内容实体类 (存储在MongoDB中) + * + * @author your-name + */ +@Data +@Document(collection = "h5_font_content") +public class FontContent { + + /** + * 主键ID,与MySQL中Font的ID对应 + */ + @Id + private Long id; + + /** + * 字体来源ID + */ + private String sourceId; + + /** + * 字体名称 + */ + private String name; + + /** + * 预览信息 + */ + private Preview preview; + + /** + * 价格 + */ + private Object price; + + /** + * 项目列表 + */ + private List items; + + /** + * 字体内容详情 + */ + private Content content; + + /** + * 内容ID + */ + private Object contentId; + + /** + * 内容URL + */ + private String contentUrl; + + /** + * 语言 + */ + private String lang; + + /** + * 别名 + */ + private String alias; + + /** + * 授权ID + */ + private Long authorizationId; + + /** + * 用户角色 + */ + private Integer userOverRole; + + /** + * 销售类型 + */ + private Integer saleType; + + /** + * 创建时间戳 + */ + private Long createTime; + + /** + * 更新时间戳 + */ + private Long updateTime; + + /** + * 预览信息类 + */ + @Data + public static class Preview { + private String url; + private Integer width; + private Integer height; + private String partialVideo; + private String video; + private String hex; + private Integer duration; + } + + /** + * 内容详情类 + */ + @Data + public static class Content { + private String family; + private String alias; + private String style; + private Integer weight; + private String woff; + private String ttf; + private String lang; + private OriginFile originFile; + private Integer woffSize; + private Integer ttfSize; + private MetaData metaData; + } + + /** + * 原始文件信息类 + */ + @Data + public static class OriginFile { + private Integer size; + private String url; + } + + /** + * 元数据类 + */ + @Data + public static class MetaData { + private Integer ascent; + private Integer descent; + private Integer emSize; + private Integer typoAscent; + private Integer typoDescent; + private Integer typoLineGap; + private Integer winAscent; + private Integer winDescent; + private Integer capitalHeight; + private Integer underlinePosition; + private Integer underlineThickness; + private Integer fsType; + private Integer hheadAscent; + private Integer hheadDescent; + private Integer hheadLineGap; + private Integer xheight; + } +} \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/FontService.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/FontService.java new file mode 100644 index 000000000..31d0eaa2a --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/FontService.java @@ -0,0 +1,53 @@ +package com.luban.api.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.luban.api.entity.Font; +import com.luban.api.mongo.entity.FontContent; + +import java.util.List; + +/** + *

+ * 字体 服务类 + *

+ * + * @author your-name + */ +public interface FontService extends IService { + + /** + * 批量上传字体 + * + * @param fontContents 字体内容列表 + * @return 是否保存成功 + */ + boolean batchSaveFonts(List fontContents); + + /** + * 分页查询字体 + * + * @param type 字体类型:zh-中文,en-英文 + * @param name 字体名称(模糊查询) + * @param pageNum 页码 + * @param pageSize 每页大小 + * @return 字体分页数据 + */ + IPage pageFonts(String type, String name, Integer pageNum, Integer pageSize); + + /** + * 根据字体族名称批量查询字体 + * + * @param fontFamilyList 字体族名称列表 + * @return 字体列表 + */ + List listFontsByFamilyNames(List fontFamilyList); + + /** + * 根据ID获取字体详情 + * + * @param id 字体ID + * @return 字体详情 + */ + FontContent getFontDetail(Long id); +} \ No newline at end of file diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/FontServiceImpl.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/FontServiceImpl.java new file mode 100644 index 000000000..714ffb61d --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/FontServiceImpl.java @@ -0,0 +1,121 @@ +package com.luban.api.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.luban.api.dao.FontDao; +import com.luban.api.entity.Font; +import com.luban.api.mongo.dao.FontContentRepository; +import com.luban.api.mongo.entity.FontContent; +import com.luban.api.service.FontService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 字体 服务实现类 + *

+ * + * @author your-name + */ +@Service +public class FontServiceImpl extends ServiceImpl implements FontService { + + @Autowired + private FontContentRepository fontContentRepository; + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean batchSaveFonts(List fontContents) { + if (CollectionUtils.isEmpty(fontContents)) { + return false; + } + + // 获取当前时间戳(秒) + long currentTime = System.currentTimeMillis() / 1000; + for (FontContent fontContent : fontContents) { + // 保存到MongoDB + fontContent.setCreateTime(currentTime); + fontContent.setUpdateTime(currentTime); + fontContentRepository.save(fontContent); + + // 保存基本信息到MySQL + Font font = new Font(); + font.setId(fontContent.getId()); + font.setSource(fontContent.getSourceId()); + font.setName(fontContent.getName()); + font.setFontFamily(fontContent.getContent().getFamily()); + font.setLang(fontContent.getContent().getLang()); + font.setAlias(fontContent.getContent().getAlias()); + font.setAuthorizationId(fontContent.getAuthorizationId()); + font.setUserOverRole(fontContent.getUserOverRole()); + font.setSaleType(fontContent.getSaleType()); + font.setCreateTime(currentTime); + font.setUpdateTime(currentTime); + + // 使用insertOrUpdate避免重复插入 + this.saveOrUpdate(font); + } + + return true; + } + + @Override + public IPage pageFonts(String type, String name, Integer pageNum, Integer pageSize) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + // 根据语言类型查询 + if (StringUtils.hasText(type)) { + queryWrapper.eq(Font::getLang, type); + } + + // 根据名称模糊查询 + if (StringUtils.hasText(name)) { + queryWrapper.like(Font::getName, name); + } + + queryWrapper.orderByDesc(Font::getCreateTime); + + IPage page = new Page<>(pageNum, pageSize); + return this.page(page, queryWrapper); + } + + @Override + public List listFontsByFamilyNames(List fontFamilyList) { + if (CollectionUtils.isEmpty(fontFamilyList)) { + return null; + } + + // 先从MySQL查询ID列表 + List fonts = this.list(new LambdaQueryWrapper() + .in(Font::getFontFamily, fontFamilyList)); + + if (CollectionUtils.isEmpty(fonts)) { + return null; + } + + // 根据ID列表从MongoDB查询详细信息 + List fontContents = new ArrayList<>(); + for (Font font : fonts) { + FontContent fontContent = fontContentRepository.findById(font.getId()).orElse(null); + if (fontContent != null) { + fontContents.add(fontContent); + } + } + + return fontContents; + } + + @Override + public FontContent getFontDetail(Long id) { + return fontContentRepository.findById(id).orElse(null); + } +} \ No newline at end of file