font初始化

This commit is contained in:
lizhengwei 2025-11-14 11:29:14 +08:00
parent 10ffca8d24
commit aa485e3405
10 changed files with 658 additions and 12 deletions

View File

@ -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;

View File

@ -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

View File

@ -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
}

View File

@ -1,39 +1,55 @@
package com.luban.api.controller; 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.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@RestController @RestController
@RequestMapping("font") @RequestMapping("font")
@Tag(name = "字体") @Tag(name = "字体")
@Slf4j @Slf4j
public class FontController { public class FontController {
@Autowired
private FontService fontService;
@Operation(summary = "批量上传字体") @Operation(summary = "批量上传字体")
@PostMapping("create") @PostMapping("create")
public List<Object> create(@RequestBody List<Object> list) { public Boolean create(@RequestBody List<FontContent> fontContents) {
return new ArrayList<>(); return fontService.batchSaveFonts(fontContents);
} }
@Operation(summary = "分页查询字体") @Operation(summary = "分页查询字体")
@GetMapping("page") @GetMapping("page")
public List<Object> page(@RequestParam String type//中文英文 public IPage<Font> page(@RequestParam(required = false) String type,
, @RequestParam String name) { @RequestParam(required = false) String name,
return new ArrayList<>(); @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return fontService.pageFonts(type, name, pageNum, pageSize);
} }
@Operation(summary = "查询字体") @Operation(summary = "根据字体族名称列表查询字体")
@GetMapping("list") @PostMapping("list")
public List<Object> list(@RequestParam List<String> nameLike) { public List<FontContent> list(@RequestBody List<String> fontFamilyNames) {
return new ArrayList<>(); List<FontContent> 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);
}
} }

View File

@ -0,0 +1,15 @@
package com.luban.api.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.luban.api.entity.Font;
/**
* <p>
* 字体 Mapper 接口
* </p>
*
* @author your-name
*/
public interface FontDao extends BaseMapper<Font> {
}

View File

@ -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;
}

View File

@ -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<FontContent, Long> {
}

View File

@ -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<Object> 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;
}
}

View File

@ -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;
/**
* <p>
* 字体 服务类
* </p>
*
* @author your-name
*/
public interface FontService extends IService<Font> {
/**
* 批量上传字体
*
* @param fontContents 字体内容列表
* @return 是否保存成功
*/
boolean batchSaveFonts(List<FontContent> fontContents);
/**
* 分页查询字体
*
* @param type 字体类型zh-中文en-英文
* @param name 字体名称模糊查询
* @param pageNum 页码
* @param pageSize 每页大小
* @return 字体分页数据
*/
IPage<Font> pageFonts(String type, String name, Integer pageNum, Integer pageSize);
/**
* 根据字体族名称批量查询字体
*
* @param fontFamilyList 字体族名称列表
* @return 字体列表
*/
List<FontContent> listFontsByFamilyNames(List<String> fontFamilyList);
/**
* 根据ID获取字体详情
*
* @param id 字体ID
* @return 字体详情
*/
FontContent getFontDetail(Long id);
}

View File

@ -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;
/**
* <p>
* 字体 服务实现类
* </p>
*
* @author your-name
*/
@Service
public class FontServiceImpl extends ServiceImpl<FontDao, Font> implements FontService {
@Autowired
private FontContentRepository fontContentRepository;
@Override
@Transactional(rollbackFor = Exception.class)
public boolean batchSaveFonts(List<FontContent> 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<Font> pageFonts(String type, String name, Integer pageNum, Integer pageSize) {
LambdaQueryWrapper<Font> 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<Font> page = new Page<>(pageNum, pageSize);
return this.page(page, queryWrapper);
}
@Override
public List<FontContent> listFontsByFamilyNames(List<String> fontFamilyList) {
if (CollectionUtils.isEmpty(fontFamilyList)) {
return null;
}
// 先从MySQL查询ID列表
List<Font> fonts = this.list(new LambdaQueryWrapper<Font>()
.in(Font::getFontFamily, fontFamilyList));
if (CollectionUtils.isEmpty(fonts)) {
return null;
}
// 根据ID列表从MongoDB查询详细信息
List<FontContent> 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);
}
}