diff --git a/.style/Java开发手册(黄山版).pdf b/.style/Java开发手册(黄山版).pdf
new file mode 100644
index 0000000..6ff47d6
Binary files /dev/null and b/.style/Java开发手册(黄山版).pdf differ
diff --git a/.style/p3c-codestyle.xml b/.style/p3c-codestyle.xml
new file mode 100644
index 0000000..fb5f47f
--- /dev/null
+++ b/.style/p3c-codestyle.xml
@@ -0,0 +1,380 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f50c997
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/continew-admin-business/pom.xml b/continew-admin-business/pom.xml
new file mode 100644
index 0000000..42d6e68
--- /dev/null
+++ b/continew-admin-business/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+
+ top.continew
+ continew-admin
+ ${revision}
+
+
+ continew-admin-business
+ 业务管理模块(存放业务管理相关业务功能,例如:模型、作业等)
+
+
+
+
+ top.continew
+ continew-admin-common
+
+
+
+ top.continew
+ continew-admin-system
+
+
+ top.continew
+ continew-admin-system
+
+
+
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/enums/AssignmentsTypeEnum.java b/continew-admin-business/src/main/java/top/continew/admin/business/enums/AssignmentsTypeEnum.java
new file mode 100644
index 0000000..83d00be
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/enums/AssignmentsTypeEnum.java
@@ -0,0 +1,29 @@
+package top.continew.admin.business.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import top.continew.starter.core.enums.BaseEnum;
+
+/**
+ * 消息类型枚举
+ *
+ * @author Charles7c
+ * @since 2023/11/2 20:08
+ */
+@Getter
+@RequiredArgsConstructor
+public enum AssignmentsTypeEnum implements BaseEnum {
+
+ /**
+ * 作业
+ */
+ ASSIGNMENTS(1, "作业"),
+
+ /**
+ * 考试
+ */
+ EXAMINATION(2, "考试"),;
+
+ private final Integer value;
+ private final String description;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/enums/BillingRuleEnum.java b/continew-admin-business/src/main/java/top/continew/admin/business/enums/BillingRuleEnum.java
new file mode 100644
index 0000000..16c2517
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/enums/BillingRuleEnum.java
@@ -0,0 +1,123 @@
+package top.continew.admin.business.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.math.BigDecimal;
+
+/**
+ * 计费规则枚举
+ *
+ * @author jiay
+ * @since 2025/09/22
+ */
+@Getter
+@AllArgsConstructor
+public enum BillingRuleEnum {
+
+ // 生成平台-艺术类
+ AI_PAINTING(10000L, "生成平台-艺术类", "AI绘画", new BigDecimal("0.13")),
+ AI_MUSIC(10002L, "生成平台-艺术类", "AI音乐", new BigDecimal("0.4")),
+ AI_VIDEO_TEXT(10003L, "生成平台-艺术类", "AI视频-文生视频", new BigDecimal("1.5")),
+ AI_VIDEO_IMAGE(10004L, "生成平台-艺术类", "AI视频-图生视频", new BigDecimal("1.5")),
+ AI_3D(10005L, "生成平台-艺术类", "AI3D", new BigDecimal("0.5")),
+
+ // 效率工具 - AI绘画
+ AI_PAINTING_GENERAL(10006L, "效率工具", "AI绘画-通用", new BigDecimal("0.3")),
+ AI_PAINTING_PORTRAIT(10007L, "效率工具", "AI绘画-人物肖像", new BigDecimal("0.3")),
+ AI_PAINTING_FLAT_DESIGN(10008L, "效率工具", "AI绘画-平面设计", new BigDecimal("0.3")),
+ AI_PAINTING_ART_DESIGN(10009L, "效率工具", "AI绘画-环艺设计", new BigDecimal("0.3")),
+ AI_PAINTING_ECOMMERCE(10010L, "效率工具", "AI绘画-电商产品", new BigDecimal("0.3")),
+
+ // 效率工具 - AI视频
+ AI_AUDIO(10011L, "效率工具", "AI音频", new BigDecimal("0.3")),
+ AI_VIDEO_PREPRODUCTION(10012L, "效率工具", "AI视频-前期制作", new BigDecimal("0.5")),
+ AI_VIDEO_SPECIAL_EFFECTS(10013L, "效率工具", "AI视频-视频特效", new BigDecimal("1")),
+ AI_VIDEO_PRODUCTION(10014L, "效率工具", "AI视频-视频生成", new BigDecimal("1")),
+
+ // 效率工具 - AI3D
+ AI_3D_TOOL(10015L, "效率工具", "AI3D", new BigDecimal("0.5")),
+
+ // 大语言模型
+ LANGUAGE_MODEL_MULTIMODAL(10016L, "大语言模型", "多模态", new BigDecimal("0.01")), // 1000 token 扣0.01元
+
+ // AI写作
+ AI_WRITING_IMAGE(10001L, "AI写作", "图片", new BigDecimal("1")), // KEXUE_MULTIMODAL
+ AI_WRITING_TEXT(10018L, "AI写作", "文本", new BigDecimal("0.01")), // 1000 token 扣0.01元
+
+ // deep research
+ DEEP_RESEARCH(10019L, "deep research", "深度研究", new BigDecimal("1")),
+
+ // AI编程级
+ AI_PROGRAMMING_MONKEY_OUTLOOK(10020L, "AI编程级", "monkey outlook", new BigDecimal("0.2")),
+
+ // AI编程入门
+ AI_PROGRAMMING_CANVAS(10021L, "AI编程入门", "canvas", new BigDecimal("0.03")),
+
+ // 智能体开发
+ AGENT_DEVELOPMENT_ADVANCED(10022L, "智能体开发", "包含高级", new BigDecimal("0.1")),
+
+ // 教学智能体
+ TEACHING_AGENT(10023L, "教学智能体", "基础", new BigDecimal("0.1")),
+
+ // genie research
+ GENIE_RESEARCH(10024L, "GENIE research", "京东智能体", new BigDecimal("1"))
+
+ ;
+
+ /**
+ * 平台编码
+ */
+ private final Long platformId;
+
+ /**
+ * 大类
+ */
+ private final String majorCategory;
+
+ /**
+ * 分类
+ */
+ private final String subCategory;
+
+ /**
+ * 计费金额(元)
+ */
+ private final BigDecimal price;
+
+ /**
+ * 根据平台编码获取计费规则
+ *
+ * @param platformId 平台编码
+ * @return 计费规则
+ */
+ public static BillingRuleEnum getByPlatformId(Long platformId) {
+ for (BillingRuleEnum rule : values()) {
+ if (rule.getPlatformId().equals(platformId)) {
+ return rule;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 根据平台编码获取计费金额
+ *
+ * @param platformId 平台编码
+ * @return 计费金额(元)
+ */
+ public static BigDecimal getPriceByPlatformId(Long platformId) {
+ BillingRuleEnum rule = getByPlatformId(platformId);
+ return rule != null ? rule.getPrice() : BigDecimal.ZERO;
+ }
+
+ /**
+ * 检查平台编码是否为token计费类型
+ *
+ * @param platformId 平台编码
+ * @return 是否为token计费
+ */
+ public static boolean isTokenBilling(Long platformId) {
+ return 10016L == platformId || 10018L == platformId;
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/enums/ChargeTypeEnum.java b/continew-admin-business/src/main/java/top/continew/admin/business/enums/ChargeTypeEnum.java
new file mode 100644
index 0000000..d6430c2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/enums/ChargeTypeEnum.java
@@ -0,0 +1,48 @@
+package top.continew.admin.business.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 平台子账号类型枚举
+ *
+ * @author jiay
+ */
+@Getter
+@AllArgsConstructor
+public enum ChargeTypeEnum {
+
+ CHAT(0, "TOKEN"), IMAGE(1, "图"), AUDIO(3, "音频"), VIDEO(4, "视频"), D3D(5, "3D"), TEACHER_AGENT(6, "教学智能体"),
+ DEEP_RESEARCH(7, "DEEP_RESEARCH"), MULTIMODAL(8, "多模态"), AI_CODE(9, "AI编程"), AGENT_DEVELOPMENT(10, "智能体开发")
+
+ ;
+
+ /**
+ * 模型平台类型
+ */
+ private final Integer typeId;
+ /**
+ * 描述
+ */
+ private final String desc;
+
+ public static String convertDesc(Long typeId) {
+ ChargeTypeEnum[] values = ChargeTypeEnum.values();
+ for (ChargeTypeEnum va : values) {
+ if (va.getTypeId().equals(typeId)) {
+ return va.getDesc();
+ }
+ }
+ return "--";
+ }
+
+ public static Integer getType(Integer index) {
+ ChargeTypeEnum[] values = ChargeTypeEnum.values();
+ if (index != null && index >= 0 && index < values.length) {
+ return values[index].getTypeId();
+ }
+ return -1;
+
+ }
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/enums/PlantformBalanceEnum.java b/continew-admin-business/src/main/java/top/continew/admin/business/enums/PlantformBalanceEnum.java
new file mode 100644
index 0000000..540722d
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/enums/PlantformBalanceEnum.java
@@ -0,0 +1,57 @@
+package top.continew.admin.business.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 平台子账号类型枚举
+ *
+ * @author jiay
+ */
+@Getter
+@AllArgsConstructor
+public enum PlantformBalanceEnum {
+
+ CHAT(10000L, "大模型对话", 0), IMAGE(10001L, "图片大模型", 1), MEDIA(10002L, "视频大模型", 4),;
+
+ /**
+ * 模型平台类型
+ */
+ private final Long plantformId;
+ /**
+ * 描述
+ */
+ private final String desc;
+
+ /**
+ * 类型
+ */
+ private final Integer type;
+
+ public static String convertDesc(Integer plantformId) {
+ PlantformBalanceEnum[] values = PlantformBalanceEnum.values();
+ for (PlantformBalanceEnum va : values) {
+ if (va.getPlantformId().equals(plantformId)) {
+ return va.getDesc();
+ }
+ }
+ return "--";
+ }
+
+ public static Integer getType(Integer index) {
+ PlantformBalanceEnum[] values = PlantformBalanceEnum.values();
+ if (index != null && index >= 0 && index < values.length) {
+ return values[index].getType();
+ }
+ return -1;
+
+ }
+
+ public static Long getPlantform(Integer index) {
+ PlantformBalanceEnum[] values = PlantformBalanceEnum.values();
+ if (index != null && index >= 0 && index < values.length) {
+ return values[index].getPlantformId();
+ }
+ return -1L;
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/enums/RoleEnum.java b/continew-admin-business/src/main/java/top/continew/admin/business/enums/RoleEnum.java
new file mode 100644
index 0000000..b09b300
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/enums/RoleEnum.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * @author 张波
+ * @since 2024/10/22 14:27
+ */
+@Getter
+@RequiredArgsConstructor
+public enum RoleEnum {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/file/CommonMultipartFile.java b/continew-admin-business/src/main/java/top/continew/admin/business/file/CommonMultipartFile.java
new file mode 100644
index 0000000..c305998
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/file/CommonMultipartFile.java
@@ -0,0 +1,129 @@
+package top.continew.admin.business.file;
+
+import org.springframework.lang.NonNull;
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @Author: jia
+ * @Date: 2025/05/21/15:42
+ * @Description:
+ */
+public class CommonMultipartFile implements MultipartFile {
+
+ private final String name;
+
+ private final String originalFilename;
+
+ @Nullable
+ private final String contentType;
+
+ private final byte[] content;
+
+ /**
+ * Create a new CommonMultipartFile with the given content.
+ *
+ * @param name the name of the file
+ * @param content the content of the file
+ */
+ public CommonMultipartFile(String name, @Nullable byte[] content) {
+ this(name, "", null, content);
+ }
+
+ /**
+ * Create a new CommonMultipartFile with the given content.
+ *
+ * @param name the name of the file
+ * @param contentStream the content of the file as stream
+ * @throws IOException if reading from the stream failed
+ */
+ public CommonMultipartFile(String name, InputStream contentStream) throws IOException {
+ this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));
+ }
+
+ /**
+ * Create a new CommonMultipartFile with the given content.
+ *
+ * @param name the name of the file
+ * @param originalFilename the original filename (as on the client's machine)
+ * @param contentType the content type (if known)
+ * @param content the content of the file
+ */
+ public CommonMultipartFile(String name,
+ @Nullable String originalFilename,
+ @Nullable String contentType,
+ @Nullable byte[] content) {
+
+ Assert.hasLength(name, "Name must not be empty");
+ this.name = name;
+ this.originalFilename = (originalFilename != null ? originalFilename : "");
+ this.contentType = contentType;
+ this.content = (content != null ? content : new byte[0]);
+ }
+
+ /**
+ * Create a new CommonMultipartFile with the given content.
+ *
+ * @param name the name of the file
+ * @param originalFilename the original filename (as on the client's machine)
+ * @param contentType the content type (if known)
+ * @param contentStream the content of the file as stream
+ * @throws IOException if reading from the stream failed
+ */
+ public CommonMultipartFile(String name,
+ @Nullable String originalFilename,
+ @Nullable String contentType,
+ InputStream contentStream) throws IOException {
+
+ this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ @NonNull
+ public String getOriginalFilename() {
+ return this.originalFilename;
+ }
+
+ @Override
+ @Nullable
+ public String getContentType() {
+ return this.contentType;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return (this.content.length == 0);
+ }
+
+ @Override
+ public long getSize() {
+ return this.content.length;
+ }
+
+ @Override
+ public byte[] getBytes() throws IOException {
+ return this.content;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(this.content);
+ }
+
+ @Override
+ public void transferTo(File dest) throws IOException, IllegalStateException {
+ FileCopyUtils.copy(this.content, dest);
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/AssignmentSubmissionsMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/AssignmentSubmissionsMapper.java
new file mode 100644
index 0000000..7d5e35c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/AssignmentSubmissionsMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.AssignmentSubmissionsDO;
+
+/**
+ * 作业提交 Mapper
+ *
+ * @author 张波
+ * @since 2024/10/22 12:02
+ */
+public interface AssignmentSubmissionsMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/AssignmentsMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/AssignmentsMapper.java
new file mode 100644
index 0000000..b7c1c33
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/AssignmentsMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.AssignmentsDO;
+
+/**
+ * 作业表 Mapper
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+public interface AssignmentsMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/BillingRuleMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/BillingRuleMapper.java
new file mode 100644
index 0000000..94f2045
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/BillingRuleMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.admin.business.model.entity.BillingRuleDO;
+import top.continew.starter.data.mp.base.BaseMapper;
+
+/**
+ * 计费规则 Mapper
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+public interface BillingRuleMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ConsumptionHistoryMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ConsumptionHistoryMapper.java
new file mode 100644
index 0000000..137af90
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ConsumptionHistoryMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.ConsumptionHistoryDO;
+
+/**
+ * 用户充值消费历史记录 Mapper
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+public interface ConsumptionHistoryMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CopyrightMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CopyrightMapper.java
new file mode 100644
index 0000000..63858b9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CopyrightMapper.java
@@ -0,0 +1,16 @@
+package top.continew.admin.business.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.Copyright;
+import top.continew.starter.data.mp.base.BaseMapper;
+
+/**
+ * 数字人-文案 Mapper 接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Mapper
+public interface CopyrightMapper extends BaseMapper {
+ // 可根据需要添加额外的查询方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CourseUserMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CourseUserMapper.java
new file mode 100644
index 0000000..0446914
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CourseUserMapper.java
@@ -0,0 +1,11 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.CourseUserDO;
+
+/**
+ * @author 张波
+ * @since 2024/10/22 12:19
+ */
+public interface CourseUserMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CoursesMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CoursesMapper.java
new file mode 100644
index 0000000..9cccf44
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/CoursesMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.CoursesDO;
+
+/**
+ * 课程 Mapper
+ *
+ * @author 张波
+ * @since 2024/10/22 11:58
+ */
+public interface CoursesMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DeptModelMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DeptModelMapper.java
new file mode 100644
index 0000000..1d4e7f9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DeptModelMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.DeptModelDO;
+
+/**
+ * 部门与模型绑定 Mapper
+ *
+ * @author 张波
+ * @since 2024/10/20 14:26
+ */
+public interface DeptModelMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DeptPlatformMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DeptPlatformMapper.java
new file mode 100644
index 0000000..c091617
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DeptPlatformMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.DeptPlatformDO;
+
+/**
+ * 部门与操作平台绑定 Mapper
+ *
+ * @author 张波
+ * @since 2024/10/20 14:42
+ */
+public interface DeptPlatformMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DigitalHumanMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DigitalHumanMapper.java
new file mode 100644
index 0000000..c6d8a09
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/DigitalHumanMapper.java
@@ -0,0 +1,16 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.DigitalHuman;
+
+/**
+ * 数字人Mapper接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Mapper
+public interface DigitalHumanMapper extends BaseMapper {
+ // 可根据需要添加额外的数据库操作方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/EffectMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/EffectMapper.java
new file mode 100644
index 0000000..598a684
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/EffectMapper.java
@@ -0,0 +1,16 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.Effect;
+
+/**
+ * 数字人-特效Mapper接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Mapper
+public interface EffectMapper extends BaseMapper {
+ // 可根据需要添加额外的数据库操作方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/EffectTemplateMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/EffectTemplateMapper.java
new file mode 100644
index 0000000..af838e1
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/EffectTemplateMapper.java
@@ -0,0 +1,16 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.EffectTemplate;
+
+/**
+ * 数字人-特效模板Mapper接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Mapper
+public interface EffectTemplateMapper extends BaseMapper {
+ // 可根据需要添加额外的数据库操作方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/FreeQuotaConfigMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/FreeQuotaConfigMapper.java
new file mode 100644
index 0000000..92f3be6
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/FreeQuotaConfigMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.admin.business.model.entity.FreeQuotaConfigDO;
+import top.continew.starter.data.mp.base.BaseMapper;
+
+/**
+ * 免费额度配置 Mapper
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+public interface FreeQuotaConfigMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/HomeworkMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/HomeworkMapper.java
new file mode 100644
index 0000000..0ec538f
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/HomeworkMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.HomeworkDO;
+
+/**
+ * business Mapper
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+public interface HomeworkMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/HuandaResourceMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/HuandaResourceMapper.java
new file mode 100644
index 0000000..e2e43c2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/HuandaResourceMapper.java
@@ -0,0 +1,14 @@
+package top.continew.admin.business.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.HuandaResourceDO;
+import top.continew.starter.data.mp.base.BaseMapper;
+
+/**
+ * 换哒-文件资源 Mapper
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Mapper
+public interface HuandaResourceMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ModelCategoryMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ModelCategoryMapper.java
new file mode 100644
index 0000000..871f988
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ModelCategoryMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.ModelCategoryDO;
+
+/**
+ * 模型分类Mapper
+ *
+ * @author 张波
+ * @since 2024/10/20 19:50
+ */
+public interface ModelCategoryMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ModelMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ModelMapper.java
new file mode 100644
index 0000000..5c31386
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ModelMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.admin.business.model.entity.ModelDO;
+import top.continew.starter.data.mp.base.BaseMapper;
+
+/**
+ * 模型 Mapper
+ *
+ * @author 张波
+ * @since 2024/10/19 15:51
+ */
+public interface ModelMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderAudioMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderAudioMapper.java
new file mode 100644
index 0000000..28df33a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderAudioMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.OrderAudioDo;
+
+/**
+ * 音频 Mapper
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+public interface OrderAudioMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderHistoryMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderHistoryMapper.java
new file mode 100644
index 0000000..35d2f31
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderHistoryMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.OrderHistoryDo;
+
+/**
+ * 点数历史记录 Mapper
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+public interface OrderHistoryMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderThreeMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderThreeMapper.java
new file mode 100644
index 0000000..04fc20c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderThreeMapper.java
@@ -0,0 +1,13 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.OrderThreeDo;
+
+/**
+ * 3D平台 Mapper
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+public interface OrderThreeMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderVideoMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderVideoMapper.java
new file mode 100644
index 0000000..7de0e27
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/OrderVideoMapper.java
@@ -0,0 +1,15 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.OrderVideoDo;
+
+/**
+ * 视频 Mapper
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+@Mapper
+public interface OrderVideoMapper extends BaseMapper {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/PlantformBalanceMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/PlantformBalanceMapper.java
new file mode 100644
index 0000000..fa1d4db
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/PlantformBalanceMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.PlantformBalanceDO;
+
+/**
+ * business Mapper
+ *
+ * @author jiay
+ * @since 2025/06/24 16:47
+ */
+public interface PlantformBalanceMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ScoreMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ScoreMapper.java
new file mode 100644
index 0000000..c59193a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/ScoreMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.ScoreDO;
+
+/**
+ * business Mapper
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+public interface ScoreMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SignInMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SignInMapper.java
new file mode 100644
index 0000000..ac2f464
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SignInMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.SignInDO;
+
+/**
+ * business Mapper
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+public interface SignInMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SubtitleItemMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SubtitleItemMapper.java
new file mode 100644
index 0000000..055ed7d
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SubtitleItemMapper.java
@@ -0,0 +1,16 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.SubtitleItem;
+
+/**
+ * 数字人-字幕项Mapper接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Mapper
+public interface SubtitleItemMapper extends BaseMapper {
+ // 可根据需要添加额外的数据库操作方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SubtitleStyleMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SubtitleStyleMapper.java
new file mode 100644
index 0000000..1998181
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/SubtitleStyleMapper.java
@@ -0,0 +1,16 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import top.continew.admin.business.model.entity.SubtitleStyle;
+
+/**
+ * 数字人-字幕样式Mapper接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Mapper
+public interface SubtitleStyleMapper extends BaseMapper {
+ // 可根据需要添加额外的数据库操作方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/mapper/TaskRecordHistoryMapper.java b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/TaskRecordHistoryMapper.java
new file mode 100644
index 0000000..c12d23c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/mapper/TaskRecordHistoryMapper.java
@@ -0,0 +1,12 @@
+package top.continew.admin.business.mapper;
+
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.admin.business.model.entity.TaskRecordHistoryDO;
+
+/**
+ * 音视图文生成记录 Mapper
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+public interface TaskRecordHistoryMapper extends BaseMapper {}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/AssignmentSubmissionsDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/AssignmentSubmissionsDO.java
new file mode 100644
index 0000000..c0db9b3
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/AssignmentSubmissionsDO.java
@@ -0,0 +1,71 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 作业提交实体
+ *
+ * @author 张波
+ * @since 2024/10/22 12:01
+ */
+@Data
+@TableName("assignment_submissions")
+public class AssignmentSubmissionsDO extends BaseIdDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 作业ID
+ */
+ private Long assignmentId;
+
+ /**
+ * 学生ID
+ */
+ private Long userId;
+
+ /**
+ * 图片标题
+ */
+ private String imageTitle;
+
+ /**
+ * 图片标签
+ */
+ private String imageTag;
+
+ /**
+ * 图片地址
+ */
+ private String imageUrl;
+
+ /**
+ * 分数
+ */
+ private Integer score;
+
+ /**
+ * 评语
+ */
+ private String feedback;
+
+ /**
+ * 创建人
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/AssignmentsDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/AssignmentsDO.java
new file mode 100644
index 0000000..8aa485a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/AssignmentsDO.java
@@ -0,0 +1,77 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.admin.business.enums.AssignmentsTypeEnum;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 作业表实体
+ *
+ * @author 张波
+ * @since 2024/10/22 11:44
+ */
+@Data
+@TableName("assignments")
+public class AssignmentsDO extends BaseIdDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程表ID
+ */
+ private Long courseId;
+
+ /**
+ * 分类(1:作业,2:考试)
+ */
+ private AssignmentsTypeEnum type;
+
+ /**
+ * 作业名称
+ */
+ private String name;
+
+ /**
+ * 作业要求
+ */
+ private String requirements;
+
+ /**
+ * 满分
+ */
+ private Integer fullScore;
+
+ /**
+ * 开始时间
+ */
+ private LocalDateTime startTime;
+
+ /**
+ * 结束时间
+ */
+ private LocalDateTime endTime;
+
+ /**
+ * 示例图片
+ */
+ private String exampleImages;
+
+ /**
+ * 创建人
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/BillingRuleDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/BillingRuleDO.java
new file mode 100644
index 0000000..7d33b07
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/BillingRuleDO.java
@@ -0,0 +1,81 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.io.Serial;
+
+/**
+ * 计费规则实体
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+@Data
+@TableName("t_billing_rule")
+public class BillingRuleDO extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 平台名称
+ */
+ private String platformName;
+
+ /**
+ * 账户类型
+ */
+ private String type;
+
+ /**
+ * 平台ID
+ */
+ private Long platformId;
+
+ /**
+ * 平台编码
+ */
+ private String platformCode;
+
+ /**
+ * 扣费编码
+ */
+ private String chargeCode;
+
+ /**
+ * 计费类型
+ */
+ private Integer chargeType;
+
+ /**
+ * 模型名称
+ */
+ private String modelName;
+
+ /**
+ * 主账户扣减单价(分/次/整数量)
+ */
+ private Long price;
+
+ /**
+ * 子账户单价(次/个/数量)
+ */
+ private Long subAccountPrice;
+
+ /**
+ * 计费单位
+ */
+ private String unit;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 是否启用(0:禁用 1:启用)
+ */
+ private Integer enabled;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ConsumptionHistoryDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ConsumptionHistoryDO.java
new file mode 100644
index 0000000..19d8114
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ConsumptionHistoryDO.java
@@ -0,0 +1,58 @@
+package top.continew.admin.business.model.entity;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.io.Serial;
+
+/**
+ * 用户充值消费历史记录实体
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@TableName("t_consumption_history")
+public class ConsumptionHistoryDO extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+
+ /**
+ * 生成平台
+ */
+ private Long platformId;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ private Integer taskType;
+
+ /**
+ * 点数量
+ */
+ private Long chargePoints;
+
+ /**
+ * 剩余的点数
+ */
+ private Long remainingPoints;
+
+ /**
+ * 记录类型(0充点 1 次数 2 点数)
+ */
+ private Integer type;
+
+ /**
+ * 子账号类型(0主账号,1子账号)
+ */
+ private Integer accountType;
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/Copyright.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/Copyright.java
new file mode 100644
index 0000000..b3b672a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/Copyright.java
@@ -0,0 +1,36 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.time.LocalDateTime;
+
+/**
+ * 数字人-文案实体类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dh_copyright")
+public class Copyright extends BaseDO {
+
+ /**
+ * 文案 ID
+ */
+ private Long id;
+
+ /**
+ * 用户 ID
+ */
+ private String userId;
+
+ /**
+ * 文案内容
+ */
+ private String text;
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/CourseUserDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/CourseUserDO.java
new file mode 100644
index 0000000..5a7ab9b
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/CourseUserDO.java
@@ -0,0 +1,45 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 课程关联学生实体
+ *
+ * @author 张波
+ * @since 2024/10/22 12:14
+ */
+@Data
+@TableName("course_user")
+public class CourseUserDO extends BaseIdDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程ID
+ */
+ private Long courseId;
+
+ /**
+ * 学生ID
+ */
+ private Long userId;
+
+ /**
+ * 学生姓名
+ */
+ private String nickname;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/CoursesDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/CoursesDO.java
new file mode 100644
index 0000000..c0c91dc
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/CoursesDO.java
@@ -0,0 +1,66 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 课程实体
+ *
+ * @author 张波
+ * @since 2024/10/22 11:58
+ */
+@Data
+@TableName("courses")
+public class CoursesDO extends BaseIdDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程名称
+ */
+ private String name;
+
+ /**
+ * 描述
+ */
+ private String description;
+
+ /**
+ * 班级
+ */
+ private String className;
+
+ /**
+ * 封面
+ */
+ private String coverImage;
+
+ /**
+ * 开始时间
+ */
+ private LocalDateTime startTime;
+
+ /**
+ * 结束时间
+ */
+ private LocalDateTime endTime;
+
+ /**
+ * 创建人
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DeptModelDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DeptModelDO.java
new file mode 100644
index 0000000..9b452b3
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DeptModelDO.java
@@ -0,0 +1,31 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.io.Serial;
+
+/**
+ * 部门与模型绑定实体类
+ *
+ * @author 张波
+ * @since 2024/10/20 14:24
+ */
+@Data
+@TableName("dept_model")
+public class DeptModelDO extends BaseIdDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 部门ID
+ */
+ private Long deptId;
+
+ /**
+ * 模型ID
+ */
+ private Integer modelId;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DeptPlatformDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DeptPlatformDO.java
new file mode 100644
index 0000000..114adc6
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DeptPlatformDO.java
@@ -0,0 +1,26 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+/**
+ * 部门与操作平台绑定实体类
+ *
+ * @author 张波
+ * @since 2024/10/20 14:34
+ */
+@Data
+@TableName("dept_platform")
+public class DeptPlatformDO extends BaseIdDO {
+
+ /**
+ * 部门ID
+ */
+ private Long deptId;
+
+ /**
+ * 操作平台
+ */
+ private String platform;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DigitalHuman.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DigitalHuman.java
new file mode 100644
index 0000000..40895ed
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/DigitalHuman.java
@@ -0,0 +1,74 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+/**
+ * 数字人实体类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dh_digital_human")
+public class DigitalHuman extends BaseDO {
+
+ /**
+ * 数字人唯一标识符
+ */
+ private Long id;
+
+ /**
+ * 创建数字人的用户ID
+ */
+ private String userId;
+
+ /**
+ * 用户输入的文案提示
+ */
+ private String copywriting;
+
+ /**
+ * 生成语音文件的URL
+ */
+ private String generatedVoiceUrl;
+
+ /**
+ * 生成帧图像URL(或空字符串)
+ */
+ private String generatedFrameImageUrl;
+
+ /**
+ * 最终合成视频URL
+ */
+ private String generatedVideoUrl;
+
+ /**
+ * 字幕项列表(冗余存储,用于快速回显)
+ */
+ private String subtitle;
+
+ /**
+ * 字幕样式配置(冗余或快照)
+ */
+ private String subtitleStyle;
+
+ /**
+ * 特效列表(冗余存储)
+ */
+ private String effects;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/Effect.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/Effect.java
new file mode 100644
index 0000000..1063a5b
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/Effect.java
@@ -0,0 +1,113 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+/**
+ * 数字人-特效实体类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dh_effect")
+public class Effect extends BaseDO {
+
+ /**
+ * 特效ID(通常来自模板或任务生成)
+ */
+ private Long id;
+
+ /**
+ * 特效名称
+ */
+ private String name;
+
+ /**
+ * 特效模板ID
+ */
+ private Long templateId;
+
+ /**
+ * 关联的数字人任务ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 特效类型('text','image','music','audio')
+ */
+ private String type;
+
+ /**
+ * 特效资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 特效显示位置X坐标(像素)
+ */
+ private Integer positionX;
+
+ /**
+ * 特效显示位置Y坐标(像素)
+ */
+ private Integer positionY;
+
+ /**
+ * 特效宽度(像素)
+ */
+ private Integer sizeWidth;
+
+ /**
+ * 特效高度(像素)
+ */
+ private Integer sizeHeight;
+
+ /**
+ * 特效最大持续时间(秒)
+ */
+ private Double length;
+
+ /**
+ * 特效文本内容(仅文本类型有效)
+ */
+ private String subtitleText;
+
+ /**
+ * 字幕样式配置(JSON格式)
+ */
+ private String subtitleStyle;
+
+ /**
+ * 字幕中心位置({x, y})
+ */
+ private String subtitlePosition;
+
+ /**
+ * 特效开始偏移时间(秒)
+ */
+ private Double offset;
+
+ /**
+ * 特效播放时间段({"start": x, "end": y})
+ */
+ private String duration;
+
+ /**
+ * 渲染层级(Z轴顺序)
+ */
+ private Integer zIndex;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/EffectTemplate.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/EffectTemplate.java
new file mode 100644
index 0000000..21451e4
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/EffectTemplate.java
@@ -0,0 +1,95 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+/**
+ * 数字人-特效模板实体类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dh_effect_template")
+public class EffectTemplate extends BaseDO {
+
+ /**
+ * 特效模板ID
+ */
+ private Long id;
+
+ /**
+ * 模板名称
+ */
+ private String name;
+
+ /**
+ * 是否为用户自定义特效(true/false)
+ */
+ private String isCustom;
+
+ /**
+ * 上传自定义特效的用户ID(目前仅支持音乐)
+ */
+ private String userId;
+
+ /**
+ * 特效类型
+ */
+ private String type;
+
+ /**
+ * 默认资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 默认尺寸({"width": w, "height": h})
+ */
+ private String size_width;
+
+ private String size_height;
+
+ /**
+ * 默认持续时间(秒),0表示无限
+ */
+ private Double length;
+
+ /**
+ * 默认字幕文本(仅文本类型)
+ */
+ private String subtitleText;
+
+ /**
+ * 关联的字幕样式ID
+ */
+ private Long subtitleStyleId;
+
+ /**
+ * 字幕默认X位置(可为固定值或表达式)
+ */
+ private String subtitlePositionX;
+
+ /**
+ * 字幕默认Y位置
+ */
+ private String subtitlePositionY;
+
+ /**
+ * 封面图URL
+ */
+ private String coverUrl;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/FreeQuotaConfigDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/FreeQuotaConfigDO.java
new file mode 100644
index 0000000..00b942a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/FreeQuotaConfigDO.java
@@ -0,0 +1,67 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.io.Serial;
+import java.math.BigDecimal;
+
+/**
+ * 免费额度配置实体
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Data
+@TableName("t_free_quota_config")
+public class FreeQuotaConfigDO extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 类别编码
+ */
+ private String categoryCode;
+
+ /**
+ * 类别名称
+ */
+ private String categoryName;
+
+ /**
+ * 单位
+ */
+ private String unit;
+
+ /**
+ * 额度
+ */
+ private BigDecimal quota;
+
+ /**
+ * 计费类型(对应ChargeTypeEnum)
+ */
+ private Integer chargeType;
+
+ /**
+ * 账户类型 1:次数 2:点数
+ */
+ private Integer type;
+
+ /**
+ * 描述
+ */
+ private String description;
+
+ /**
+ * 排序
+ */
+ private Integer sort;
+
+ /**
+ * 是否启用 0:禁用 1:启用
+ */
+ private Boolean isEnabled;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/HomeworkDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/HomeworkDO.java
new file mode 100644
index 0000000..ee8209c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/HomeworkDO.java
@@ -0,0 +1,41 @@
+package top.continew.admin.business.model.entity;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+import java.io.Serial;
+
+/**
+ * 作业实体
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@TableName("t_homework")
+public class HomeworkDO extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ private Long courseId;
+
+ /**
+ * 未交原因
+ */
+ private String cause;
+
+ /**
+ * 1、已交 2、未交
+ */
+ private Integer handedIn;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/HuandaResourceDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/HuandaResourceDO.java
new file mode 100644
index 0000000..bf7c786
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/HuandaResourceDO.java
@@ -0,0 +1,61 @@
+package top.continew.admin.business.model.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+/**
+ * 换哒-文件资源实体
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Data
+@TableName("t_huanda_resource")
+public class HuandaResourceDO extends BaseDO {
+
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 用户ID
+ */
+ private String userId;
+
+ /**
+ * 资源地址
+ */
+ private String url;
+
+ /**
+ * 资源类型:1.服装,2模特,3自定义服装,4.自定义背景
+ */
+ private Integer resourceType;
+
+ @Schema(description = "人物图片年龄")
+ private String age;
+
+ @Schema(description = "人物图片性别:男,女")
+ private String gender;
+
+ @Schema(description = "人物图片区域")
+ private String region;
+
+ // 显式忽略审计字段,防止插入时出错
+ @TableField(exist = false)
+ private Long createUser;
+
+ @TableField(exist = false)
+ private java.time.LocalDateTime createTime;
+
+ @TableField(exist = false)
+ private Long updateUser;
+
+ @TableField(exist = false)
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ModelCategoryDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ModelCategoryDO.java
new file mode 100644
index 0000000..4ba1f6a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ModelCategoryDO.java
@@ -0,0 +1,36 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.io.Serial;
+
+/**
+ * 模型分类表
+ *
+ * @author 张波
+ * @since 2024/10/20 19:42
+ */
+@Data
+@TableName("model_category")
+public class ModelCategoryDO extends BaseIdDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 上级ID
+ */
+ private Long parentId;
+
+ /**
+ * 类型
+ */
+ private String type;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ModelDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ModelDO.java
new file mode 100644
index 0000000..73cd706
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ModelDO.java
@@ -0,0 +1,93 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.admin.common.enums.DisEnableStatusEnum;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.io.Serial;
+
+/**
+ * 模型实体类
+ *
+ * @author 张波
+ * @since 2024/10/19 15:11
+ */
+@Data
+@TableName(value = "model")
+public class ModelDO extends BaseIdDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 模型名称
+ */
+ private String name;
+
+ /**
+ * 平台分类
+ */
+ private String platformCategory;
+
+ /**
+ * 类型
+ */
+ private String type;
+
+ /**
+ * 版本
+ */
+ private String version;
+
+ /**
+ * 分类
+ */
+ private String category;
+
+ /**
+ * 专业分类
+ */
+ private String professionalCategory;
+
+ /**
+ * 系列
+ */
+ private String series;
+
+ /**
+ * 轮播图信息
+ */
+ private String images;
+
+ /**
+ * 推荐分辨率
+ */
+ private String recommendedResolution;
+
+ /**
+ * 提示词是否开启
+ */
+ private DisEnableStatusEnum promptEnabled;
+
+ /**
+ * 采样方法
+ */
+ private String samplingMethod;
+
+ /**
+ * CFG
+ */
+ private Integer cfg;
+
+ /**
+ * VAE
+ */
+ private String vae;
+
+ /**
+ * 采样步数
+ */
+ private Integer samplingSteps;
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderAudioDo.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderAudioDo.java
new file mode 100644
index 0000000..0bb713e
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderAudioDo.java
@@ -0,0 +1,49 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.io.Serial;
+
+/**
+ * 音频平台任务订单表
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+@Data
+@TableName("order_audio")
+public class OrderAudioDo extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 状态
+ */
+ private String state;
+ /**
+ * 删除标示
+ */
+ private String deleteFlag;
+ /**
+ * 任务类型
+ */
+ private String type;
+ /**
+ * 使用的模型
+ */
+ private String model;
+ /**
+ * 消耗点数
+ */
+ private Integer inviteBeans;
+ /**
+ * 存储结果文件路径
+ */
+ private String fileUrl;
+ /**
+ * 订单 类型
+ */
+ private Integer orderType;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderHistoryDo.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderHistoryDo.java
new file mode 100644
index 0000000..1e81177
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderHistoryDo.java
@@ -0,0 +1,53 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.io.Serial;
+
+/**
+ * 平台任务订单历史表
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+@Data
+@TableName("order_history")
+public class OrderHistoryDo extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 状态
+ */
+ private String state;
+ /**
+ * 删除标示
+ */
+ private String deleteFlag;
+ /**
+ * 任务类型
+ */
+ private String type;
+ /**
+ * 使用的模型
+ */
+ private String model;
+ /**
+ * 消耗点数
+ */
+ private Integer inviteBeans;
+ /**
+ * 剩余的点数
+ */
+ private Integer remainder;
+ /**
+ * 记录类型:支出;增加
+ */
+ private String formType;
+ /**
+ * 生成平台
+ */
+ private String platform;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderThreeDo.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderThreeDo.java
new file mode 100644
index 0000000..c2580bf
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderThreeDo.java
@@ -0,0 +1,49 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.io.Serial;
+
+/**
+ * 3D平台任务订单表
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+@Data
+@TableName("order_three")
+public class OrderThreeDo extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 状态
+ */
+ private String state;
+ /**
+ * 删除标示
+ */
+ private String deleteFlag;
+ /**
+ * 任务类型
+ */
+ private String type;
+ /**
+ * 使用的模型
+ */
+ private String model;
+ /**
+ * 消耗点数
+ */
+ private Integer inviteBeans;
+ /**
+ * 存储结果文件路径
+ */
+ private String fileUrl;
+ /**
+ * 订单 类型
+ */
+ private Integer orderType;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderVideoDo.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderVideoDo.java
new file mode 100644
index 0000000..b74ef50
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/OrderVideoDo.java
@@ -0,0 +1,48 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serial;
+
+/**
+ * 视频平台任务订单表
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+@Data
+@TableName("order_video")
+public class OrderVideoDo {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 状态
+ */
+ private String state;
+ /**
+ * 删除标示
+ */
+ private String deleteFlag;
+ /**
+ * 任务类型
+ */
+ private String type;
+ /**
+ * 使用的模型
+ */
+ private String model;
+ /**
+ * 消耗点数
+ */
+ private Integer inviteBeans;
+ /**
+ * 存储结果文件路径
+ */
+ private String fileUrl;
+ /**
+ * 订单 类型
+ */
+ private Integer orderType;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/PlantformBalanceDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/PlantformBalanceDO.java
new file mode 100644
index 0000000..242e487
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/PlantformBalanceDO.java
@@ -0,0 +1,58 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户子账号余额表实体
+ *
+ * @author jiay
+ * @since 2025/06/24 16:47
+ */
+@Data
+@TableName("t_plantform_balance")
+public class PlantformBalanceDO extends BaseIdDO {
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+
+ /**
+ * 账户类型 1 次数 2 点数
+ */
+ private Integer type;
+
+ /**
+ * 余额
+ */
+ private Long balance;
+
+ /**
+ * 计费类型(token:0, 图:1, 音频:3, 视频:4, 白膜贴图/3D:5)
+ */
+ private Integer chargeType;
+
+ /**
+ * 修改人
+ */
+ @TableField(fill = FieldFill.UPDATE)
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @TableField(fill = FieldFill.UPDATE)
+ private LocalDateTime updateTime;
+
+ /**
+ * 预扣减金额(正在进行的任务消耗)
+ */
+ private Long preDeductBalance = 0L;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ScoreDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ScoreDO.java
new file mode 100644
index 0000000..9b08728
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/ScoreDO.java
@@ -0,0 +1,61 @@
+package top.continew.admin.business.model.entity;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+import java.io.Serial;
+
+/**
+ * 分数实体
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@TableName("t_score")
+public class ScoreDO extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ private Long courseId;
+
+ /**
+ * 考试分数
+ */
+ private Integer examScore;
+
+ /**
+ * 作业分数
+ */
+ private Integer homeworkScore;
+
+ /**
+ * 签到分数
+ */
+ private Integer score;
+
+ /**
+ * 最终总分数
+ */
+ private Integer signInScore;
+
+ /**
+ * 1、已考 2、未考
+ */
+ private Integer takeExam;
+
+ /**
+ * 未考试原因
+ */
+ private String cause;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SignInDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SignInDO.java
new file mode 100644
index 0000000..34f608c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SignInDO.java
@@ -0,0 +1,59 @@
+package top.continew.admin.business.model.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+import java.io.Serial;
+
+/**
+ * 签到实体
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@TableName("t_sign_in")
+public class SignInDO extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+ private String userName;
+
+ /**
+ * 学号
+ */
+ private String stuNo;
+
+ /**
+ * 手机
+ */
+ @Schema(description = "手机")
+ private String phone;
+
+ /**
+ * 课程id
+ */
+ private Long courseId;
+ private String courseName;
+ /**
+ * 请假原因
+ */
+ private String leaveCause;
+
+ /**
+ * 1、签到 2、请假 3、旷课
+ */
+ private Integer signIn;
+
+ /**
+ * 经纬度
+ */
+ private String location;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SubtitleItem.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SubtitleItem.java
new file mode 100644
index 0000000..1370859
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SubtitleItem.java
@@ -0,0 +1,53 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+/**
+ * 数字人-字幕项实体类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dh_subtitle_item")
+public class SubtitleItem extends BaseDO {
+
+ /**
+ * 字幕项ID
+ */
+ private Long id;
+
+ /**
+ * 关联的数字人ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字幕文本内容
+ */
+ private String text;
+
+ /**
+ * 字幕开始时间(秒)
+ */
+ private Double startTime;
+
+ /**
+ * 字幕结束时间(秒)
+ */
+ private Double endTime;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SubtitleStyle.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SubtitleStyle.java
new file mode 100644
index 0000000..f902977
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/SubtitleStyle.java
@@ -0,0 +1,83 @@
+package top.continew.admin.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+/**
+ * 数字人-字幕样式实体类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dh_subtitle_style")
+public class SubtitleStyle extends BaseDO {
+
+ /**
+ * 字幕样式ID
+ */
+ private Long id;
+
+ /**
+ * 关联的数字人ID(可为空,用于全局/默认样式)
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字体大小(像素)
+ */
+ private Integer fontSize;
+
+ /**
+ * 字体族(如微软雅黑、Arial等)
+ */
+ private String fontFamily;
+
+ /**
+ * 文字颜色(CSS格式,如 #FFFFFF)
+ */
+ private String color;
+
+ /**
+ * 描边颜色
+ */
+ private String strokeColor;
+
+ /**
+ * 描边宽度(像素)
+ */
+ private Integer strokeWidth;
+
+ /**
+ * 阴影颜色
+ */
+ private String shadowColor;
+
+ /**
+ * 阴影模糊半径(像素)
+ */
+ private Integer shadowBlur;
+
+ /**
+ * 底部内边距(像素)
+ */
+ private Integer paddingBottom;
+
+ /**
+ * 行高(像素或倍数)
+ */
+ private Integer lineHeight;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/TaskRecordHistoryDO.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/TaskRecordHistoryDO.java
new file mode 100644
index 0000000..4a1bbc9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/entity/TaskRecordHistoryDO.java
@@ -0,0 +1,114 @@
+package top.continew.admin.business.model.entity;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import top.continew.starter.extension.crud.model.entity.BaseDO;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * 换哒-任务生成记录实体
+ *
+ * @author 王志维
+ * @since 2025/12/19 15:37
+ */
+@Data
+@TableName("t_task_record_history")
+public class TaskRecordHistoryDO extends BaseDO {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+
+ /**
+ * 文件名
+ */
+ private String title;
+
+ /**
+ * 根任务ID
+ */
+ private String taskRootId;
+
+ /**
+ * 任务订单号
+ */
+ private String taskId;
+
+ /**
+ * 记录父任务 ID
+ */
+ private String parentTaskId;
+
+ /**
+ * 生成平台
+ */
+ private Long platformId;
+
+ /**
+ * 内容来源的平台
+ */
+ private String platformCode;
+
+ /**
+ * 任务类型:1 - 初始模特穿衣生成(仅根任务可用),2 - 对话修改,3 - 生成视频
+ */
+ private Integer taskType;
+
+ /**
+ * 使用的模型
+ */
+ private String modelName;
+
+ /**
+ * 消耗点数
+ */
+ private Long consumptionPoints;
+
+ /**
+ * 存储结果文件路径
+ */
+ private String fileUrl;
+
+ /**
+ * 消费的token数
+ */
+ private long tokens;
+
+ /**
+ * 生成的文字
+ */
+ private String result;
+
+ /**
+ * 父任务创建时间
+ */
+ private LocalDateTime parentCreateTime;
+
+ /**
+ * 任务类型(文字内容:0, 图:2,音效:3,视频:4, 白膜贴图:5)
+ */
+ private Integer chargeType;
+
+ /**
+ * 文件类型
+ */
+ private String fileType;
+
+ /**
+ * 消费类型(0充点,1按次数,2按点数)
+ */
+ private Integer type;
+
+ /**
+ * 从哪个账户进行的扣费
+ */
+ private String accountType;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/AssignmentsQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/AssignmentsQuery.java
new file mode 100644
index 0000000..b0ce084
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/AssignmentsQuery.java
@@ -0,0 +1,37 @@
+package top.continew.admin.business.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 作业表查询条件
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+@Data
+@Schema(description = "作业表查询条件")
+public class AssignmentsQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程表ID
+ */
+ @Schema(description = "课程表ID")
+ @Query(type = QueryType.EQ)
+ private Long courseId;
+
+ /**
+ * 作业名称
+ */
+ @Schema(description = "作业名称")
+ @Query(type = QueryType.EQ)
+ private String name;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/BillingRuleQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/BillingRuleQuery.java
new file mode 100644
index 0000000..7a29689
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/BillingRuleQuery.java
@@ -0,0 +1,65 @@
+package top.continew.admin.business.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 计费规则查询条件
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+@Data
+@Schema(description = "计费规则查询条件")
+public class BillingRuleQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 平台名称
+ */
+ @Schema(description = "平台名称", example = "AI绘画")
+ @Query(columns = {"platform_name"}, type = QueryType.LIKE)
+ private String platformName;
+
+ /**
+ * 平台ID
+ */
+ @Schema(description = "平台ID", example = "10000")
+ @Query(columns = {"platform_id"}, type = QueryType.EQ)
+ private Long platformId;
+
+ /**
+ * 平台编码
+ */
+ @Schema(description = "平台编码", example = "KEXUE_CHAT")
+ @Query(columns = {"platform_code"}, type = QueryType.EQ)
+ private String platformCode;
+
+ /**
+ * 扣费编码
+ */
+ @Schema(description = "扣费编码", example = "C0001")
+ @Query(columns = {"charge_code"}, type = QueryType.EQ)
+ private String chargeCode;
+
+ /**
+ * 模型名称
+ */
+ @Schema(description = "模型名称", example = "flux")
+ @Query(columns = {"model_name"}, type = QueryType.LIKE)
+ private String modelName;
+
+ /**
+ * 是否启用
+ */
+ @Schema(description = "是否启用", example = "1")
+ @Query(columns = {"enabled"}, type = QueryType.EQ)
+ private Integer enabled;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ConsumptionHistoryQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ConsumptionHistoryQuery.java
new file mode 100644
index 0000000..ab13720
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ConsumptionHistoryQuery.java
@@ -0,0 +1,81 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.*;
+
+/**
+ * 用户充值消费历史记录查询条件
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "用户充值消费历史记录查询条件")
+public class ConsumptionHistoryQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @Query(type = QueryType.EQ)
+ private Long userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ @Query(type = QueryType.EQ)
+ private Long platformId;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ @Query(type = QueryType.EQ)
+ private Integer taskType;
+
+ /**
+ * 点数量
+ */
+ @Schema(description = "点数量")
+ @Query(type = QueryType.EQ)
+ private Long chargePoints;
+
+ /**
+ * 剩余的点数
+ */
+ @Schema(description = "剩余的点数")
+ @Query(type = QueryType.EQ)
+ private Long remainingPoints;
+
+ /**
+ * 记录类型(0充点 1 次数 2 点数)
+ */
+ @Schema(description = "记录类型(0充点 1 次数 2 点数)")
+ @Query(type = QueryType.EQ)
+ private Integer chargeType;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ @Query(type = QueryType.EQ)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Query(type = QueryType.EQ)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/CopyrightPageQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/CopyrightPageQuery.java
new file mode 100644
index 0000000..b998042
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/CopyrightPageQuery.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+
+/**
+ * 文案分页查询对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CopyrightPageQuery extends PageQuery {
+ // 可根据需要添加额外的分页查询条件
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/CopyrightQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/CopyrightQuery.java
new file mode 100644
index 0000000..ca0ff23
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/CopyrightQuery.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 文案查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+public class CopyrightQuery implements Serializable {
+ private String userId;
+ private String text;
+ private String createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/DigitalHumanPageQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/DigitalHumanPageQuery.java
new file mode 100644
index 0000000..0c3d30a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/DigitalHumanPageQuery.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+
+/**
+ * 数字人分页查询对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DigitalHumanPageQuery extends PageQuery {
+ // 可根据需要添加额外的分页查询条件
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/DigitalHumanQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/DigitalHumanQuery.java
new file mode 100644
index 0000000..1df0d32
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/DigitalHumanQuery.java
@@ -0,0 +1,22 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 数字人查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+public class DigitalHumanQuery implements Serializable {
+ private String userId;
+ private String copywriting;
+ private String generatedVoiceUrl;
+ private String generatedFrameImageUrl;
+ private String generatedVideoUrl;
+ private String subtitle;
+ private String subtitleStyle;
+ private String effects;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectPageQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectPageQuery.java
new file mode 100644
index 0000000..3dff23b
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectPageQuery.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+
+/**
+ * 特效分页查询对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectPageQuery extends PageQuery {
+ // 可根据需要添加额外的分页查询条件
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectQuery.java
new file mode 100644
index 0000000..55a8b76
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectQuery.java
@@ -0,0 +1,30 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 特效查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+public class EffectQuery implements Serializable {
+ private String name;
+ private Long templateId;
+ private Long digitalHumanId;
+ private String type;
+ private String sourceUrl;
+ private Integer positionX;
+ private Integer positionY;
+ private Integer sizeWidth;
+ private Integer sizeHeight;
+ private Double length;
+ private String subtitleText;
+ private String subtitleStyle;
+ private String subtitlePosition;
+ private Double offset;
+ private String duration;
+ private Integer zIndex;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectTemplatePageQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectTemplatePageQuery.java
new file mode 100644
index 0000000..710e1a1
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectTemplatePageQuery.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+
+/**
+ * 特效模板分页查询对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectTemplatePageQuery extends PageQuery {
+ // 可根据需要添加额外的分页查询条件
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectTemplateQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectTemplateQuery.java
new file mode 100644
index 0000000..841f020
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/EffectTemplateQuery.java
@@ -0,0 +1,26 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 特效模板查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+public class EffectTemplateQuery implements Serializable {
+ private String name;
+ private String isCustom;
+ private String userId;
+ private String type;
+ private String sourceUrl;
+ private String size;
+ private Double length;
+ private String subtitleText;
+ private Long subtitleStyleId;
+ private String subtitlePositionX;
+ private String subtitlePositionY;
+ private String coverUrl;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/FreeQuotaConfigQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/FreeQuotaConfigQuery.java
new file mode 100644
index 0000000..7f689cd
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/FreeQuotaConfigQuery.java
@@ -0,0 +1,58 @@
+package top.continew.admin.business.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 免费额度配置查询条件
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Data
+@Schema(description = "免费额度配置查询条件")
+public class FreeQuotaConfigQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 类别编码
+ */
+ @Schema(description = "类别编码", example = "TOKEN")
+ @Query(columns = {"category_code"}, type = QueryType.EQ)
+ private String categoryCode;
+
+ /**
+ * 类别名称
+ */
+ @Schema(description = "类别名称", example = "大模型")
+ @Query(columns = {"category_name"}, type = QueryType.LIKE)
+ private String categoryName;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型", example = "0")
+ @Query(columns = {"charge_type"}, type = QueryType.EQ)
+ private Integer chargeType;
+
+ /**
+ * 账户类型
+ */
+ @Schema(description = "账户类型", example = "1")
+ @Query(columns = {"type"}, type = QueryType.EQ)
+ private Integer type;
+
+ /**
+ * 是否启用
+ */
+ @Schema(description = "是否启用", example = "true")
+ @Query(columns = {"is_enabled"}, type = QueryType.EQ)
+ private Boolean isEnabled;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HomeworkQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HomeworkQuery.java
new file mode 100644
index 0000000..006ac31
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HomeworkQuery.java
@@ -0,0 +1,65 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.*;
+
+/**
+ * 作业查询条件
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@Schema(description = "作业查询条件")
+public class HomeworkQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ @Query(type = QueryType.EQ)
+ private Long courseId;
+
+ /**
+ * 未交原因
+ */
+ @Schema(description = "未交原因")
+ @Query(type = QueryType.LIKE)
+ private String cause;
+
+ /**
+ * 1、已交 2、未交
+ */
+ @Schema(description = "已交/未交")
+ @Query(type = QueryType.EQ)
+ private Integer handedIn;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ @Query(type = QueryType.EQ)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Query(type = QueryType.EQ)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HuandaResourcePageQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HuandaResourcePageQuery.java
new file mode 100644
index 0000000..321b691
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HuandaResourcePageQuery.java
@@ -0,0 +1,40 @@
+package top.continew.admin.business.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 换哒-文件资源查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Data
+@Schema(description = "换哒-文件资源查询条件")
+public class HuandaResourcePageQuery extends PageQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "资源ID")
+ private Long id;
+
+ @Schema(description = "用户ID")
+ private String userId;
+
+ @Schema(description = "资源类型:1.服装,2模特,3自定义服装,4.自定义背景")
+ private Integer resourceType;
+
+ @Schema(description = "人物图片年龄")
+ private String age;
+
+ @Schema(description = "人物图片性别:男,女")
+ private String gender;
+
+ @Schema(description = "人物图片区域")
+ private String region;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HuandaResourceQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HuandaResourceQuery.java
new file mode 100644
index 0000000..170b885
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/HuandaResourceQuery.java
@@ -0,0 +1,39 @@
+package top.continew.admin.business.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 换哒-文件资源查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Data
+@Schema(description = "换哒-文件资源查询条件")
+public class HuandaResourceQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "资源ID")
+ private Long id;
+
+ @Schema(description = "用户ID")
+ private String userId;
+
+ @Schema(description = "资源类型:1.服装,2模特,3自定义服装,4.自定义背景")
+ private Integer resourceType;
+
+ @Schema(description = "人物图片年龄")
+ private String age;
+
+ @Schema(description = "人物图片性别:男,女")
+ private String gender;
+
+ @Schema(description = "人物图片区域")
+ private String region;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ModelQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ModelQuery.java
new file mode 100644
index 0000000..dffebba
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ModelQuery.java
@@ -0,0 +1,77 @@
+package top.continew.admin.business.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 模型查询条件
+ *
+ * @author 张波
+ * @since 2024/10/19 15:38
+ */
+@Data
+@Schema(description = "模型查询条件")
+public class ModelQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "模型ID", example = "1")
+ @Query(columns = {"id"}, type = QueryType.IN)
+ private List ids;
+
+ /**
+ * 模型名称
+ */
+ @Schema(description = "模型名称", example = "测试模型")
+ @Query(columns = {"name"}, type = QueryType.LIKE)
+ private String name;
+
+ /**
+ * 平台分类
+ */
+ @Schema(description = "平台分类", example = "绘画")
+ @Query(columns = {"platform_category"}, type = QueryType.EQ)
+ private String platformCategory;
+
+ /**
+ * 类型
+ */
+ @Schema(description = "类型", example = "Lora")
+ @Query(columns = {"type"}, type = QueryType.EQ)
+ private String type;
+
+ /**
+ * 版本
+ */
+ @Schema(description = "版本", example = "SDXL")
+ @Query(columns = {"version"}, type = QueryType.EQ)
+ private String version;
+
+ /**
+ * 分类
+ */
+ @Schema(description = "分类", example = "动漫游戏")
+ @Query(columns = {"category"}, type = QueryType.EQ)
+ private String category;
+
+ /**
+ * 专业分类
+ */
+ @Schema(description = "专业分类", example = "环境艺术")
+ @Query(columns = "professional_category", type = QueryType.EQ)
+ private String professionalCategory;
+
+ /**
+ * 系列
+ */
+ @Schema(description = "系列", example = "室内系列")
+ @Query(columns = {"series"}, type = QueryType.EQ)
+ private String series;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/PlantformBalanceQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/PlantformBalanceQuery.java
new file mode 100644
index 0000000..6d93f34
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/PlantformBalanceQuery.java
@@ -0,0 +1,46 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.*;
+
+/**
+ * 用户子账号余额表 查询条件
+ *
+ * @author jiay
+ * @since 2025/06/24 16:47
+ */
+@Data
+@Schema(description = "business查询条件")
+public class PlantformBalanceQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @Query(type = QueryType.EQ)
+ private Long userId;
+
+ /**
+ * 账户类型 1 次数 2 点数
+ */
+ @Schema(description = "账户类型")
+ @Query(type = QueryType.EQ)
+ private Integer type;
+
+ /**
+ * 平台
+ */
+ @Schema(description = "平台")
+ @Query(type = QueryType.EQ)
+ private Long platformId;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ScoreQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ScoreQuery.java
new file mode 100644
index 0000000..afff08d
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/ScoreQuery.java
@@ -0,0 +1,53 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.*;
+
+/**
+ * 分数查询条件
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@Schema(description = "分数查询条件")
+public class ScoreQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @Query(type = QueryType.EQ)
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ @Query(type = QueryType.EQ)
+ private Long courseId;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ @Query(type = QueryType.EQ)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Query(type = QueryType.EQ)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SignInQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SignInQuery.java
new file mode 100644
index 0000000..55c1f7d
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SignInQuery.java
@@ -0,0 +1,77 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.*;
+
+/**
+ * 签到查询条件
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@Schema(description = "签到查询条件")
+public class SignInQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @Query(type = QueryType.EQ)
+ private Long userId;
+ private String userName;
+
+ /**
+ * 学号
+ */
+ private String stuNo;
+
+ /**
+ * 手机
+ */
+ @Schema(description = "手机")
+ private String phone;
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ @Query(type = QueryType.EQ)
+ private Long courseId;
+ private String courseName;
+ /**
+ * 请假原因
+ */
+ @Schema(description = "请假原因")
+ @Query(type = QueryType.LIKE)
+ private String leaveCause;
+
+ /**
+ * 1、签到 2、请假 3、旷课
+ */
+ @Schema(description = "签到")
+ @Query(type = QueryType.EQ)
+ private Integer signIn;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ @Query(type = QueryType.EQ)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Query(type = QueryType.EQ)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleItemPageQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleItemPageQuery.java
new file mode 100644
index 0000000..a5bfee6
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleItemPageQuery.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+
+/**
+ * 字幕项分页查询对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleItemPageQuery extends PageQuery {
+ // 可根据需要添加额外的分页查询条件
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleItemQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleItemQuery.java
new file mode 100644
index 0000000..72e69d2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleItemQuery.java
@@ -0,0 +1,18 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 字幕项查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+public class SubtitleItemQuery implements Serializable {
+ private Long digitalHumanId;
+ private String text;
+ private Double startTime;
+ private Double endTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleStylePageQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleStylePageQuery.java
new file mode 100644
index 0000000..a48a45c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleStylePageQuery.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+
+/**
+ * 字幕样式分页查询对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleStylePageQuery extends PageQuery {
+ // 可根据需要添加额外的分页查询条件
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleStyleQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleStyleQuery.java
new file mode 100644
index 0000000..865e3cb
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/SubtitleStyleQuery.java
@@ -0,0 +1,24 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 字幕样式查询条件
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+public class SubtitleStyleQuery implements Serializable {
+ private Long digitalHumanId;
+ private Integer fontSize;
+ private String fontFamily;
+ private String color;
+ private String strokeColor;
+ private Integer strokeWidth;
+ private String shadowColor;
+ private Integer shadowBlur;
+ private Integer paddingBottom;
+ private Integer lineHeight;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/query/TaskRecordHistoryQuery.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/TaskRecordHistoryQuery.java
new file mode 100644
index 0000000..9afa4fa
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/query/TaskRecordHistoryQuery.java
@@ -0,0 +1,88 @@
+package top.continew.admin.business.model.query;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import top.continew.starter.data.core.annotation.Query;
+import top.continew.starter.data.core.enums.QueryType;
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.*;
+
+/**
+ * 音视图文生成记录查询条件
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "音视图文生成记录查询条件")
+public class TaskRecordHistoryQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @Query(type = QueryType.EQ)
+ private Long userId;
+
+ /**
+ * 任务订单号
+ */
+ @Schema(description = "任务订单号")
+ @Query(type = QueryType.EQ)
+ private String taskId;
+
+ /**
+ * 文件名
+ */
+ @Schema(description = "文件名")
+ @Query(type = QueryType.EQ)
+ private String title;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ @Query(type = QueryType.EQ)
+ private Long platformId;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ @Query(type = QueryType.EQ)
+ private Integer taskType;
+
+ /**
+ * 计费类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "计费类型(token:0, 图:1, 音效:3, 视频:4, 白膜贴图:5)")
+ @Query(type = QueryType.EQ)
+ private Integer chargeType;
+
+ /**
+ * 存储结果文件路径
+ */
+ @Schema(description = "存储结果文件路径")
+ @Query(type = QueryType.EQ)
+ private String fileUrl;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ @Query(type = QueryType.EQ)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Query(type = QueryType.EQ)
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentSubmissionsReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentSubmissionsReq.java
new file mode 100644
index 0000000..ff1ccf2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentSubmissionsReq.java
@@ -0,0 +1,45 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+
+/**
+ * 作业提交请求参数
+ *
+ * @author 张波
+ * @since 2024/10/22 12:01
+ */
+@Data
+@Schema(description = "作业提交请求参数")
+public class AssignmentSubmissionsReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 作业ID
+ */
+ @Schema(description = "作业ID")
+ private Long assignmentId;
+
+ /**
+ * 图片标题
+ */
+ @Schema(description = "图片标题")
+ private String imageTitle;
+
+ /**
+ * 图片标签
+ */
+ @Schema(description = "图片标签")
+ private String imageTag;
+
+ /**
+ * 图片地址
+ */
+ @Schema(description = "图片地址")
+ private String imageUrl;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentsCorrectReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentsCorrectReq.java
new file mode 100644
index 0000000..1048ca2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentsCorrectReq.java
@@ -0,0 +1,46 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.Max;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+
+/**
+ * 作业批改请求参数
+ *
+ * @author 张波
+ * @since 2024/10/23 19:56
+ */
+@Data
+@Schema(description = "作业批改请求参数")
+public class AssignmentsCorrectReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 作业ID
+ */
+ @Schema(description = "作业提交记录ID")
+ @NotNull(message = "作业提交记录ID")
+ private Long id;
+
+ /**
+ * 分数
+ */
+ @Schema(description = "分数")
+ @NotNull(message = "分数不能为空")
+ @Max(value = 200, message = "满分不能大于200")
+ @Min(value = 0, message = "分数不能小于0")
+ private Integer score;
+
+ /**
+ * 评语
+ */
+ @Schema(description = "评语")
+ private String feedback;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentsReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentsReq.java
new file mode 100644
index 0000000..b755e01
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/AssignmentsReq.java
@@ -0,0 +1,82 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.Max;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+import top.continew.admin.business.enums.AssignmentsTypeEnum;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 创建或修改作业表信息
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+@Data
+@Schema(description = "创建或修改作业表信息")
+public class AssignmentsReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程表ID
+ */
+ @Schema(description = "课程表ID")
+ @NotNull(message = "课程表ID不能为空")
+ private Long courseId;
+
+ /**
+ * 分类(1:作业,2:考试)
+ */
+ @Schema(description = "类型", example = "1")
+ @NotNull(message = "类型不能为空")
+ private AssignmentsTypeEnum type;
+
+ /**
+ * 作业名称
+ */
+ @Schema(description = "作业名称")
+ @NotBlank(message = "作业名称不能为空")
+ @Length(max = 255, message = "作业名称长度不能超过 {max} 个字符")
+ private String name;
+
+ /**
+ * 作业要求
+ */
+ @Schema(description = "作业要求")
+ @Length(max = 255, message = "作业名称长度不能超过 {max} 个字符")
+ private String requirements;
+
+ /**
+ * 满分
+ */
+ @Schema(description = "满分", example = "100")
+ @Max(value = 200, message = "满分不能超过200")
+ private Integer fullScore;
+
+ /**
+ * 开始时间
+ */
+ @Schema(description = "开始时间")
+ @NotNull(message = "开始时间不能为空")
+ private LocalDateTime startTime;
+
+ /**
+ * 结束时间
+ */
+ @Schema(description = "结束时间")
+ @NotNull(message = "结束时间不能为空")
+ private LocalDateTime endTime;
+
+ /**
+ * 示例图片
+ */
+ private String exampleImages;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BatchReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BatchReq.java
new file mode 100644
index 0000000..434ef23
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BatchReq.java
@@ -0,0 +1,27 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 批量换哒资源操作请求
+ *
+ * @author your name
+ * @since 2025/12/25 15:00
+ */
+@Data
+@Schema(description = "批量换哒资源操作请求")
+public class BatchReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ @NotEmpty(message = "资源ID列表不能为空")
+ @Schema(description = "资源ID列表", example = "[1,2,3]")
+ private List ids;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingJudgeReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingJudgeReq.java
new file mode 100644
index 0000000..931e764
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingJudgeReq.java
@@ -0,0 +1,78 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotNull;
+
+/**
+ * 计费判断请求参数
+ *
+ * @author jiay
+ * @since 2025/08/28 16:23
+ */
+@Data
+public class BillingJudgeReq {
+
+ /**
+ * 平台编码
+ */
+ @Schema(description = "平台编码")
+ private String platformCode;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台id")
+ @NotNull(message = "生成平台不能为空")
+ private Long platformId;
+
+ /**
+ * 使用的模型
+ */
+ @Schema(description = "使用的模型")
+ private String modelName;
+
+ /**
+ * 扣费编码
+ */
+ @Schema(description = "扣费编码", example = "C0001")
+ @NotNull(message = "扣费编码不能为空")
+ private String chargeCode;
+
+ /**
+ * 本次生成数量
+ */
+ @Schema(description = "本次生成数量", example = "1")
+ @NotNull(message = "本次生成数量不能为空")
+ private Integer quantity;
+
+ /**
+ * 本次生成数量
+ */
+ @Schema(description = "本次生成数量", example = "1")
+ @NotNull(message = "本次生成数量不能为空")
+ private Long tokens;
+
+ /**
+ * 计费类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "计费类型(token:0, 图:1, 音效:3, 视频:4, 白膜贴图:5)")
+ @NotNull(message = "计费类型不能为空")
+ private Integer chargeType;
+
+ /**
+ * * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ @NotNull(message = "任务类型不能为空")
+ private Integer taskType;
+
+ /**
+ * 计费类型(0充点,1按次数,2按点数)
+ */
+ @Schema(description = "消费类型(0充点,1按次数,2按点数)")
+ @NotNull(message = "消费类型不能为空")
+ private Integer type;
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingJudgeWithAmountReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingJudgeWithAmountReq.java
new file mode 100644
index 0000000..5e03d9f
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingJudgeWithAmountReq.java
@@ -0,0 +1,22 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 计费判断请求参数(带第三方平台传入的金额)
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class BillingJudgeWithAmountReq extends BillingJudgeReq {
+
+ /**
+ * 预扣减金额(分)- 由第三方平台传入
+ */
+ @Schema(description = "预扣减金额(分)", example = "100")
+ private Long preDeductAmount;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingRuleReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingRuleReq.java
new file mode 100644
index 0000000..5fa03fc
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/BillingRuleReq.java
@@ -0,0 +1,98 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+
+/**
+ * 创建或修改计费规则信息
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+@Data
+@Schema(description = "创建或修改计费规则信息")
+public class BillingRuleReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 平台名称
+ */
+ @Schema(description = "平台名称", example = "AI绘画")
+ @NotBlank(message = "平台名称不能为空")
+ private String platformName;
+
+ /**
+ * 账户类型
+ */
+ @Schema(description = "账户类型", example = "图片")
+ private String type;
+
+ /**
+ * 平台ID
+ */
+ @Schema(description = "平台ID", example = "10000")
+ @NotNull(message = "平台ID不能为空")
+ private Long platformId;
+
+ /**
+ * 平台编码
+ */
+ @Schema(description = "平台编码", example = "KEXUE_CHAT")
+ private String platformCode;
+
+ /**
+ * 扣费编码
+ */
+ @Schema(description = "扣费编码", example = "C0001")
+ @NotBlank(message = "扣费编码不能为空")
+ private String chargeCode;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型", example = "1")
+ private Integer chargeType;
+
+ /**
+ * 模型名称
+ */
+ @Schema(description = "模型名称", example = "flux")
+ private String modelName;
+
+ /**
+ * 主账户单价(分/次/整数量)
+ */
+ @Schema(description = "主账户单价(分/次/整数量)", example = "13")
+ private Long price;
+
+ /**
+ * 子账户单价(次/个/数量)
+ */
+ @Schema(description = "子账户单价(次/个/数量)", example = "1")
+ private Long subAccountPrice;
+
+ /**
+ * 计费单位
+ */
+ @Schema(description = "计费单位", example = "张")
+ private String unit;
+
+ /**
+ * 备注
+ */
+ @Schema(description = "备注", example = "")
+ private String remark;
+
+ /**
+ * 是否启用(0:禁用 1:启用)
+ */
+ @Schema(description = "是否启用", example = "1")
+ private Integer enabled;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CheckPlantBalanceReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CheckPlantBalanceReq.java
new file mode 100644
index 0000000..2b9c519
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CheckPlantBalanceReq.java
@@ -0,0 +1,45 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @Author: jia
+ * @Date: 2025/05/26/9:04
+ * @Description:
+ */
+
+@Data
+@Schema(description = "用户消耗点数余额")
+public class CheckPlantBalanceReq {
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 平台
+ */
+ @Schema(description = "平台")
+ private Long platformId;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型")
+ private Integer chargeType;
+
+ /**
+ * 账号类型
+ */
+ @Schema(description = "类型")
+ private Integer type;
+
+ /**
+ * 点数
+ */
+ @Schema(description = "点数")
+ private Long chargePoints;
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionHistoryAddReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionHistoryAddReq.java
new file mode 100644
index 0000000..98b821c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionHistoryAddReq.java
@@ -0,0 +1,70 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 用户充值消费历史记录创建或修改参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "用户充值消费历史记录创建或修改参数")
+public class ConsumptionHistoryAddReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private String userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ private Long platformId;
+
+ /**
+ * 任务类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(文生:1,图生:2,音效生成:3,参考生视频:4 token:5)")
+ private Integer taskType;
+
+ /**
+ * 点数量
+ */
+ @Schema(description = "点数量")
+ private Long chargePoints;
+
+ /**
+ * 剩余的点数
+ */
+ @Schema(description = "剩余的点数")
+ private Long remainingPoints;
+
+ /**
+ * 记录类型(0充点 1 次数 2 点数)
+ */
+ @Schema(description = "记录类型(0充点 1 次数 2 点数)")
+ private Integer chargeType;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionHistoryEditReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionHistoryEditReq.java
new file mode 100644
index 0000000..fedc89e
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionHistoryEditReq.java
@@ -0,0 +1,72 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户充值消费历史记录创建或修改参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "用户充值消费历史记录创建或修改参数")
+public class ConsumptionHistoryEditReq extends BaseReq {
+
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ private Long id;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ private Long platformId;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 点数量
+ */
+ @Schema(description = "点数量")
+ private Long chargePoints;
+
+ /**
+ * 剩余的点数
+ */
+ @Schema(description = "剩余的点数")
+ private Long remainingPoints;
+
+ /**
+ * 记录类型(0充点 1 次数 2 点数)
+ */
+ @Schema(description = "记录类型(0充点 1 次数 2 点数)")
+ private Integer chargeType;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionReq.java
new file mode 100644
index 0000000..a20a0b6
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ConsumptionReq.java
@@ -0,0 +1,26 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @Author: jia
+ * @Date: 2025/05/26/9:04
+ * @Description:
+ */
+
+@Data
+@Schema(description = "用户消耗点数余额判断参数")
+public class ConsumptionReq {
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 消耗点数量
+ */
+ @Schema(description = "消耗点数量")
+ private Long chargePoints;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CopyrightReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CopyrightReq.java
new file mode 100644
index 0000000..20b039b
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CopyrightReq.java
@@ -0,0 +1,31 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 数字人-文案请求参数对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CopyrightReq extends BaseReq {
+
+ /**
+ * 用户 ID
+ */
+ private String userId;
+
+ /**
+ * 文案内容
+ */
+ private String text;
+
+ /**
+ * 文案创建日期
+ */
+ private String createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CourseUserReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CourseUserReq.java
new file mode 100644
index 0000000..9d1cac9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CourseUserReq.java
@@ -0,0 +1,25 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+
+/**
+ * @author 张波
+ * @since 2024/10/23 21:15
+ */
+@Data
+@Schema(description = "课程关联学生请求")
+public class CourseUserReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "学生ID")
+ private Long userId;
+
+ @Schema(description = "学生姓名")
+ private String nickname;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CoursesReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CoursesReq.java
new file mode 100644
index 0000000..8c51aa9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/CoursesReq.java
@@ -0,0 +1,69 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 创建课程信息
+ *
+ * @author 张波
+ * @since 2024/10/22 11:58
+ */
+@Data
+public class CoursesReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程名称
+ */
+ @Schema(description = "课程名称")
+ @NotNull(message = "课程名称不能为空")
+ private String name;
+
+ /**
+ * 描述
+ */
+ @Schema(description = "课程简介")
+ @NotNull(message = "课程简介不能为空")
+ private String description;
+
+ /**
+ * 班级
+ */
+ @Schema(description = "班级")
+ @NotNull(message = "班级不能为空")
+ private String className;
+
+ /**
+ * 封面
+ */
+ @Schema(description = "封面Url")
+ @NotNull(message = "封面Url不能为空")
+ private String coverImage;
+
+ /**
+ * 开始时间
+ */
+ @Schema(description = "开始时间")
+ @NotNull(message = "开始时间不能为空")
+ private LocalDateTime startTime;
+
+ /**
+ * 结束时间
+ */
+ @Schema(description = "结束时间")
+ @NotNull(message = "结束时间不能为空")
+ private LocalDateTime endTime;
+
+ @Schema(description = "关联学生列表")
+ @NotNull(message = "关联学生不能为空")
+ private List users;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DeptModelReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DeptModelReq.java
new file mode 100644
index 0000000..5952930
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DeptModelReq.java
@@ -0,0 +1,31 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 修改部门与模型绑定关系
+ *
+ * @author 张波
+ * @since 2024/10/20 14:28
+ */
+@Data
+@Schema(description = "修改部门与模型绑定关系")
+public class DeptModelReq {
+
+ /**
+ * 部门ID
+ */
+ @Schema(description = "部门ID", example = "1")
+ @NotNull(message = "部门ID不能为空")
+ private Long deptId;
+
+ /**
+ * 模型ID列表
+ */
+ @Schema(description = "模型ID列表", example = "1,2")
+ private List modelIds;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DeptPlatformReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DeptPlatformReq.java
new file mode 100644
index 0000000..f8d682a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DeptPlatformReq.java
@@ -0,0 +1,30 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 修改部门与操作平台绑定关系
+ *
+ * @author 张波
+ * @since 2024/10/20 14:37
+ */
+@Data
+public class DeptPlatformReq {
+
+ /**
+ * 部门ID
+ */
+ @Schema(description = "部门ID", example = "1")
+ @NotNull(message = "部门ID不能为空")
+ private Long deptId;
+
+ /**
+ * 操作平台列表
+ */
+ @Schema(description = "操作平台列表", example = "AI绘画,comfyUI")
+ private List platforms;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DigitalHumanReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DigitalHumanReq.java
new file mode 100644
index 0000000..8f828dc
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/DigitalHumanReq.java
@@ -0,0 +1,56 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 数字人请求参数对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DigitalHumanReq extends BaseReq {
+
+ /**
+ * 创建数字人的用户ID
+ */
+ private String userId;
+
+ /**
+ * 用户输入的文案提示
+ */
+ private String copywriting;
+
+ /**
+ * 生成语音文件的URL
+ */
+ private String generatedVoiceUrl;
+
+ /**
+ * 生成帧图像URL(或空字符串)
+ */
+ private String generatedFrameImageUrl;
+
+ /**
+ * 最终合成视频URL
+ */
+ private String generatedVideoUrl;
+
+ /**
+ * 字幕项列表(冗余存储,用于快速回显)
+ */
+ private String subtitle;
+
+ /**
+ * 字幕样式配置(冗余或快照)
+ */
+ private String subtitleStyle;
+
+ /**
+ * 特效列表(冗余存储)
+ */
+ private String effects;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/EffectReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/EffectReq.java
new file mode 100644
index 0000000..706ffc3
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/EffectReq.java
@@ -0,0 +1,96 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 数字人-特效请求参数对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectReq extends BaseReq {
+
+ /**
+ * 特效名称
+ */
+ private String name;
+
+ /**
+ * 特效模板ID
+ */
+ private Long templateId;
+
+ /**
+ * 关联的数字人任务ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 特效类型('text','image','music','audio')
+ */
+ private String type;
+
+ /**
+ * 特效资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 特效显示位置X坐标(像素)
+ */
+ private Integer positionX;
+
+ /**
+ * 特效显示位置Y坐标(像素)
+ */
+ private Integer positionY;
+
+ /**
+ * 特效宽度(像素)
+ */
+ private Integer sizeWidth;
+
+ /**
+ * 特效高度(像素)
+ */
+ private Integer sizeHeight;
+
+ /**
+ * 特效最大持续时间(秒)
+ */
+ private Double length;
+
+ /**
+ * 特效文本内容(仅文本类型有效)
+ */
+ private String subtitleText;
+
+ /**
+ * 字幕样式配置(JSON格式)
+ */
+ private String subtitleStyle;
+
+ /**
+ * 字幕中心位置({x, y})
+ */
+ private String subtitlePosition;
+
+ /**
+ * 特效开始偏移时间(秒)
+ */
+ private Double offset;
+
+ /**
+ * 特效播放时间段({"start": x, "end": y})
+ */
+ private String duration;
+
+ /**
+ * 渲染层级(Z轴顺序)
+ */
+ private Integer zIndex;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/EffectTemplateReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/EffectTemplateReq.java
new file mode 100644
index 0000000..dd5b134
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/EffectTemplateReq.java
@@ -0,0 +1,76 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 数字人-特效模板请求参数对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectTemplateReq extends BaseReq {
+
+ /**
+ * 模板名称
+ */
+ private String name;
+
+ /**
+ * 是否为用户自定义特效(true/false)
+ */
+ private String isCustom;
+
+ /**
+ * 上传自定义特效的用户ID(目前仅支持音乐)
+ */
+ private String userId;
+
+ /**
+ * 特效类型
+ */
+ private String type;
+
+ /**
+ * 默认资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 默认尺寸({"width": w, "height": h})
+ */
+ private String size;
+
+ /**
+ * 默认持续时间(秒),0表示无限
+ */
+ private Double length;
+
+ /**
+ * 默认字幕文本(仅文本类型)
+ */
+ private String subtitleText;
+
+ /**
+ * 关联的字幕样式ID
+ */
+ private Long subtitleStyleId;
+
+ /**
+ * 字幕默认X位置(可为固定值或表达式)
+ */
+ private String subtitlePositionX;
+
+ /**
+ * 字幕默认Y位置
+ */
+ private String subtitlePositionY;
+
+ /**
+ * 封面图URL
+ */
+ private String coverUrl;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/FreeQuotaConfigReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/FreeQuotaConfigReq.java
new file mode 100644
index 0000000..80b1dce
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/FreeQuotaConfigReq.java
@@ -0,0 +1,82 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+import java.math.BigDecimal;
+
+/**
+ * 免费额度配置请求信息
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Data
+@Schema(description = "免费额度配置请求信息")
+public class FreeQuotaConfigReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 类别编码
+ */
+ @Schema(description = "类别编码", example = "TOKEN")
+ private String categoryCode;
+
+ /**
+ * 类别名称
+ */
+ @Schema(description = "类别名称", example = "大模型")
+ @NotBlank(message = "类别名称不能为空")
+ private String categoryName;
+
+ /**
+ * 单位
+ */
+ @Schema(description = "单位", example = "token")
+ @NotBlank(message = "单位不能为空")
+ private String unit;
+
+ /**
+ * 额度
+ */
+ @Schema(description = "额度", example = "500000")
+ @NotNull(message = "额度不能为空")
+ private BigDecimal quota;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型", example = "0")
+ private Integer chargeType;
+
+ /**
+ * 账户类型 1:次数 2:点数
+ */
+ @Schema(description = "账户类型", example = "1")
+ @NotNull(message = "账户类型不能为空")
+ private Integer type;
+
+ /**
+ * 描述
+ */
+ @Schema(description = "描述", example = "大模型对话额度")
+ private String description;
+
+ /**
+ * 排序
+ */
+ @Schema(description = "排序", example = "1")
+ private Integer sort;
+
+ /**
+ * 是否启用
+ */
+ @Schema(description = "是否启用", example = "true")
+ private Boolean isEnabled;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/FreeQuotaGrantReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/FreeQuotaGrantReq.java
new file mode 100644
index 0000000..29f1db9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/FreeQuotaGrantReq.java
@@ -0,0 +1,94 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 免费额度赠送请求信息
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Data
+@Schema(description = "免费额度赠送请求信息")
+public class FreeQuotaGrantReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户ID列表
+ */
+ @Schema(description = "用户ID列表")
+ private List userIds;
+
+ /**
+ * 部门ID列表
+ */
+ @Schema(description = "部门ID列表")
+ private List deptIds;
+
+ /**
+ * 额度配置列表(如果为空,则使用默认配置)
+ */
+ @Schema(description = "额度配置列表")
+ private List quotaItems;
+
+ /**
+ * 额度配置项
+ */
+ @Data
+ @Schema(description = "额度配置项")
+ public static class QuotaItem implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 配置ID(从FreeQuotaConfig表获取)
+ */
+ @Schema(description = "配置ID", example = "1")
+ private Long configId;
+
+ /**
+ * 类别编码
+ */
+ @Schema(description = "类别编码", example = "TOKEN")
+ private String categoryCode;
+
+ /**
+ * 类别名称
+ */
+ @Schema(description = "类别名称", example = "大模型")
+ private String categoryName;
+
+ /**
+ * 赠送额度(如果不指定,使用配置中的默认额度)
+ */
+ @Schema(description = "赠送额度", example = "500000")
+ private BigDecimal grantQuota;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型", example = "0")
+ private Integer chargeType;
+
+ /**
+ * 账户类型 1:次数 2:点数
+ */
+ @Schema(description = "账户类型", example = "1")
+ private Integer type;
+
+ /**
+ * 是否启用此项赠送
+ */
+ @Schema(description = "是否启用", example = "true")
+ private Boolean enabled;
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HomeworkAddReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HomeworkAddReq.java
new file mode 100644
index 0000000..b33e3cf
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HomeworkAddReq.java
@@ -0,0 +1,45 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 作业实体创建参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "作业实体创建参数")
+public class HomeworkAddReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+
+ /**
+ * 未交原因
+ */
+ @Schema(description = "未交原因")
+ private String cause;
+
+ /**
+ * 1、已交 2、未交
+ */
+ @Schema(description = "1、已交 2、未交")
+ private Integer handedIn;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HomeworkEditReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HomeworkEditReq.java
new file mode 100644
index 0000000..ab26b7b
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HomeworkEditReq.java
@@ -0,0 +1,46 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 作业实体修改参数
+ *
+ * @author jiay
+ * @since 2025/06/25 08:52
+ */
+@Data
+@Schema(description = "作业实体修改参数")
+public class HomeworkEditReq extends BaseReq {
+
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ private Long id;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+
+ /**
+ * 未交原因
+ */
+ @Schema(description = "未交原因")
+ private String cause;
+
+ /**
+ * 1、已交 2、未交
+ */
+ @Schema(description = "1、已交 2、未交")
+ private Integer handedIn;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HuandaResourceReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HuandaResourceReq.java
new file mode 100644
index 0000000..3900273
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/HuandaResourceReq.java
@@ -0,0 +1,55 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 换哒-文件资源创建或修改参数
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Data
+@Schema(description = "换哒-文件资源创建或修改参数")
+public class HuandaResourceReq extends BaseReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 资源ID
+ */
+ @Schema(description = "资源ID")
+ private Long id;
+
+ /**
+ * 用户ID
+ */
+ @Schema(description = "用户ID")
+ private String userId;
+
+ /**
+ * 资源地址
+ */
+ @Schema(description = "资源地址")
+ private String url;
+
+ /**
+ * 资源类型:1.服装,2模特,3自定义服装,4.自定义背景
+ */
+ @Schema(description = "资源类型:1.服装,2模特,3自定义服装,4.自定义背景")
+ private Integer resourceType;
+
+ @Schema(description = "人物图片年龄")
+ private String age;
+
+ @Schema(description = "人物图片性别:男,女")
+ private String gender;
+
+ @Schema(description = "人物图片区域")
+ private String region;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ModelReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ModelReq.java
new file mode 100644
index 0000000..4a00450
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ModelReq.java
@@ -0,0 +1,108 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import jakarta.validation.constraints.NotNull;
+import top.continew.admin.common.enums.DisEnableStatusEnum;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+
+/**
+ * 创建或修改模型信息
+ *
+ * @author 张波
+ * @since 2024/10/19 15:47
+ */
+@Data
+@Schema(description = "创建或修改模型信息")
+public class ModelReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 模型名称
+ */
+ @Schema(description = "模型名称", example = "测试模型")
+ @NotNull(message = "模型名称不能为空")
+ private String name;
+
+ /**
+ * 平台分类
+ */
+ @Schema(description = "平台分类", example = "绘画")
+ private String platformCategory;
+
+ /**
+ * 类型
+ */
+ @Schema(description = "类型", example = "Lora")
+ private String type;
+
+ /**
+ * 版本
+ */
+ @Schema(description = "版本", example = "SDXL")
+ private String version;
+
+ /**
+ * 分类
+ */
+ @Schema(description = "分类", example = "动漫游戏")
+ private String category;
+
+ /**
+ * 专业分类
+ */
+ @Schema(description = "专业分类", example = "环境艺术")
+ private String professionalCategory;
+
+ /**
+ * 系列
+ */
+ @Schema(description = "系列", example = "室内系列")
+ private String series;
+
+ /**
+ * 轮播图地址
+ */
+ @Schema(description = "轮播图地址", example = "无")
+ private String images;
+
+ /**
+ * 推荐分辨率
+ */
+ @Schema(description = "推荐分辨率", example = "1536*1024")
+ private String recommendedResolution;
+
+ /**
+ * 提示词是否开启
+ */
+ @Schema(description = "提示词是否开启", example = "是/否")
+ private DisEnableStatusEnum promptEnabled;
+
+ /**
+ * 采样方法
+ */
+ @Schema(description = "采样方法", example = "Euler a")
+ private String samplingMethod;
+
+ /**
+ * CFG
+ */
+ @Schema(description = "CFG", example = "3")
+ private Integer cfg;
+
+ /**
+ * VAE
+ */
+ @Schema(description = "VAE", example = "无")
+ private String vae;
+
+ /**
+ * 采样步数
+ */
+ @Schema(description = "采样步数", example = "20")
+ private Integer samplingSteps;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/OrderAudioReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/OrderAudioReq.java
new file mode 100644
index 0000000..7761a29
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/OrderAudioReq.java
@@ -0,0 +1,47 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+
+/**
+ * 音频平台任务订单表
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+@Data
+public class OrderAudioReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 状态
+ */
+ private String state;
+ /**
+ * 删除标示
+ */
+ private String deleteFlag;
+ /**
+ * 任务类型
+ */
+ private String type;
+ /**
+ * 使用的模型
+ */
+ private String model;
+ /**
+ * 消耗点数
+ */
+ private Integer inviteBeans;
+ /**
+ * 存储结果文件路径
+ */
+ private String fileUrl;
+ /**
+ * 订单 类型
+ */
+ private Integer orderType;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/OrderVideoReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/OrderVideoReq.java
new file mode 100644
index 0000000..f4c6066
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/OrderVideoReq.java
@@ -0,0 +1,47 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.io.Serial;
+
+/**
+ * 视频平台任务订单表
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+@Data
+public class OrderVideoReq extends BaseReq {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /**
+ * 状态
+ */
+ private String state;
+ /**
+ * 删除标示
+ */
+ private String deleteFlag;
+ /**
+ * 任务类型
+ */
+ private String type;
+ /**
+ * 使用的模型
+ */
+ private String model;
+ /**
+ * 消耗点数
+ */
+ private Integer inviteBeans;
+ /**
+ * 存储结果文件路径
+ */
+ private String fileUrl;
+ /**
+ * 订单 类型
+ */
+ private Integer orderType;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/PlantformBalanceAddReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/PlantformBalanceAddReq.java
new file mode 100644
index 0000000..e3fa47a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/PlantformBalanceAddReq.java
@@ -0,0 +1,65 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 用户子账号余额表创建参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "用户子账号余额表创建参数")
+public class PlantformBalanceAddReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 账户类型 1 次数 2 点数
+ */
+ @Schema(description = "账户类型")
+ private Integer type;
+
+ /**
+ * 余额
+ */
+ @Schema(description = "余额")
+ private Double balance;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型")
+ private Integer chargeType;
+
+ /**
+ * 平台
+ */
+ @Schema(description = "平台")
+ private Long platformId;
+
+ public PlantformBalanceAddReq initPlantformBalance(CheckPlantBalanceReq req) {
+ initPlantformBalance();
+ this.platformId = req.getPlatformId();
+ this.chargeType = req.getChargeType();
+ this.type = req.getType();
+ this.userId = req.getUserId();
+ return this;
+ }
+
+ public PlantformBalanceAddReq initPlantformBalance() {
+ this.balance = 5D;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/PlantformBalanceEditReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/PlantformBalanceEditReq.java
new file mode 100644
index 0000000..fb26ac7
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/PlantformBalanceEditReq.java
@@ -0,0 +1,46 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 用户子账号余额表修改参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "用户子账号余额表修改参数")
+public class PlantformBalanceEditReq extends BaseReq {
+
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ private Long id;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 账户类型 1 次数 2 点数
+ */
+ @Schema(description = "账户类型")
+ private Integer type;
+
+ /**
+ * 余额
+ */
+ @Schema(description = "余额")
+ private Long balance;
+
+ /**
+ * 平台
+ */
+ @Schema(description = "平台")
+ private Long platformId;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ScoreAddReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ScoreAddReq.java
new file mode 100644
index 0000000..64a2a67
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ScoreAddReq.java
@@ -0,0 +1,69 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 分数创建参数
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@Schema(description = "分数创建参数")
+public class ScoreAddReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+
+ /**
+ * 考试分数
+ */
+ @Schema(description = "考试分数")
+ private Integer examScore;
+
+ /**
+ * 作业分数
+ */
+ @Schema(description = "作业分数")
+ private Integer homeworkScore;
+
+ /**
+ * 签到分数
+ */
+ @Schema(description = "签到分数")
+ private Integer score;
+
+ /**
+ * 最终总分数
+ */
+ @Schema(description = "最终总分数")
+ private Integer signInScore;
+
+ /**
+ * 1、已考 2、未考
+ */
+ @Schema(description = "1、已考 2、未考")
+ private Integer takeExam;
+
+ /**
+ * 未考试原因
+ */
+ @Schema(description = "未考试原因")
+ private String cause;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ScoreEditReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ScoreEditReq.java
new file mode 100644
index 0000000..4f5e5a1
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/ScoreEditReq.java
@@ -0,0 +1,69 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 分数修改参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "分数修改参数")
+public class ScoreEditReq extends BaseReq {
+
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ private Long id;
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+
+ /**
+ * 考试分数
+ */
+ @Schema(description = "考试分数")
+ private Integer examScore;
+
+ /**
+ * 作业分数
+ */
+ @Schema(description = "作业分数")
+ private Integer homeworkScore;
+
+ /**
+ * 签到分数
+ */
+ @Schema(description = "签到分数")
+ private Integer score;
+
+ /**
+ * 最终总分数
+ */
+ @Schema(description = "最终总分数")
+ private Integer signInScore;
+
+ /**
+ * 1、已考 2、未考
+ */
+ @Schema(description = "1、已考 2、未考")
+ private Integer takeExam;
+
+ /**
+ * 未考试原因
+ */
+ @Schema(description = "未考试原因")
+ private String cause;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SignInAddReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SignInAddReq.java
new file mode 100644
index 0000000..6f3cff6
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SignInAddReq.java
@@ -0,0 +1,64 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 签到创建参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "签到创建参数")
+public class SignInAddReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ private String userName;
+
+ /**
+ * 学号
+ */
+ private String stuNo;
+
+ /**
+ * 手机
+ */
+ @Schema(description = "手机")
+ private String phone;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+ private String courseName;
+
+ /**
+ * 请假原因
+ */
+ @Schema(description = "请假原因")
+ private String leaveCause;
+
+ /**
+ * 1、签到 2、请假 3、旷课
+ */
+ @Schema(description = " 1、签到 2、请假 3、旷课")
+ private Integer signIn;
+
+ /**
+ * 经纬度
+ */
+ private String Location;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SignInEditReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SignInEditReq.java
new file mode 100644
index 0000000..a992a17
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SignInEditReq.java
@@ -0,0 +1,61 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 签到修改参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "签到修改参数")
+public class SignInEditReq extends BaseReq {
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ private Long id;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+ private String userName;
+ /**
+ * 学号
+ */
+ private String stuNo;
+
+ /**
+ * 手机
+ */
+ @Schema(description = "手机")
+ private String phone;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+ private String courseName;
+ /**
+ * 请假原因
+ */
+ @Schema(description = "请假原因")
+ private String leaveCause;
+
+ /**
+ * 1、签到 2、请假 3、旷课
+ */
+ @Schema(description = " 1、签到 2、请假 3、旷课")
+ private Integer signIn;
+
+ /**
+ * 经纬度
+ */
+ private String Location;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SubtitleItemReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SubtitleItemReq.java
new file mode 100644
index 0000000..2c8dfce
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SubtitleItemReq.java
@@ -0,0 +1,36 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 数字人-字幕项请求参数对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleItemReq extends BaseReq {
+
+ /**
+ * 关联的数字人ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字幕文本内容
+ */
+ private String text;
+
+ /**
+ * 字幕开始时间(秒)
+ */
+ private Double startTime;
+
+ /**
+ * 字幕结束时间(秒)
+ */
+ private Double endTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SubtitleStyleReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SubtitleStyleReq.java
new file mode 100644
index 0000000..0020907
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/SubtitleStyleReq.java
@@ -0,0 +1,66 @@
+package top.continew.admin.business.model.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+/**
+ * 数字人-字幕样式请求参数对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleStyleReq extends BaseReq {
+
+ /**
+ * 关联的数字人ID(可为空,用于全局/默认样式)
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字体大小(像素)
+ */
+ private Integer fontSize;
+
+ /**
+ * 字体族(如微软雅黑、Arial等)
+ */
+ private String fontFamily;
+
+ /**
+ * 文字颜色(CSS格式,如 #FFFFFF)
+ */
+ private String color;
+
+ /**
+ * 描边颜色
+ */
+ private String strokeColor;
+
+ /**
+ * 描边宽度(像素)
+ */
+ private Integer strokeWidth;
+
+ /**
+ * 阴影颜色
+ */
+ private String shadowColor;
+
+ /**
+ * 阴影模糊半径(像素)
+ */
+ private Integer shadowBlur;
+
+ /**
+ * 底部内边距(像素)
+ */
+ private Integer paddingBottom;
+
+ /**
+ * 行高(像素或倍数)
+ */
+ private Integer lineHeight;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskCallbackReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskCallbackReq.java
new file mode 100644
index 0000000..8368b73
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskCallbackReq.java
@@ -0,0 +1,130 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+/**
+ * 任务回调请求参数
+ *
+ * @author jiay
+ * @since 2025/08/28 16:35
+ */
+@Data
+public class TaskCallbackReq {
+
+ /**
+ * 平台编码
+ */
+ @Schema(description = "平台编码")
+ @NotBlank(message = "平台编码不能为空")
+ private String platformCode;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台ID")
+ @NotNull(message = "生成平台不能为空")
+ private Long platformId;
+
+ /**
+ * 任务订单号
+ */
+ @Schema(description = "任务订单号")
+ @NotBlank(message = "任务订单号不能为空")
+ private String taskId;
+
+ /**
+ * 文件名
+ */
+ @Schema(description = "文件名")
+ private String title;
+
+ /**
+ * 使用的模型
+ */
+ @Schema(description = "使用的模型")
+ private String modelName;
+
+ /**
+ * 扣费编码
+ */
+ @Schema(description = "扣费编码", example = "C0001")
+ private String chargeCode;
+
+ /**
+ * 实际生成数量
+ */
+ @Schema(description = "实际生成数量", example = "1")
+ private Integer quantity;
+
+ /**
+ * 任务状态 (0:进行中, 1:成功, 2:失败)
+ */
+ @Schema(description = "任务状态 (0:进行中, 1:成功, 2:失败)")
+ @NotNull(message = "任务状态不能为空")
+ private Integer status;
+
+ /**
+ * 生成的文字内容(文字类型时填写)
+ */
+ @Schema(description = "生成的文字内容(文字类型时填写)")
+ private String result;
+
+ /**
+ * 消费的token数(文字类型时填写)
+ */
+ @Schema(description = "消费的token数(文字类型时填写)")
+ private Long tokens;
+
+ /**
+ * 文件路径(音视频图片类型时填写)
+ */
+ @Schema(description = "文件路径(音视频图片类型时填写)")
+ private String fileUrl;
+
+ /**
+ * 错误消息(失败时填写)
+ */
+ @Schema(description = "错误消息(失败时填写)")
+ private String errorMessage;
+
+ /**
+ * 计费类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "计费类型(token:0, 图:1, 音效:3, 视频:4, 白膜贴图:5)")
+ @NotNull(message = "计费类型不能为空")
+ private Integer chargeType;
+
+ /**
+ * * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ @NotNull(message = "任务类型不能为空")
+ private Integer taskType;
+
+ /**
+ * 计费类型(0充点,1按次数,2按点数)
+ */
+ @Schema(description = "消费类型(0充点,1按次数,2按点数)")
+ @NotNull(message = "消费类型不能为空")
+ private Integer type;
+
+ /**
+ * 文件类型
+ */
+ @Schema(description = "文件类型")
+ private String fileType;
+
+ @Schema(description = "父任务ID")
+ private String parentTaskId;
+
+ @Schema(description = "父任务创建时间")
+ private String parentCreateTime;
+
+ @Schema(description = "根任务ID")
+ @NotBlank(message = "根任务ID不能为空")
+ private String taskRootId;
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskCallbackWithAmountReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskCallbackWithAmountReq.java
new file mode 100644
index 0000000..253ed71
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskCallbackWithAmountReq.java
@@ -0,0 +1,25 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import jakarta.validation.constraints.NotNull;
+
+/**
+ * 任务回调请求参数(带第三方平台传入的实际消费金额)
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TaskCallbackWithAmountReq extends TaskCallbackReq {
+
+ /**
+ * 实际消费金额(分)- 由第三方平台传入
+ */
+ @Schema(description = "实际消费金额(分)", example = "100")
+ @NotNull(message = "实际消费金额不能为空")
+ private Long actualAmount;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskQueryReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskQueryReq.java
new file mode 100644
index 0000000..cad2550
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskQueryReq.java
@@ -0,0 +1,32 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.Min;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 任务查询请求参数
+ *
+ * @author wangzhiwei
+ * @since 2025/08/28 16:35
+ */
+@Data
+public class TaskQueryReq implements Serializable {
+
+ @Schema(description = "根任务ID")
+ @NotBlank(message = "根任务ID不能为空")
+ private String taskRootId;
+
+ @Min(value = 1, message = "查询页码必须大于0")
+ @Schema(description = "查询页码")
+ private int page = 1;
+
+ @Positive(message = "每页数量必须大于0")
+ @Schema(description = "每页数量")
+ private int size = 10;
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskRecordHistoryAddReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskRecordHistoryAddReq.java
new file mode 100644
index 0000000..a9c814e
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskRecordHistoryAddReq.java
@@ -0,0 +1,74 @@
+package top.continew.admin.business.model.req;
+
+import jakarta.validation.constraints.*;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.*;
+import java.util.List;
+
+/**
+ * 音视图文生成记录创建或修改参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "音视图文生成记录创建或修改参数")
+public class TaskRecordHistoryAddReq implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private String userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ private Long platformId;
+
+ /**
+ * 任务订单号
+ */
+ @Schema(description = "任务订单号")
+ private String taskId;
+
+ /**
+ * 文件名
+ */
+ @Schema(description = "文件名")
+ private String title;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 存储结果文件路径
+ */
+ @Schema(description = "存储结果文件路径")
+ private List fileUrl;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskRecordHistoryEditReq.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskRecordHistoryEditReq.java
new file mode 100644
index 0000000..5b099f6
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/req/TaskRecordHistoryEditReq.java
@@ -0,0 +1,72 @@
+package top.continew.admin.business.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.req.BaseReq;
+
+import java.time.LocalDateTime;
+
+/**
+ * 音视图文生成记录创建或修改参数
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "音视图文生成记录创建或修改参数")
+public class TaskRecordHistoryEditReq extends BaseReq {
+
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ private Long id;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ private Long platformId;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 任务订单号
+ */
+ @Schema(description = "任务订单号")
+ private String taskId;
+
+ /**
+ * 文件名
+ */
+ @Schema(description = "文件名")
+ private String title;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 存储结果文件路径
+ */
+ @Schema(description = "存储结果文件路径")
+ private String fileUrl;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsDetailResp.java
new file mode 100644
index 0000000..e9206cc
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsDetailResp.java
@@ -0,0 +1,80 @@
+package top.continew.admin.business.model.resp;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 作业表详情信息
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "作业表详情信息")
+public class AssignmentsDetailResp extends BaseDetailResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程表ID
+ */
+ @Schema(description = "课程表ID")
+ @ExcelProperty(value = "课程表ID")
+ private Long courseId;
+
+ /**
+ * 分类(1:作业,2:考试)
+ */
+ @Schema(description = "分类(1:作业,2:考试)")
+ @ExcelProperty(value = "分类(1:作业,2:考试)")
+ private Integer type;
+
+ /**
+ * 作业名称
+ */
+ @Schema(description = "作业名称")
+ @ExcelProperty(value = "作业名称")
+ private String name;
+
+ /**
+ * 作业要求
+ */
+ @Schema(description = "作业要求")
+ @ExcelProperty(value = "作业要求")
+ private String requirements;
+
+ /**
+ * 满分
+ */
+ @Schema(description = "满分")
+ @ExcelProperty(value = "满分")
+ private Integer fullScore;
+
+ /**
+ * 开始时间
+ */
+ @Schema(description = "开始时间")
+ @ExcelProperty(value = "开始时间")
+ private LocalDateTime startTime;
+
+ /**
+ * 结束时间
+ */
+ @Schema(description = "结束时间")
+ @ExcelProperty(value = "结束时间")
+ private LocalDateTime endTime;
+
+ /**
+ * 示例图片
+ */
+ @Schema(description = "示例图片")
+ private String exampleImages;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsProgressResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsProgressResp.java
new file mode 100644
index 0000000..d981010
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsProgressResp.java
@@ -0,0 +1,34 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @author 张波
+ * @since 2024/10/23 21:08
+ */
+@Data
+@Schema(description = "作业进度")
+public class AssignmentsProgressResp {
+
+ @Schema(description = "提交记录ID")
+ private Long submissionsId;
+
+ /**
+ * 学生姓名
+ */
+ @Schema(description = "学生姓名")
+ private String nickname;
+
+ /**
+ * 完成情况
+ */
+ @Schema(description = "是否提交作业")
+ private Boolean degreeOfCompletion;
+
+ /**
+ * 批改情况
+ */
+ @Schema(description = "是否批改作业")
+ private Boolean degreeOfCorrection;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsResp.java
new file mode 100644
index 0000000..6e3d8b1
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsResp.java
@@ -0,0 +1,51 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+
+/**
+ * 作业表信息
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+@Data
+@Schema(description = "作业表信息")
+public class AssignmentsResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 课程表ID
+ */
+ @Schema(description = "课程表ID")
+ private Long courseId;
+
+ /**
+ * 作业名称
+ */
+ @Schema(description = "作业名称")
+ private String name;
+
+ /**
+ * 完成情况
+ */
+ @Schema(description = "完成情况,学生为已完成/未完成,老师为百分比", example = "100")
+ private String degreeOfCompletion;
+
+ /**
+ * 示例图片
+ */
+ private String exampleImages;
+
+ /**
+ * 学生角色查询如果已提交作业返回作业提交ID
+ */
+ @Schema(description = "学生角色查询如果已提交作业返回作业提交ID")
+ private Long assignmentsSubmissionsId;
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsSubmissionsDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsSubmissionsDetailResp.java
new file mode 100644
index 0000000..ecb2541
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/AssignmentsSubmissionsDetailResp.java
@@ -0,0 +1,88 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 作业提交记录表详情信息
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+@Data
+@Schema(description = "作业提交记录表详情信息")
+public class AssignmentsSubmissionsDetailResp extends BaseDetailResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 作业名称
+ */
+ @Schema(description = "作业名称")
+ private String name;
+
+ /**
+ * 作业要求
+ */
+ @Schema(description = "作业要求")
+ private String requirements;
+
+ /**
+ * 满分
+ */
+ @Schema(description = "满分")
+ private Integer fullScore;
+
+ /**
+ * 开始时间
+ */
+ @Schema(description = "开始时间")
+ private LocalDateTime startTime;
+
+ /**
+ * 结束时间
+ */
+ @Schema(description = "结束时间")
+ private LocalDateTime endTime;
+
+ /**
+ * 示例图片
+ */
+ @Schema(description = "示例图片")
+ private String exampleImages;
+
+ /**
+ * 图片标题
+ */
+ @Schema(description = "图片标题")
+ private String imageTitle;
+
+ /**
+ * 图片标签
+ */
+ @Schema(description = "图片标签")
+ private String imageTag;
+
+ /**
+ * 图片地址
+ */
+ @Schema(description = "图片地址")
+ private String imageUrl;
+
+ /**
+ * 分数
+ */
+ @Schema(description = "分数")
+ private Integer score;
+
+ /**
+ * 评语
+ */
+ @Schema(description = "评语")
+ private String feedback;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/BillingDeductResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/BillingDeductResp.java
new file mode 100644
index 0000000..cd641ce
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/BillingDeductResp.java
@@ -0,0 +1,34 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 计费扣减响应参数
+ *
+ * @author jiay
+ * @since 2025/08/28 00:00
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BillingDeductResp {
+
+ /**
+ * 扣减是否成功
+ */
+ private boolean success;
+
+ /**
+ * 用户剩余余额
+ */
+ private Integer remainingBalance;
+
+ /**
+ * 错误消息
+ */
+ private String errorMessage;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/BillingRuleResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/BillingRuleResp.java
new file mode 100644
index 0000000..7c32a0f
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/BillingRuleResp.java
@@ -0,0 +1,108 @@
+package top.continew.admin.business.model.resp;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+
+/**
+ * 计费规则信息
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "计费规则信息")
+public class BillingRuleResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 平台名称
+ */
+ @Schema(description = "平台名称", example = "AI绘画")
+ @ExcelProperty(value = "平台名称", order = 2)
+ private String platformName;
+
+ /**
+ * 账户类型
+ */
+ @Schema(description = "账户类型", example = "图片")
+ @ExcelProperty(value = "账户类型", order = 3)
+ private String type;
+
+ /**
+ * 平台ID
+ */
+ @Schema(description = "平台ID", example = "10000")
+ @ExcelProperty(value = "平台ID", order = 4)
+ private Long platformId;
+
+ /**
+ * 平台编码
+ */
+ @Schema(description = "平台编码", example = "KEXUE_CHAT")
+ @ExcelProperty(value = "平台编码", order = 5)
+ private String platformCode;
+
+ /**
+ * 扣费编码
+ */
+ @Schema(description = "扣费编码", example = "C0001")
+ @ExcelProperty(value = "扣费编码", order = 6)
+ private String chargeCode;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型", example = "1")
+ @ExcelProperty(value = "计费类型", order = 7)
+ private Integer chargeType;
+
+ /**
+ * 模型名称
+ */
+ @Schema(description = "模型名称", example = "flux")
+ @ExcelProperty(value = "模型名称", order = 8)
+ private String modelName;
+
+ /**
+ * 主账户单价(分/次/整数量)
+ */
+ @Schema(description = "主账户单价(分/次/整数量)", example = "13")
+ @ExcelProperty(value = "主账户单价(分)", order = 9)
+ private Long price;
+
+ /**
+ * 子账户单价(次/个/数量)
+ */
+ @Schema(description = "子账户单价(次/个/数量)", example = "1")
+ @ExcelProperty(value = "子账户单价", order = 10)
+ private Long subAccountPrice;
+
+ /**
+ * 计费单位
+ */
+ @Schema(description = "计费单位", example = "张")
+ @ExcelProperty(value = "计费单位", order = 11)
+ private String unit;
+
+ /**
+ * 备注
+ */
+ @Schema(description = "备注", example = "")
+ @ExcelProperty(value = "备注", order = 12)
+ private String remark;
+
+ /**
+ * 是否启用(0:禁用 1:启用)
+ */
+ @Schema(description = "是否启用", example = "1")
+ @ExcelProperty(value = "是否启用", order = 13)
+ private Integer enabled;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CheckBalanceResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CheckBalanceResp.java
new file mode 100644
index 0000000..10d7f92
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CheckBalanceResp.java
@@ -0,0 +1,65 @@
+package top.continew.admin.business.model.resp;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+
+/**
+ * @Author: jia
+ * @Date: 2025/05/26/16:26
+ * @Description:
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "用户充值消费历史记录详情信息")
+public class CheckBalanceResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @ExcelProperty(value = "用户id")
+ private Long userId;
+
+ /**
+ * 任务订单号
+ */
+ @Schema(description = "任务订单号")
+ @ExcelProperty(value = "任务订单号")
+ private String taskId;
+
+ /**
+ * 任务类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ @ExcelProperty(value = "任务类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 使用的模型
+ */
+ @Schema(description = "使用的模型")
+ @ExcelProperty(value = "使用的模型")
+ private String modelName;
+
+ /**
+ * 消耗点数
+ */
+ @Schema(description = "消耗点数")
+ @ExcelProperty(value = "消耗点数")
+ private Long consumptionPoints;
+
+ /**
+ * 存储结果文件路径
+ */
+ @Schema(description = "存储结果文件路径")
+ @ExcelProperty(value = "存储结果文件路径")
+ private Integer fileUrl;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ConsumptionHistoryDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ConsumptionHistoryDetailResp.java
new file mode 100644
index 0000000..f71b22a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ConsumptionHistoryDetailResp.java
@@ -0,0 +1,67 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
+import java.io.Serial;
+
+/**
+ * 用户充值消费历史记录详情信息
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "用户充值消费历史记录详情信息")
+public class ConsumptionHistoryDetailResp extends BaseDetailResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @ExcelProperty(value = "用户id")
+ private Long userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ @ExcelProperty(value = "生成平台")
+ private Long platformId;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ @ExcelProperty(value = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 点数量
+ */
+ @Schema(description = "点数量")
+ @ExcelProperty(value = "点数量")
+ private Long chargePoints;
+
+ /**
+ * 剩余的点数
+ */
+ @Schema(description = "剩余的点数")
+ @ExcelProperty(value = "剩余的点数")
+ private Long remainingPoints;
+
+ /**
+ * 记录类型(0充点 1 次数 2 点数)
+ */
+ @Schema(description = "记录类型(0充点 1 次数 2 点数)")
+ @ExcelProperty(value = "记录类型(0充点 1 次数 2 点数)")
+ private Integer chargeType;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ConsumptionHistoryResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ConsumptionHistoryResp.java
new file mode 100644
index 0000000..415e991
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ConsumptionHistoryResp.java
@@ -0,0 +1,71 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * 用户充值消费历史记录信息
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "用户充值消费历史记录信息")
+public class ConsumptionHistoryResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ private Long platformId;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 点数量
+ */
+ @Schema(description = "点数量")
+ private Long chargePoints;
+
+ /**
+ * 剩余的点数
+ */
+ @Schema(description = "剩余的点数")
+ private Long remainingPoints;
+
+ /**
+ * 记录类型(0充点 1 次数 2 点数)
+ */
+ @Schema(description = "记录类型(0充点 1 次数 2 点数)")
+ private Integer type;
+
+ /**
+ * 修改人
+ */
+ @Schema(description = "修改人")
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @Schema(description = "修改时间")
+ private LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CopyrightDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CopyrightDetailResp.java
new file mode 100644
index 0000000..cef248b
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CopyrightDetailResp.java
@@ -0,0 +1,43 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.time.LocalDateTime;
+
+/**
+ * 数字人-文案详情响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CopyrightDetailResp extends BaseResp {
+
+ /**
+ * 文案 ID
+ */
+ private Long id;
+
+ /**
+ * 用户 ID
+ */
+ private String userId;
+
+ /**
+ * 文案内容
+ */
+ private String text;
+
+ /**
+ * 文案创建日期
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updatedTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CopyrightResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CopyrightResp.java
new file mode 100644
index 0000000..4986785
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CopyrightResp.java
@@ -0,0 +1,43 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.time.LocalDateTime;
+
+/**
+ * 数字人-文案响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CopyrightResp extends BaseResp {
+
+ /**
+ * 文案 ID
+ */
+ private Long id;
+
+ /**
+ * 用户 ID
+ */
+ private String userId;
+
+ /**
+ * 文案内容
+ */
+ private String text;
+
+ /**
+ * 文案创建日期
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updatedTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CoursesResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CoursesResp.java
new file mode 100644
index 0000000..b88c984
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/CoursesResp.java
@@ -0,0 +1,46 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author 张波
+ * @since 2024/10/22 14:34
+ */
+@Data
+@Schema(description = "课程表信息")
+public class CoursesResp extends BaseResp {
+
+ /**
+ * 课程名称
+ */
+ @Schema(description = "课程名称")
+ private String name;
+
+ /**
+ * 班级
+ */
+ @Schema(description = "班级")
+ private String className;
+
+ /**
+ * 封面
+ */
+ @Schema(description = "封面")
+ private String coverImage;
+
+ /**
+ * 开始时间
+ */
+ @Schema(description = "开始时间")
+ private LocalDateTime startTime;
+
+ /**
+ * 结束时间
+ */
+ @Schema(description = "结束时间")
+ private LocalDateTime endTime;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/DigitalHumanDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/DigitalHumanDetailResp.java
new file mode 100644
index 0000000..4f4baf6
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/DigitalHumanDetailResp.java
@@ -0,0 +1,71 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人详情响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DigitalHumanDetailResp extends BaseResp {
+
+ /**
+ * 数字人唯一标识符
+ */
+ private Long id;
+
+ /**
+ * 创建数字人的用户ID
+ */
+ private String userId;
+
+ /**
+ * 用户输入的文案提示
+ */
+ private String copywriting;
+
+ /**
+ * 生成语音文件的URL
+ */
+ private String generatedVoiceUrl;
+
+ /**
+ * 生成帧图像URL(或空字符串)
+ */
+ private String generatedFrameImageUrl;
+
+ /**
+ * 最终合成视频URL
+ */
+ private String generatedVideoUrl;
+
+ /**
+ * 字幕项列表(冗余存储,用于快速回显)
+ */
+ private String subtitle;
+
+ /**
+ * 字幕样式配置(冗余或快照)
+ */
+ private String subtitleStyle;
+
+ /**
+ * 特效列表(冗余存储)
+ */
+ private String effects;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/DigitalHumanResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/DigitalHumanResp.java
new file mode 100644
index 0000000..c81d6d7
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/DigitalHumanResp.java
@@ -0,0 +1,80 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.admin.business.model.entity.Effect;
+import top.continew.admin.business.model.entity.SubtitleItem;
+import top.continew.admin.business.model.entity.SubtitleStyle;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.util.List;
+
+/**
+ * 数字人响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DigitalHumanResp extends BaseResp {
+
+ /**
+ * 数字人唯一标识符
+ */
+ private Long id;
+
+ /**
+ * 创建数字人的用户ID
+ */
+ private String userId;
+
+ /**
+ * 用户输入的文案提示
+ */
+ private String copywriting;
+
+ /**
+ * 生成语音文件的URL
+ */
+ private String generatedVoiceUrl;
+
+ /**
+ * 生成帧图像URL(或空字符串)
+ */
+ private String generatedFrameImageUrl;
+
+ /**
+ * 最终合成视频URL
+ */
+ private String generatedVideoUrl;
+
+// /**
+// * 字幕项列表(冗余存储,用于快速回显)
+// */
+// private String subtitle;
+//
+// /**
+// * 字幕样式配置(冗余或快照)
+// */
+// private String subtitleStyle;
+//
+// /**
+// * 特效列表(冗余存储)
+// */
+// private String effects;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+
+ private List subtitles;
+ private SubtitleStyle subtitleStyle;
+ private List effects;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectDetailResp.java
new file mode 100644
index 0000000..0d71c66
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectDetailResp.java
@@ -0,0 +1,111 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-特效详情响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectDetailResp extends BaseResp {
+
+ /**
+ * 特效ID(通常来自模板或任务生成)
+ */
+ private Long id;
+
+ /**
+ * 特效名称
+ */
+ private String name;
+
+ /**
+ * 特效模板ID
+ */
+ private Long templateId;
+
+ /**
+ * 关联的数字人任务ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 特效类型('text','image','music','audio')
+ */
+ private String type;
+
+ /**
+ * 特效资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 特效显示位置X坐标(像素)
+ */
+ private Integer positionX;
+
+ /**
+ * 特效显示位置Y坐标(像素)
+ */
+ private Integer positionY;
+
+ /**
+ * 特效宽度(像素)
+ */
+ private Integer sizeWidth;
+
+ /**
+ * 特效高度(像素)
+ */
+ private Integer sizeHeight;
+
+ /**
+ * 特效最大持续时间(秒)
+ */
+ private Double length;
+
+ /**
+ * 特效文本内容(仅文本类型有效)
+ */
+ private String subtitleText;
+
+ /**
+ * 字幕样式配置(JSON格式)
+ */
+ private String subtitleStyle;
+
+ /**
+ * 字幕中心位置({x, y})
+ */
+ private String subtitlePosition;
+
+ /**
+ * 特效开始偏移时间(秒)
+ */
+ private Double offset;
+
+ /**
+ * 特效播放时间段({"start": x, "end": y})
+ */
+ private String duration;
+
+ /**
+ * 渲染层级(Z轴顺序)
+ */
+ private Integer zIndex;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectResp.java
new file mode 100644
index 0000000..93ea881
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectResp.java
@@ -0,0 +1,111 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-特效响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectResp extends BaseResp {
+
+ /**
+ * 特效ID(通常来自模板或任务生成)
+ */
+ private Long id;
+
+ /**
+ * 特效名称
+ */
+ private String name;
+
+ /**
+ * 特效模板ID
+ */
+ private Long templateId;
+
+ /**
+ * 关联的数字人任务ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 特效类型('text','image','music','audio')
+ */
+ private String type;
+
+ /**
+ * 特效资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 特效显示位置X坐标(像素)
+ */
+ private Integer positionX;
+
+ /**
+ * 特效显示位置Y坐标(像素)
+ */
+ private Integer positionY;
+
+ /**
+ * 特效宽度(像素)
+ */
+ private Integer sizeWidth;
+
+ /**
+ * 特效高度(像素)
+ */
+ private Integer sizeHeight;
+
+ /**
+ * 特效最大持续时间(秒)
+ */
+ private Double length;
+
+ /**
+ * 特效文本内容(仅文本类型有效)
+ */
+ private String subtitleText;
+
+ /**
+ * 字幕样式配置(JSON格式)
+ */
+ private String subtitleStyle;
+
+ /**
+ * 字幕中心位置({x, y})
+ */
+ private String subtitlePosition;
+
+ /**
+ * 特效开始偏移时间(秒)
+ */
+ private Double offset;
+
+ /**
+ * 特效播放时间段({"start": x, "end": y})
+ */
+ private String duration;
+
+ /**
+ * 渲染层级(Z轴顺序)
+ */
+ private Integer zIndex;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectTemplateDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectTemplateDetailResp.java
new file mode 100644
index 0000000..05525f1
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectTemplateDetailResp.java
@@ -0,0 +1,91 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-特效模板详情响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectTemplateDetailResp extends BaseResp {
+
+ /**
+ * 特效模板ID
+ */
+ private Long id;
+
+ /**
+ * 模板名称
+ */
+ private String name;
+
+ /**
+ * 是否为用户自定义特效(true/false)
+ */
+ private String isCustom;
+
+ /**
+ * 上传自定义特效的用户ID(目前仅支持音乐)
+ */
+ private String userId;
+
+ /**
+ * 特效类型
+ */
+ private String type;
+
+ /**
+ * 默认资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 默认尺寸({"width": w, "height": h})
+ */
+ private String size;
+
+ /**
+ * 默认持续时间(秒),0表示无限
+ */
+ private Double length;
+
+ /**
+ * 默认字幕文本(仅文本类型)
+ */
+ private String subtitleText;
+
+ /**
+ * 关联的字幕样式ID
+ */
+ private Long subtitleStyleId;
+
+ /**
+ * 字幕默认X位置(可为固定值或表达式)
+ */
+ private String subtitlePositionX;
+
+ /**
+ * 字幕默认Y位置
+ */
+ private String subtitlePositionY;
+
+ /**
+ * 封面图URL
+ */
+ private String coverUrl;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectTemplateResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectTemplateResp.java
new file mode 100644
index 0000000..d3acf05
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/EffectTemplateResp.java
@@ -0,0 +1,93 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-特效模板响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EffectTemplateResp extends BaseResp {
+
+ /**
+ * 特效模板ID
+ */
+ private Long id;
+
+ /**
+ * 模板名称
+ */
+ private String name;
+
+ /**
+ * 是否为用户自定义特效(true/false)
+ */
+ private String isCustom;
+
+ /**
+ * 上传自定义特效的用户ID(目前仅支持音乐)
+ */
+ private String userId;
+
+ /**
+ * 特效类型
+ */
+ private String type;
+
+ /**
+ * 默认资源URL
+ */
+ private String sourceUrl;
+
+ /**
+ * 默认尺寸({"width": w, "height": h})
+ */
+ private String size_width;
+
+ private String size_height;
+
+ /**
+ * 默认持续时间(秒),0表示无限
+ */
+ private Double length;
+
+ /**
+ * 默认字幕文本(仅文本类型)
+ */
+ private String subtitleText;
+
+ /**
+ * 关联的字幕样式ID
+ */
+ private Long subtitleStyleId;
+
+ /**
+ * 字幕默认X位置(可为固定值或表达式)
+ */
+ private String subtitlePositionX;
+
+ /**
+ * 字幕默认Y位置
+ */
+ private String subtitlePositionY;
+
+ /**
+ * 封面图URL
+ */
+ private String coverUrl;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/FreeQuotaConfigResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/FreeQuotaConfigResp.java
new file mode 100644
index 0000000..cad943c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/FreeQuotaConfigResp.java
@@ -0,0 +1,95 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 免费额度配置响应信息
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Data
+@Schema(description = "免费额度配置响应信息")
+public class FreeQuotaConfigResp implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * ID
+ */
+ @Schema(description = "ID", example = "1")
+ private Long id;
+
+ /**
+ * 类别编码
+ */
+ @Schema(description = "类别编码", example = "TOKEN")
+ private String categoryCode;
+
+ /**
+ * 类别名称
+ */
+ @Schema(description = "类别名称", example = "大模型")
+ private String categoryName;
+
+ /**
+ * 单位
+ */
+ @Schema(description = "单位", example = "token")
+ private String unit;
+
+ /**
+ * 额度
+ */
+ @Schema(description = "额度", example = "500000")
+ private BigDecimal quota;
+
+ /**
+ * 计费类型
+ */
+ @Schema(description = "计费类型", example = "0")
+ private Integer chargeType;
+
+ /**
+ * 账户类型 1:次数 2:点数
+ */
+ @Schema(description = "账户类型", example = "1")
+ private Integer type;
+
+ /**
+ * 描述
+ */
+ @Schema(description = "描述", example = "大模型对话额度")
+ private String description;
+
+ /**
+ * 排序
+ */
+ @Schema(description = "排序", example = "1")
+ private Integer sort;
+
+ /**
+ * 是否启用
+ */
+ @Schema(description = "是否启用", example = "true")
+ private Boolean isEnabled;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间", example = "2025-11-17 10:00:00")
+ private LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ @Schema(description = "更新时间", example = "2025-11-17 10:00:00")
+ private LocalDateTime updateTime;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/FreeQuotaGrantResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/FreeQuotaGrantResp.java
new file mode 100644
index 0000000..94b2085
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/FreeQuotaGrantResp.java
@@ -0,0 +1,78 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 免费额度赠送响应信息
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Data
+@Builder
+@Schema(description = "免费额度赠送响应信息")
+public class FreeQuotaGrantResp implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 赠送是否成功
+ */
+ @Schema(description = "赠送是否成功", example = "true")
+ private Boolean success;
+
+ /**
+ * 总用户数
+ */
+ @Schema(description = "总用户数", example = "10")
+ private Integer totalUsers;
+
+ /**
+ * 成功赠送的用户数
+ */
+ @Schema(description = "成功赠送的用户数", example = "10")
+ private Integer successUsers;
+
+ /**
+ * 失败的用户数
+ */
+ @Schema(description = "失败的用户数", example = "0")
+ private Integer failedUsers;
+
+ /**
+ * 总赠送项数
+ */
+ @Schema(description = "总赠送项数", example = "100")
+ private Integer totalItems;
+
+ /**
+ * 成功的项数
+ */
+ @Schema(description = "成功的项数", example = "98")
+ private Integer successItems;
+
+ /**
+ * 失败的项数
+ */
+ @Schema(description = "失败的项数", example = "2")
+ private Integer failedItems;
+
+ /**
+ * 消息
+ */
+ @Schema(description = "消息", example = "批量赠送完成")
+ private String message;
+
+ /**
+ * 详细日志
+ */
+ @Schema(description = "详细日志")
+ private List logs;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HomeworkDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HomeworkDetailResp.java
new file mode 100644
index 0000000..dbf61a9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HomeworkDetailResp.java
@@ -0,0 +1,53 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
+import java.io.Serial;
+
+/**
+ * business详情信息
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "business详情信息")
+public class HomeworkDetailResp extends BaseDetailResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @ExcelProperty(value = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ @ExcelProperty(value = "课程id")
+ private Long courseId;
+
+ /**
+ * 未交原因
+ */
+ @Schema(description = "未交原因")
+ @ExcelProperty(value = "未交原因")
+ private String cause;
+
+ /**
+ * 1、已交 2、未交
+ */
+ @Schema(description = "1、已交 2、未交")
+ @ExcelProperty(value = "1、已交 2、未交")
+ private Integer handedIn;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HomeworkResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HomeworkResp.java
new file mode 100644
index 0000000..9f90773
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HomeworkResp.java
@@ -0,0 +1,59 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * business信息
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@Schema(description = "business信息")
+public class HomeworkResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+
+ /**
+ * 未交原因
+ */
+ @Schema(description = "未交原因")
+ private String cause;
+
+ /**
+ * 1、已交 2、未交
+ */
+ @Schema(description = "1、已交 2、未交")
+ private Integer handedIn;
+
+ /**
+ * 修改人
+ */
+ @Schema(description = "修改人")
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @Schema(description = "修改时间")
+ private LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HuandaResourceDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HuandaResourceDetailResp.java
new file mode 100644
index 0000000..6aa9f6a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HuandaResourceDetailResp.java
@@ -0,0 +1,54 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
+
+import java.io.Serial;
+
+/**
+ * 换哒-文件资源详情信息
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Data
+@Schema(description = "换哒-文件资源详情信息")
+public class HuandaResourceDetailResp extends BaseDetailResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 资源ID
+ */
+ @Schema(description = "资源ID")
+ private Long id;
+
+ /**
+ * 用户ID
+ */
+ @Schema(description = "用户ID")
+ private String userId;
+
+ /**
+ * 资源地址
+ */
+ @Schema(description = "资源地址")
+ private String url;
+
+ /**
+ * 资源类型:1.服装,2模特,3自定义服装,4.自定义背景
+ */
+ @Schema(description = "资源类型:1.服装,2模特,3自定义服装,4.自定义背景")
+ private Integer resourceType;
+
+ @Schema(description = "人物图片年龄")
+ private String age;
+
+ @Schema(description = "人物图片性别:男,女")
+ private String gender;
+
+ @Schema(description = "人物图片区域")
+ private String region;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HuandaResourceResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HuandaResourceResp.java
new file mode 100644
index 0000000..7c478e0
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/HuandaResourceResp.java
@@ -0,0 +1,54 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+
+/**
+ * 换哒-文件资源信息
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Data
+@Schema(description = "换哒-文件资源信息")
+public class HuandaResourceResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 资源ID
+ */
+ @Schema(description = "资源ID")
+ private Long id;
+
+ /**
+ * 用户ID
+ */
+ @Schema(description = "用户ID")
+ private String userId;
+
+ /**
+ * 资源地址
+ */
+ @Schema(description = "资源地址")
+ private String url;
+
+ /**
+ * 资源类型:1.服装,2模特,3自定义服装,4.自定义背景
+ */
+ @Schema(description = "资源类型:1.服装,2模特,3自定义服装,4.自定义背景")
+ private Integer resourceType;
+
+ @Schema(description = "人物图片年龄")
+ private String age;
+
+ @Schema(description = "人物图片性别:男,女")
+ private String gender;
+
+ @Schema(description = "人物图片区域")
+ private String region;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ModelCategoryResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ModelCategoryResp.java
new file mode 100644
index 0000000..9b31098
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ModelCategoryResp.java
@@ -0,0 +1,34 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @author 张波
+ * @since 2024/10/20 19:45
+ */
+@Data
+@Schema(description = "模型信息")
+public class ModelCategoryResp {
+
+ @Schema(description = "ID", example = "1")
+ private Long id;
+
+ /**
+ * 名称
+ */
+ @Schema(description = "名称", example = "绘画")
+ private String name;
+
+ /**
+ * 上级ID
+ */
+ @Schema(description = "上级ID", example = "0")
+ private Long parentId;
+
+ /**
+ * 类型
+ */
+ @Schema(description = "类型", example = "平台分类")
+ private String type;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ModelResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ModelResp.java
new file mode 100644
index 0000000..9baa777
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ModelResp.java
@@ -0,0 +1,81 @@
+package top.continew.admin.business.model.resp;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import top.continew.admin.common.enums.DisEnableStatusEnum;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+import top.continew.starter.file.excel.converter.ExcelBaseEnumConverter;
+
+import java.io.Serial;
+
+/**
+ * 模型信息
+ *
+ * @author 张波
+ * @since 2024/10/19 15:41
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "模型信息")
+public class ModelResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 模型名称
+ */
+ @Schema(description = "模型名称", example = "测试模型")
+ @ExcelProperty(value = "模型名称", order = 2)
+ private String name;
+
+ @Schema(description = "轮播图地址", example = "无")
+ private String images;
+
+ @Schema(description = "基础模型", example = "SDXL")
+ private String version;
+
+ /**
+ * 推荐分辨率
+ */
+ @Schema(description = "推荐分辨率", example = "1536*1024")
+ @ExcelProperty(value = "推荐分辨率", order = 4)
+ private String recommendedResolution;
+
+ /**
+ * 提示词是否开启
+ */
+ @Schema(description = "提示词是否开启", example = "是/否")
+ @ExcelProperty(value = "提示词是否开启", converter = ExcelBaseEnumConverter.class, order = 5)
+ private DisEnableStatusEnum promptEnabled;
+
+ /**
+ * 采样方法
+ */
+ @Schema(description = "采样方法", example = "Euler a")
+ @ExcelProperty(value = "采样方法", order = 6)
+ private String samplingMethod;
+
+ /**
+ * CFG
+ */
+ @Schema(description = "CFG", example = "3")
+ @ExcelProperty(value = "CFG", order = 7)
+ private Integer cfg;
+
+ /**
+ * VAE
+ */
+ @Schema(description = "VAE", example = "无")
+ @ExcelProperty(value = "VAE", order = 8)
+ private String vae;
+
+ /**
+ * 采样步数
+ */
+ @Schema(description = "采样步数", example = "20")
+ @ExcelProperty(value = "采样步数", order = 9)
+ private Integer samplingSteps;
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/PlantformBalanceDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/PlantformBalanceDetailResp.java
new file mode 100644
index 0000000..435ecee
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/PlantformBalanceDetailResp.java
@@ -0,0 +1,51 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import io.swagger.v3.oas.annotations.media.Schema;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+import java.io.Serial;
+
+/**
+ * 用户子账号余额表 详情信息
+ *
+ * @author jiay
+ * @since 2025/06/24 16:47
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "business详情信息")
+public class PlantformBalanceDetailResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @ExcelProperty(value = "用户id")
+ private Long userId;
+
+ /**
+ * 账户类型 1 次数 2 点数
+ */
+ @Schema(description = "账户类型 1 次数 2 点数")
+ @ExcelProperty(value = "账户类型 1 次数 2 点数")
+ private Integer type;
+
+ /**
+ * 余额
+ */
+ @Schema(description = "余额")
+ @ExcelProperty(value = "余额")
+ private Long balance;
+
+ /**
+ * 平台
+ */
+ @Schema(description = "平台")
+ @ExcelProperty(value = "平台")
+ private Long platformId;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/PlantformBalanceResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/PlantformBalanceResp.java
new file mode 100644
index 0000000..dd36470
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/PlantformBalanceResp.java
@@ -0,0 +1,62 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import io.swagger.v3.oas.annotations.media.Schema;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * 用户子账号余额表 信息
+ *
+ * @author jiay
+ * @since 2025/06/24 16:47
+ */
+@Data
+@Schema(description = "business信息")
+public class PlantformBalanceResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 账户类型 1 次数 2 点数
+ */
+ @Schema(description = "账户类型 1 次数 2 点数")
+ private Integer type;
+
+ /**
+ * 计费类型(token:0, 图:1, 音频:3, 视频:4, 白膜贴图/3D:5)
+ */
+ private Integer chargeType;
+
+ /**
+ * 余额
+ */
+ @Schema(description = "余额")
+ private Long balance;
+
+ /**
+ * 平台
+ */
+ @Schema(description = "平台")
+ private Long platformId;
+
+ /**
+ * 修改人
+ */
+ @Schema(description = "修改人")
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @Schema(description = "修改时间")
+ private LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ScoreDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ScoreDetailResp.java
new file mode 100644
index 0000000..699925c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ScoreDetailResp.java
@@ -0,0 +1,82 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * business详情信息
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "business详情信息")
+public class ScoreDetailResp extends BaseDetailResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @ExcelProperty(value = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ @ExcelProperty(value = "课程id")
+ private Long courseId;
+
+ /**
+ * 考试分数
+ */
+ @Schema(description = "考试分数")
+ @ExcelProperty(value = "考试分数")
+ private Integer examScore;
+
+ /**
+ * 作业分数
+ */
+ @Schema(description = "作业分数")
+ @ExcelProperty(value = "作业分数")
+ private Integer homeworkScore;
+
+ /**
+ * 签到分数
+ */
+ @Schema(description = "签到分数")
+ @ExcelProperty(value = "签到分数")
+ private Integer score;
+
+ /**
+ * 最终总分数
+ */
+ @Schema(description = "最终总分数")
+ @ExcelProperty(value = "最终总分数")
+ private Integer signInScore;
+
+ /**
+ * 1、已考 2、未考
+ */
+ @Schema(description = "1、已考 2、未考")
+ @ExcelProperty(value = "1、已考 2、未考")
+ private Integer takeExam;
+
+ /**
+ * 未考试原因
+ */
+ @Schema(description = "未考试原因")
+ @ExcelProperty(value = "未考试原因")
+ private String cause;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ScoreResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ScoreResp.java
new file mode 100644
index 0000000..ad9317d
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/ScoreResp.java
@@ -0,0 +1,83 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * business信息
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@Schema(description = "business信息")
+public class ScoreResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+
+ /**
+ * 考试分数
+ */
+ @Schema(description = "考试分数")
+ private Integer examScore;
+
+ /**
+ * 作业分数
+ */
+ @Schema(description = "作业分数")
+ private Integer homeworkScore;
+
+ /**
+ * 签到分数
+ */
+ @Schema(description = "签到分数")
+ private Integer score;
+
+ /**
+ * 最终总分数
+ */
+ @Schema(description = "最终总分数")
+ private Integer signInScore;
+
+ /**
+ * 1、已考 2、未考
+ */
+ @Schema(description = "1、已考 2、未考")
+ private Integer takeExam;
+
+ /**
+ * 未考试原因
+ */
+ @Schema(description = "未考试原因")
+ private String cause;
+
+ /**
+ * 修改人
+ */
+ @Schema(description = "修改人")
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @Schema(description = "修改时间")
+ private LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInDetailResp.java
new file mode 100644
index 0000000..2975312
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInDetailResp.java
@@ -0,0 +1,55 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * business详情信息
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "business详情信息")
+public class SignInDetailResp extends BaseDetailResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @ExcelProperty(value = "用户id")
+ private Long userId;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ @ExcelProperty(value = "课程id")
+ private Long courseId;
+
+ /**
+ * 请假原因
+ */
+ @Schema(description = "请假原因")
+ @ExcelProperty(value = "请假原因")
+ private String leaveCause;
+
+ /**
+ * 1、签到 2、请假 3、旷课
+ */
+ @Schema(description = "1、签到 2、请假 3、旷课")
+ @ExcelProperty(value = "1、签到 2、请假 3、旷课")
+ private Integer signIn;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInExportResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInExportResp.java
new file mode 100644
index 0000000..765a8a8
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInExportResp.java
@@ -0,0 +1,67 @@
+package top.continew.admin.business.model.resp;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @Author: jia
+ * @Date: 2025/07/01/15:32
+ * @Description:
+ */
+
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "导出信息")
+public class SignInExportResp implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户名
+ */
+ @Schema(description = "用户名")
+ @ExcelProperty(value = "用户名")
+ private String userName;
+
+ /**
+ * 异常
+ */
+ @Schema(description = "异常")
+ @ExcelProperty(value = "异常")
+ private Integer abnormal;
+
+ /**
+ * 缺课次数
+ */
+ @Schema(description = "缺课次数")
+ @ExcelProperty(value = "缺课次数")
+ private Integer absent;
+
+ /**
+ * 签到次数
+ */
+ @Schema(description = "签到次数")
+ @ExcelProperty(value = "签到次数")
+ private Integer present;
+
+ /**
+ * 假条数量
+ */
+ @Schema(description = "假条数量")
+ @ExcelProperty(value = "假条数量")
+ private Integer leaveCount;
+
+ /**
+ * 缺课率
+ */
+ @Schema(description = "缺课率")
+ @ExcelProperty(value = "缺课率")
+ private Double absenceRate;
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInResp.java
new file mode 100644
index 0000000..b70e53a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SignInResp.java
@@ -0,0 +1,98 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * business信息
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Data
+@Schema(description = "business信息")
+public class SignInResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+ private String userName;
+
+ /**
+ * 学号
+ */
+ private String stuNo;
+
+ /**
+ * 手机
+ */
+ @Schema(description = "手机")
+ private String phone;
+
+ /**
+ * 课程id
+ */
+ @Schema(description = "课程id")
+ private Long courseId;
+ private String courseName;
+ /**
+ * 请假原因
+ */
+ @Schema(description = "请假原因")
+ private String leaveCause;
+
+ /**
+ * 1、签到 2、请假 3、旷课
+ */
+ @Schema(description = "1、签到 2、请假 3、旷课")
+ private Integer signIn;
+ /**
+ * 经纬度
+ */
+ private String location;
+ /**
+ * 修改人
+ */
+ @Schema(description = "修改人")
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @Schema(description = "修改时间")
+ private LocalDateTime updateTime;
+
+ /**
+ * 异常
+ */
+ @Schema(description = "异常")
+ private Integer abnormal;
+
+ /**
+ * 缺课次数
+ */
+ @Schema(description = "缺课次数")
+ private Integer absent;
+
+ /**
+ * 签到次数
+ */
+ @Schema(description = "签到次数")
+ private Integer present;
+
+ /**
+ * 假条数量
+ */
+ @Schema(description = "假条数量")
+ private Integer leaveCount;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleItemDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleItemDetailResp.java
new file mode 100644
index 0000000..44217c8
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleItemDetailResp.java
@@ -0,0 +1,51 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-字幕项详情响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleItemDetailResp extends BaseResp {
+
+ /**
+ * 字幕项ID
+ */
+ private Long id;
+
+ /**
+ * 关联的数字人ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字幕文本内容
+ */
+ private String text;
+
+ /**
+ * 字幕开始时间(秒)
+ */
+ private Double startTime;
+
+ /**
+ * 字幕结束时间(秒)
+ */
+ private Double endTime;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleItemResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleItemResp.java
new file mode 100644
index 0000000..4653b06
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleItemResp.java
@@ -0,0 +1,51 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-字幕项响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleItemResp extends BaseResp {
+
+ /**
+ * 字幕项ID
+ */
+ private Long id;
+
+ /**
+ * 关联的数字人ID
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字幕文本内容
+ */
+ private String text;
+
+ /**
+ * 字幕开始时间(秒)
+ */
+ private Double startTime;
+
+ /**
+ * 字幕结束时间(秒)
+ */
+ private Double endTime;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleStyleDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleStyleDetailResp.java
new file mode 100644
index 0000000..98bfc05
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleStyleDetailResp.java
@@ -0,0 +1,81 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-字幕样式详情响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleStyleDetailResp extends BaseResp {
+
+ /**
+ * 字幕样式ID
+ */
+ private Long id;
+
+ /**
+ * 关联的数字人ID(可为空,用于全局/默认样式)
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字体大小(像素)
+ */
+ private Integer fontSize;
+
+ /**
+ * 字体族(如微软雅黑、Arial等)
+ */
+ private String fontFamily;
+
+ /**
+ * 文字颜色(CSS格式,如 #FFFFFF)
+ */
+ private String color;
+
+ /**
+ * 描边颜色
+ */
+ private String strokeColor;
+
+ /**
+ * 描边宽度(像素)
+ */
+ private Integer strokeWidth;
+
+ /**
+ * 阴影颜色
+ */
+ private String shadowColor;
+
+ /**
+ * 阴影模糊半径(像素)
+ */
+ private Integer shadowBlur;
+
+ /**
+ * 底部内边距(像素)
+ */
+ private Integer paddingBottom;
+
+ /**
+ * 行高(像素或倍数)
+ */
+ private Integer lineHeight;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleStyleResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleStyleResp.java
new file mode 100644
index 0000000..f960888
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/SubtitleStyleResp.java
@@ -0,0 +1,81 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+/**
+ * 数字人-字幕样式响应对象
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SubtitleStyleResp extends BaseResp {
+
+ /**
+ * 字幕样式ID
+ */
+ private Long id;
+
+ /**
+ * 关联的数字人ID(可为空,用于全局/默认样式)
+ */
+ private Long digitalHumanId;
+
+ /**
+ * 字体大小(像素)
+ */
+ private Integer fontSize;
+
+ /**
+ * 字体族(如微软雅黑、Arial等)
+ */
+ private String fontFamily;
+
+ /**
+ * 文字颜色(CSS格式,如 #FFFFFF)
+ */
+ private String color;
+
+ /**
+ * 描边颜色
+ */
+ private String strokeColor;
+
+ /**
+ * 描边宽度(像素)
+ */
+ private Integer strokeWidth;
+
+ /**
+ * 阴影颜色
+ */
+ private String shadowColor;
+
+ /**
+ * 阴影模糊半径(像素)
+ */
+ private Integer shadowBlur;
+
+ /**
+ * 底部内边距(像素)
+ */
+ private Integer paddingBottom;
+
+ /**
+ * 行高(像素或倍数)
+ */
+ private Integer lineHeight;
+
+ /**
+ * 创建时间
+ */
+ private java.time.LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private java.time.LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskCallbackResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskCallbackResp.java
new file mode 100644
index 0000000..2642c96
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskCallbackResp.java
@@ -0,0 +1,34 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 任务回调响应参数
+ *
+ * @author jiay
+ * @since 2025/08/28 00:00
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TaskCallbackResp {
+
+ /**
+ * 回调是否成功
+ */
+ private boolean success;
+
+ /**
+ * 消息
+ */
+ private String message;
+
+ /**
+ * 任务记录ID
+ */
+ private Long taskRecordId;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskRecordHistoryDetailResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskRecordHistoryDetailResp.java
new file mode 100644
index 0000000..a0fd2be
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskRecordHistoryDetailResp.java
@@ -0,0 +1,83 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * 用户充值消费历史记录详情信息
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "用户充值消费历史记录详情信息")
+public class TaskRecordHistoryDetailResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @ExcelProperty(value = "用户id")
+ private Long userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ @ExcelProperty(value = "生成平台")
+ private Long platformId;
+
+ /**
+ * 任务订单号
+ */
+ @Schema(description = "任务订单号")
+ @ExcelProperty(value = "任务订单号")
+ private String taskId;
+
+ /**
+ * 文件名
+ */
+ @Schema(description = "文件名")
+ @ExcelProperty(value = "文件名")
+ private String title;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ @ExcelProperty(value = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 使用的模型
+ */
+ @Schema(description = "使用的模型")
+ @ExcelProperty(value = "使用的模型")
+ private String modelName;
+
+ /**
+ * 消耗点数
+ */
+ @Schema(description = "消耗点数")
+ @ExcelProperty(value = "消耗点数")
+ private Long consumptionPoints;
+
+ /**
+ * 存储结果文件路径
+ */
+ @Schema(description = "存储结果文件路径")
+ @ExcelProperty(value = "存储结果文件路径")
+ private String fileUrl;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskRecordHistoryResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskRecordHistoryResp.java
new file mode 100644
index 0000000..80f0aa4
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TaskRecordHistoryResp.java
@@ -0,0 +1,95 @@
+package top.continew.admin.business.model.resp;
+
+import lombok.Data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import top.continew.starter.extension.crud.model.resp.BaseResp;
+
+import java.io.Serial;
+import java.time.*;
+
+/**
+ * 用户充值消费历史记录信息
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+@Data
+@Schema(description = "用户充值消费历史记录信息")
+public class TaskRecordHistoryResp extends BaseResp {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ private Long userId;
+
+ /**
+ * 生成平台
+ */
+ @Schema(description = "生成平台")
+ private Long platformId;
+
+ /**
+ * 任务订单号
+ */
+ @Schema(description = "任务订单号")
+ private String taskId;
+
+ /**
+ * 文件名
+ */
+ @Schema(description = "文件名")
+ private String title;
+
+ /**
+ * 任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "任务类型(token:0, 文生图:1,图生图:2,音效生成:3,参考生视频:4, 白膜贴图:5)")
+ private Integer taskType;
+
+ /**
+ * 文件类型
+ */
+ @Schema(description = "文件类型")
+ private String fileType;
+
+ /**
+ * 计费类型(token:0, 图:1,音效生成:3,参考生视频:4, 白膜贴图:5)
+ */
+ @Schema(description = "计费类型(token:0, 图:1, 音效:3, 视频:4, 白膜贴图:5)")
+ private Integer chargeType;
+
+ /**
+ * 使用的模型
+ */
+ @Schema(description = "使用的模型")
+ private String modelName;
+
+ /**
+ * 消耗点数
+ */
+ @Schema(description = "消耗点数")
+ private Long consumptionPoints;
+
+ /**
+ * 存储结果文件路径
+ */
+ @Schema(description = "存储结果文件路径")
+ private String fileUrl;
+
+ /**
+ * 修改人
+ */
+ @Schema(description = "修改人")
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @Schema(description = "修改时间")
+ private LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TodayNosignInExportResp.java b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TodayNosignInExportResp.java
new file mode 100644
index 0000000..e72059c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/model/resp/TodayNosignInExportResp.java
@@ -0,0 +1,45 @@
+package top.continew.admin.business.model.resp;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @Author: jia
+ * @Date: 2025/07/01/15:31
+ * @Description:
+ */
+@Data
+@ExcelIgnoreUnannotated
+@Schema(description = "导出信息")
+public class TodayNosignInExportResp implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户名
+ */
+ @Schema(description = "用户名")
+ @ExcelProperty(value = "用户名")
+ private String userName;
+
+ /**
+ * 请假原因
+ */
+ @Schema(description = "请假原因")
+ @ExcelProperty(value = "请假原因")
+ private String leaveCause;
+
+ /**
+ * 1、签到 2、请假 3、旷课
+ */
+ @Schema(description = "1、签到 2、请假 3、旷课")
+ @ExcelProperty(value = "1、签到 2、请假 3、旷课")
+ private String signIn;
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/AssignmentSubmissionsService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/AssignmentSubmissionsService.java
new file mode 100644
index 0000000..93c75bc
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/AssignmentSubmissionsService.java
@@ -0,0 +1,56 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.AssignmentSubmissionsDO;
+import top.continew.admin.business.model.req.AssignmentSubmissionsReq;
+import top.continew.admin.business.model.req.AssignmentsCorrectReq;
+import top.continew.admin.business.model.resp.AssignmentsProgressResp;
+import top.continew.admin.business.model.resp.AssignmentsSubmissionsDetailResp;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+/**
+ * @author 张波
+ * @since 2024/10/22 15:38
+ */
+public interface AssignmentSubmissionsService extends IService {
+
+ /**
+ * 提交作业
+ *
+ * @param req 作业ID&作业图片信息
+ */
+ void submit(AssignmentSubmissionsReq req);
+
+ /**
+ * 批改作业
+ *
+ * @param req 作业提交记录ID&分叔&评语
+ */
+ void correct(AssignmentsCorrectReq req);
+
+ /**
+ * 查询作业完成情况
+ *
+ * @param assignmentsId 作业ID
+ * @param pageQuery 分页参数
+ * @return 学生作业完成情况
+ */
+ PageResp degreeOfCompletion(Long assignmentsId, PageQuery pageQuery);
+
+ /**
+ * 查询作业提交记录详情
+ *
+ * @param submissionsId 提交记录ID
+ * @return 提交记录详情
+ */
+ AssignmentsSubmissionsDetailResp detail(Long submissionsId);
+
+ /**
+ * 查询优秀图片列表
+ *
+ * @param pageQuery 分页条件
+ * @return 图片列表
+ */
+ PageResp getGoodImageList(String dbName, PageQuery pageQuery);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/AssignmentsService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/AssignmentsService.java
new file mode 100644
index 0000000..7b6d824
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/AssignmentsService.java
@@ -0,0 +1,26 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.AssignmentsDO;
+import top.continew.admin.business.model.req.AssignmentsReq;
+import top.continew.admin.business.model.resp.AssignmentsDetailResp;
+
+/**
+ * 作业表业务接口
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+public interface AssignmentsService extends IService {
+
+ // 创建作业
+ Long add(AssignmentsReq assignmentsReq);
+
+ /**
+ * 根据作业ID查询作业详情
+ *
+ * @param assignmentsId 作业ID
+ * @return 作业详情
+ */
+ AssignmentsDetailResp detail(Long assignmentsId);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/BillingRuleService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/BillingRuleService.java
new file mode 100644
index 0000000..f284549
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/BillingRuleService.java
@@ -0,0 +1,41 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.BillingRuleDO;
+import top.continew.admin.business.model.query.BillingRuleQuery;
+import top.continew.admin.business.model.req.BillingRuleReq;
+import top.continew.admin.business.model.resp.BillingRuleResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 计费规则服务
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+public interface BillingRuleService extends BaseService, IService {
+
+ /**
+ * 根据平台ID获取计费规则
+ *
+ * @param platformId 平台ID
+ * @return 计费规则
+ */
+ BillingRuleDO getByPlatformId(Long platformId);
+
+ /**
+ * 根据平台ID获取计费金额
+ *
+ * @param platformId 平台ID
+ * @return 计费金额(分/次/整数量)
+ */
+ Long getPriceByPlatformId(Long platformId);
+
+ /**
+ * 根据扣费编码获取计费规则
+ *
+ * @param chargeCode 扣费编码
+ * @return 计费规则
+ */
+ BillingRuleDO getByChargeCode(String chargeCode);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/BillingService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/BillingService.java
new file mode 100644
index 0000000..d7f33ea
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/BillingService.java
@@ -0,0 +1,51 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import jakarta.validation.Valid;
+import top.continew.admin.business.model.entity.TaskRecordHistoryDO;
+import top.continew.admin.business.model.req.*;
+import top.continew.admin.business.model.resp.BillingDeductResp;
+import top.continew.admin.business.model.resp.TaskCallbackResp;
+
+/**
+ * 计费服务接口
+ *
+ * @author jiay
+ * @since 2025/08/28 00:00
+ */
+public interface BillingService {
+
+ /**
+ * 扣减用户余额(本地计算费用)
+ *
+ * @param req 扣减请求
+ * @return 扣减结果
+ */
+ BillingDeductResp judgeBalance(BillingJudgeReq req);
+
+ /**
+ * 扣减用户余额(第三方平台传入费用)
+ *
+ * @param req 扣减请求(包含预扣减金额)
+ * @return 扣减结果
+ */
+ BillingDeductResp judgeBalanceWithAmount(BillingJudgeWithAmountReq req);
+
+ /**
+ * 任务完成回调(本地计算费用)
+ *
+ * @param req 回调请求
+ * @return 回调结果
+ */
+ TaskCallbackResp taskCallback(TaskCallbackReq req);
+
+ /**
+ * 任务完成回调(第三方平台传入费用)
+ *
+ * @param req 回调请求(包含实际消费金额)
+ * @return 回调结果
+ */
+ TaskCallbackResp taskCallbackWithAmount(TaskCallbackWithAmountReq req);
+
+ Page queryTaskListByRootId(@Valid TaskQueryReq req);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/ConsumptionHistoryService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/ConsumptionHistoryService.java
new file mode 100644
index 0000000..3de900a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/ConsumptionHistoryService.java
@@ -0,0 +1,81 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.ConsumptionHistoryDO;
+import top.continew.admin.business.model.query.ConsumptionHistoryQuery;
+import top.continew.admin.business.model.req.ConsumptionHistoryAddReq;
+import top.continew.admin.business.model.req.ConsumptionHistoryEditReq;
+import top.continew.admin.business.model.req.ConsumptionReq;
+import top.continew.admin.business.model.resp.ConsumptionHistoryResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.web.model.R;
+
+import java.util.List;
+
+/**
+ * 用户充值消费历史记录业务接口
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+
+public interface ConsumptionHistoryService extends IService {
+
+ /**
+ * 获取用户充值消费历史记录列表
+ *
+ * @param query 用户充值消费历史记录查询条件
+ * @return 用户充值消费历史记录列表
+ */
+ List getConsumptionHistoryList(ConsumptionHistoryQuery query);
+
+ /**
+ * 添加用户充值消费历史记录
+ *
+ * @param req 用户充值消费历史记录
+ * @return 添加是否成功
+ */
+ boolean addConsumptionHistory(ConsumptionHistoryAddReq req);
+
+ /**
+ * 添加用户充值消费历史记录
+ *
+ * @param req 用户充值消费历史记录
+ * @return 添加是否成功
+ */
+ boolean editConsumptionHistory(ConsumptionHistoryEditReq req);
+
+ /**
+ * 添加用户充值消费历史记录
+ *
+ * @param id 用户充值消费历史记录id
+ * @return 添加是否成功
+ */
+ boolean deleteConsumptionHistory(Long id);
+
+ /**
+ * 添加用户充值消费历史记录
+ *
+ * @param id 用户充值消费历史记录id
+ * @return 用户充值消费历史记录
+ */
+ ConsumptionHistoryResp getConsumptionHistory(Long id);
+
+ /**
+ * 添加用户充值消费历史记录
+ *
+ * @param query 用户充值消费历史记录查询条件
+ * @param pageQuery 分页参数
+ * @return 用户充值消费历史记录分页列表
+ */
+ PageResp getConsumptionHistoryPage(ConsumptionHistoryQuery query, PageQuery pageQuery);
+
+ /**
+ * 判断余额是否充足
+ *
+ * @param req 用户充值消费历史记录查询条件
+ * @return 余额是否充足
+ */
+ R checkBalance(ConsumptionReq req);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/CopyrightService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/CopyrightService.java
new file mode 100644
index 0000000..b5b1702
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/CopyrightService.java
@@ -0,0 +1,22 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.query.CopyrightQuery;
+import top.continew.admin.business.model.query.CopyrightPageQuery;
+import top.continew.admin.business.model.req.CopyrightReq;
+import top.continew.admin.business.model.resp.CopyrightDetailResp;
+import top.continew.admin.business.model.resp.CopyrightResp;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 数字人-文案服务接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+public interface CopyrightService extends BaseService {
+
+ PageResp pageList(CopyrightQuery query, CopyrightPageQuery pageQuery);
+
+ // 可根据需要添加额外的业务方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/CourseUserService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/CourseUserService.java
new file mode 100644
index 0000000..72ffda2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/CourseUserService.java
@@ -0,0 +1,11 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.CourseUserDO;
+
+/**
+ * @author 张波
+ * @since 2024/10/22 12:20
+ */
+public interface CourseUserService extends IService {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/CoursesService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/CoursesService.java
new file mode 100644
index 0000000..5d0d85c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/CoursesService.java
@@ -0,0 +1,47 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.enums.AssignmentsTypeEnum;
+import top.continew.admin.business.model.entity.CoursesDO;
+import top.continew.admin.business.model.req.CoursesReq;
+import top.continew.admin.business.model.resp.AssignmentsResp;
+import top.continew.admin.business.model.resp.CoursesResp;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+import java.util.List;
+
+/**
+ * 课程业务接口
+ *
+ * @author 张波
+ * @since 2024/10/22 11:58
+ */
+public interface CoursesService extends IService {
+
+ /**
+ * 创建课程
+ *
+ * @param req 参数
+ */
+ void add(CoursesReq req);
+
+ /**
+ * 分页查询课程列表
+ *
+ * @param role 角色(学生/老师)
+ * @param pageQuery 分页查询条件
+ * @return 课程列表
+ */
+ PageResp list(String db, String role, PageQuery pageQuery);
+
+ /**
+ * 查询课程里作业列表
+ *
+ * @param coursesId 课程ID
+ * @param type 类型(作业/考试)
+ * @param role 角色(学生/老师)
+ * @return 作业名称以及完成度
+ */
+ List assignmentsList(Long coursesId, AssignmentsTypeEnum type, String role);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/DeptModelService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/DeptModelService.java
new file mode 100644
index 0000000..226fe39
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/DeptModelService.java
@@ -0,0 +1,42 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.DeptModelDO;
+import top.continew.admin.business.model.query.ModelQuery;
+import top.continew.admin.business.model.req.DeptModelReq;
+import top.continew.admin.business.model.resp.ModelResp;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+import java.util.List;
+
+/**
+ * @author 张波
+ * @since 2024/10/20 14:42
+ */
+public interface DeptModelService extends IService {
+
+ /**
+ * 部门与模型绑定
+ *
+ * @param req 请求参数
+ */
+ void bind(DeptModelReq req);
+
+ /**
+ * 获取用户所在部门可见模型
+ *
+ * @param query 查询条件
+ * @param pageQuery 分页条件
+ * @return 用户所在部门可见模型
+ */
+ PageResp getModels(ModelQuery query, PageQuery pageQuery);
+
+ /**
+ * 获取部门绑定的操作平台列表
+ *
+ * @param deptId 部门ID
+ * @return 操作平台列表
+ */
+ List getModelByDept(Long deptId);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/DeptPlatformService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/DeptPlatformService.java
new file mode 100644
index 0000000..0ced4a0
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/DeptPlatformService.java
@@ -0,0 +1,36 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.DeptPlatformDO;
+import top.continew.admin.business.model.req.DeptPlatformReq;
+import top.continew.starter.data.mp.service.IService;
+
+import java.util.List;
+
+/**
+ * @author 张波
+ * @since 2024/10/20 14:49
+ */
+public interface DeptPlatformService extends IService {
+
+ /**
+ * 部门与操作平台绑定接口
+ *
+ * @param req 请求参数
+ */
+ void bind(DeptPlatformReq req);
+
+ /**
+ * 获取用户可见操作平台
+ *
+ * @return 用户所在部门可见操作平台
+ */
+ List getPlatforms();
+
+ /**
+ * 获取部门绑定的操作平台列表
+ *
+ * @param deptId 部门ID
+ * @return 操作平台列表
+ */
+ List getPlatformByDept(Long deptId);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/DigitalHumanService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/DigitalHumanService.java
new file mode 100644
index 0000000..0e63c0d
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/DigitalHumanService.java
@@ -0,0 +1,20 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.query.DigitalHumanQuery;
+import top.continew.admin.business.model.query.DigitalHumanPageQuery;
+import top.continew.admin.business.model.req.DigitalHumanReq;
+import top.continew.admin.business.model.resp.DigitalHumanDetailResp;
+import top.continew.admin.business.model.resp.DigitalHumanResp;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 数字人服务接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+public interface DigitalHumanService extends BaseService {
+ // 可根据需要添加额外的业务方法
+ PageResp pageList(DigitalHumanQuery query, DigitalHumanPageQuery pageQuery);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/EffectService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/EffectService.java
new file mode 100644
index 0000000..68d948c
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/EffectService.java
@@ -0,0 +1,20 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.query.EffectPageQuery;
+import top.continew.admin.business.model.query.EffectQuery;
+import top.continew.admin.business.model.req.EffectReq;
+import top.continew.admin.business.model.resp.EffectDetailResp;
+import top.continew.admin.business.model.resp.EffectResp;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 数字人-特效服务接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+public interface EffectService extends BaseService {
+ PageResp pageList(EffectQuery query, EffectPageQuery pageQuery);
+ // 可根据需要添加额外的业务方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/EffectTemplateService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/EffectTemplateService.java
new file mode 100644
index 0000000..7711ea1
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/EffectTemplateService.java
@@ -0,0 +1,23 @@
+package top.continew.admin.business.service;
+
+import org.springframework.web.multipart.MultipartFile;
+import top.continew.admin.business.model.query.EffectTemplatePageQuery;
+import top.continew.admin.business.model.query.EffectTemplateQuery;
+import top.continew.admin.business.model.req.EffectTemplateReq;
+import top.continew.admin.business.model.resp.EffectTemplateDetailResp;
+import top.continew.admin.business.model.resp.EffectTemplateResp;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 数字人-特效模板服务接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+public interface EffectTemplateService extends BaseService {
+ PageResp pageList(EffectTemplateQuery query, EffectTemplatePageQuery pageQuery);
+
+ // 可根据需要添加额外的业务方法
+ Long uploadTemplate(MultipartFile file, String name, String type, String userId);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/FreeQuotaConfigService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/FreeQuotaConfigService.java
new file mode 100644
index 0000000..69bbbf4
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/FreeQuotaConfigService.java
@@ -0,0 +1,42 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.FreeQuotaConfigDO;
+import top.continew.admin.business.model.query.FreeQuotaConfigQuery;
+import top.continew.admin.business.model.req.FreeQuotaConfigReq;
+import top.continew.admin.business.model.resp.FreeQuotaConfigResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.service.BaseService;
+
+import java.util.List;
+
+/**
+ * 免费额度配置服务
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+public interface FreeQuotaConfigService extends BaseService, IService {
+
+ /**
+ * 获取所有启用的配置
+ *
+ * @return 配置列表
+ */
+ List listEnabled();
+
+ /**
+ * 根据类别编码获取配置
+ *
+ * @param categoryCode 类别编码
+ * @return 配置信息
+ */
+ FreeQuotaConfigDO getByCategoryCode(String categoryCode);
+
+ /**
+ * 根据计费类型获取配置
+ *
+ * @param chargeType 计费类型
+ * @return 配置信息
+ */
+ FreeQuotaConfigDO getByChargeType(Integer chargeType);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/FreeQuotaGrantService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/FreeQuotaGrantService.java
new file mode 100644
index 0000000..1cd4dcc
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/FreeQuotaGrantService.java
@@ -0,0 +1,37 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.req.FreeQuotaGrantReq;
+import top.continew.admin.business.model.resp.FreeQuotaGrantResp;
+
+/**
+ * 免费额度赠送服务
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+public interface FreeQuotaGrantService {
+
+ /**
+ * 批量赠送免费额度
+ *
+ * @param req 赠送请求
+ * @return 赠送结果
+ */
+ FreeQuotaGrantResp batchGrant(FreeQuotaGrantReq req);
+
+ /**
+ * 给单个用户赠送默认免费额度
+ *
+ * @param userId 用户ID
+ * @return 赠送结果
+ */
+ FreeQuotaGrantResp grantToUser(Long userId);
+
+ /**
+ * 给部门下所有用户赠送默认免费额度
+ *
+ * @param deptId 部门ID
+ * @return 赠送结果
+ */
+ FreeQuotaGrantResp grantToDept(Long deptId);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/HomeworkService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/HomeworkService.java
new file mode 100644
index 0000000..2e5eabd
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/HomeworkService.java
@@ -0,0 +1,69 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.HomeworkDO;
+import top.continew.admin.business.model.query.HomeworkQuery;
+import top.continew.admin.business.model.req.HomeworkAddReq;
+import top.continew.admin.business.model.req.HomeworkEditReq;
+import top.continew.admin.business.model.resp.HomeworkResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import java.util.List;
+
+/**
+ * 作业业务接口
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+public interface HomeworkService extends IService {
+
+ /**
+ * 获取作业列表
+ *
+ * @param query 作业查询条件
+ * @return 作业列表
+ */
+ List getHomeworkList(HomeworkQuery query);
+
+ /**
+ * 添加作业
+ *
+ * @param req 作业
+ * @return url
+ */
+ boolean addHomework(HomeworkAddReq req);
+
+ /**
+ * 添加作业
+ *
+ * @param req 作业
+ * @return 添加是否成功
+ */
+ boolean editHomework(HomeworkEditReq req);
+
+ /**
+ * 添加作业
+ *
+ * @param id 作业id
+ * @return 添加是否成功
+ */
+ boolean deleteHomework(Long id);
+
+ /**
+ * 添加作业
+ *
+ * @param id 作业id
+ * @return 作业
+ */
+ HomeworkResp getHomework(Long id);
+
+ /**
+ * 添加作业
+ *
+ * @param query 作业查询条件
+ * @param pageQuery 分页参数
+ * @return 作业分页列表
+ */
+ PageResp getHomeworkPage(HomeworkQuery query, PageQuery pageQuery);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/HuandaResourceService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/HuandaResourceService.java
new file mode 100644
index 0000000..fae8b8f
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/HuandaResourceService.java
@@ -0,0 +1,29 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.HuandaResourceDO;
+import top.continew.admin.business.model.query.HuandaResourcePageQuery;
+import top.continew.admin.business.model.query.HuandaResourceQuery;
+import top.continew.admin.business.model.req.HuandaResourceReq;
+import top.continew.admin.business.model.resp.HuandaResourceDetailResp;
+import top.continew.admin.business.model.resp.HuandaResourceResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 换哒-文件资源业务接口
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+
+/**
+ * 换哒-文件资源业务接口
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+public interface HuandaResourceService extends BaseService, IService {
+
+ PageResp pageList(HuandaResourceQuery query, HuandaResourcePageQuery pageQuery);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/ModelCategoryService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/ModelCategoryService.java
new file mode 100644
index 0000000..e1a09c4
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/ModelCategoryService.java
@@ -0,0 +1,11 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.ModelCategoryDO;
+
+/**
+ * @author 张波
+ * @since 2024/10/20 19:51
+ */
+public interface ModelCategoryService extends IService {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/ModelService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/ModelService.java
new file mode 100644
index 0000000..b0528ae
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/ModelService.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.ModelDO;
+import top.continew.admin.business.model.query.ModelQuery;
+import top.continew.admin.business.model.req.ModelReq;
+import top.continew.admin.business.model.resp.ModelResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 模型服务
+ *
+ * @author 张波
+ * @since 2024/10/19 15:32
+ */
+public interface ModelService extends BaseService, IService {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/OrderAudioService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/OrderAudioService.java
new file mode 100644
index 0000000..aeea182
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/OrderAudioService.java
@@ -0,0 +1,20 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.OrderAudioDo;
+import top.continew.admin.business.model.req.OrderAudioReq;
+
+/**
+ * 音频订单任务业务接口
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+public interface OrderAudioService extends IService {
+ /**
+ * 创建音频订单任务
+ *
+ * @param req 参数
+ */
+ void add(OrderAudioReq req);
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/OrderHistoryService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/OrderHistoryService.java
new file mode 100644
index 0000000..69d9680
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/OrderHistoryService.java
@@ -0,0 +1,14 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.OrderHistoryDo;
+
+/**
+ * 订单任务历史业务接口
+ *
+ * @author hzy
+ * @since 2024/10/22 11:58
+ */
+public interface OrderHistoryService extends IService {
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/PlantformBalanceService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/PlantformBalanceService.java
new file mode 100644
index 0000000..61fbe65
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/PlantformBalanceService.java
@@ -0,0 +1,88 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.PlantformBalanceDO;
+import top.continew.admin.business.model.query.PlantformBalanceQuery;
+import top.continew.admin.business.model.req.CheckPlantBalanceReq;
+import top.continew.admin.business.model.req.PlantformBalanceAddReq;
+import top.continew.admin.business.model.req.PlantformBalanceEditReq;
+import top.continew.admin.business.model.resp.PlantformBalanceResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.web.model.R;
+
+import java.util.List;
+
+/**
+ * 用户子账号余额表业务接口
+ *
+ * @author jiay
+ * @since 2025/06/24 16:47
+ */
+public interface PlantformBalanceService extends IService {
+
+ /**
+ * 获取用户子账号余额列表
+ *
+ * @param query 用户子账号余额查询条件
+ * @return 用户子账号余额列表
+ */
+ List getPlantformBalanceList(PlantformBalanceQuery query);
+
+ /**
+ * 添加用户子账号余额
+ *
+ * @param req 用户子账号余额
+ * @return url
+ */
+ boolean addPlantformBalance(PlantformBalanceAddReq req);
+
+ /**
+ * 添加用户子账号余额
+ *
+ * @param req 用户子账号余额
+ * @return 添加是否成功
+ */
+ boolean editPlantformBalance(PlantformBalanceEditReq req);
+
+ /**
+ * 添加用户子账号余额
+ *
+ * @param id 用户子账号余额id
+ * @return 添加是否成功
+ */
+ boolean deletePlantformBalance(Long id);
+
+ /**
+ * 添加用户子账号余额
+ *
+ * @param id 用户子账号余额id
+ * @return 用户子账号余额
+ */
+ PlantformBalanceResp getPlantformBalance(Long id);
+
+ /**
+ * 添加用户子账号余额
+ *
+ * @param query 用户子账号余额查询条件
+ * @param pageQuery 分页参数
+ * @return 用户子账号余额分页列表
+ */
+ PageResp getPlantformBalancePage(PlantformBalanceQuery query, PageQuery pageQuery);
+
+ /**
+ * 根据用户ID获取用户所有子账户余额
+ *
+ * @param userId 用户ID
+ * @return 用户子账号余额列表
+ */
+ List getUserBalancesByUserId(Long userId);
+
+ /**
+ * 判断余额是否充足
+ *
+ * @param req 用子账号余额查询条件
+ * @return 子账号余额是否充足
+ */
+ R checkPlantBalance(CheckPlantBalanceReq req);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/ScoreService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/ScoreService.java
new file mode 100644
index 0000000..e04837a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/ScoreService.java
@@ -0,0 +1,71 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.ScoreDO;
+import top.continew.admin.business.model.query.ScoreQuery;
+import top.continew.admin.business.model.req.ScoreAddReq;
+import top.continew.admin.business.model.req.ScoreEditReq;
+import top.continew.admin.business.model.resp.ScoreResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+import java.util.List;
+
+/**
+ * 分数业务接口
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+public interface ScoreService extends IService {
+
+ /**
+ * 获取分数列表
+ *
+ * @param query 分数查询条件
+ * @return 分数列表
+ */
+ List getScoreList(ScoreQuery query);
+
+ /**
+ * 添加分数
+ *
+ * @param req 分数
+ * @return url
+ */
+ boolean addScore(ScoreAddReq req);
+
+ /**
+ * 添加分数
+ *
+ * @param req 分数
+ * @return 添加是否成功
+ */
+ boolean editScore(ScoreEditReq req);
+
+ /**
+ * 添加分数
+ *
+ * @param id 分数id
+ * @return 添加是否成功
+ */
+ boolean deleteScore(Long id);
+
+ /**
+ * 添加分数
+ *
+ * @param id 分数id
+ * @return 分数
+ */
+ ScoreResp getScore(Long id);
+
+ /**
+ * 添加分数
+ *
+ * @param query 分数查询条件
+ * @param pageQuery 分页参数
+ * @return 分数分页列表
+ */
+ PageResp getScorePage(ScoreQuery query, PageQuery pageQuery);
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/SignInService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/SignInService.java
new file mode 100644
index 0000000..2087aa2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/SignInService.java
@@ -0,0 +1,106 @@
+package top.continew.admin.business.service;
+
+import jakarta.servlet.http.HttpServletResponse;
+import top.continew.admin.business.model.entity.SignInDO;
+import top.continew.admin.business.model.query.SignInQuery;
+import top.continew.admin.business.model.req.SignInAddReq;
+import top.continew.admin.business.model.req.SignInEditReq;
+import top.continew.admin.business.model.resp.SignInResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.query.SortQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import java.util.List;
+
+/**
+ * 签到业务接口
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+public interface SignInService extends IService {
+
+ /**
+ * 获取签到列表
+ *
+ * @param query 签到查询条件
+ * @return 签到列表
+ */
+ List getSignInList(SignInQuery query);
+
+ /**
+ * 添加签到
+ *
+ * @param req 签到
+ * @return url
+ */
+ boolean addSignIn(SignInAddReq req);
+
+ /**
+ * 添加签到
+ *
+ * @param req 签到
+ * @return 添加是否成功
+ */
+ boolean editSignIn(SignInEditReq req);
+
+ /**
+ * 添加签到
+ *
+ * @param id 签到id
+ * @return 添加是否成功
+ */
+ boolean deleteSignIn(Long id);
+
+ /**
+ * 添加签到
+ *
+ * @param id 签到id
+ * @return 签到
+ */
+ SignInResp getSignIn(Long id);
+
+ /**
+ * 添加签到
+ *
+ * @param query 签到查询条件
+ * @param pageQuery 分页参数
+ * @return 签到分页列表
+ */
+ PageResp getSignInPage(SignInQuery query, PageQuery pageQuery);
+
+ /**
+ * 查询今日未签到列表
+ *
+ * @param query 签到查询条件
+ * @return 今日未签到列表
+ */
+ List getTodayNosignInList(SignInQuery query);
+
+ /**
+ * 分页查询历史签到列表
+ *
+ * @param query 签到查询条件
+ * @param pageQuery 分页参数
+ * @return 签到分页列表
+ */
+ PageResp getHisSignInList(SignInQuery query, PageQuery pageQuery);
+
+ /**
+ * 导出历史签到列表
+ *
+ * @param query 查询条件
+ * @param sortQuery 排序参数
+ * @param response 参数
+ */
+ void exportHisSignInList(SignInQuery query, SortQuery sortQuery, HttpServletResponse response);
+
+ /**
+ * 导出今日未签到列表
+ *
+ * @param query 查询条件
+ * @param sortQuery 排序参数
+ * @param response 参数
+ */
+ void exportTodayNosignInList(SignInQuery query, SortQuery sortQuery, HttpServletResponse response);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/SubtitleItemService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/SubtitleItemService.java
new file mode 100644
index 0000000..776addb
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/SubtitleItemService.java
@@ -0,0 +1,22 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.query.SubtitleItemQuery;
+import top.continew.admin.business.model.req.SubtitleItemReq;
+import top.continew.admin.business.model.resp.SubtitleItemDetailResp;
+import top.continew.admin.business.model.resp.SubtitleItemResp;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 数字人-字幕项服务接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+public interface SubtitleItemService extends BaseService {
+
+ PageResp pageList(SubtitleItemQuery query,
+ top.continew.admin.business.model.query.SubtitleItemPageQuery pageQuery);
+
+ // 可根据需要添加额外的业务方法
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/SubtitleStyleService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/SubtitleStyleService.java
new file mode 100644
index 0000000..1e3edd9
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/SubtitleStyleService.java
@@ -0,0 +1,20 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.query.SubtitleStyleQuery;
+import top.continew.admin.business.model.req.SubtitleStyleReq;
+import top.continew.admin.business.model.resp.SubtitleStyleDetailResp;
+import top.continew.admin.business.model.resp.SubtitleStyleResp;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.BaseService;
+
+/**
+ * 数字人-字幕样式服务接口
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+public interface SubtitleStyleService extends BaseService {
+ // 可根据需要添加额外的业务方法
+ PageResp pageList(SubtitleStyleQuery query,
+ top.continew.admin.business.model.query.SubtitleStylePageQuery pageQuery);
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/TaskRecordHistoryService.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/TaskRecordHistoryService.java
new file mode 100644
index 0000000..5151370
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/TaskRecordHistoryService.java
@@ -0,0 +1,70 @@
+package top.continew.admin.business.service;
+
+import top.continew.admin.business.model.entity.TaskRecordHistoryDO;
+import top.continew.admin.business.model.query.TaskRecordHistoryQuery;
+import top.continew.admin.business.model.req.TaskRecordHistoryAddReq;
+import top.continew.admin.business.model.req.TaskRecordHistoryEditReq;
+import top.continew.admin.business.model.resp.TaskRecordHistoryResp;
+import top.continew.starter.data.mp.service.IService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import java.util.List;
+
+/**
+ * 音视图文生成记录业务接口
+ *
+ * @author jiay
+ * @since 2025/05/23 07:51
+ */
+public interface TaskRecordHistoryService extends IService {
+
+ /**
+ * 获取音视图文生成记录列表
+ *
+ * @param query 音视图文生成记录查询条件
+ * @return 音视图文生成记录列表
+ */
+ List getTaskRecordHistoryList(TaskRecordHistoryQuery query);
+
+ /**
+ * 添加音视图文生成记录
+ *
+ * @param req 音视图文生成记录
+ * @return url
+ */
+ List addTaskRecordHistory(TaskRecordHistoryAddReq req);
+
+ /**
+ * 添加音视图文生成记录
+ *
+ * @param req 音视图文生成记录
+ * @return 添加是否成功
+ */
+ boolean editTaskRecordHistory(TaskRecordHistoryEditReq req);
+
+ /**
+ * 添加音视图文生成记录
+ *
+ * @param id 音视图文生成记录id
+ * @return 添加是否成功
+ */
+ boolean deleteTaskRecordHistory(Long id);
+
+ /**
+ * 添加音视图文生成记录
+ *
+ * @param id 音视图文生成记录id
+ * @return 音视图文生成记录
+ */
+ TaskRecordHistoryResp getTaskRecordHistory(Long id);
+
+ /**
+ * 添加音视图文生成记录
+ *
+ * @param query 音视图文生成记录查询条件
+ * @param pageQuery 分页参数
+ * @return 音视图文生成记录分页列表
+ */
+ PageResp getTaskRecordHistoryPage(TaskRecordHistoryQuery query, PageQuery pageQuery);
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/AssignmentSubmissionsServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/AssignmentSubmissionsServiceImpl.java
new file mode 100644
index 0000000..f53a3f7
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/AssignmentSubmissionsServiceImpl.java
@@ -0,0 +1,151 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.AssignmentSubmissionsMapper;
+import top.continew.admin.business.model.entity.AssignmentSubmissionsDO;
+import top.continew.admin.business.model.entity.AssignmentsDO;
+import top.continew.admin.business.model.entity.CourseUserDO;
+import top.continew.admin.business.model.req.AssignmentSubmissionsReq;
+import top.continew.admin.business.model.req.AssignmentsCorrectReq;
+import top.continew.admin.business.model.resp.AssignmentsProgressResp;
+import top.continew.admin.business.model.resp.AssignmentsSubmissionsDetailResp;
+import top.continew.admin.business.service.AssignmentSubmissionsService;
+import top.continew.admin.business.service.AssignmentsService;
+import top.continew.admin.business.service.CourseUserService;
+import top.continew.admin.common.util.helper.LoginHelper;
+import top.continew.starter.core.util.validate.CheckUtils;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author 张波
+ * @since 2024/10/22 15:38
+ */
+@Service
+@RequiredArgsConstructor
+public class AssignmentSubmissionsServiceImpl extends ServiceImpl implements AssignmentSubmissionsService {
+
+ private final CourseUserService courseUserService;
+
+ private final AssignmentsService assignmentsService;
+
+ @Override
+ public void submit(AssignmentSubmissionsReq req) {
+ Long loginUserId = LoginHelper.getUserId();
+
+ boolean exists = lambdaQuery().eq(AssignmentSubmissionsDO::getAssignmentId, req.getAssignmentId())
+ .eq(AssignmentSubmissionsDO::getUserId, loginUserId)
+ .exists();
+
+ CheckUtils.throwIf(exists, "作业已提交,请勿重复提交!");
+
+ AssignmentSubmissionsDO saveDb = BeanUtil.copyProperties(req, AssignmentSubmissionsDO.class);
+ saveDb.setUserId(loginUserId);
+ save(saveDb);
+ }
+
+ @Override
+ public void correct(AssignmentsCorrectReq req) {
+ // 查询作业提交记录
+ AssignmentSubmissionsDO assignmentSubmissions = getById(req.getId());
+
+ // 检查是否已经批改
+ CheckUtils.throwIf(assignmentSubmissions.getScore() != null, "作业已批改,请勿重复批改!");
+
+ // 修改分数以及评语
+ lambdaUpdate().eq(AssignmentSubmissionsDO::getId, req.getId())
+ .set(AssignmentSubmissionsDO::getScore, req.getScore())
+ .set(StrUtil.isNotBlank(req.getFeedback()), AssignmentSubmissionsDO::getFeedback, req.getFeedback())
+ .update();
+ }
+
+ @Override
+ public AssignmentsSubmissionsDetailResp detail(Long submissionsId) {
+ // 查询提交记录
+ AssignmentSubmissionsDO submissionsDO = getById(submissionsId);
+ CheckUtils.throwIfNull(submissionsDO, "作业提交记录不存在");
+
+ // 查询作业信息
+ AssignmentsDO assignmentsDO = assignmentsService.getById(submissionsDO.getAssignmentId());
+
+ // 拷贝相关信息 构建返回对象
+ AssignmentsSubmissionsDetailResp res = BeanUtil
+ .copyProperties(assignmentsDO, AssignmentsSubmissionsDetailResp.class);
+ BeanUtil.copyProperties(submissionsDO, res);
+
+ return res;
+ }
+
+ @DS("#dbName")
+ @Override
+ public PageResp getGoodImageList(String dbName, PageQuery pageQuery) {
+ // 查询分数80以上的作业
+ Page page = lambdaQuery().select(AssignmentSubmissionsDO::getImageUrl)
+ .ge(AssignmentSubmissionsDO::getScore, 80)
+ .orderByDesc(AssignmentSubmissionsDO::getCreateTime)
+ .page(new Page<>(pageQuery.getPage(), pageQuery.getSize()));
+
+ // 提取图片地址
+ List imageUrlList = page.getRecords().stream().map(AssignmentSubmissionsDO::getImageUrl).toList();
+
+ // 构建分页返回
+ return new PageResp<>(imageUrlList, page.getTotal());
+ }
+
+ @Override
+ public PageResp degreeOfCompletion(Long assignmentsId, PageQuery pageQuery) {
+ // 检查作业是否存在
+ AssignmentsDO assignmentsDO = assignmentsService.getById(assignmentsId);
+ CheckUtils.throwIfNull(assignmentsDO, "作业不存在!");
+
+ // 分页查询作业有哪些学生
+ Page page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
+ page = courseUserService.lambdaQuery().eq(CourseUserDO::getCourseId, assignmentsDO.getCourseId()).page(page);
+
+ List records = page.getRecords();
+ if (CollUtil.isEmpty(records)) {
+ return new PageResp<>(Collections.emptyList(), 0L);
+ }
+
+ // 提取学生ID 查询提交记录表
+ List userIds = records.stream().map(CourseUserDO::getUserId).toList();
+ Map submissionsMap = lambdaQuery()
+ .eq(AssignmentSubmissionsDO::getAssignmentId, assignmentsId)
+ .in(AssignmentSubmissionsDO::getUserId, userIds)
+ .list()
+ .stream()
+ .collect(Collectors.toMap(AssignmentSubmissionsDO::getUserId, Function.identity()));
+
+ // 查询是否有提交记录,判断学生是否提交作业,判断是否有分数,判断老师是否批改作业
+ List res = records.stream().map(courseUser -> {
+ AssignmentsProgressResp temp = new AssignmentsProgressResp();
+ temp.setNickname(courseUser.getNickname());
+
+ AssignmentSubmissionsDO submissions = submissionsMap.get(courseUser.getUserId());
+ if (submissions == null) {
+ temp.setDegreeOfCompletion(false);
+ temp.setDegreeOfCorrection(false);
+ } else {
+ temp.setSubmissionsId(submissions.getId());
+ temp.setDegreeOfCompletion(true);
+ temp.setDegreeOfCorrection(submissions.getScore() != null);
+ }
+ return temp;
+ }).toList();
+
+ return new PageResp<>(res, page.getTotal());
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/AssignmentsServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/AssignmentsServiceImpl.java
new file mode 100644
index 0000000..7178350
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/AssignmentsServiceImpl.java
@@ -0,0 +1,48 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.AssignmentsMapper;
+import top.continew.admin.business.model.entity.AssignmentsDO;
+import top.continew.admin.business.model.req.AssignmentsReq;
+import top.continew.admin.business.model.resp.AssignmentsDetailResp;
+import top.continew.admin.business.service.AssignmentsService;
+import top.continew.starter.core.util.validate.CheckUtils;
+
+/**
+ * 作业表业务实现
+ *
+ * @author 张波
+ * @since 2024/10/22 11:45
+ */
+@Service
+@RequiredArgsConstructor
+public class AssignmentsServiceImpl extends ServiceImpl implements AssignmentsService {
+
+ @Override
+ public Long add(AssignmentsReq assignmentsReq) {
+ // 检查名字是否存在
+ boolean exists = lambdaQuery().eq(AssignmentsDO::getCourseId, assignmentsReq.getCourseId())
+ .eq(AssignmentsDO::getName, assignmentsReq.getName())
+ .exists();
+ CheckUtils.throwIf(exists, "作业名称已存在,请检查");
+
+ // copy数据 保存到数据库
+ AssignmentsDO saveDb = BeanUtil.copyProperties(assignmentsReq, AssignmentsDO.class);
+ save(saveDb);
+
+ // 返回存储的ID
+ return saveDb.getId();
+ }
+
+ @Override
+ public AssignmentsDetailResp detail(Long assignmentsId) {
+ // 查询库中数据
+ AssignmentsDO assignmentsDO = getById(assignmentsId);
+
+ // 转为Resp
+ return BeanUtil.copyProperties(assignmentsDO, AssignmentsDetailResp.class);
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/BillingRuleServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/BillingRuleServiceImpl.java
new file mode 100644
index 0000000..e694dd2
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/BillingRuleServiceImpl.java
@@ -0,0 +1,85 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.BillingRuleMapper;
+import top.continew.admin.business.model.entity.BillingRuleDO;
+import top.continew.admin.business.model.query.BillingRuleQuery;
+import top.continew.admin.business.model.req.BillingRuleReq;
+import top.continew.admin.business.model.resp.BillingRuleResp;
+import top.continew.admin.business.service.BillingRuleService;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+import java.util.List;
+
+/**
+ * 计费规则业务实现
+ *
+ * @author jiay
+ * @since 2025/11/14
+ */
+@Service
+@RequiredArgsConstructor
+public class BillingRuleServiceImpl extends BaseServiceImpl implements BillingRuleService {
+
+ /**
+ * 根据平台ID获取计费规则(带缓存)
+ */
+ @Override
+ @Cacheable(value = "billingRule", key = "#platformId", unless = "#result == null")
+ public BillingRuleDO getByPlatformId(Long platformId) {
+ return baseMapper.selectOne(new LambdaQueryWrapper().eq(BillingRuleDO::getPlatformId, platformId)
+ .eq(BillingRuleDO::getEnabled, 1)
+ .last("LIMIT 1"));
+ }
+
+ /**
+ * 根据平台ID获取计费金额
+ */
+ @Override
+ public Long getPriceByPlatformId(Long platformId) {
+ BillingRuleDO rule = getByPlatformId(platformId);
+ return rule != null && rule.getPrice() != null ? rule.getPrice() : 0L;
+ }
+
+ /**
+ * 新增或修改后清除缓存
+ */
+ @Override
+ @CacheEvict(value = "billingRule", allEntries = true)
+ public Long add(BillingRuleReq req) {
+ return super.add(req);
+ }
+
+ /**
+ * 更新后清除缓存
+ */
+ @Override
+ @CacheEvict(value = "billingRule", allEntries = true)
+ public void update(BillingRuleReq req, Long id) {
+ super.update(req, id);
+ }
+
+ /**
+ * 删除后清除缓存(批量删除)
+ */
+ @Override
+ @CacheEvict(value = "billingRule", allEntries = true)
+ public void delete(List ids) {
+ super.delete(ids);
+ }
+
+ /**
+ * 根据扣费编码获取计费规则(带缓存)
+ */
+ @Override
+ @Cacheable(value = "billingRule", key = "'charge_' + #chargeCode", unless = "#result == null")
+ public BillingRuleDO getByChargeCode(String chargeCode) {
+ return baseMapper.selectOne(new LambdaQueryWrapper().eq(BillingRuleDO::getChargeCode, chargeCode)
+ .eq(BillingRuleDO::getEnabled, 1)
+ .last("LIMIT 1"));
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/BillingServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/BillingServiceImpl.java
new file mode 100644
index 0000000..ddb5827
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/BillingServiceImpl.java
@@ -0,0 +1,913 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.x.file.storage.core.FileInfo;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import org.springframework.util.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
+import top.continew.admin.business.file.CommonMultipartFile;
+import top.continew.admin.business.model.entity.BillingRuleDO;
+import top.continew.admin.business.model.entity.ConsumptionHistoryDO;
+import top.continew.admin.business.model.entity.PlantformBalanceDO;
+import top.continew.admin.business.model.entity.TaskRecordHistoryDO;
+import top.continew.admin.business.model.req.*;
+import top.continew.admin.system.model.entity.TaskPreDeductDO;
+import top.continew.admin.business.model.resp.BillingDeductResp;
+import top.continew.admin.business.model.resp.TaskCallbackResp;
+import top.continew.admin.business.service.BillingService;
+import top.continew.admin.business.service.BillingRuleService;
+import top.continew.admin.business.mapper.ConsumptionHistoryMapper;
+import top.continew.admin.business.mapper.PlantformBalanceMapper;
+import top.continew.admin.business.mapper.TaskRecordHistoryMapper;
+import top.continew.admin.system.mapper.TaskPreDeductMapper;
+import top.continew.admin.system.model.entity.UserDO;
+import top.continew.admin.system.mapper.UserMapper;
+import cn.dev33.satoken.stp.StpUtil;
+import top.continew.admin.system.service.FileService;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 计费服务实现类
+ *
+ * @author jiay
+ * @since 2025/08/28 00:00
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class BillingServiceImpl implements BillingService {
+
+ private final TaskRecordHistoryMapper taskRecordHistoryMapper;
+ private final ConsumptionHistoryMapper consumptionHistoryMapper;
+ private final PlantformBalanceMapper plantformBalanceMapper;
+ private final TaskPreDeductMapper taskPreDeductMapper;
+ private final UserMapper userMapper;
+ private final FileService fileService;
+ private final BillingRuleService billingRuleService;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public BillingDeductResp judgeBalance(BillingJudgeReq req) {
+ Long userId = StpUtil.getLoginIdAsLong();
+ try {
+ // 1. 获取用户信息
+ UserDO user = userMapper.selectById(userId);
+ if (user == null) {
+ return BillingDeductResp.builder().success(false).errorMessage("用户不存在").build();
+ }
+
+ // 2. 充点类型不需要预扣减
+ if (req.getType() == 0) {
+ return BillingDeductResp.builder()
+ .success(true)
+ .remainingBalance(user.getSysBeans())
+ .errorMessage("无需预扣减,充点类型")
+ .build();
+ }
+
+ // 3. 根据chargeCode从数据库查询计费规则
+ BillingRuleDO billingRule = billingRuleService.getByChargeCode(req.getChargeCode());
+ if (billingRule == null) {
+ log.error("未找到扣费编码 {} 的计费规则", req.getChargeCode());
+ return BillingDeductResp.builder().success(false).errorMessage("未找到对应的计费规则").build();
+ }
+
+ Integer quantity = req.getQuantity();
+ Long price = billingRule.getPrice() != null ? billingRule.getPrice() : 0L;
+ Long subAccountPrice = billingRule.getSubAccountPrice() != null ? billingRule.getSubAccountPrice() : 0L;
+ Integer chargeType = billingRule.getChargeType();
+
+ String deductSource = "";
+ boolean canDeduct = false;
+ Long preDeductAmount = 0L;
+
+ // 4. 优先级1:根据chargeType及用户id从t_plantform_balance取子账户
+ if (chargeType != null && subAccountPrice > 0) {
+ PlantformBalanceDO subBalance = plantformBalanceMapper
+ .selectOne(new LambdaQueryWrapper().eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, chargeType));
+
+ if (subBalance != null) {
+ Long availableBalance = subBalance.getBalance() - subBalance.getPreDeductBalance();
+ Long requiredAmount = quantity * subAccountPrice;
+ //大语言模型 Token计费
+ if (chargeType == 0) {
+ requiredAmount = req.getTokens();
+ }
+ if (availableBalance >= requiredAmount) {
+ // 子账户余额足够,使用子账户单价
+ deductSource = "sub_account_" + chargeType;
+ canDeduct = true;
+ preDeductAmount = requiredAmount;
+
+ // 更新子账号预扣减金额
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, chargeType)
+ .setSql("pre_deduct_balance = pre_deduct_balance + " + preDeductAmount));
+
+ log.info("使用子账户扣减, chargeCode: {}, chargeType: {}, requiredAmount: {}, subAccountPrice: {}, preDeductAmount: {}, 剩余子账户: {}", req
+ .getChargeCode(), chargeType, requiredAmount, subAccountPrice, preDeductAmount, availableBalance - preDeductAmount);
+ }
+ }
+ }
+
+ // 5. 优先级2:如果子账户余额不足,根据用户id及chargeType=11从t_plantform_balance取可学豆子账户
+ if (!canDeduct) {
+ PlantformBalanceDO kexuedouBalance = plantformBalanceMapper
+ .selectOne(new LambdaQueryWrapper().eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11)); // chargeType=11 是可学豆子账户
+
+ if (kexuedouBalance != null) {
+ Long requiredAmount;
+ if (chargeType != null && chargeType == 0) {
+ // Token类型,需要将token数量转换为点数
+ requiredAmount = calculateTokenToPoints(req.getChargeCode(), req.getTokens());
+ log.info("Token转换为点数, tokens: {}, points: {}", req.getTokens(), requiredAmount);
+ } else {
+ // 非token类型,直接使用 quantity * price
+ requiredAmount = quantity * price;
+ }
+ Long availableBalance = kexuedouBalance.getBalance() - kexuedouBalance.getPreDeductBalance();
+
+ if (availableBalance >= requiredAmount) {
+ deductSource = "kexuedou_account";
+ canDeduct = true;
+ preDeductAmount = requiredAmount;
+
+ // 更新可学豆子账户预扣减金额
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11)
+ .setSql("pre_deduct_balance = pre_deduct_balance + " + preDeductAmount));
+
+ }
+ }
+ }
+
+ if (!canDeduct) {
+ Long requiredAmount;
+ if (chargeType != null && chargeType == 0) {
+ // Token类型,需要将token数量转换为点数
+ requiredAmount = calculateTokenToPoints(req.getChargeCode(), req.getTokens());
+ log.info("Token转换为点数(主账户), tokens: {}, points: {}", req.getTokens(), requiredAmount);
+ } else {
+ // 非token类型,直接使用 quantity * price
+ requiredAmount = quantity * price;
+ }
+ Long actualBalance = (user.getSysBeans() != null ? user.getSysBeans().longValue() : 0L);
+ Long preDeductedBalance = (user.getPreDeductBeans() != null
+ ? user.getPreDeductBeans().longValue()
+ : 0L);
+ Long availableBalance = actualBalance - preDeductedBalance;
+
+ if (availableBalance >= requiredAmount) {
+ deductSource = "main_account";
+ canDeduct = true;
+ preDeductAmount = requiredAmount;
+
+ // 更新主账户预扣减金额
+ userMapper.addPreDeductBeansById(userId, preDeductAmount);
+
+ } else {
+ log.warn("主账户余额不足, chargeCode: {}, 需要: {}分, 可用: {}分", req
+ .getChargeCode(), requiredAmount, availableBalance);
+ }
+ }
+
+ if (!canDeduct) {
+ return BillingDeductResp.builder().success(false).errorMessage("可用余额不足,请充值").build();
+ }
+
+ // 7. 创建或更新预扣减记录
+ TaskPreDeductDO existingPreDeduct = taskPreDeductMapper.selectOne(new LambdaQueryWrapper()
+ .eq(TaskPreDeductDO::getUserId, userId)
+ .eq(TaskPreDeductDO::getChargeType, req.getChargeType()));
+
+ if (existingPreDeduct != null) {
+ // 存在记录,更新
+ existingPreDeduct.setPreDeductAmount(preDeductAmount + existingPreDeduct.getPreDeductAmount());
+ existingPreDeduct.setDeductSource(deductSource);
+ existingPreDeduct.setStatus(0); // 0: 进行中
+
+ taskPreDeductMapper.updateById(existingPreDeduct);
+ } else {
+ // 不存在记录,新增
+ TaskPreDeductDO preDeductRecord = new TaskPreDeductDO();
+ preDeductRecord.setUserId(userId);
+ preDeductRecord.setChargeType(req.getChargeType());
+ preDeductRecord.setPreDeductAmount(preDeductAmount);
+ preDeductRecord.setDeductSource(deductSource);
+ preDeductRecord.setStatus(0); // 0: 进行中
+
+ taskPreDeductMapper.insert(preDeductRecord);
+ }
+
+ // 8. 返回校验成功结果
+ return BillingDeductResp.builder()
+ .success(true)
+ .remainingBalance(user.getSysBeans())
+ .errorMessage("余额校验通过并已预扣减,来源: " + deductSource)
+ .build();
+
+ } catch (Exception e) {
+ log.error("余额校验失败, userId: {}, req: {}", userId, req, e);
+ throw e;
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public TaskCallbackResp taskCallback(TaskCallbackReq req) {
+ Long userId = StpUtil.getLoginIdAsLong();
+ try {
+ // 1. 查找预扣减记录
+ TaskPreDeductDO preDeductRecord = taskPreDeductMapper.selectOne(new LambdaQueryWrapper()
+ .eq(TaskPreDeductDO::getUserId, userId)
+ .eq(TaskPreDeductDO::getChargeType, req.getChargeType())
+ // .eq(TaskPreDeductDO::getStatus, 0) // 进行中的任务
+ );
+
+ if (preDeductRecord == null) {
+ return TaskCallbackResp.builder().success(false).message("未找到对应的预扣减记录").build();
+ }
+
+ // 2. 根据任务状态处理
+ if (req.getStatus() == 1) { // 任务成功
+ return handleSuccessCallback(req, preDeductRecord, userId);
+ } else if (req.getStatus() == 0) {
+ return TaskCallbackResp.builder().success(false).message("任务进行中").build();
+ } else { // 任务失败或取消
+ return handleFailureCallback(req, preDeductRecord, userId);
+ }
+
+ } catch (Exception e) {
+ log.error("任务回调异常, taskId: {}, req: {}", req.getTaskId(), req, e);
+ return TaskCallbackResp.builder().success(false).message("任务回调异常: " + e.getMessage()).build();
+ }
+ }
+
+ /**
+ * 处理任务成功的回调
+ */
+ private TaskCallbackResp handleSuccessCallback(TaskCallbackReq req, TaskPreDeductDO preDeductRecord, Long userId) {
+ // 1. 根据chargeCode查询计费规则,计算实际消费点数
+ Long actualConsumptionPoints;
+ Integer actualQuantity = req.getQuantity() != null ? req.getQuantity() : 1;
+
+ if (req.getChargeCode() == null) {
+ log.error("扣费编码不能为空");
+ return TaskCallbackResp.builder().success(false).message("扣费编码不能为空").build();
+ }
+
+ // 查询计费规则
+ BillingRuleDO billingRule = billingRuleService.getByChargeCode(req.getChargeCode());
+ if (billingRule == null) {
+ log.error("未找到扣费编码 {} 的计费规则", req.getChargeCode());
+ return TaskCallbackResp.builder().success(false).message("未找到对应的计费规则").build();
+ }
+
+ String deductSource = preDeductRecord.getDeductSource();
+ Integer chargeType = billingRule.getChargeType();
+
+ // 特殊处理:chargeType=0 表示大语言模型,使用token计费
+ if (chargeType != null && chargeType == 0) {
+ // Token计费类型
+ if (deductSource != null && deductSource.startsWith("sub_account_")) {
+ actualConsumptionPoints = req.getTokens();
+ // 从token子账户扣减,直接扣除token数量
+ log.info("Token子账户扣费, chargeCode: {}, actualTokens: {}", req.getChargeCode(), actualConsumptionPoints);
+ } else {
+ // 从可学豆或主账户扣减,需要根据扣费编码计算点数
+ actualConsumptionPoints = calculateTokenToPoints(req.getChargeCode(), req.getTokens());
+ }
+ } else {
+ // 非token类型,按数量计费
+ if (deductSource != null && deductSource.startsWith("sub_account_")) {
+ // 子账户扣减,使用子账户单价
+ Long subAccountPrice = billingRule.getSubAccountPrice() != null ? billingRule.getSubAccountPrice() : 0L;
+ actualConsumptionPoints = actualQuantity * subAccountPrice;
+ } else {
+ // 可学豆子账户或主账户扣减,使用主账户单价
+ Long price = billingRule.getPrice() != null ? billingRule.getPrice() : 0L;
+ actualConsumptionPoints = actualQuantity * price;
+ }
+ }
+
+ // 2. 创建任务记录
+ TaskRecordHistoryDO taskRecord = new TaskRecordHistoryDO();
+ taskRecord.setUserId(userId);
+ taskRecord.setPlatformId(req.getPlatformId());
+ taskRecord.setTaskId(req.getTaskId());
+ taskRecord.setTitle(req.getTitle());
+ taskRecord.setTaskType(req.getTaskType());
+ taskRecord.setChargeType(req.getChargeType());
+ taskRecord.setModelName(req.getModelName());
+ taskRecord.setConsumptionPoints(actualConsumptionPoints);
+ taskRecord.setPlatformCode(req.getPlatformCode());
+ taskRecord.setAccountType(deductSource);
+
+ //换哒新表补充字段
+ taskRecord.setParentCreateTime(extractDateTime(req.getParentCreateTime()));
+ taskRecord.setTaskRootId(req.getTaskRootId());
+ if (req.getParentTaskId() != null) {
+ taskRecord.setParentTaskId(req.getParentTaskId());
+ }
+
+ // 设置文件路径或文字内容
+ if (req.getTaskType() == 0 || !StringUtils.hasText(req.getFileUrl())) { // token类型或文字类型
+ taskRecord.setResult(req.getResult());
+ taskRecord.setTokens(req.getTokens());
+ taskRecordHistoryMapper.insert(taskRecord);
+ } else { // 音视频图片类型(2,3,4,5)
+ addTaskRecordHistory(taskRecord, req);
+ }
+
+ // 3. 创建消费记录
+ ConsumptionHistoryDO consumption = new ConsumptionHistoryDO();
+ consumption.setUserId(userId);
+ consumption.setPlatformId(req.getPlatformId());
+ consumption.setTaskType(req.getTaskType());
+ consumption.setChargePoints(actualConsumptionPoints);
+
+ // 4. 根据扣减来源进行实际扣费和清零预扣减
+ if (deductSource != null && deductSource.startsWith("sub_account_")) {
+ // 子账户扣费(chargeType特定的子账户,如sub_account_1, sub_account_3等)
+ PlantformBalanceDO balance = plantformBalanceMapper.selectOne(new LambdaQueryWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, chargeType));
+
+ consumption.setRemainingPoints(balance.getBalance() - actualConsumptionPoints);
+ consumption.setType(req.getType()); // 消费类型
+ consumption.setAccountType(1); // 1子账号
+
+ // 扣减实际金额并清零预扣减
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, chargeType)
+ .setSql("balance = balance - " + actualConsumptionPoints + ", pre_deduct_balance = pre_deduct_balance - " + preDeductRecord
+ .getPreDeductAmount()));
+
+ } else if ("kexuedou_account".equals(deductSource)) {
+ // 可学豆子账户扣费(chargeType=11的子账户)
+ PlantformBalanceDO balance = plantformBalanceMapper.selectOne(new LambdaQueryWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11));
+
+ consumption.setRemainingPoints(balance.getBalance() - actualConsumptionPoints);
+ consumption.setType(req.getType()); // 消费类型
+ consumption.setAccountType(1); // 1子账号
+
+ // 扣减实际金额并清零预扣减
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11)
+ .setSql("balance = balance - " + actualConsumptionPoints + ", pre_deduct_balance = pre_deduct_balance - " + preDeductRecord
+ .getPreDeductAmount()));
+
+ log.info("可学豆子账户扣费完成, actualConsumption: {}", actualConsumptionPoints);
+ } else if ("main_account".equals(deductSource)) {
+ // 主账户sys_beans扣费
+ UserDO user = userMapper.selectById(userId);
+ consumption.setRemainingPoints(user.getSysBeans().longValue() - actualConsumptionPoints);
+ consumption.setType(req.getType()); // 消费类型
+ consumption.setAccountType(0); // 0主账号
+
+ // 原子操作:扣减实际金额并清零预扣减 单位为分
+ int updateResult = userMapper.deductActualAndClearPreDeduct(userId, preDeductRecord
+ .getPreDeductAmount(), actualConsumptionPoints);
+ if (updateResult == 0) {
+ throw new RuntimeException("扣减用户余额失败");
+ }
+
+ log.info("主账户扣费完成, actualConsumption: {}", actualConsumptionPoints);
+ } else {
+ log.error("未知的扣减来源: {}", deductSource);
+ throw new RuntimeException("未知的扣减来源: " + deductSource);
+ }
+
+ consumptionHistoryMapper.insert(consumption);
+
+ // 5. 更新预扣减记录状态
+ preDeductRecord.setStatus(1); // 1: 已完成
+ taskPreDeductMapper.updateById(preDeductRecord);
+
+ log.info("任务成功回调完成, taskId: {}, userId: {}, platformCode: {}, preDeduct: {}, actual: {}", req
+ .getTaskId(), userId, req.getPlatformCode(), preDeductRecord.getPreDeductAmount(), actualConsumptionPoints);
+
+ return TaskCallbackResp.builder().success(true).message("任务成功,扣费完成").taskRecordId(taskRecord.getId()).build();
+ }
+
+ /**
+ * 从字符串中提取时间
+ *
+ * @param dateTimeString 时间字符串
+ * @return LocalDateTime
+ */
+ private static LocalDateTime extractDateTime(String dateTimeString) {
+ try {
+ if (dateTimeString == null || dateTimeString.isEmpty()) {
+ return null;
+ }
+ return LocalDateTime.parse(dateTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 将token数量转换为点数(用于从可学豆或主账户扣减)
+ *
+ * @param chargeCode 扣费编码
+ * @param tokens token数量
+ * @return 消费点数(分)
+ */
+ private Long calculateTokenToPoints(String chargeCode, Long tokens) {
+ if (tokens == null || tokens <= 0) {
+ return 0L;
+ }
+
+ Long points;
+ Long minPoints;
+
+ // 根据扣费编码确定费率和最低扣费
+ switch (chargeCode) {
+ case "C5000":
+ // 100万token=200分,单次最低2分
+ points = (tokens * 200 + 999999) / 1000000; // 向上取整
+ minPoints = 2L;
+ break;
+ case "C5001":
+ // 100万token=150分,单次最低2分
+ points = (tokens * 150 + 999999) / 1000000; // 向上取整
+ minPoints = 2L;
+ break;
+ case "C5002":
+ // 100万token=400分,单次最低5分
+ points = (tokens * 400 + 999999) / 1000000; // 向上取整
+ minPoints = 5L;
+ break;
+ case "C5003":
+ // 100万token=200分,单次最低6分
+ points = (tokens * 200 + 999999) / 1000000; // 向上取整
+ minPoints = 6L;
+ break;
+ case "C7000":
+ // 100万token=200分,单次最低3分
+ points = (tokens * 200 + 999999) / 1000000; // 向上取整
+ minPoints = 3L;
+ break;
+ default:
+ log.warn("未配置扣费编码 {} 的token转换规则,使用默认规则", chargeCode);
+ // 默认:100万token=200分,单次最低2分
+ points = (tokens * 200 + 999999) / 1000000;
+ minPoints = 2L;
+ break;
+ }
+
+ // 确保不低于最低扣费
+ return Math.max(points, minPoints);
+ }
+
+ /**
+ * 处理任务失败的回调
+ */
+ private TaskCallbackResp handleFailureCallback(TaskCallbackReq req, TaskPreDeductDO preDeductRecord, Long userId) {
+ // 1. 恢复预扣减的金额
+ String deductSource = preDeductRecord.getDeductSource();
+ if (deductSource != null && deductSource.startsWith("sub_account_")) {
+ // 恢复子账户预扣减金额(chargeType特定的子账户)
+ // 从deductSource中提取chargeType
+ Integer chargeType = Integer.parseInt(deductSource.substring("sub_account_".length()));
+
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, chargeType)
+ .setSql("pre_deduct_balance = pre_deduct_balance - " + preDeductRecord.getPreDeductAmount()));
+
+ log.info("子账户预扣减恢复完成, chargeType: {}, amount: {}", chargeType, preDeductRecord.getPreDeductAmount());
+ } else if ("kexuedou_account".equals(deductSource)) {
+ // 恢复可学豆子账户预扣减金额(chargeType=11)
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11)
+ .setSql("pre_deduct_balance = pre_deduct_balance - " + preDeductRecord.getPreDeductAmount()));
+
+ log.info("可学豆子账户预扣减恢复完成, amount: {}", preDeductRecord.getPreDeductAmount());
+ } else if ("main_account".equals(deductSource)) {
+ // 恢复主账户预扣减金额
+ userMapper.clearPreDeductBeansById(userId, preDeductRecord.getPreDeductAmount());
+
+ log.info("主账户预扣减恢复完成, amount: {}", preDeductRecord.getPreDeductAmount());
+ } else {
+ log.error("未知的扣减来源: {}", deductSource);
+ throw new RuntimeException("未知的扣减来源: " + deductSource);
+ }
+
+ // 2. 更新预扣减记录状态
+ preDeductRecord.setStatus(req.getStatus() == 2 ? 2 : 3); // 2: 已失败, 3: 已取消
+ taskPreDeductMapper.updateById(preDeductRecord);
+
+ return TaskCallbackResp.builder().success(true).message("任务失败,预扣减金额已恢复").build();
+ }
+
+ private void addTaskRecordHistory(TaskRecordHistoryDO taskRecord, TaskCallbackReq req) {
+ String fileStr = req.getFileUrl();
+ //先下载文件
+ List fileUrls = Arrays.asList(fileStr.split(","));
+ if (!fileUrls.isEmpty()) {
+ fileUrls.forEach(fileUrl -> {
+ if (StrUtil.isEmpty(fileUrl)) {
+ throw new RuntimeException("文件url地址为空");
+ }
+ FileInfo upload;
+ try {
+ // 1. 构造URL格式
+ URL url = new URL(fileUrl);
+ // 2. 打开HTTP连接并配置参数
+ HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+ connection.setRequestMethod("GET");
+ // 5秒连接超时
+ connection.setConnectTimeout(5000);
+ // 10秒读取超时
+ connection.setReadTimeout(10000);
+ // 设置User-Agent
+ connection.setRequestProperty("User-Agent", "Mozilla/5.0");
+ // 3. 检查HTTP响应状态码
+ int responseCode = connection.getResponseCode();
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ throw new IOException("HTTP请求失败,状态码: " + responseCode);
+ }
+ // 4. 获取输入流(注意:调用者需负责关闭此流)
+ InputStream inputStream = connection.getInputStream();
+ String fileName = extractFileName(fileUrl);
+ // 过滤非法字符
+ String safeFileName = sanitizeFileName(fileName);
+ String uniqueName = UUID.randomUUID() + "_" + safeFileName;
+ MultipartFile multipartFile = new CommonMultipartFile(uniqueName, safeFileName, MediaType.MULTIPART_FORM_DATA_VALUE, inputStream);
+ upload = fileService.upload(multipartFile);
+
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ throw new RuntimeException("文件下载失败");
+ }
+ //插入记录到数据库
+ taskRecord.setFileUrl(upload.getUrl());
+ taskRecordHistoryMapper.insert(taskRecord);
+ });
+ }
+ }
+
+ private static String extractFileName(String fileUrl) {
+ try {
+ URI uri = URI.create(fileUrl);
+ String path = uri.getPath();
+ if (path == null || path.isEmpty()) {
+ return "unknown_" + System.currentTimeMillis();
+ }
+ // 提取最后一个斜杠后的内容
+ String rawName = path.substring(path.lastIndexOf('/') + 1);
+
+ // 去除URL参数(如?foo=bar)
+ return rawName.contains("?") ? rawName.split("\\?")[0] : rawName;
+ } catch (Exception e) {
+ return "unknown_" + System.currentTimeMillis();
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public BillingDeductResp judgeBalanceWithAmount(BillingJudgeWithAmountReq req) {
+ Long userId = StpUtil.getLoginIdAsLong();
+ try {
+ // 1. 获取用户信息
+ UserDO user = userMapper.selectById(userId);
+ if (user == null) {
+ return BillingDeductResp.builder().success(false).errorMessage("用户不存在").build();
+ }
+
+ String deductSource = "";
+ boolean canDeduct = false;
+ Integer chargeType = req.getChargeType();
+ Long preDeductAmount = 0L;
+ // 2. 充点类型不需要预扣减
+ if (req.getType() == 0) {
+ return BillingDeductResp.builder()
+ .success(true)
+ .remainingBalance(user.getSysBeans())
+ .errorMessage("无需预扣减,充点类型")
+ .build();
+ } else if (req.getType() == 1) {
+ // 3. 使用第三方平台传入的预扣减金额
+ preDeductAmount = req.getQuantity().longValue();
+ // 4. 优先级1:检查子账户余额
+ PlantformBalanceDO subBalance = plantformBalanceMapper
+ .selectOne(new LambdaQueryWrapper().eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, chargeType));
+
+ if (subBalance != null) {
+ Long availableBalance = subBalance.getBalance() - subBalance.getPreDeductBalance();
+
+ if (availableBalance >= preDeductAmount) {
+ // 子账户余额足够
+ deductSource = "sub_account_" + chargeType;
+ canDeduct = true;
+
+ // 更新子账号预扣减金额
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, chargeType)
+ .setSql("pre_deduct_balance = pre_deduct_balance + " + preDeductAmount));
+ }
+ }
+ } else if (req.getType() == 2) {
+ preDeductAmount = req.getPreDeductAmount();
+ // 5. 优先级2:如果子账户余额不足,检查可学豆子账户
+ if (!canDeduct) {
+ PlantformBalanceDO kexuedouBalance = plantformBalanceMapper
+ .selectOne(new LambdaQueryWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11)); // chargeType=11 是可学豆子账户
+
+ if (kexuedouBalance != null) {
+ Long availableBalance = kexuedouBalance.getBalance() - kexuedouBalance.getPreDeductBalance();
+
+ if (availableBalance >= preDeductAmount) {
+ deductSource = "kexuedou_account";
+ canDeduct = true;
+
+ // 更新可学豆子账户预扣减金额
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11)
+ .setSql("pre_deduct_balance = pre_deduct_balance + " + preDeductAmount));
+ }
+ }
+ }
+ if (!canDeduct) {
+ Long actualBalance = (user.getSysBeans() != null ? user.getSysBeans().longValue() : 0L);
+ Long preDeductedBalance = (user.getPreDeductBeans() != null
+ ? user.getPreDeductBeans().longValue()
+ : 0L);
+ Long availableBalance = actualBalance - preDeductedBalance;
+
+ if (availableBalance >= preDeductAmount) {
+ deductSource = "main_account";
+ canDeduct = true;
+
+ // 更新主账户预扣减金额
+ userMapper.addPreDeductBeansById(userId, preDeductAmount);
+
+ log.info("使用主账户扣减(第三方金额), preDeductAmount: {}分, 剩余主账户: {}分", preDeductAmount, availableBalance - preDeductAmount);
+ } else {
+ log.warn("主账户余额不足(第三方金额), 需要: {}分, 可用: {}分", preDeductAmount, availableBalance);
+ }
+ }
+ }
+
+ if (!canDeduct) {
+ return BillingDeductResp.builder().success(false).errorMessage("可用余额不足,请充值").build();
+ }
+
+ // 7. 创建或更新预扣减记录
+ TaskPreDeductDO existingPreDeduct = taskPreDeductMapper.selectOne(new LambdaQueryWrapper()
+ .eq(TaskPreDeductDO::getUserId, userId)
+ .eq(TaskPreDeductDO::getChargeType, chargeType));
+
+ if (existingPreDeduct != null) {
+ // 存在记录,更新
+ existingPreDeduct.setPreDeductAmount(preDeductAmount + existingPreDeduct.getPreDeductAmount());
+ existingPreDeduct.setDeductSource(deductSource);
+ existingPreDeduct.setStatus(0); // 0: 进行中
+
+ taskPreDeductMapper.updateById(existingPreDeduct);
+ log.info("更新预扣减记录成功(第三方金额), userId: {}, amount: {}, source: {}", userId, preDeductAmount, deductSource);
+ } else {
+ // 不存在记录,新增
+ TaskPreDeductDO preDeductRecord = new TaskPreDeductDO();
+ preDeductRecord.setUserId(userId);
+ preDeductRecord.setChargeType(chargeType);
+ preDeductRecord.setPreDeductAmount(preDeductAmount);
+ preDeductRecord.setDeductSource(deductSource);
+ preDeductRecord.setStatus(0); // 0: 进行中
+
+ taskPreDeductMapper.insert(preDeductRecord);
+ log.info("创建预扣减记录成功(第三方金额), userId: {}, amount: {}, source: {}", userId, preDeductAmount, deductSource);
+ }
+
+ // 8. 返回校验成功结果
+ return BillingDeductResp.builder()
+ .success(true)
+ .remainingBalance(user.getSysBeans())
+ .errorMessage("余额校验通过并已预扣减(第三方金额),来源: " + deductSource)
+ .build();
+
+ } catch (Exception e) {
+ log.error("余额校验失败(第三方金额), userId: {}, req: {}", userId, req, e);
+ throw e;
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public TaskCallbackResp taskCallbackWithAmount(TaskCallbackWithAmountReq req) {
+ Long userId = StpUtil.getLoginIdAsLong();
+ try {
+ // 1. 查找预扣减记录
+ TaskPreDeductDO preDeductRecord = taskPreDeductMapper.selectOne(new LambdaQueryWrapper()
+ .eq(TaskPreDeductDO::getUserId, userId)
+ .eq(TaskPreDeductDO::getChargeType, req.getChargeType())
+ //.eq(TaskPreDeductDO::getStatus, 0) // 进行中的任务
+ );
+
+ if (preDeductRecord == null) {
+ return TaskCallbackResp.builder().success(false).message("未找到对应的预扣减记录").build();
+ }
+
+ // 2. 根据任务状态处理
+ if (req.getStatus() == 1) {
+ // 任务成功,使用第三方传入的实际消费金额进行扣费
+ return handleSuccessCallbackWithAmount(req, preDeductRecord, userId);
+ } else {
+ // 任务失败或取消,恢复预扣减(与原逻辑相同)
+ return handleFailureCallback(req, preDeductRecord, userId);
+ }
+
+ } catch (Exception e) {
+ log.error("任务回调失败(第三方金额), userId: {}, taskId: {}", userId, req.getTaskId(), e);
+ throw e;
+ }
+ }
+
+ @Override
+ public Page queryTaskListByRootId(TaskQueryReq req) {
+ try {
+ // 根据根任务ID查询任务列表
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(TaskRecordHistoryDO::getTaskRootId, req.getTaskRootId());
+ queryWrapper.orderByDesc(TaskRecordHistoryDO::getCreateTime);
+
+ // 分页查询
+ Page page = new Page<>(req.getPage(), req.getSize());
+ Page resultPage = taskRecordHistoryMapper.selectPage(page, queryWrapper);
+
+ return resultPage;
+ } catch (Exception e) {
+ log.error("查询任务列表失败, taskRootId: {}", req.getTaskRootId(), e);
+ return null;
+ }
+ }
+
+ /**
+ * 处理任务成功的回调(使用第三方传入的实际消费金额)
+ */
+ private TaskCallbackResp handleSuccessCallbackWithAmount(TaskCallbackWithAmountReq req,
+ TaskPreDeductDO preDeductRecord,
+ Long userId) {
+ String deductSource = preDeductRecord.getDeductSource();
+ Integer chargeType = req.getChargeType();
+
+ // 使用第三方平台传入的实际消费金额
+ Long actualConsumptionPoints = req.getActualAmount();
+ if (req.getType() == 1) {
+ actualConsumptionPoints = req.getQuantity().longValue();
+ }
+
+ log.info("使用第三方传入的实际消费金额, actualAmount: {}", actualConsumptionPoints);
+
+ // 2. 创建任务记录
+ TaskRecordHistoryDO taskRecord = new TaskRecordHistoryDO();
+ taskRecord.setUserId(userId);
+ taskRecord.setPlatformId(req.getPlatformId());
+ taskRecord.setTaskId(req.getTaskId());
+ taskRecord.setTitle(req.getTitle());
+ taskRecord.setTaskType(req.getTaskType());
+ taskRecord.setChargeType(req.getChargeType());
+ taskRecord.setModelName(req.getModelName());
+ taskRecord.setConsumptionPoints(actualConsumptionPoints);
+ taskRecord.setPlatformCode(req.getPlatformCode());
+ taskRecord.setAccountType(deductSource);
+
+ //换哒新表补充字段
+ taskRecord.setParentCreateTime(extractDateTime(req.getParentCreateTime()));
+ taskRecord.setTaskRootId(req.getTaskRootId());
+ if (req.getParentTaskId() != null) {
+ taskRecord.setParentTaskId(req.getParentTaskId());
+ }
+
+ // 设置文件路径或文字内容
+ if (req.getTaskType() == 0 || !StringUtils.hasText(req.getFileUrl())) { // token类型或文字类型
+ taskRecord.setResult(req.getResult());
+ taskRecord.setTokens(req.getTokens());
+ taskRecordHistoryMapper.insert(taskRecord);
+ } else { // 音视频图片类型(2,3,4,5)
+ addTaskRecordHistory(taskRecord, req);
+ }
+
+ // 3. 创建消费记录
+ ConsumptionHistoryDO consumption = new ConsumptionHistoryDO();
+ consumption.setUserId(userId);
+ consumption.setPlatformId(req.getPlatformId());
+ consumption.setTaskType(req.getTaskType());
+ consumption.setChargePoints(actualConsumptionPoints);
+
+ // 4. 根据扣减来源进行实际扣费和清零预扣减
+ if (deductSource != null && deductSource.startsWith("sub_account_")) {
+ // 子账户扣费(chargeType特定的子账户)
+ Integer extractedChargeType = Integer.parseInt(deductSource.substring("sub_account_".length()));
+
+ PlantformBalanceDO balance = plantformBalanceMapper.selectOne(new LambdaQueryWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, extractedChargeType));
+
+ consumption.setRemainingPoints(balance.getBalance() - actualConsumptionPoints);
+ consumption.setType(req.getType()); // 消费类型
+ consumption.setAccountType(1); // 1子账号
+
+ // 扣减实际金额并清零预扣减
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, extractedChargeType)
+ .setSql("balance = balance - " + actualConsumptionPoints + ", pre_deduct_balance = pre_deduct_balance - " + preDeductRecord
+ .getPreDeductAmount()));
+
+ log.info("子账户扣费完成(第三方金额), chargeType: {}, actualConsumption: {}", extractedChargeType, actualConsumptionPoints);
+ } else if ("kexuedou_account".equals(deductSource)) {
+ // 可学豆子账户扣费(chargeType=11的子账户)
+ PlantformBalanceDO balance = plantformBalanceMapper.selectOne(new LambdaQueryWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11));
+
+ consumption.setRemainingPoints(balance.getBalance() - actualConsumptionPoints);
+ consumption.setType(req.getType()); // 消费类型
+ consumption.setAccountType(1); // 1子账号
+
+ // 扣减实际金额并清零预扣减
+ plantformBalanceMapper.update(null, new LambdaUpdateWrapper()
+ .eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getChargeType, 11)
+ .setSql("balance = balance - " + actualConsumptionPoints + ", pre_deduct_balance = pre_deduct_balance - " + preDeductRecord
+ .getPreDeductAmount()));
+
+ log.info("可学豆子账户扣费完成(第三方金额), actualConsumption: {}", actualConsumptionPoints);
+ } else if ("main_account".equals(deductSource)) {
+ // 主账户sys_beans扣费
+ UserDO user = userMapper.selectById(userId);
+ consumption.setRemainingPoints(user.getSysBeans().longValue() - actualConsumptionPoints);
+ consumption.setType(req.getType()); // 消费类型
+ consumption.setAccountType(0); // 0主账号
+
+ // 原子操作:扣减实际金额并清零预扣减 单位为分
+ int updateResult = userMapper.deductActualAndClearPreDeduct(userId, preDeductRecord
+ .getPreDeductAmount(), actualConsumptionPoints);
+ if (updateResult == 0) {
+ throw new RuntimeException("扣减用户余额失败");
+ }
+
+ log.info("主账户扣费完成(第三方金额), actualConsumption: {}", actualConsumptionPoints);
+ } else {
+ log.error("未知的扣减来源: {}", deductSource);
+ throw new RuntimeException("未知的扣减来源: " + deductSource);
+ }
+
+ consumptionHistoryMapper.insert(consumption);
+
+ // 5. 更新预扣减记录状态
+ preDeductRecord.setStatus(1); // 1: 已完成
+ taskPreDeductMapper.updateById(preDeductRecord);
+
+ log.info("任务成功回调完成(第三方金额), taskId: {}, userId: {}, platformCode: {}, preDeduct: {}, actual: {}", req
+ .getTaskId(), userId, req.getPlatformCode(), preDeductRecord.getPreDeductAmount(), actualConsumptionPoints);
+
+ return TaskCallbackResp.builder()
+ .success(true)
+ .message("任务成功,扣费完成(第三方金额)")
+ .taskRecordId(taskRecord.getId())
+ .build();
+ }
+
+ // 过滤非法文件名字符(Windows/Linux兼容)
+ private static String sanitizeFileName(String fileName) {
+ // 替换非法字符为下划线
+ return fileName.replaceAll("[\\\\/:*?\"<>|]", "_");
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ConsumptionHistoryServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ConsumptionHistoryServiceImpl.java
new file mode 100644
index 0000000..83fbb79
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ConsumptionHistoryServiceImpl.java
@@ -0,0 +1,136 @@
+package top.continew.admin.business.service.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.ConsumptionHistoryMapper;
+import top.continew.admin.business.model.entity.ConsumptionHistoryDO;
+import top.continew.admin.business.model.query.ConsumptionHistoryQuery;
+import top.continew.admin.business.model.req.ConsumptionHistoryAddReq;
+import top.continew.admin.business.model.req.ConsumptionHistoryEditReq;
+import top.continew.admin.business.model.req.ConsumptionReq;
+import top.continew.admin.business.model.resp.ConsumptionHistoryResp;
+import top.continew.admin.business.service.ConsumptionHistoryService;
+import top.continew.admin.system.mapper.UserMapper;
+import top.continew.admin.system.model.entity.UserDO;
+import top.continew.admin.system.service.UserService;
+import top.continew.starter.data.mp.service.impl.ServiceImpl;
+import top.continew.starter.data.mp.util.QueryWrapperHelper;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.web.model.R;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 用户充值消费历史记录业务实现
+ *
+ * @author jiay
+ * @since 2025/extends7:51
+ */
+@Service
+@RequiredArgsConstructor
+public class ConsumptionHistoryServiceImpl extends ServiceImpl implements ConsumptionHistoryService {
+ private final ConsumptionHistoryMapper consumptionHistoryMapper;
+ private final UserMapper userMapper;
+ private final UserService userService;
+
+ @Override
+ public List getConsumptionHistoryList(ConsumptionHistoryQuery query) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ List list = this.list(queryWrapper);
+
+ if (CollectionUtil.isNotEmpty(list)) {
+ return BeanUtil.copyToList(list, ConsumptionHistoryResp.class);
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean addConsumptionHistory(ConsumptionHistoryAddReq req) {
+ //先校验userId
+ String userId = req.getUserId();
+ if (!StpUtil.isLogin(userId)) {
+ StpUtil.login(userId);
+ }
+
+ userMapper.updateSysBeansById(Long.parseLong(userId), req.getChargePoints());
+
+ ConsumptionHistoryDO entity = BeanUtil.copyProperties(req, ConsumptionHistoryDO.class);
+ entity.setCreateUser(Long.parseLong(req.getUserId()));
+ return consumptionHistoryMapper.insert(entity) > 0;
+ }
+
+ @Override
+ public boolean editConsumptionHistory(ConsumptionHistoryEditReq req) {
+ ConsumptionHistoryDO ConsumptionHistoryDO = BeanUtil.copyProperties(req, ConsumptionHistoryDO.class);
+ return consumptionHistoryMapper.updateById(ConsumptionHistoryDO) > 0;
+
+ }
+
+ @Override
+ public boolean deleteConsumptionHistory(Long id) {
+ if (id != null) {
+ return consumptionHistoryMapper.deleteById(id) > 0;
+ }
+ return false;
+ }
+
+ @Override
+ public ConsumptionHistoryResp getConsumptionHistory(Long id) {
+ ConsumptionHistoryDO ConsumptionHistoryDO = consumptionHistoryMapper.selectById(id);
+ ConsumptionHistoryResp ConsumptionHistoryResp = new ConsumptionHistoryResp();
+ if (ConsumptionHistoryDO != null) {
+ ConsumptionHistoryResp = BeanUtil.copyProperties(ConsumptionHistoryDO, ConsumptionHistoryResp.class);
+ }
+ return ConsumptionHistoryResp;
+ }
+
+ @Override
+ public PageResp getConsumptionHistoryPage(ConsumptionHistoryQuery query,
+ PageQuery pageQuery) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ this.sort(queryWrapper, pageQuery.getSort());
+ Page page = consumptionHistoryMapper.selectPage(new Page<>(pageQuery.getPage(), pageQuery
+ .getSize()), queryWrapper);
+ return PageResp.build(page);
+ }
+
+ /**
+ * 设置排序
+ *
+ * @param queryWrapper 查询条件封装对象
+ * @param sort 排序查询条件
+ */
+ private void sort(QueryWrapper queryWrapper, Sort sort) {
+ if (sort == null || sort.isUnsorted()) {
+ return;
+ }
+ for (Sort.Order order : sort) {
+ String property = order.getProperty();
+ queryWrapper.orderBy(true, order.isAscending(), CharSequenceUtil.toUnderlineCase(property));
+ }
+ }
+
+ @Override
+ public R checkBalance(ConsumptionReq req) {
+ //先校验userId
+ Long userId = req.getUserId();
+ if (!StpUtil.isLogin(userId)) {
+ StpUtil.login(userId);
+ }
+ UserDO user = userService.getById(req.getUserId());
+ if (user.getSysBeans() < req.getChargePoints()) {
+ return R.fail(R.fail().getCode(), "余额不足,请充值!");
+ }
+ return R.ok();
+ }
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CopyrightServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CopyrightServiceImpl.java
new file mode 100644
index 0000000..c0cbcba
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CopyrightServiceImpl.java
@@ -0,0 +1,69 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.CopyrightMapper;
+import top.continew.admin.business.model.entity.Copyright;
+import top.continew.admin.business.model.query.CopyrightPageQuery;
+import top.continew.admin.business.model.query.CopyrightQuery;
+import top.continew.admin.business.model.req.CopyrightReq;
+import top.continew.admin.business.model.resp.CopyrightDetailResp;
+import top.continew.admin.business.model.resp.CopyrightResp;
+import top.continew.admin.business.service.CopyrightService;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+/**
+ * 数字人-文案服务实现类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Service
+@RequiredArgsConstructor
+public class CopyrightServiceImpl extends BaseServiceImpl implements CopyrightService {
+
+ private final CopyrightMapper copyrightMapper;
+
+ @Override
+ public PageResp pageList(CopyrightQuery query, CopyrightPageQuery pageQuery) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ if (query.getUserId() != null) {
+ wrapper.eq(Copyright::getUserId, query.getUserId());
+ }
+ if (query.getText() != null) {
+ wrapper.like(Copyright::getText, query.getText());
+ }
+
+ // 默认格局createTime 倒叙排列
+ wrapper.orderByDesc(Copyright::getCreateTime);
+
+
+ Page page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
+ Page result = copyrightMapper.selectPage(page, wrapper);
+
+ PageResp pageResp = new PageResp();
+ pageResp.setTotal(result.getTotal());
+ pageResp.setList(result.getRecords().stream().map(this::convertToResp).toList());
+ return pageResp;
+ }
+
+ @Override
+ public Long add(CopyrightReq req) {
+ Copyright copyright = new Copyright();
+ BeanUtils.copyProperties(req, copyright);
+ copyright.setCreateTime(java.time.LocalDateTime.now());
+ copyright.setUpdateTime(java.time.LocalDateTime.now());
+ copyrightMapper.insert(copyright);
+ return copyright.getId();
+ }
+
+ private CopyrightResp convertToResp(Copyright copyright) {
+ CopyrightResp resp = new CopyrightResp();
+ BeanUtils.copyProperties(copyright, resp);
+ return resp;
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CourseUserServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CourseUserServiceImpl.java
new file mode 100644
index 0000000..b1632a8
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CourseUserServiceImpl.java
@@ -0,0 +1,15 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.CourseUserMapper;
+import top.continew.admin.business.model.entity.CourseUserDO;
+import top.continew.admin.business.service.CourseUserService;
+
+/**
+ * @author 张波
+ * @since 2024/10/22 12:21
+ */
+@Service
+public class CourseUserServiceImpl extends ServiceImpl implements CourseUserService {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CoursesServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CoursesServiceImpl.java
new file mode 100644
index 0000000..f3eb10e
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/CoursesServiceImpl.java
@@ -0,0 +1,213 @@
+package top.continew.admin.business.service.impl;
+
+import cn.crane4j.core.support.OperateTemplate;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import net.dreamlu.mica.core.utils.BeanUtil;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import top.continew.admin.business.enums.AssignmentsTypeEnum;
+import top.continew.admin.business.mapper.CoursesMapper;
+import top.continew.admin.business.model.entity.AssignmentSubmissionsDO;
+import top.continew.admin.business.model.entity.AssignmentsDO;
+import top.continew.admin.business.model.entity.CourseUserDO;
+import top.continew.admin.business.model.entity.CoursesDO;
+import top.continew.admin.business.model.req.CoursesReq;
+import top.continew.admin.business.model.resp.AssignmentsResp;
+import top.continew.admin.business.model.resp.CoursesResp;
+import top.continew.admin.business.service.AssignmentSubmissionsService;
+import top.continew.admin.business.service.AssignmentsService;
+import top.continew.admin.business.service.CourseUserService;
+import top.continew.admin.business.service.CoursesService;
+import top.continew.admin.common.util.helper.LoginHelper;
+import top.continew.admin.system.enums.MessageTemplateEnum;
+import top.continew.admin.system.enums.MessageTypeEnum;
+import top.continew.admin.system.model.req.MessageReq;
+import top.continew.admin.system.service.MessageService;
+import top.continew.admin.system.service.MessageUserService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 课程业务实现
+ *
+ * @author 张波
+ * @since 2024/10/22 11:58
+ */
+@Service
+@RequiredArgsConstructor
+public class CoursesServiceImpl extends ServiceImpl implements CoursesService {
+
+ private final CourseUserService courseUserService;
+
+ private final AssignmentsService assignmentsService;
+
+ private final AssignmentSubmissionsService assignmentSubmissionsService;
+
+ private final MessageService messageService;
+
+ private final MessageUserService messageUserService;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void add(CoursesReq req) {
+ // 保存课程基础信息
+ CoursesDO saveDb = new CoursesDO();
+ BeanUtil.copyProperties(req, saveDb);
+ save(saveDb);
+
+ // 构建课程-学生关联信息 并保存
+ List courseUserList = req.getUsers().stream().map(user -> {
+ CourseUserDO temp = new CourseUserDO();
+
+ temp.setCourseId(saveDb.getId());
+ temp.setUserId(user.getUserId());
+ temp.setNickname(user.getNickname());
+ //发送消息
+ MessageReq messageReq = new MessageReq();
+ MessageTemplateEnum socialRegister = MessageTemplateEnum.SOCIAL_COUR;
+ messageReq.setTitle(socialRegister.getTitle().formatted(req.getName()));
+ messageReq.setContent(socialRegister.getContent().formatted(user.getNickname(), req.getName()));
+ messageReq.setType(MessageTypeEnum.SECURITY);
+ messageService.add(messageReq, CollUtil.toList(user.getUserId()));
+ return temp;
+ }).toList();
+ courseUserService.saveBatch(courseUserList);
+ }
+
+ /**
+ *
+ * @param db 动态数据库
+ * @param role 角色(学生/老师)
+ * @param pageQuery 分页查询条件
+ * @return
+ */
+ @Override
+ @DS("#db")
+ public PageResp list(String db, String role, PageQuery pageQuery) {
+ Page page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
+
+ // 查询当前登录用户ID
+ Long loginUserId = LoginHelper.getUserId();
+
+ // 如果登录用户是学生则关联课程
+ if (role.equals("pupil")) {
+ List courseIdList = courseUserService.lambdaQuery()
+ .select(CourseUserDO::getCourseId)
+ .eq(CourseUserDO::getUserId, loginUserId)
+ .list()
+ .stream()
+ .map(CourseUserDO::getCourseId)
+ .toList();
+ if (CollUtil.isEmpty(courseIdList)) {
+ return new PageResp<>(Collections.emptyList(), 0L);
+ }
+
+ // 根据关联ID查询课程信息
+ page = lambdaQuery().in(CoursesDO::getId, courseIdList).orderByDesc(CoursesDO::getCreateTime).page(page);
+ // 如果为老师则查询当前登录人创建的课程信息
+ } else if (role.equals("teacher")) {
+ page = lambdaQuery().eq(CoursesDO::getCreateUser, loginUserId)
+ .orderByDesc(CoursesDO::getCreateTime)
+ .page(page);
+ }
+
+ // 封装响应
+ PageResp pageResp = PageResp.build(page, CoursesResp.class);
+ pageResp.getList().forEach(obj -> {
+ if (null == obj) {
+ return;
+ }
+
+ OperateTemplate operateTemplate = SpringUtil.getBean(OperateTemplate.class);
+ operateTemplate.execute(obj);
+ });
+
+ return pageResp;
+ }
+
+ @Override
+ public List assignmentsList(Long coursesId, AssignmentsTypeEnum type, String role) {
+ // 查询课程所有作业
+ List assignmentsList = assignmentsService.lambdaQuery()
+ .select(AssignmentsDO::getId, AssignmentsDO::getName, AssignmentsDO::getExampleImages)
+ .eq(AssignmentsDO::getCourseId, coursesId)
+ .eq(AssignmentsDO::getType, type.getValue())
+ .list();
+
+ // 如果没有查询到作业直接返回
+ if (CollUtil.isEmpty(assignmentsList)) {
+ return Collections.emptyList();
+ }
+
+ // 提取作业ID列表 后续查询用
+ List assignmentsIdList = assignmentsList.stream().map(AssignmentsDO::getId).toList();
+
+ // 如果是学生 则判断学生是否提交作业,如果提交进度改为100 未提交进度0
+ if (role.equals("pupil")) {
+ // 获取当前登录用户ID
+ Long userId = LoginHelper.getUserId();
+
+ // 查询已提交作业的作业ID与提交记录IDMap
+ Map submissionIdMap = assignmentSubmissionsService.lambdaQuery()
+ .select(AssignmentSubmissionsDO::getAssignmentId, AssignmentSubmissionsDO::getId)
+ .in(AssignmentSubmissionsDO::getAssignmentId, assignmentsIdList)
+ .eq(AssignmentSubmissionsDO::getUserId, userId)
+ .list()
+ .stream()
+ .collect(Collectors.toMap(AssignmentSubmissionsDO::getAssignmentId, AssignmentSubmissionsDO::getId));
+
+ // 计算作业完成度
+ return assignmentsList.stream().map(assignmentsDO -> {
+ AssignmentsResp temp = new AssignmentsResp();
+ temp.setCourseId(coursesId);
+ temp.setId(assignmentsDO.getId());
+ temp.setName(assignmentsDO.getName());
+ temp.setDegreeOfCompletion(submissionIdMap.containsKey(assignmentsDO.getId()) ? "已完成" : "未完成");
+ temp.setAssignmentsSubmissionsId(submissionIdMap.get(assignmentsDO.getId()));
+ temp.setExampleImages(assignmentsDO.getExampleImages());
+ return temp;
+ }).toList();
+ // 如果是老师,则统计作业提交的学生数量计算进度
+ } else if (role.equals("teacher")) {
+ // 查询课程绑定学生数量
+ Long userCount = courseUserService.lambdaQuery().eq(CourseUserDO::getCourseId, coursesId).count();
+
+ // 查询各任务已提交作业数量
+ Map assignmentSubmissionCountMap = assignmentSubmissionsService.listMaps(Wrappers
+ .query()
+ .select("assignment_id", "count(*)")
+ .in("assignment_id", assignmentsList)
+ .groupBy("assignment_id"))
+ .stream()
+ .collect(Collectors.toMap(map -> Long.valueOf(map.get("assignment_id").toString()), map -> Long
+ .valueOf(map.get("count(*)").toString())));
+
+ // 计算完成度
+ return assignmentsList.stream().map(assignmentsDO -> {
+ BigDecimal div = NumberUtil.div(assignmentSubmissionCountMap.get(assignmentsDO.getId()), userCount);
+ AssignmentsResp temp = new AssignmentsResp();
+ temp.setCourseId(coursesId);
+ temp.setId(assignmentsDO.getId());
+ temp.setName(assignmentsDO.getName());
+ temp.setDegreeOfCompletion(NumberUtil.decimalFormat("#.##%", div));
+ temp.setExampleImages(assignmentsDO.getExampleImages());
+ return temp;
+ }).toList();
+ }
+
+ return Collections.emptyList();
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DeptModeServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DeptModeServiceImpl.java
new file mode 100644
index 0000000..f10a313
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DeptModeServiceImpl.java
@@ -0,0 +1,93 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import top.continew.admin.business.mapper.DeptModelMapper;
+import top.continew.admin.business.model.entity.DeptModelDO;
+import top.continew.admin.business.model.query.ModelQuery;
+import top.continew.admin.business.model.req.DeptModelReq;
+import top.continew.admin.business.model.resp.ModelResp;
+import top.continew.admin.business.service.DeptModelService;
+import top.continew.admin.business.service.ModelService;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+import java.util.List;
+
+/**
+ * 部门与模型绑定业务实现
+ *
+ * @author 张波
+ * @since 2024/10/20 14:43
+ */
+@Service
+@RequiredArgsConstructor
+public class DeptModeServiceImpl extends ServiceImpl implements DeptModelService {
+
+ private final ModelService modelService;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void bind(DeptModelReq req) {
+ // 查询数据库中已绑定的数据
+ List dbList = lambdaQuery().eq(DeptModelDO::getDeptId, req.getDeptId()).list();
+
+ // 筛选出数据库中存在 新绑定不存在的 进行删除
+ List removeIds = dbList.stream()
+ .filter(d -> !req.getModelIds().contains(d.getModelId()))
+ .map(DeptModelDO::getId)
+ .toList();
+ if (CollUtil.isNotEmpty(removeIds)) {
+ removeBatchByIds(removeIds);
+ }
+
+ if (CollUtil.isNotEmpty(req.getModelIds())) {
+ // 筛选出新列表存在 数据库中不存在的 进行新增
+ List saveList = req.getModelIds()
+ .stream()
+ .filter(p -> dbList.stream().noneMatch(d -> p.equals(d.getModelId())))
+ .map(i -> {
+ DeptModelDO temp = new DeptModelDO();
+ temp.setDeptId(req.getDeptId());
+ temp.setModelId(i);
+ return temp;
+ })
+ .toList();
+ saveBatch(saveList);
+ }
+ }
+
+ @Override
+ public PageResp getModels(ModelQuery query, PageQuery pageQuery) {
+ // 获取当前登录用户信息
+ //LoginUser loginUser = LoginHelper.getLoginUser();
+ //List deptIds = loginUser.getModelDeptIds();
+
+ // 部门为空不限制 查询所有模型
+ /*if (CollUtil.isNotEmpty(deptIds)) {
+ List modelIds = lambdaQuery().in(DeptModelDO::getDeptId, deptIds)
+ .list()
+ .stream()
+ .map(DeptModelDO::getModelId)
+ .toList();
+
+ // 不是管理员并且没有绑定的模型, 返回空
+ if (!loginUser.isAdmin() && CollUtil.isEmpty(modelIds)) {
+ return PageResp.build(null);
+ }
+
+ query.setIds(modelIds);
+ }*/
+
+ // 根据登录用户所在部门查询可见模型
+ return modelService.page(query, pageQuery);
+ }
+
+ @Override
+ public List getModelByDept(Long deptId) {
+ return lambdaQuery().eq(DeptModelDO::getDeptId, deptId).list().stream().map(DeptModelDO::getModelId).toList();
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DeptPlatformServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DeptPlatformServiceImpl.java
new file mode 100644
index 0000000..8035c86
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DeptPlatformServiceImpl.java
@@ -0,0 +1,85 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import top.continew.admin.business.mapper.DeptPlatformMapper;
+import top.continew.admin.business.model.entity.DeptPlatformDO;
+import top.continew.admin.business.model.req.DeptPlatformReq;
+import top.continew.admin.business.service.DeptPlatformService;
+import top.continew.admin.common.model.dto.LoginUser;
+import top.continew.admin.common.util.helper.LoginHelper;
+import top.continew.starter.extension.crud.model.entity.BaseIdDO;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 部门与平台绑表业务实现
+ *
+ * @author 张波
+ * @since 2024/10/20 14:49
+ */
+@Service
+public class DeptPlatformServiceImpl extends ServiceImpl implements DeptPlatformService {
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void bind(DeptPlatformReq req) {
+ // 查询现有绑定关系
+ List list = lambdaQuery().eq(DeptPlatformDO::getDeptId, req.getDeptId()).list();
+
+ // 筛选出数据库中存在 新绑定不存在的 进行删除
+ List removeIds = list.stream()
+ .filter(d -> !req.getPlatforms().contains(d.getPlatform()))
+ .map(BaseIdDO::getId)
+ .toList();
+ if (CollUtil.isNotEmpty(removeIds)) {
+ removeBatchByIds(removeIds);
+ }
+
+ if (CollUtil.isNotEmpty(req.getPlatforms())) {
+ // 筛选出新列表存在 数据库中不存在的 进行新增
+ List saveList = req.getPlatforms()
+ .stream()
+ .filter(p -> list.stream().noneMatch(d -> p.equals(d.getPlatform())))
+ .map(i -> {
+ DeptPlatformDO temp = new DeptPlatformDO();
+ temp.setDeptId(req.getDeptId());
+ temp.setPlatform(i);
+ return temp;
+ })
+ .toList();
+ saveBatch(saveList);
+ }
+ }
+
+ @Override
+ public List getPlatforms() {
+ // 获取当前登录用户信息
+ LoginUser loginUser = LoginHelper.getLoginUser();
+ Long deptId = loginUser.getDeptId();
+
+ // 如果不存在部门ID,则返回空
+ if (deptId == null) {
+ return Collections.emptyList();
+ }
+
+ // 根据登录用户所在部门查询可见操作平台
+ return lambdaQuery().eq(DeptPlatformDO::getDeptId, deptId)
+ .list()
+ .stream()
+ .map(DeptPlatformDO::getPlatform)
+ .toList();
+ }
+
+ @Override
+ public List getPlatformByDept(Long deptId) {
+ return lambdaQuery().eq(DeptPlatformDO::getDeptId, deptId)
+ .list()
+ .stream()
+ .map(DeptPlatformDO::getPlatform)
+ .toList();
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DigitalHumanServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DigitalHumanServiceImpl.java
new file mode 100644
index 0000000..4f25f08
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/DigitalHumanServiceImpl.java
@@ -0,0 +1,124 @@
+package top.continew.admin.business.service.impl;
+
+import cn.crane4j.core.util.CollectionUtils;
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import jodd.util.CollectionUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.DigitalHumanMapper;
+import top.continew.admin.business.mapper.EffectMapper;
+import top.continew.admin.business.mapper.SubtitleItemMapper;
+import top.continew.admin.business.mapper.SubtitleStyleMapper;
+import top.continew.admin.business.model.entity.*;
+import top.continew.admin.business.model.query.DigitalHumanPageQuery;
+import top.continew.admin.business.model.query.DigitalHumanQuery;
+import top.continew.admin.business.model.req.DigitalHumanReq;
+import top.continew.admin.business.model.resp.DigitalHumanDetailResp;
+import top.continew.admin.business.model.resp.DigitalHumanResp;
+import top.continew.admin.business.service.DigitalHumanService;
+import top.continew.admin.common.util.helper.LoginHelper;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 数字人服务实现类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Service
+@RequiredArgsConstructor
+public class DigitalHumanServiceImpl extends BaseServiceImpl implements DigitalHumanService {
+
+ private final DigitalHumanMapper digitalHumanMapper;
+ private final SubtitleStyleMapper subtitleStyleMapper;
+ private final SubtitleItemMapper subtitleItemMapper;
+ private final EffectMapper effectMapper;
+
+ @Override
+ public List list(DigitalHumanQuery query,
+ top.continew.starter.extension.crud.model.query.SortQuery sortQuery) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ if (query.getUserId() != null) {
+ wrapper.eq(DigitalHuman::getUserId, query.getUserId());
+ }
+ if (query.getCopywriting() != null) {
+ wrapper.like(DigitalHuman::getCopywriting, query.getCopywriting());
+ }
+ if (query.getGeneratedVoiceUrl() != null) {
+ wrapper.eq(DigitalHuman::getGeneratedVoiceUrl, query.getGeneratedVoiceUrl());
+ }
+ if (query.getGeneratedFrameImageUrl() != null) {
+ wrapper.eq(DigitalHuman::getGeneratedFrameImageUrl, query.getGeneratedFrameImageUrl());
+ }
+ if (query.getGeneratedVideoUrl() != null) {
+ wrapper.eq(DigitalHuman::getGeneratedVideoUrl, query.getGeneratedVideoUrl());
+ }
+
+ return digitalHumanMapper.selectList(wrapper).stream().map(this::convertToResp).collect(Collectors.toList());
+ }
+
+ @Override
+ public top.continew.starter.extension.crud.model.resp.PageResp pageList(DigitalHumanQuery query,
+ DigitalHumanPageQuery pageQuery) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ query.setUserId(LoginHelper.getUserId().toString());
+ if (query.getUserId() != null) {
+ wrapper.eq(DigitalHuman::getUserId, query.getUserId());
+ }
+ if (query.getCopywriting() != null) {
+ wrapper.like(DigitalHuman::getCopywriting, query.getCopywriting());
+ }
+ if (query.getGeneratedVoiceUrl() != null) {
+ wrapper.eq(DigitalHuman::getGeneratedVoiceUrl, query.getGeneratedVoiceUrl());
+ }
+ if (query.getGeneratedFrameImageUrl() != null) {
+ wrapper.eq(DigitalHuman::getGeneratedFrameImageUrl, query.getGeneratedFrameImageUrl());
+ }
+ if (query.getGeneratedVideoUrl() != null) {
+ wrapper.eq(DigitalHuman::getGeneratedVideoUrl, query.getGeneratedVideoUrl());
+ }
+
+ wrapper.orderByDesc(DigitalHuman::getCreateTime);
+
+ Page page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
+ Page result = digitalHumanMapper.selectPage(page, wrapper);
+
+ PageResp pageResp = new PageResp();
+ pageResp.setTotal(result.getTotal());
+ pageResp.setList(result.getRecords().stream().map(this::convertToResp).toList());
+ return pageResp;
+ }
+
+ @Override
+ public Long add(DigitalHumanReq req) {
+ DigitalHuman digitalHuman = new DigitalHuman();
+ BeanUtils.copyProperties(req, digitalHuman);
+ digitalHuman.setCreateTime(java.time.LocalDateTime.now());
+ digitalHuman.setUpdateTime(java.time.LocalDateTime.now());
+ digitalHumanMapper.insert(digitalHuman);
+ return digitalHuman.getId();
+ }
+
+ @Override
+ public void delete(List ids) {
+ digitalHumanMapper.deleteBatchIds(ids);
+ }
+
+ private DigitalHumanResp convertToResp(DigitalHuman digitalHuman) {
+ DigitalHumanResp resp = new DigitalHumanResp();
+ BeanUtils.copyProperties(digitalHuman, resp);
+ // 处理关联数据
+ List subtitleStyles = subtitleStyleMapper.selectList(new LambdaQueryWrapper().eq(SubtitleStyle::getDigitalHumanId, digitalHuman.getId()));
+ resp.setSubtitleStyle(CollectionUtils.isNotEmpty(subtitleStyles)? subtitleStyles.get(0) : null);
+ resp.setEffects(effectMapper.selectList(new LambdaQueryWrapper().eq(Effect::getDigitalHumanId, digitalHuman.getId())));
+ resp.setSubtitles(subtitleItemMapper.selectList(new LambdaQueryWrapper().eq(SubtitleItem::getDigitalHumanId, digitalHuman.getId())));
+ return resp;
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/EffectServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/EffectServiceImpl.java
new file mode 100644
index 0000000..f42e45e
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/EffectServiceImpl.java
@@ -0,0 +1,74 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.EffectMapper;
+import top.continew.admin.business.model.entity.DigitalHuman;
+import top.continew.admin.business.model.entity.Effect;
+import top.continew.admin.business.model.query.EffectPageQuery;
+import top.continew.admin.business.model.query.EffectQuery;
+import top.continew.admin.business.model.req.EffectReq;
+import top.continew.admin.business.model.resp.EffectDetailResp;
+import top.continew.admin.business.model.resp.EffectResp;
+import top.continew.admin.business.service.EffectService;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+/**
+ * 数字人-特效服务实现类
+ *
+ * @author 王志维
+ * @since 2025/12/29
+ */
+@Service
+@RequiredArgsConstructor
+public class EffectServiceImpl extends BaseServiceImpl implements EffectService {
+
+ private final EffectMapper effectMapper;
+
+ @Override
+ public PageResp pageList(EffectQuery query, EffectPageQuery pageQuery) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ if (query.getName() != null) {
+ wrapper.like(Effect::getName, query.getName());
+ }
+ if (query.getType() != null) {
+ wrapper.eq(Effect::getType, query.getType());
+ }
+ if (query.getTemplateId() != null) {
+ wrapper.eq(Effect::getTemplateId, query.getTemplateId());
+ }
+ if (query.getDigitalHumanId() != null) {
+ wrapper.eq(Effect::getDigitalHumanId, query.getDigitalHumanId());
+ }
+
+ wrapper.orderByDesc(Effect::getCreateTime);
+
+ Page page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
+ Page result = effectMapper.selectPage(page, wrapper);
+
+ PageResp pageResp = new PageResp();
+ pageResp.setTotal(result.getTotal());
+ pageResp.setList(result.getRecords().stream().map(this::convertToResp).toList());
+ return pageResp;
+ }
+
+ @Override
+ public Long add(EffectReq req) {
+ Effect effect = new Effect();
+ BeanUtils.copyProperties(req, effect);
+ effect.setCreateTime(java.time.LocalDateTime.now());
+ effect.setUpdateTime(java.time.LocalDateTime.now());
+ effectMapper.insert(effect);
+ return effect.getId();
+ }
+
+ private EffectResp convertToResp(Effect effect) {
+ EffectResp resp = new EffectResp();
+ BeanUtils.copyProperties(effect, resp);
+ return resp;
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/EffectTemplateServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/EffectTemplateServiceImpl.java
new file mode 100644
index 0000000..9ff5752
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/EffectTemplateServiceImpl.java
@@ -0,0 +1,97 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import org.dromara.x.file.storage.core.FileInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import top.continew.admin.business.mapper.EffectTemplateMapper;
+import top.continew.admin.business.model.entity.Effect;
+import top.continew.admin.business.model.entity.EffectTemplate;
+import top.continew.admin.business.model.query.EffectTemplatePageQuery;
+import top.continew.admin.business.model.query.EffectTemplateQuery;
+import top.continew.admin.business.model.req.EffectTemplateReq;
+import top.continew.admin.business.model.resp.EffectTemplateDetailResp;
+import top.continew.admin.business.model.resp.EffectTemplateResp;
+import top.continew.admin.business.service.EffectTemplateService;
+import top.continew.admin.common.util.helper.LoginHelper;
+import top.continew.admin.system.service.FileService;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+@Service
+@RequiredArgsConstructor
+public class EffectTemplateServiceImpl extends BaseServiceImpl implements EffectTemplateService {
+
+ private final EffectTemplateMapper effectTemplateMapper;
+ private final FileService fileService;
+
+ @Override
+ public PageResp pageList(EffectTemplateQuery query, EffectTemplatePageQuery pageQuery) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ if (query.getName() != null) {
+ wrapper.like(EffectTemplate::getName, query.getName());
+ }
+ if (query.getType() != null) {
+ wrapper.eq(EffectTemplate::getType, query.getType());
+ }
+ if (query.getIsCustom() != null) {
+ wrapper.eq(EffectTemplate::getIsCustom, query.getIsCustom());
+ }
+ query.setUserId(LoginHelper.getUserId().toString());
+ if (query.getUserId() != null) {
+ wrapper.eq(EffectTemplate::getUserId, query.getUserId());
+ }
+
+ wrapper.orderByDesc(EffectTemplate::getCreateTime);
+
+ Page page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
+ Page result = effectTemplateMapper.selectPage(page, wrapper);
+
+ PageResp pageResp = new PageResp();
+ pageResp.setTotal(result.getTotal());
+ pageResp.setList(result.getRecords().stream().map(this::convertToResp).toList());
+ return pageResp;
+ }
+
+ @Override
+ public Long add(EffectTemplateReq req) {
+ EffectTemplate effectTemplate = new EffectTemplate();
+ BeanUtils.copyProperties(req, effectTemplate);
+ effectTemplate.setCreateTime(java.time.LocalDateTime.now());
+ effectTemplate.setUpdateTime(java.time.LocalDateTime.now());
+ effectTemplateMapper.insert(effectTemplate);
+ return effectTemplate.getId();
+ }
+
+ @Override
+ public Long uploadTemplate(MultipartFile file, String name, String type, String userId) {
+ if (file == null || file.isEmpty()) {
+ throw new IllegalArgumentException("上传文件不能为空");
+ }
+
+ // 保存文件
+ FileInfo uploadResult = fileService.upload(file);
+
+ // 创建特效模板记录
+ EffectTemplate effectTemplate = new EffectTemplate();
+ effectTemplate.setName(name);
+ effectTemplate.setType(type);
+ effectTemplate.setUserId(userId);
+ effectTemplate.setIsCustom("true"); // 标记为自定义模板
+ effectTemplate.setSourceUrl(uploadResult.getUrl());
+ effectTemplate.setCreateTime(java.time.LocalDateTime.now());
+ effectTemplate.setUpdateTime(java.time.LocalDateTime.now());
+
+ effectTemplateMapper.insert(effectTemplate);
+ return effectTemplate.getId();
+ }
+
+ private EffectTemplateResp convertToResp(EffectTemplate effectTemplate) {
+ EffectTemplateResp resp = new EffectTemplateResp();
+ BeanUtils.copyProperties(effectTemplate, resp);
+ return resp;
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/FreeQuotaConfigServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/FreeQuotaConfigServiceImpl.java
new file mode 100644
index 0000000..6e95fe4
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/FreeQuotaConfigServiceImpl.java
@@ -0,0 +1,89 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.FreeQuotaConfigMapper;
+import top.continew.admin.business.model.entity.FreeQuotaConfigDO;
+import top.continew.admin.business.model.query.FreeQuotaConfigQuery;
+import top.continew.admin.business.model.req.FreeQuotaConfigReq;
+import top.continew.admin.business.model.resp.FreeQuotaConfigResp;
+import top.continew.admin.business.service.FreeQuotaConfigService;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+import java.util.List;
+
+/**
+ * 免费额度配置业务实现
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Service
+@RequiredArgsConstructor
+public class FreeQuotaConfigServiceImpl extends BaseServiceImpl implements FreeQuotaConfigService {
+
+ /**
+ * 获取所有启用的配置
+ */
+ @Override
+ @Cacheable(value = "freeQuotaConfig", key = "'enabled'", unless = "#result == null || #result.isEmpty()")
+ public List listEnabled() {
+ return baseMapper.selectList(new LambdaQueryWrapper()
+ .eq(FreeQuotaConfigDO::getIsEnabled, true)
+ .orderByAsc(FreeQuotaConfigDO::getSort));
+ }
+
+ /**
+ * 根据类别编码获取配置
+ */
+ @Override
+ @Cacheable(value = "freeQuotaConfig", key = "'code_' + #categoryCode", unless = "#result == null")
+ public FreeQuotaConfigDO getByCategoryCode(String categoryCode) {
+ return baseMapper.selectOne(new LambdaQueryWrapper()
+ .eq(FreeQuotaConfigDO::getCategoryCode, categoryCode)
+ .eq(FreeQuotaConfigDO::getIsEnabled, true)
+ .last("LIMIT 1"));
+ }
+
+ /**
+ * 根据计费类型获取配置
+ */
+ @Override
+ @Cacheable(value = "freeQuotaConfig", key = "'chargeType_' + #chargeType", unless = "#result == null")
+ public FreeQuotaConfigDO getByChargeType(Integer chargeType) {
+ return baseMapper.selectOne(new LambdaQueryWrapper()
+ .eq(FreeQuotaConfigDO::getChargeType, chargeType)
+ .eq(FreeQuotaConfigDO::getIsEnabled, true)
+ .last("LIMIT 1"));
+ }
+
+ /**
+ * 新增后清除缓存
+ */
+ @Override
+ @CacheEvict(value = "freeQuotaConfig", allEntries = true)
+ public Long add(FreeQuotaConfigReq req) {
+ return super.add(req);
+ }
+
+ /**
+ * 更新后清除缓存
+ */
+ @Override
+ @CacheEvict(value = "freeQuotaConfig", allEntries = true)
+ public void update(FreeQuotaConfigReq req, Long id) {
+ super.update(req, id);
+ }
+
+ /**
+ * 删除后清除缓存
+ */
+ @Override
+ @CacheEvict(value = "freeQuotaConfig", allEntries = true)
+ public void delete(List ids) {
+ super.delete(ids);
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/FreeQuotaGrantServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/FreeQuotaGrantServiceImpl.java
new file mode 100644
index 0000000..8eed730
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/FreeQuotaGrantServiceImpl.java
@@ -0,0 +1,209 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import top.continew.admin.business.mapper.PlantformBalanceMapper;
+import top.continew.admin.business.model.entity.FreeQuotaConfigDO;
+import top.continew.admin.business.model.entity.PlantformBalanceDO;
+import top.continew.admin.business.model.req.FreeQuotaGrantReq;
+import top.continew.admin.business.model.resp.FreeQuotaGrantResp;
+import top.continew.admin.business.service.FreeQuotaConfigService;
+import top.continew.admin.business.service.FreeQuotaGrantService;
+import top.continew.admin.system.mapper.UserMapper;
+import top.continew.admin.system.model.entity.UserDO;
+import top.continew.starter.core.exception.BusinessException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 免费额度赠送服务实现
+ *
+ * @author jiay
+ * @since 2025/11/17
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class FreeQuotaGrantServiceImpl implements FreeQuotaGrantService {
+
+ private final FreeQuotaConfigService freeQuotaConfigService;
+ private final PlantformBalanceMapper plantformBalanceMapper;
+ private final UserMapper userMapper;
+
+ /**
+ * 批量赠送免费额度
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public FreeQuotaGrantResp batchGrant(FreeQuotaGrantReq req) {
+ List logs = new ArrayList<>();
+ List allUserIds = new ArrayList<>();
+
+ // 1. 收集所有用户ID
+ if (CollUtil.isNotEmpty(req.getUserIds())) {
+ allUserIds.addAll(req.getUserIds());
+ logs.add("指定用户数: " + req.getUserIds().size());
+ }
+
+ if (CollUtil.isNotEmpty(req.getDeptIds())) {
+ for (Long deptId : req.getDeptIds()) {
+ List deptUsers = userMapper.selectList(new LambdaQueryWrapper()
+ .eq(UserDO::getDeptId, deptId));
+ List deptUserIds = deptUsers.stream().map(UserDO::getId).collect(Collectors.toList());
+ allUserIds.addAll(deptUserIds);
+ logs.add(StrUtil.format("部门ID {} 用户数: {}", deptId, deptUserIds.size()));
+ }
+ }
+
+ if (CollUtil.isEmpty(allUserIds)) {
+ throw new BusinessException("未找到需要赠送的用户");
+ }
+
+ // 去重
+ allUserIds = allUserIds.stream().distinct().collect(Collectors.toList());
+ logs.add("总用户数(去重后): " + allUserIds.size());
+
+ // 2. 准备赠送配置
+ List quotaItems;
+ if (CollUtil.isNotEmpty(req.getQuotaItems())) {
+ // 使用自定义配置
+ quotaItems = req.getQuotaItems()
+ .stream()
+ .filter(item -> item.getEnabled() != null && item.getEnabled())
+ .collect(Collectors.toList());
+ logs.add("使用自定义配置,项数: " + quotaItems.size());
+ } else {
+ // 使用默认配置
+ List configs = freeQuotaConfigService.listEnabled();
+ quotaItems = configs.stream().map(config -> {
+ FreeQuotaGrantReq.QuotaItem item = new FreeQuotaGrantReq.QuotaItem();
+ item.setConfigId(config.getId());
+ item.setCategoryCode(config.getCategoryCode());
+ item.setCategoryName(config.getCategoryName());
+ item.setGrantQuota(config.getQuota());
+ item.setChargeType(config.getChargeType());
+ item.setType(config.getType());
+ item.setEnabled(true);
+ return item;
+ }).collect(Collectors.toList());
+ logs.add("使用默认配置,项数: " + quotaItems.size());
+ }
+
+ if (CollUtil.isEmpty(quotaItems)) {
+ throw new BusinessException("未找到可赠送的额度配置");
+ }
+
+ // 3. 执行批量赠送
+ int totalUsers = allUserIds.size();
+ int successUsers = 0;
+ int failedUsers = 0;
+ int totalItems = 0;
+ int successItems = 0;
+ int failedItems = 0;
+
+ for (Long userId : allUserIds) {
+ boolean userSuccess = true;
+ logs.add(StrUtil.format("\n--- 用户 ID: {} ---", userId));
+
+ for (FreeQuotaGrantReq.QuotaItem item : quotaItems) {
+ totalItems++;
+ try {
+ // 执行赠送
+ boolean success = grantQuotaToUser(userId, item);
+ if (success) {
+ successItems++;
+ logs.add(StrUtil.format("✓ {} : {} {}", item.getCategoryName(), item.getGrantQuota(), "[成功]"));
+ } else {
+ failedItems++;
+ userSuccess = false;
+ logs.add(StrUtil.format("✗ {} [失败]", item.getCategoryName()));
+ }
+ } catch (Exception e) {
+ failedItems++;
+ userSuccess = false;
+ log.error("赠送额度失败: userId={}, item={}", userId, item.getCategoryName(), e);
+ logs.add(StrUtil.format("✗ {} [异常: {}]", item.getCategoryName(), e.getMessage()));
+ }
+ }
+
+ if (userSuccess) {
+ successUsers++;
+ } else {
+ failedUsers++;
+ }
+ }
+
+ logs.add("\n========== 赠送完成 ==========");
+ logs.add(StrUtil.format("用户: 成功 {} 个, 失败 {} 个", successUsers, failedUsers));
+ logs.add(StrUtil.format("项目: 成功 {} 项, 失败 {} 项", successItems, failedItems));
+
+ return FreeQuotaGrantResp.builder()
+ .success(failedItems == 0)
+ .totalUsers(totalUsers)
+ .successUsers(successUsers)
+ .failedUsers(failedUsers)
+ .totalItems(totalItems)
+ .successItems(successItems)
+ .failedItems(failedItems)
+ .message(StrUtil.format("批量赠送完成! 用户: {}/{}, 项目: {}/{}", successUsers, totalUsers, successItems, totalItems))
+ .logs(logs)
+ .build();
+ }
+
+ /**
+ * 给单个用户赠送默认免费额度
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public FreeQuotaGrantResp grantToUser(Long userId) {
+ FreeQuotaGrantReq req = new FreeQuotaGrantReq();
+ req.setUserIds(CollUtil.newArrayList(userId));
+ return batchGrant(req);
+ }
+
+ /**
+ * 给部门下所有用户赠送默认免费额度
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public FreeQuotaGrantResp grantToDept(Long deptId) {
+ FreeQuotaGrantReq req = new FreeQuotaGrantReq();
+ req.setDeptIds(CollUtil.newArrayList(deptId));
+ return batchGrant(req);
+ }
+
+ /**
+ * 给用户赠送单项额度
+ */
+ private boolean grantQuotaToUser(Long userId, FreeQuotaGrantReq.QuotaItem item) {
+ // 查询是否已存在
+ PlantformBalanceDO existingBalance = plantformBalanceMapper
+ .selectOne(new LambdaQueryWrapper().eq(PlantformBalanceDO::getUserId, userId)
+ .eq(PlantformBalanceDO::getType, item.getType())
+ .eq(item.getChargeType() != null, PlantformBalanceDO::getChargeType, item.getChargeType()));
+
+ Long grantAmount = item.getGrantQuota().longValue();
+
+ if (existingBalance != null) {
+ // 更新余额(增加)
+ existingBalance.setBalance(existingBalance.getBalance() + grantAmount);
+ return plantformBalanceMapper.updateById(existingBalance) > 0;
+ } else {
+ // 插入新记录
+ PlantformBalanceDO newBalance = new PlantformBalanceDO();
+ newBalance.setUserId(userId);
+ newBalance.setType(item.getType());
+ newBalance.setBalance(grantAmount);
+ newBalance.setChargeType(item.getChargeType());
+ newBalance.setPreDeductBalance(0L);
+ return plantformBalanceMapper.insert(newBalance) > 0;
+ }
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/HomeworkServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/HomeworkServiceImpl.java
new file mode 100644
index 0000000..7de798a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/HomeworkServiceImpl.java
@@ -0,0 +1,87 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.HomeworkMapper;
+import top.continew.admin.business.model.entity.HomeworkDO;
+import top.continew.admin.business.model.query.HomeworkQuery;
+import top.continew.admin.business.model.req.HomeworkAddReq;
+import top.continew.admin.business.model.req.HomeworkEditReq;
+import top.continew.admin.business.model.resp.HomeworkResp;
+import top.continew.admin.business.service.HomeworkService;
+import top.continew.starter.data.mp.util.QueryWrapperHelper;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * business业务实现
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Service
+@RequiredArgsConstructor
+public class HomeworkServiceImpl extends ServiceImpl implements HomeworkService {
+
+ private final HomeworkMapper homeworkMapper;
+
+ @Override
+ public List getHomeworkList(HomeworkQuery query) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ List list = this.list(queryWrapper);
+
+ if (CollectionUtil.isNotEmpty(list)) {
+ return BeanUtil.copyToList(list, HomeworkResp.class);
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean addHomework(HomeworkAddReq req) {
+ //插入记录到数据库
+ HomeworkDO entity = BeanUtil.copyProperties(req, HomeworkDO.class);
+ return homeworkMapper.insert(entity) > 0;
+
+ }
+
+ @Override
+ public boolean editHomework(HomeworkEditReq req) {
+ HomeworkDO HomeworkDO = BeanUtil.copyProperties(req, HomeworkDO.class);
+ return homeworkMapper.updateById(HomeworkDO) > 0;
+
+ }
+
+ @Override
+ public boolean deleteHomework(Long id) {
+ if (id != null) {
+ return homeworkMapper.deleteById(id) > 0;
+ }
+ return false;
+ }
+
+ @Override
+ public HomeworkResp getHomework(Long id) {
+ HomeworkDO HomeworkDO = homeworkMapper.selectById(id);
+ HomeworkResp HomeworkResp = new HomeworkResp();
+ if (HomeworkDO != null) {
+ HomeworkResp = BeanUtil.copyProperties(HomeworkDO, HomeworkResp.class);
+ }
+ return HomeworkResp;
+ }
+
+ @Override
+ public PageResp getHomeworkPage(HomeworkQuery query, PageQuery pageQuery) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ Page page = homeworkMapper.selectPage(new Page<>(pageQuery.getPage(), pageQuery.getSize()), queryWrapper);
+ return PageResp.build(page);
+ }
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/HuandaResourceServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/HuandaResourceServiceImpl.java
new file mode 100644
index 0000000..5d5f846
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/HuandaResourceServiceImpl.java
@@ -0,0 +1,53 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.micrometer.common.util.StringUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.HuandaResourceMapper;
+import top.continew.admin.business.model.entity.HuandaResourceDO;
+import top.continew.admin.business.model.query.HuandaResourcePageQuery;
+import top.continew.admin.business.model.query.HuandaResourceQuery;
+import top.continew.admin.business.model.req.HuandaResourceReq;
+import top.continew.admin.business.model.resp.HuandaResourceDetailResp;
+import top.continew.admin.business.model.resp.HuandaResourceResp;
+import top.continew.admin.business.service.HuandaResourceService;
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+/**
+ * 换哒-文件资源服务实现
+ *
+ * @author 王志维
+ * @since 2025/12/23 16:53
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class HuandaResourceServiceImpl extends BaseServiceImpl implements HuandaResourceService {
+ @Override
+ public PageResp pageList(HuandaResourceQuery query, HuandaResourcePageQuery pageQuery) {
+ QueryWrapper queryWrapper = this.buildQueryWrapper(query);
+ //如果age,gender,region不为空,则添加相应的查询条件到queryWrapper
+ if (StringUtils.isNotBlank(pageQuery.getAge())) {
+ queryWrapper.eq("age", pageQuery.getAge());
+ }
+ if (StringUtils.isNotBlank(pageQuery.getGender())) {
+ queryWrapper.eq("gender", pageQuery.getGender());
+ }
+ if (StringUtils.isNotBlank(pageQuery.getRegion())) {
+ queryWrapper.eq("region", pageQuery.getRegion());
+ }
+ this.sort(queryWrapper, pageQuery);
+ IPage page = ((BaseMapper)this.baseMapper).selectPage(new Page((long)pageQuery
+ .getPage(), (long)pageQuery.getSize()), queryWrapper);
+ PageResp pageResp = PageResp.build(page, this.getListClass());
+ pageResp.getList().forEach(this::fill);
+ return pageResp;
+ }
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ModelCategoryServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ModelCategoryServiceImpl.java
new file mode 100644
index 0000000..81ede9a
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ModelCategoryServiceImpl.java
@@ -0,0 +1,17 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.ModelCategoryMapper;
+import top.continew.admin.business.model.entity.ModelCategoryDO;
+import top.continew.admin.business.service.ModelCategoryService;
+
+/**
+ * 模型分类业务实现
+ *
+ * @author 张波
+ * @since 2024/10/20 19:51
+ */
+@Service
+public class ModelCategoryServiceImpl extends ServiceImpl implements ModelCategoryService {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ModelServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ModelServiceImpl.java
new file mode 100644
index 0000000..120e391
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ModelServiceImpl.java
@@ -0,0 +1,20 @@
+package top.continew.admin.business.service.impl;
+
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.ModelMapper;
+import top.continew.admin.business.model.entity.ModelDO;
+import top.continew.admin.business.model.query.ModelQuery;
+import top.continew.admin.business.model.req.ModelReq;
+import top.continew.admin.business.model.resp.ModelResp;
+import top.continew.admin.business.service.ModelService;
+import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
+
+/**
+ * 模型业务实现
+ *
+ * @author 张波
+ * @since 2024/10/19 15:32
+ */
+@Service
+public class ModelServiceImpl extends BaseServiceImpl implements ModelService {
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/OrderAudioServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/OrderAudioServiceImpl.java
new file mode 100644
index 0000000..6d19d22
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/OrderAudioServiceImpl.java
@@ -0,0 +1,74 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import jakarta.annotation.Resource;
+import lombok.RequiredArgsConstructor;
+import net.dreamlu.mica.core.utils.BeanUtil;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import top.continew.admin.business.mapper.OrderAudioMapper;
+import top.continew.admin.business.mapper.OrderHistoryMapper;
+import top.continew.admin.business.mapper.OrderThreeMapper;
+import top.continew.admin.business.mapper.OrderVideoMapper;
+import top.continew.admin.business.model.entity.OrderAudioDo;
+import top.continew.admin.business.model.entity.OrderHistoryDo;
+import top.continew.admin.business.model.entity.OrderThreeDo;
+import top.continew.admin.business.model.entity.OrderVideoDo;
+import top.continew.admin.business.model.req.OrderAudioReq;
+import top.continew.admin.business.service.OrderAudioService;
+import top.continew.admin.system.mapper.UserMapper;
+import top.continew.admin.system.model.entity.UserDO;
+
+/**
+ * 音频业务实现
+ *
+ * @author hzy
+ * @since 2025/10/22 11:58
+ */
+@Service
+@RequiredArgsConstructor
+public class OrderAudioServiceImpl extends ServiceImpl implements OrderAudioService {
+ @Resource
+ private OrderVideoMapper orderVideoMapper;
+ @Resource
+ private OrderThreeMapper orderThreeMapper;
+ @Resource
+ private OrderHistoryMapper orderHistoryMapper;
+ @Resource
+ private UserMapper userMapper;
+
+ /**
+ * 保存音频任务订单信息
+ *
+ * @param req 参数
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void add(OrderAudioReq req) {
+ OrderAudioDo saveDb = new OrderAudioDo();
+ BeanUtil.copyProperties(req, saveDb);
+ save(saveDb);
+ //保存视频订单任务
+ if (req.getOrderType() != null && req.getOrderType() == 2) {
+ OrderVideoDo orderVideoDo = new OrderVideoDo();
+ BeanUtil.copyProperties(req, orderVideoDo);
+ orderVideoMapper.insert(orderVideoDo);
+ }
+ //保存3D订单任务
+ if (req.getOrderType() != null && req.getOrderType() == 3) {
+ OrderThreeDo orderThreeDo = new OrderThreeDo();
+ BeanUtil.copyProperties(req, orderThreeDo);
+ orderThreeMapper.insert(orderThreeDo);
+ }
+ //保存3D订单任务
+ OrderHistoryDo orderHistoryDo = new OrderHistoryDo();
+ BeanUtil.copyProperties(req, orderHistoryDo);
+ orderHistoryDo.setFormType("支出");
+ //剩余点数
+ UserDO userDO = userMapper.selectById(saveDb.getCreateUser());
+ int payBeans = userDO.getSysBeans();
+
+ orderHistoryDo.setRemainder(payBeans - userDO.getInviteBeans());
+ orderHistoryMapper.insert(orderHistoryDo);
+ }
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/OrderHistoryServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/OrderHistoryServiceImpl.java
new file mode 100644
index 0000000..eaa4675
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/OrderHistoryServiceImpl.java
@@ -0,0 +1,32 @@
+package top.continew.admin.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import jakarta.annotation.Resource;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.OrderHistoryMapper;
+import top.continew.admin.business.mapper.OrderThreeMapper;
+import top.continew.admin.business.mapper.OrderVideoMapper;
+import top.continew.admin.business.model.entity.OrderHistoryDo;
+import top.continew.admin.business.service.OrderHistoryService;
+import top.continew.admin.system.mapper.UserMapper;
+
+/**
+ * 订单任务历史业务接口实现
+ *
+ * @author hzy
+ * @since 2025/10/22 11:58
+ */
+@Service
+@RequiredArgsConstructor
+public class OrderHistoryServiceImpl extends ServiceImpl implements OrderHistoryService {
+ @Resource
+ private OrderVideoMapper orderVideoMapper;
+ @Resource
+ private OrderThreeMapper orderThreeMapper;
+ @Resource
+ private OrderHistoryMapper orderHistoryMapper;
+ @Resource
+ private UserMapper userMapper;
+
+}
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/PlantformBalanceServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/PlantformBalanceServiceImpl.java
new file mode 100644
index 0000000..765df48
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/PlantformBalanceServiceImpl.java
@@ -0,0 +1,138 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.PlantformBalanceMapper;
+import top.continew.admin.business.model.entity.PlantformBalanceDO;
+import top.continew.admin.business.model.query.PlantformBalanceQuery;
+import top.continew.admin.business.model.req.CheckPlantBalanceReq;
+import top.continew.admin.business.model.req.PlantformBalanceAddReq;
+import top.continew.admin.business.model.req.PlantformBalanceEditReq;
+import top.continew.admin.business.model.resp.PlantformBalanceResp;
+import top.continew.admin.business.service.PlantformBalanceService;
+import top.continew.starter.data.mp.util.QueryWrapperHelper;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.web.model.R;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * business业务实现
+ *
+ * @author jiay
+ * @since 2025/06/24 16:47
+ */
+@Service
+@RequiredArgsConstructor
+public class PlantformBalanceServiceImpl extends ServiceImpl implements PlantformBalanceService {
+
+ private final PlantformBalanceMapper plantformBalanceMapper;
+
+ @Override
+ public List getPlantformBalanceList(PlantformBalanceQuery query) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ List list = this.list(queryWrapper);
+
+ if (CollectionUtil.isNotEmpty(list)) {
+ return BeanUtil.copyToList(list, PlantformBalanceResp.class);
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean addPlantformBalance(PlantformBalanceAddReq req) {
+ //插入记录到数据库
+ PlantformBalanceDO entity = BeanUtil.copyProperties(req, PlantformBalanceDO.class);
+ return plantformBalanceMapper.insert(entity) > 0;
+
+ }
+
+ @Override
+ public boolean editPlantformBalance(PlantformBalanceEditReq req) {
+ PlantformBalanceDO PlantformBalanceDO = BeanUtil.copyProperties(req, PlantformBalanceDO.class);
+ return plantformBalanceMapper.updateById(PlantformBalanceDO) > 0;
+
+ }
+
+ @Override
+ public boolean deletePlantformBalance(Long id) {
+ if (id != null) {
+ return plantformBalanceMapper.deleteById(id) > 0;
+ }
+ return false;
+ }
+
+ @Override
+ public PlantformBalanceResp getPlantformBalance(Long id) {
+ PlantformBalanceDO PlantformBalanceDO = plantformBalanceMapper.selectById(id);
+ PlantformBalanceResp PlantformBalanceResp = new PlantformBalanceResp();
+ if (PlantformBalanceDO != null) {
+ PlantformBalanceResp = BeanUtil.copyProperties(PlantformBalanceDO, PlantformBalanceResp.class);
+ }
+ return PlantformBalanceResp;
+ }
+
+ @Override
+ public PageResp getPlantformBalancePage(PlantformBalanceQuery query, PageQuery pageQuery) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ this.sort(queryWrapper, pageQuery.getSort());
+ Page page = plantformBalanceMapper.selectPage(new Page<>(pageQuery.getPage(), pageQuery
+ .getSize()), queryWrapper);
+ return PageResp.build(page);
+ }
+
+ /**
+ * 设置排序
+ *
+ * @param queryWrapper 查询条件封装对象
+ * @param sort 排序查询条件
+ */
+ private void sort(QueryWrapper queryWrapper, Sort sort) {
+ if (sort == null || sort.isUnsorted()) {
+ return;
+ }
+ for (Sort.Order order : sort) {
+ String property = order.getProperty();
+ queryWrapper.orderBy(true, order.isAscending(), CharSequenceUtil.toUnderlineCase(property));
+ }
+ }
+
+ @Override
+ public List getUserBalancesByUserId(Long userId) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(PlantformBalanceDO::getUserId, userId);
+ List list = this.list(queryWrapper);
+
+ if (CollectionUtil.isNotEmpty(list)) {
+ return BeanUtil.copyToList(list, PlantformBalanceResp.class);
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public R checkPlantBalance(CheckPlantBalanceReq req) {
+ QueryWrapper queryWrapper = new QueryWrapper();
+ queryWrapper.eq("user_id", req.getUserId());
+ queryWrapper.eq("charge_type", req.getChargeType());
+ PlantformBalanceDO one = plantformBalanceMapper.selectOne(queryWrapper);
+ if (one == null) {
+ PlantformBalanceAddReq addReq = new PlantformBalanceAddReq().initPlantformBalance(req);
+ this.addPlantformBalance(addReq);
+ }
+ if (one.getBalance() < req.getChargePoints()) {
+ return R.fail(R.fail().getCode(), "余额不足,请充值!");
+ }
+ return R.ok();
+ }
+
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ScoreServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ScoreServiceImpl.java
new file mode 100644
index 0000000..97c9193
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/ScoreServiceImpl.java
@@ -0,0 +1,85 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.ScoreMapper;
+import top.continew.admin.business.model.entity.ScoreDO;
+import top.continew.admin.business.model.query.ScoreQuery;
+import top.continew.admin.business.model.req.ScoreAddReq;
+import top.continew.admin.business.model.req.ScoreEditReq;
+import top.continew.admin.business.model.resp.ScoreResp;
+import top.continew.admin.business.service.ScoreService;
+import top.continew.starter.data.mp.util.QueryWrapperHelper;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * business业务实现
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Service
+@RequiredArgsConstructor
+public class ScoreServiceImpl extends ServiceImpl implements ScoreService {
+
+ private final ScoreMapper scoreMapper;
+
+ @Override
+ public List getScoreList(ScoreQuery query) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ List list = this.list(queryWrapper);
+
+ if (CollectionUtil.isNotEmpty(list)) {
+ return BeanUtil.copyToList(list, ScoreResp.class);
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean addScore(ScoreAddReq req) {
+ //插入记录到数据库
+ ScoreDO entity = BeanUtil.copyProperties(req, ScoreDO.class);
+ return scoreMapper.insert(entity) > 0;
+
+ }
+
+ @Override
+ public boolean editScore(ScoreEditReq req) {
+ ScoreDO ScoreDO = BeanUtil.copyProperties(req, ScoreDO.class);
+ return scoreMapper.updateById(ScoreDO) > 0;
+
+ }
+
+ @Override
+ public boolean deleteScore(Long id) {
+ if (id != null) {
+ return scoreMapper.deleteById(id) > 0;
+ }
+ return false;
+ }
+
+ @Override
+ public ScoreResp getScore(Long id) {
+ ScoreDO ScoreDO = scoreMapper.selectById(id);
+ ScoreResp ScoreResp = new ScoreResp();
+ if (ScoreDO != null) {
+ ScoreResp = BeanUtil.copyProperties(ScoreDO, ScoreResp.class);
+ }
+ return ScoreResp;
+ }
+
+ @Override
+ public PageResp getScorePage(ScoreQuery query, PageQuery pageQuery) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ Page page = scoreMapper.selectPage(new Page<>(pageQuery.getPage(), pageQuery.getSize()), queryWrapper);
+ return PageResp.build(page);
+ }
+}
\ No newline at end of file
diff --git a/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/SignInServiceImpl.java b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/SignInServiceImpl.java
new file mode 100644
index 0000000..18e23d0
--- /dev/null
+++ b/continew-admin-business/src/main/java/top/continew/admin/business/service/impl/SignInServiceImpl.java
@@ -0,0 +1,186 @@
+package top.continew.admin.business.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.SignInMapper;
+import top.continew.admin.business.model.entity.SignInDO;
+import top.continew.admin.business.model.query.SignInQuery;
+import top.continew.admin.business.model.req.SignInAddReq;
+import top.continew.admin.business.model.req.SignInEditReq;
+import top.continew.admin.business.model.resp.SignInExportResp;
+import top.continew.admin.business.model.resp.SignInResp;
+import top.continew.admin.business.model.resp.TodayNosignInExportResp;
+import top.continew.admin.business.service.SignInService;
+import top.continew.starter.data.mp.service.impl.ServiceImpl;
+import top.continew.starter.data.mp.util.QueryWrapperHelper;
+import top.continew.starter.extension.crud.model.query.PageQuery;
+import top.continew.starter.extension.crud.model.query.SortQuery;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.file.excel.util.ExcelUtils;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * business业务实现
+ *
+ * @author jiay
+ * @since 2025/06/26 10:24
+ */
+@Service
+@RequiredArgsConstructor
+public class SignInServiceImpl extends ServiceImpl implements SignInService {
+
+ private final SignInMapper signInMapper;
+
+ @Override
+ public List getSignInList(SignInQuery query) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ List list = this.list(queryWrapper);
+
+ if (CollectionUtil.isNotEmpty(list)) {
+ return BeanUtil.copyToList(list, SignInResp.class);
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean addSignIn(SignInAddReq req) {
+ //插入记录到数据库
+ SignInDO entity = BeanUtil.copyProperties(req, SignInDO.class);
+ return signInMapper.insert(entity) > 0;
+
+ }
+
+ @Override
+ public boolean editSignIn(SignInEditReq req) {
+ SignInDO signInDO = BeanUtil.copyProperties(req, SignInDO.class);
+ return signInMapper.updateById(signInDO) > 0;
+
+ }
+
+ @Override
+ public boolean deleteSignIn(Long id) {
+ if (id != null) {
+ return signInMapper.deleteById(id) > 0;
+ }
+ return false;
+ }
+
+ @Override
+ public SignInResp getSignIn(Long id) {
+ SignInDO signInDO = signInMapper.selectById(id);
+ SignInResp signInResp = new SignInResp();
+ if (signInDO != null) {
+ signInResp = BeanUtil.copyProperties(signInDO, SignInResp.class);
+ }
+ return signInResp;
+ }
+
+ @Override
+ public PageResp getSignInPage(SignInQuery query, PageQuery pageQuery) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ Page page = signInMapper.selectPage(new Page<>(pageQuery.getPage(), pageQuery.getSize()), queryWrapper);
+ return PageResp.build(page);
+ }
+
+ @Override
+ public List getTodayNosignInList(SignInQuery query) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ List list = this.list(queryWrapper);
+
+ if (CollectionUtil.isNotEmpty(list)) {
+ List signInResps = BeanUtil.copyToList(list, SignInResp.class);
+ signInResps.stream().forEach(e -> {
+ //todo
+ Random random = new Random(100);
+ e.setPresent(random.nextInt(10));
+ e.setAbnormal(random.nextInt(10));
+ e.setAbsent(random.nextInt(10));
+ e.setLeaveCount(random.nextInt(10));
+ e.setLeaveCause("生病假!");
+ });
+ return signInResps;
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public PageResp getHisSignInList(SignInQuery query, PageQuery pageQuery) {
+ QueryWrapper queryWrapper = QueryWrapperHelper.build(query);
+ Page page = signInMapper.selectPage(new Page<>(pageQuery.getPage(), pageQuery.getSize()), queryWrapper);
+ if (CollectionUtil.isNotEmpty(page.getRecords())) {
+ List signInResps = BeanUtil.copyToList(page.getRecords(), SignInResp.class);
+ signInResps.forEach(e -> {
+ //todo
+ Random random = new Random(100);
+ e.setPresent(random.nextInt(10));
+ e.setAbnormal(random.nextInt(10));
+ e.setAbsent(random.nextInt(10));
+ e.setLeaveCount(random.nextInt(10));
+ e.setLeaveCause("生病假");
+ });
+ page.setRecords(signInResps);
+ }
+ return PageResp.build(page);
+ }
+
+ @Override
+ public void exportHisSignInList(SignInQuery query, SortQuery sortQuery, HttpServletResponse response) {
+ List list = getTodayNosignInList(query);
+ List res = BeanUtil.copyToList(list, SignInExportResp.class);
+ res.forEach(e -> {
+
+ });
+ ExcelUtils.export(res, "导出历史签到列表", SignInExportResp.class, response);
+ }
+
+ @Override
+ public void exportTodayNosignInList(SignInQuery query, SortQuery sortQuery, HttpServletResponse response) {
+ PageResp list = getHisSignInList(query, null);
+ List res = BeanUtil.copyToList(list.getList(), TodayNosignInExportResp.class);
+ res.forEach(e -> {
+
+ });
+ ExcelUtils.export(res, "导出今日未签到列表", TodayNosignInExportResp.class, response);
+ }
+
+ /**
+ * 设置排序
+ *
+ * @param queryWrapper 查询条件封装对象
+ * @param sortQuery 排序查询条件
+ */
+ private void sort(QueryWrapper queryWrapper, SortQuery sortQuery) {
+ if (sortQuery == null || sortQuery.getSort().isUnsorted()) {
+ return;
+ }
+ for (Sort.Order order : sortQuery.getSort()) {
+ String property = order.getProperty();
+ queryWrapper.orderBy(true, order.isAscending(), CharSequenceUtil.toUnderlineCase(property));
+ }
+ }
+
+ /**
+ * 构建 QueryWrapper
+ *
+ * @param query 查询条件
+ * @return QueryWrapper
+ */
+ private QueryWrapper buildQueryWrapper(SignInQuery query) {
+ String courseName = query.getCourseName();
+ String userName = query.getUserName();
+ return new QueryWrapper