init: 导入团队知识库内容

This commit is contained in:
yueqian-ai
2026-05-14 16:56:48 +08:00
commit acca2041f0
1681 changed files with 285734 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright © 2026 Qiantong Technology Co., Ltd.
qModel Model Platform(Open Source Edition)
*
License:
Released under the Apache License, Version 2.0.
You may use, modify, and distribute this software for commercial purposes
under the terms of the License.
*
Special Notice:
All derivative versions are strictly prohibited from modifying or removing
the default system logo and copyright information.
For brand customization, please apply for brand customization authorization via official channels.
*
More information: https://qmodel.qiantong.tech/business.html
*
============================================================================
*
版权所有 © 2026 江苏千桐科技有限公司
qModel 模型平台(开源版)
*
许可协议:
本项目基于 Apache License 2.0 开源协议发布,
允许在遵守协议的前提下进行商用、修改和分发。
*
特别说明:
所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
如需定制品牌,请通过官方渠道申请品牌定制授权。
*
更多信息请访问:https://qmodel.qiantong.tech/business.html
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>tech.qiantong</groupId>
<artifactId>qModel</artifactId>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>qmodel-config</module>
<module>qmodel-websocket</module>
<module>qmodel-mybatis</module>
<module>qmodel-redis</module>
<module>qmodel-quartz</module>
<module>qmodel-security</module>
<module>qmodel-generator</module>
<module>qmodel-common</module>
<module>qmodel-file</module>
<module>qmodel-es</module>
<module>qmodel-pay</module>
<module>qmodel-auth</module>
</modules>
<packaging>pom</packaging>
<artifactId>qmodel-framework</artifactId>
<description>
anivia-framework模块
</description>
</project>
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright © 2026 Qiantong Technology Co., Ltd.
qModel Model Platform(Open Source Edition)
*
License:
Released under the Apache License, Version 2.0.
You may use, modify, and distribute this software for commercial purposes
under the terms of the License.
*
Special Notice:
All derivative versions are strictly prohibited from modifying or removing
the default system logo and copyright information.
For brand customization, please apply for brand customization authorization via official channels.
*
More information: https://qmodel.qiantong.tech/business.html
*
============================================================================
*
版权所有 © 2026 江苏千桐科技有限公司
qModel 模型平台(开源版)
*
许可协议:
本项目基于 Apache License 2.0 开源协议发布,
允许在遵守协议的前提下进行商用、修改和分发。
*
特别说明:
所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
如需定制品牌,请通过官方渠道申请品牌定制授权。
*
更多信息请访问:https://qmodel.qiantong.tech/business.html
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>qmodel-framework</artifactId>
<groupId>tech.qiantong</groupId>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>qmodel-auth</artifactId>
<description>
auth模块
</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>tech.qiantong</groupId>
<artifactId>qmodel-security</artifactId>
<version>1.0.1</version>
</dependency>
<!-- 通用工具-->
<dependency>
<groupId>tech.qiantong</groupId>
<artifactId>qmodel-common</artifactId>
</dependency>
<!-- Sa-Token 权限认证, 在线文档:https://sa-token.cc -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.39.0</version>
</dependency>
<!-- Sa-Token OAuth2.0 模块 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-oauth2</artifactId>
<version>1.39.0</version>
</dependency>
<!-- Sa-Token 整合 Redis (可选) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>1.39.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,135 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.controller;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import tech.qiantong.qmodel.auth.domain.AuthClient;
import tech.qiantong.qmodel.common.annotation.Log;
import tech.qiantong.qmodel.common.core.controller.BaseController;
import tech.qiantong.qmodel.common.core.domain.AjaxResult;
import tech.qiantong.qmodel.common.core.page.TableDataInfo;
import tech.qiantong.qmodel.common.enums.BusinessType;
import tech.qiantong.qmodel.common.utils.poi.ExcelUtil;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* 应用管理Controller
*
* @author qModel
* @date 2024-08-31
*/
@RestController
@RequestMapping("/auth/client")
public class AuthClientController extends BaseController {
@Resource
private IService<AuthClient> authClientService;
/**
* 查询应用管理列表
*/
@PreAuthorize("@ss.hasPermi('auth:client:list')")
@GetMapping("/list")
public TableDataInfo list(AuthClient authClient) {
startPage();
QueryWrapper<AuthClient> queryWrapper = new QueryWrapper<>(authClient);
List<AuthClient> list = authClientService.list(queryWrapper);
return getDataTable(list);
}
/**
* 导出应用管理列表
*/
@PreAuthorize("@ss.hasPermi('auth:client:export')")
@Log(title = "应用管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AuthClient authClient) {
QueryWrapper<AuthClient> queryWrapper = new QueryWrapper<>(authClient);
List<AuthClient> list = authClientService.list(queryWrapper);
ExcelUtil<AuthClient> util = new ExcelUtil<>(AuthClient.class);
util.exportExcel(response, list, "应用管理数据");
}
/**
* 获取应用管理详细信息
*/
@PreAuthorize("@ss.hasPermi('auth:client:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(authClientService.getById(id));
}
/**
* 新增应用管理
*/
@PreAuthorize("@ss.hasPermi('auth:client:add')")
@Log(title = "应用管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AuthClient authClient) {
authClient.setCreatorId(getUserId());
authClient.setCreateBy(getNickName());
authClient.setSecretKey(IdUtil.simpleUUID());
return toAjax(authClientService.save(authClient));
}
/**
* 修改应用管理
*/
@PreAuthorize("@ss.hasPermi('auth:client:edit')")
@Log(title = "应用管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AuthClient authClient) {
authClient.setUpdatorId(getUserId());
authClient.setUpdateBy(getNickName());
authClient.setUpdateTime(new Date());
return toAjax(authClientService.updateById(authClient));
}
/**
* 删除应用管理
*/
@PreAuthorize("@ss.hasPermi('auth:client:remove')")
@Log(title = "应用管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(authClientService.removeByIds(Arrays.asList(ids)));
}
}
@@ -0,0 +1,127 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import tech.qiantong.qmodel.auth.domain.AuthClientUser;
import tech.qiantong.qmodel.common.annotation.Log;
import tech.qiantong.qmodel.common.core.controller.BaseController;
import tech.qiantong.qmodel.common.core.domain.AjaxResult;
import tech.qiantong.qmodel.common.core.page.TableDataInfo;
import tech.qiantong.qmodel.common.enums.BusinessType;
import tech.qiantong.qmodel.common.utils.poi.ExcelUtil;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
/**
* 应用和用户关联Controller
*
* @author qModel
* @date 2024-08-31
*/
@RestController
@RequestMapping("/auth/user")
public class AuthClientUserController extends BaseController {
@Resource
private IService<AuthClientUser> authClientUserService;
/**
* 查询应用和用户关联列表
*/
@PreAuthorize("@ss.hasPermi('auth:user:list')")
@GetMapping("/list")
public TableDataInfo list(AuthClientUser authClientUser) {
startPage();
QueryWrapper<AuthClientUser> queryWrapper = new QueryWrapper<>(authClientUser);
List<AuthClientUser> list = authClientUserService.list(queryWrapper);
return getDataTable(list);
}
/**
* 导出应用和用户关联列表
*/
@PreAuthorize("@ss.hasPermi('auth:user:export')")
@Log(title = "应用和用户关联", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AuthClientUser authClientUser) {
QueryWrapper<AuthClientUser> queryWrapper = new QueryWrapper<>(authClientUser);
List<AuthClientUser> list = authClientUserService.list(queryWrapper);
ExcelUtil<AuthClientUser> util = new ExcelUtil<>(AuthClientUser.class);
util.exportExcel(response, list, "应用和用户关联数据");
}
/**
* 获取应用和用户关联详细信息
*/
@PreAuthorize("@ss.hasPermi('auth:user:query')")
@GetMapping(value = "/{clientId}")
public AjaxResult getInfo(@PathVariable("clientId") Long clientId) {
return success(authClientUserService.getById(clientId));
}
/**
* 新增应用和用户关联
*/
@PreAuthorize("@ss.hasPermi('auth:user:add')")
@Log(title = "应用和用户关联", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AuthClientUser authClientUser) {
return toAjax(authClientUserService.save(authClientUser));
}
/**
* 修改应用和用户关联
*/
@PreAuthorize("@ss.hasPermi('auth:user:edit')")
@Log(title = "应用和用户关联", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AuthClientUser authClientUser) {
return toAjax(authClientUserService.updateById(authClientUser));
}
/**
* 删除应用和用户关联
*/
@PreAuthorize("@ss.hasPermi('auth:user:remove')")
@Log(title = "应用和用户关联", businessType = BusinessType.DELETE)
@DeleteMapping("/{clientIds}")
public AjaxResult remove(@PathVariable Long[] clientIds) {
return toAjax(authClientUserService.removeByIds(Arrays.asList(clientIds)));
}
}
@@ -0,0 +1,225 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
//package tech.qiantong.qmodel.controller;
//
//import cn.dev33.satoken.context.SaHolder;
//import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig;
//import cn.dev33.satoken.oauth2.processor.SaOAuth2ServerProcessor;
//import cn.dev33.satoken.oauth2.strategy.SaOAuth2Strategy;
//import cn.dev33.satoken.stp.SaLoginModel;
//import cn.dev33.satoken.stp.StpUtil;
//import cn.dev33.satoken.util.SaResult;
//import cn.hutool.core.convert.Convert;
//import tech.qiantong.qmodel.entity.domain.core.common.SysUser;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//import org.springframework.web.servlet.ModelAndView;
//
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * OAuth2 Server 的 Controller
// * 负责 OAuth2 相关的认证、登录、授权操作
// *
// * @author anivia
// */
//@RestController
//@RequestMapping("/oauth2")
//public class AuthOAuth2ServerController {
//
// @Autowired
// private ISysUserService userService;
//
// /**
// * 配置 OAuth2 认证服务
// */
// @Autowired
// public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) {
//
// // 配置登录处理
// oauth2Server.doLoginHandle = (name, pwd) -> {
// Boolean rememberMe = Convert.toBool(SaHolder.getRequest().getParam("rememberMe"));
// SysUser user = userService.findUserByNameOrPhone(name);
//
// if (user != null && user.comparePwd(pwd)) {
// SaLoginModel loginModel = new SaLoginModel()
// // 此次登录的客户端设备标识,用于在 [同账号异地登录] 时指定此次登录的设备标识
// .setDevice("PC")
// // 是否为持久 Cookie,持久 Cookie 在浏览器关闭时不会自动删除,下次打开仍然存在
// .setIsLastingCookie(rememberMe)
// .setIsWriteHeader(true);
// StpUtil.login(user.getUserId(), loginModel);
// // TODO: 缺少登录日志记录
// return SaResult.ok();
// } else {
// return SaResult.error("账号或密码错误");
// }
// };
//
// // 配置未登录时返回的 View
// oauth2Server.notLoginView = () -> {
// return new ModelAndView("sso/index.html");
// };
//
// // 配置授权确认视图
// oauth2Server.confirmView = (clientId, scopes) -> {
// Map<String, Object> map = new HashMap<>();
// map.put("clientId", clientId);
// map.put("scope", scopes);
// return new ModelAndView("sso/confirm.html", map);
// };
//
// // OAuth2 会话数据存储与访问策略
// SaOAuth2Strategy.instance.createAccessToken = (clientId, loginId, scopes) -> {
// return StpUtil.getOrCreateLoginSession(loginId);
// };
// }
//
// /**
// * 处理 OAuth2 授权请求
// * 支持授权码模式和隐式模式
// *
// * 请求参数:
// * response_type 响应类型(必填项)
// * client_id 应用 ID(必填项)
// * redirect_uri 用户确认后授权的重定向 URL 地址(必填项)
// * scope 请求授权范围,用空格分隔(必填项)
// * state 用于防止 CSRF 攻击的状态值,可选项,返回时会附加到重定向 URL(非必填项)
// *
// * @return 返回授权结果的视图
// */
// @RequestMapping("/authorize")
// public Object authorize() {
// return SaOAuth2ServerProcessor.instance.authorize();
// }
//
// /**
// * 处理用户登录请求
// *
// * 请求参数:
// * name 用户名(必填项)
// * pwd 密码(必填项)
// * rememberMe 是否记住登录状态(必填项)
// *
// * @return 用户登录的结果
// */
// @PostMapping("/doLogin")
// public Object doLogin() {
// return SaOAuth2ServerProcessor.instance.doLogin();
// }
//
// /**
// * 处理用户确认授权请求
// *
// * 请求参数:
// * client_id 应用 ID(必填项)
// * scope 确认的授权范围,用空格分隔(必填项)
// * build_redirect_uri 是否重新构建重定向 URLtrue/false)(非必填项)
// * response_type URL 上的 response_type 参数值(必填项)
// * redirect_uri URL 上的 redirect_uri 参数值(必填项)
// * state URL 上的 state 参数值(必填项)
// *
// * @return 用户确认授权的结果
// */
// @RequestMapping("/doConfirm")
// public Object doConfirm() {
// return SaOAuth2ServerProcessor.instance.doConfirm();
// }
//
// /**
// * 通过 Code 获取 Access-Token 请求
// * 支持授权码模式(Code 模式)
// *
// * 请求参数:
// * grant_type 授权类型,应填写 authorization_code(必填项)
// * client_id 应用 ID(必填项)
// * client_secret 应用密钥(必填项)
// * code 授权码(必填项)
// *
// * @return 返回 Token 结果
// */
// @PostMapping("/token")
// public Object token() {
// return SaOAuth2ServerProcessor.instance.token();
// }
//
// /**
// * 使用 Refresh-Token 刷新 Access-Token 请求
// *
// * 请求参数:
// * grant_type 授权类型,应填写 refresh_token(必填项)
// * client_id 应用 ID(必填项)
// * client_secret 应用密钥(必填项)
// * refresh_token 刷新的 Refresh-Token(必填项)
// *
// * @return 刷新 Token 的结果
// */
// @PostMapping("/refresh")
// public Object refresh() {
// return SaOAuth2ServerProcessor.instance.refresh();
// }
//
// /**
// * 撤销 Access-Token 请求
// *
// * 请求参数:
// * client_id 应用 ID(必填项)
// * client_secret 应用密钥(必填项)
// * access_token 要撤销的 Access-Token(必填项)
// *
// * @return 撤销 Token 的结果
// */
// @PostMapping("/revoke")
// public Object revoke() {
// return SaOAuth2ServerProcessor.instance.revoke();
// }
//
// /**
// * 处理客户端凭证模式(Client Credentials)获取 Access-Token 请求
// *
// * 请求参数:
// * grant_type 授权类型,应填写 client_credentials(必填项)
// * client_id 应用 ID(必填项)
// * client_secret 应用密钥(必填项)
// * scope 请求的授权范围,用空格分隔(非必填项)
// *
// * @return 凭证模式获取的 Token 结果
// */
// @PostMapping("/client_token")
// public Object clientToken() {
// return SaOAuth2ServerProcessor.instance.clientToken();
// }
//}
@@ -0,0 +1,105 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import tech.qiantong.qmodel.common.annotation.Excel;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
/**
* 应用管理对象 auth_client
*
* @author qModel
* @date 2024-08-31
*/
@Data
@TableName(value = "auth_client")
public class AuthClient extends BaseEntity {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/** 应用ID */
@TableId(type = IdType.AUTO)
private Long id;
/** 应用秘钥 */
@Excel(name = "应用秘钥")
private String secretKey;
/** 应用名称 */
@Excel(name = "应用名称")
private String name;
/** 应用类型;0Web1App2:小程序 */
@Excel(name = "应用类型;0:Web,1:App,2:小程序")
private Integer type;
/** 应用图标 */
@Excel(name = "应用图标")
private String icon;
/** 应用首页 */
@Excel(name = "应用首页")
private String homeUrl;
/** 同步地址 */
@Excel(name = "同步地址")
private String syncUrl;
/** 允许授权的url */
@Excel(name = "允许授权的url")
private String redirectUrl;
/** 是否公开 */
@Excel(name = "是否公开")
private Integer publicFlag;
/** 是否有效;0:无效,1:有效 */
@Excel(name = "是否有效;0:无效,1:有效")
private Integer validFlag;
/** 删除标志;1:已删除,0:未删除 */
@TableLogic
private Integer delFlag;
/** 创建人id;创建者的sys_user_id */
@Excel(name = "创建人id;创建者的sys_user_id")
private Long creatorId;
/** 更新人id;更新者的sys_user_id */
@Excel(name = "更新人id;更新者的sys_user_id")
private Long updatorId;
}
@@ -0,0 +1,70 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import tech.qiantong.qmodel.common.annotation.Excel;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
/**
* 应用和用户关联对象 auth_client_user
*
* @author qModel
* @date 2024-08-31
*/
@Data
@TableName(value = "auth_client_user")
public class AuthClientUser extends BaseEntity {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/** 应用ID */
@Excel(name = "应用ID")
@TableId(type = IdType.AUTO)
private Long clientId;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** open_id */
@Excel(name = "open_id")
private String openId;
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import tech.qiantong.qmodel.auth.domain.AuthClient;
/**
* 应用管理Mapper接口
*
* @author qModel
* @date 2024-08-31
*/
public interface AuthClientMapper extends BaseMapper<AuthClient> {
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import tech.qiantong.qmodel.auth.domain.AuthClientUser;
/**
* 应用和用户关联Mapper接口
*
* @author qModel
* @date 2024-08-31
*/
public interface AuthClientUserMapper extends BaseMapper<AuthClientUser> {
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.service;
import com.baomidou.mybatisplus.extension.service.IService;
import tech.qiantong.qmodel.auth.domain.AuthClient;
/**
* 应用管理Service接口
*
* @author qModel
* @date 2024-08-31
*/
public interface IAuthClientService extends IService<AuthClient> {
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.service;
import com.baomidou.mybatisplus.extension.service.IService;
import tech.qiantong.qmodel.auth.domain.AuthClientUser;
/**
* 应用和用户关联Service接口
*
* @author qModel
* @date 2024-08-31
*/
public interface IAuthClientUserService extends IService<AuthClientUser> {
}
@@ -0,0 +1,58 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tech.qiantong.qmodel.auth.domain.AuthClient;
import tech.qiantong.qmodel.auth.mapper.AuthClientMapper;
import tech.qiantong.qmodel.auth.service.IAuthClientService;
import javax.annotation.Resource;
/**
* 应用管理Service业务层处理
*
* @author qModel
* @date 2024-08-31
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AuthClientServiceImpl extends ServiceImpl<AuthClientMapper,AuthClient> implements IAuthClientService {
@Resource
private AuthClientMapper authClientMapper;
}
@@ -0,0 +1,58 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tech.qiantong.qmodel.auth.domain.AuthClientUser;
import tech.qiantong.qmodel.auth.mapper.AuthClientUserMapper;
import tech.qiantong.qmodel.auth.service.IAuthClientUserService;
import javax.annotation.Resource;
/**
* 应用和用户关联Service业务层处理
*
* @author qModel
* @date 2024-08-31
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AuthClientUserServiceImpl extends ServiceImpl<AuthClientUserMapper,AuthClientUser> implements IAuthClientUserService {
@Resource
private AuthClientUserMapper authClientUserMapper;
}
@@ -0,0 +1,119 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.service.impl;
import cn.dev33.satoken.oauth2.consts.GrantType;
import cn.dev33.satoken.oauth2.data.loader.SaOAuth2DataLoader;
import cn.dev33.satoken.oauth2.data.model.loader.SaClientModel;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import org.springframework.stereotype.Component;
import tech.qiantong.qmodel.auth.domain.AuthClient;
import tech.qiantong.qmodel.auth.domain.AuthClientUser;
import tech.qiantong.qmodel.auth.service.IAuthClientService;
import tech.qiantong.qmodel.auth.service.IAuthClientUserService;
import javax.annotation.Resource;
/**
* OAuth2.0 数据加载实现类
* 实现 SaOAuth2DataLoader 接口
* 负责提供 OAuth2.0 客户端信息及用户信息
*/
@Component
public class AuthOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
@Resource
private IAuthClientService clientService;
@Resource
private IAuthClientUserService clientUserService;
/**
* 根据 clientId 获取 Client 信息
*
* @param clientId 客户端ID
* @return SaClientModel 客户端模型
*/
@Override
public SaClientModel getClientModel(String clientId) {
AuthClient client = clientService.getById(Convert.toLong(clientId));
if (client != null) {
return new SaClientModel()
// 客户端ID
.setClientId(client.getId().toString())
// 客户端密钥
.setClientSecret(client.getSecretKey())
// 允许的重定向URL
.addAllowRedirectUris(client.getRedirectUrl().split(","))
// 允许的作用域
.addContractScopes("userinfo", "admin")
// 允许的授权模式
.addAllowGrantTypes(
GrantType.authorization_code,
GrantType.implicit,
GrantType.refresh_token,
GrantType.password,
GrantType.client_credentials
);
} else {
return null;
}
}
/**
* 根据 clientId 和 loginId 获取 openid
*
* @param clientId 客户端ID
* @param loginId 用户ID
* @return openid 用户唯一标识
*/
@Override
public String getOpenid(String clientId, Object loginId) {
AuthClientUser openid = clientUserService.lambdaQuery()
.eq(AuthClientUser::getClientId, Convert.toLong(clientId))
.eq(AuthClientUser::getUserId, Convert.toLong(loginId))
.one();
if (openid == null) {
openid = new AuthClientUser();
openid.setClientId(Convert.toLong(clientId));
openid.setUserId(Convert.toLong(loginId));
openid.setOpenId(IdUtil.simpleUUID());
clientUserService.save(openid);
}
return openid.getOpenId();
}
}
@@ -0,0 +1,49 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.auth.service.impl;
import cn.dev33.satoken.oauth2.template.SaOAuth2Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* Sa-Token OAuth2.0 整合实现 【重写框架】
* @author qModel
*/
@Component
public class AuthOAuth2TemplateImpl extends SaOAuth2Template {
private static final Logger log = LoggerFactory.getLogger(AuthOAuth2TemplateImpl.class);
}
@@ -0,0 +1,76 @@
# Copyright © 2026 Qiantong Technology Co., Ltd.
# qModel Model Platform(Open Source Edition)
# *
# License:
# Released under the Apache License, Version 2.0.
# You may use, modify, and distribute this software for commercial purposes
# under the terms of the License.
# *
# Special Notice:
# All derivative versions are strictly prohibited from modifying or removing
# the default system logo and copyright information.
# For brand customization, please apply for brand customization authorization via official channels.
# *
# More information: https://qmodel.qiantong.tech/business.html
# *
# ============================================================================
# *
# 版权所有 © 2026 江苏千桐科技有限公司
# qModel 模型平台(开源版)
# *
# 许可协议:
# 本项目基于 Apache License 2.0 开源协议发布,
# 允许在遵守协议的前提下进行商用、修改和分发。
# *
# 特别说明:
# 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
# 如需定制品牌,请通过官方渠道申请品牌定制授权。
# *
# 更多信息请访问:https://qmodel.qiantong.tech/business.html
sa-token:
# token 名称(同时也是 cookie 名称)
token-name: aniviaToken
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
timeout: 2592000
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
active-timeout: -1
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
is-share: true
# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik
token-style: uuid
# 是否输出操作日志
is-log: true
# oauth2服务配置
oauth2-server:
# 是否打开模式:授权码(Authorization Code
enable-authorization-code: true
# 是否打开模式:隐藏式(Implicit)
enable-implicit: true
# 是否打开模式:密码式(Password)
enable-password: true
# 是否打开模式:凭证式(Client Credentials
enable-client-credentials: true
# 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token
is-new-refresh: false
# Code授权码 保存的时间(单位:秒) 默认五分钟
code-timeout: 300
# Access-Token 保存的时间(单位:秒) 默认两个小时
access-token-timeout: 7200
# Refresh-Token 保存的时间(单位:秒) 默认30 天
refresh-token-timeout: 2592000
# Client-Token 保存的时间(单位:秒) 默认两个小时
client-token-timeout: 7200
# Lower-Client-Token 保存的时间(单位:秒) 默认为 -1,代表延续 Client-Token 有效期
lower-client-token-timeout: -1
# 指定高级权限,多个用逗号隔开
higher-scope: admin
# 指定低级权限,多个用逗号隔开
lower-scope: userinfo
# 模式4是否返回 AccessToken 字段
mode4-return-access-token: false
# 是否在返回值中隐藏默认的状态字段 (code、msg、data)
hide-status-field: false
@@ -0,0 +1,76 @@
# Copyright © 2026 Qiantong Technology Co., Ltd.
# qModel Model Platform(Open Source Edition)
# *
# License:
# Released under the Apache License, Version 2.0.
# You may use, modify, and distribute this software for commercial purposes
# under the terms of the License.
# *
# Special Notice:
# All derivative versions are strictly prohibited from modifying or removing
# the default system logo and copyright information.
# For brand customization, please apply for brand customization authorization via official channels.
# *
# More information: https://qmodel.qiantong.tech/business.html
# *
# ============================================================================
# *
# 版权所有 © 2026 江苏千桐科技有限公司
# qModel 模型平台(开源版)
# *
# 许可协议:
# 本项目基于 Apache License 2.0 开源协议发布,
# 允许在遵守协议的前提下进行商用、修改和分发。
# *
# 特别说明:
# 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
# 如需定制品牌,请通过官方渠道申请品牌定制授权。
# *
# 更多信息请访问:https://qmodel.qiantong.tech/business.html
sa-token:
# token 名称(同时也是 cookie 名称)
token-name: aniviaToken
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
timeout: 2592000
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
active-timeout: -1
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
is-share: true
# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik
token-style: uuid
# 是否输出操作日志
is-log: true
# oauth2服务配置
oauth2-server:
# 是否打开模式:授权码(Authorization Code
enable-authorization-code: true
# 是否打开模式:隐藏式(Implicit)
enable-implicit: true
# 是否打开模式:密码式(Password)
enable-password: true
# 是否打开模式:凭证式(Client Credentials
enable-client-credentials: true
# 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token
is-new-refresh: false
# Code授权码 保存的时间(单位:秒) 默认五分钟
code-timeout: 300
# Access-Token 保存的时间(单位:秒) 默认两个小时
access-token-timeout: 7200
# Refresh-Token 保存的时间(单位:秒) 默认30 天
refresh-token-timeout: 2592000
# Client-Token 保存的时间(单位:秒) 默认两个小时
client-token-timeout: 7200
# Lower-Client-Token 保存的时间(单位:秒) 默认为 -1,代表延续 Client-Token 有效期
lower-client-token-timeout: -1
# 指定高级权限,多个用逗号隔开
higher-scope: admin
# 指定低级权限,多个用逗号隔开
lower-scope: userinfo
# 模式4是否返回 AccessToken 字段
mode4-return-access-token: false
# 是否在返回值中隐藏默认的状态字段 (code、msg、data)
hide-status-field: false
@@ -0,0 +1,76 @@
# Copyright © 2026 Qiantong Technology Co., Ltd.
# qModel Model Platform(Open Source Edition)
# *
# License:
# Released under the Apache License, Version 2.0.
# You may use, modify, and distribute this software for commercial purposes
# under the terms of the License.
# *
# Special Notice:
# All derivative versions are strictly prohibited from modifying or removing
# the default system logo and copyright information.
# For brand customization, please apply for brand customization authorization via official channels.
# *
# More information: https://qmodel.qiantong.tech/business.html
# *
# ============================================================================
# *
# 版权所有 © 2026 江苏千桐科技有限公司
# qModel 模型平台(开源版)
# *
# 许可协议:
# 本项目基于 Apache License 2.0 开源协议发布,
# 允许在遵守协议的前提下进行商用、修改和分发。
# *
# 特别说明:
# 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
# 如需定制品牌,请通过官方渠道申请品牌定制授权。
# *
# 更多信息请访问:https://qmodel.qiantong.tech/business.html
sa-token:
# token 名称(同时也是 cookie 名称)
token-name: aniviaToken
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
timeout: 2592000
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
active-timeout: -1
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
is-share: true
# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik
token-style: uuid
# 是否输出操作日志
is-log: true
# oauth2服务配置
oauth2-server:
# 是否打开模式:授权码(Authorization Code
enable-authorization-code: true
# 是否打开模式:隐藏式(Implicit)
enable-implicit: true
# 是否打开模式:密码式(Password)
enable-password: true
# 是否打开模式:凭证式(Client Credentials
enable-client-credentials: true
# 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token
is-new-refresh: false
# Code授权码 保存的时间(单位:秒) 默认五分钟
code-timeout: 300
# Access-Token 保存的时间(单位:秒) 默认两个小时
access-token-timeout: 7200
# Refresh-Token 保存的时间(单位:秒) 默认30 天
refresh-token-timeout: 2592000
# Client-Token 保存的时间(单位:秒) 默认两个小时
client-token-timeout: 7200
# Lower-Client-Token 保存的时间(单位:秒) 默认为 -1,代表延续 Client-Token 有效期
lower-client-token-timeout: -1
# 指定高级权限,多个用逗号隔开
higher-scope: admin
# 指定低级权限,多个用逗号隔开
lower-scope: userinfo
# 模式4是否返回 AccessToken 字段
mode4-return-access-token: false
# 是否在返回值中隐藏默认的状态字段 (code、msg、data)
hide-status-field: false
@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright © 2026 Qiantong Technology Co., Ltd.
qModel Model Platform(Open Source Edition)
*
License:
Released under the Apache License, Version 2.0.
You may use, modify, and distribute this software for commercial purposes
under the terms of the License.
*
Special Notice:
All derivative versions are strictly prohibited from modifying or removing
the default system logo and copyright information.
For brand customization, please apply for brand customization authorization via official channels.
*
More information: https://qmodel.qiantong.tech/business.html
*
============================================================================
*
版权所有 © 2026 江苏千桐科技有限公司
qModel 模型平台(开源版)
*
许可协议:
本项目基于 Apache License 2.0 开源协议发布,
允许在遵守协议的前提下进行商用、修改和分发。
*
特别说明:
所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
如需定制品牌,请通过官方渠道申请品牌定制授权。
*
更多信息请访问:https://qmodel.qiantong.tech/business.html
-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.qiantong.auth.mapper.AuthClientMapper">
<resultMap type="AuthClient" id="AuthClientResult">
<result property="id" column="id" />
<result property="secretKey" column="secret_key" />
<result property="name" column="name" />
<result property="type" column="type" />
<result property="icon" column="icon" />
<result property="homeUrl" column="home_url" />
<result property="syncUrl" column="sync_url" />
<result property="redirectUrl" column="redirect_url" />
<result property="publicFlag" column="public_flag" />
<result property="validFlag" column="valid_flag" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="creatorId" column="creator_id" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updatorId" column="updator_id" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectAuthClientVo">
select id, secret_key, name, type, icon, home_url, sync_url, redirect_url, public_flag, valid_flag, del_flag, create_by, creator_id, create_time, update_by, updator_id, update_time, remark from auth_client
</sql>
<select id="selectAuthClientList" parameterType="AuthClient" resultMap="AuthClientResult">
<include refid="selectAuthClientVo"/>
<where>
<if test="id != null "> and id = #{id}</if>
<if test="secretKey != null and secretKey != ''"> and secret_key = #{secretKey}</if>
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="type != null "> and type = #{type}</if>
<if test="icon != null and icon != ''"> and icon = #{icon}</if>
<if test="homeUrl != null and homeUrl != ''"> and home_url = #{homeUrl}</if>
<if test="syncUrl != null and syncUrl != ''"> and sync_url = #{syncUrl}</if>
<if test="redirectUrl != null and redirectUrl != ''"> and redirect_url = #{redirectUrl}</if>
<if test="publicFlag != null "> and public_flag = #{publicFlag}</if>
<if test="validFlag != null "> and valid_flag = #{validFlag}</if>
<if test="delFlag != null "> and del_flag = #{delFlag}</if>
<if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if>
<if test="creatorId != null "> and creator_id = #{creatorId}</if>
<if test="createTime != null "> and create_time = #{createTime}</if>
<if test="updateBy != null and updateBy != ''"> and update_by = #{updateBy}</if>
<if test="updatorId != null and updatorId != ''"> and updator_id = #{updatorId}</if>
<if test="updateTime != null "> and update_time = #{updateTime}</if>
<if test="remark != null and remark != ''"> and remark = #{remark}</if>
</where>
</select>
<select id="selectAuthClientById" parameterType="Long" resultMap="AuthClientResult">
<include refid="selectAuthClientVo"/>
where id = #{id}
</select>
<insert id="insertAuthClient" parameterType="AuthClient" useGeneratedKeys="true" keyProperty="id">
insert into auth_client
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="secretKey != null and secretKey != ''">secret_key,</if>
<if test="name != null and name != ''">name,</if>
<if test="type != null">type,</if>
<if test="icon != null">icon,</if>
<if test="homeUrl != null">home_url,</if>
<if test="syncUrl != null and syncUrl != ''">sync_url,</if>
<if test="redirectUrl != null and redirectUrl != ''">redirect_url,</if>
<if test="publicFlag != null">public_flag,</if>
<if test="validFlag != null">valid_flag,</if>
<if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</if>
<if test="creatorId != null">creator_id,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updatorId != null">updator_id,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="secretKey != null and secretKey != ''">#{secretKey},</if>
<if test="name != null and name != ''">#{name},</if>
<if test="type != null">#{type},</if>
<if test="icon != null">#{icon},</if>
<if test="homeUrl != null">#{homeUrl},</if>
<if test="syncUrl != null and syncUrl != ''">#{syncUrl},</if>
<if test="redirectUrl != null and redirectUrl != ''">#{redirectUrl},</if>
<if test="publicFlag != null">#{publicFlag},</if>
<if test="validFlag != null">#{validFlag},</if>
<if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</if>
<if test="creatorId != null">#{creatorId},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updatorId != null">#{updatorId},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateAuthClient" parameterType="AuthClient">
update auth_client
<trim prefix="SET" suffixOverrides=",">
<if test="secretKey != null and secretKey != ''">secret_key = #{secretKey},</if>
<if test="name != null and name != ''">name = #{name},</if>
<if test="type != null">type = #{type},</if>
<if test="icon != null">icon = #{icon},</if>
<if test="homeUrl != null">home_url = #{homeUrl},</if>
<if test="syncUrl != null and syncUrl != ''">sync_url = #{syncUrl},</if>
<if test="redirectUrl != null and redirectUrl != ''">redirect_url = #{redirectUrl},</if>
<if test="publicFlag != null">public_flag = #{publicFlag},</if>
<if test="validFlag != null">valid_flag = #{validFlag},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="creatorId != null">creator_id = #{creatorId},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updatorId != null">updator_id = #{updatorId},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteAuthClientById" parameterType="Long">
delete from auth_client where id = #{id}
</delete>
<delete id="deleteAuthClientByIds" parameterType="String">
delete from auth_client where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright © 2026 Qiantong Technology Co., Ltd.
qModel Model Platform(Open Source Edition)
*
License:
Released under the Apache License, Version 2.0.
You may use, modify, and distribute this software for commercial purposes
under the terms of the License.
*
Special Notice:
All derivative versions are strictly prohibited from modifying or removing
the default system logo and copyright information.
For brand customization, please apply for brand customization authorization via official channels.
*
More information: https://qmodel.qiantong.tech/business.html
*
============================================================================
*
版权所有 © 2026 江苏千桐科技有限公司
qModel 模型平台(开源版)
*
许可协议:
本项目基于 Apache License 2.0 开源协议发布,
允许在遵守协议的前提下进行商用、修改和分发。
*
特别说明:
所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
如需定制品牌,请通过官方渠道申请品牌定制授权。
*
更多信息请访问:https://qmodel.qiantong.tech/business.html
-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.qiantong.auth.mapper.AuthClientUserMapper">
<resultMap type="AuthClientUser" id="AuthClientUserResult">
<result property="clientId" column="client_id" />
<result property="userId" column="user_id" />
<result property="openId" column="open_id" />
</resultMap>
<sql id="selectAuthClientUserVo">
select client_id, user_id, open_id from auth_client_user
</sql>
<select id="selectAuthClientUserList" parameterType="AuthClientUser" resultMap="AuthClientUserResult">
<include refid="selectAuthClientUserVo"/>
<where>
<if test="clientId != null "> and client_id = #{clientId}</if>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="openId != null and openId != ''"> and open_id = #{openId}</if>
</where>
</select>
<select id="selectAuthClientUserByClientId" parameterType="Long" resultMap="AuthClientUserResult">
<include refid="selectAuthClientUserVo"/>
where client_id = #{clientId}
</select>
<insert id="insertAuthClientUser" parameterType="AuthClientUser">
insert into auth_client_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="clientId != null">client_id,</if>
<if test="userId != null">user_id,</if>
<if test="openId != null and openId != ''">open_id,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="clientId != null">#{clientId},</if>
<if test="userId != null">#{userId},</if>
<if test="openId != null and openId != ''">#{openId},</if>
</trim>
</insert>
<update id="updateAuthClientUser" parameterType="AuthClientUser">
update auth_client_user
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="openId != null and openId != ''">open_id = #{openId},</if>
</trim>
where client_id = #{clientId}
</update>
<delete id="deleteAuthClientUserByClientId" parameterType="Long">
delete from auth_client_user where client_id = #{clientId}
</delete>
<delete id="deleteAuthClientUserByClientIds" parameterType="String">
delete from auth_client_user where client_id in
<foreach item="clientId" collection="array" open="(" separator="," close=")">
#{clientId}
</foreach>
</delete>
</mapper>
@@ -0,0 +1,244 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright © 2026 Qiantong Technology Co., Ltd.
qModel Model Platform(Open Source Edition)
*
License:
Released under the Apache License, Version 2.0.
You may use, modify, and distribute this software for commercial purposes
under the terms of the License.
*
Special Notice:
All derivative versions are strictly prohibited from modifying or removing
the default system logo and copyright information.
For brand customization, please apply for brand customization authorization via official channels.
*
More information: https://qmodel.qiantong.tech/business.html
*
============================================================================
*
版权所有 © 2026 江苏千桐科技有限公司
qModel 模型平台(开源版)
*
许可协议:
本项目基于 Apache License 2.0 开源协议发布,
允许在遵守协议的前提下进行商用、修改和分发。
*
特别说明:
所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
如需定制品牌,请通过官方渠道申请品牌定制授权。
*
更多信息请访问:https://qmodel.qiantong.tech/business.html
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>qmodel-framework</artifactId>
<groupId>tech.qiantong</groupId>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>qmodel-common</artifactId>
<description>
common通用工具
</description>
<dependencies>
<!-- Spring框架基本的核心工具 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- SpringWeb模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- spring security 安全认证 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<!-- 自定义验证注解 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- JSON工具类 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<!-- yml解析器 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<!-- Token生成与解析-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<!-- Jaxb -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<!-- redis 缓存操作 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- pool 对象池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.59</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.31</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
</dependency>
<!-- mybatis-plus 增强CRUD -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 多数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.14.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.14.0</version>
</dependency>
<!-- 对象转换 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
<version>1.5.5.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.5.5.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</dependency>
<!-- knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.1-jre</version>
<scope>compile</scope>
</dependency>
<!-- OkHttps网络请求库: http://okhttps.ejlchina.com/ -->
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps</artifactId>
<version>3.1.1</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,47 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import java.lang.annotation.*;
/**
* 匿名访问不鉴权注解
*
* @author anivia
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Anonymous
{
}
@@ -0,0 +1,61 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import java.lang.annotation.*;
/**
* 数据权限过滤注解
*
* @author anivia
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope
{
/**
* 部门表的别名
*/
public String deptAlias() default "";
/**
* 用户表的别名
*/
public String userAlias() default "";
/**
* 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
*/
public String permission() default "";
}
@@ -0,0 +1,56 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import tech.qiantong.qmodel.common.enums.DataSourceType;
import java.lang.annotation.*;
/**
* 自定义多数据源切换注解
*
* 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
*
* @author anivia
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource
{
/**
* 切换数据源名称
*/
public DataSourceType value() default DataSourceType.MASTER;
}
@@ -0,0 +1,225 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import tech.qiantong.qmodel.common.utils.poi.ExcelHandlerAdapter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.BigDecimal;
/**
* 自定义导出Excel数据注解
*
* @author anivia
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{
/**
* 导出时在excel中排序
*/
public int sort() default Integer.MAX_VALUE;
/**
* 导出到Excel中的名字.
*/
public String name() default "";
/**
* 日期格式, 如: yyyy-MM-dd
*/
public String dateFormat() default "";
/**
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
*/
public String dictType() default "";
/**
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/
public String readConverterExp() default "";
/**
* 分隔符,读取字符串组内容
*/
public String separator() default ",";
/**
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
*/
public int scale() default -1;
/**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/**
* 导出时在excel中每个列的高度
*/
public double height() default 14;
/**
* 导出时在excel中每个列的宽度
*/
public double width() default 16;
/**
* 文字后缀,如% 90 变成90%
*/
public String suffix() default "";
/**
* 当值为空时,字段的默认值
*/
public String defaultValue() default "";
/**
* 提示信息
*/
public String prompt() default "";
/**
* 设置只能选择不能输入的列内容.
*/
public String[] combo() default {};
/**
* 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解.
*/
public boolean comboReadDict() default false;
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/
public boolean needMerge() default false;
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
public boolean isExport() default true;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public String targetAttr() default "";
/**
* 是否自动统计数据,在最后追加一行统计数据总和
*/
public boolean isStatistics() default false;
/**
* 导出类型(0数字 1字符串 2图片)
*/
public ColumnType cellType() default ColumnType.STRING;
/**
* 导出列头背景颜色
*/
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
/**
* 导出列头字体颜色
*/
public IndexedColors headerColor() default IndexedColors.WHITE;
/**
* 导出单元格背景颜色
*/
public IndexedColors backgroundColor() default IndexedColors.WHITE;
/**
* 导出单元格字体颜色
*/
public IndexedColors color() default IndexedColors.BLACK;
/**
* 导出字段对齐方式
*/
public HorizontalAlignment align() default HorizontalAlignment.CENTER;
/**
* 自定义数据处理器
*/
public Class<?> handler() default ExcelHandlerAdapter.class;
/**
* 自定义数据处理器参数
*/
public String[] args() default {};
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/
Type type() default Type.ALL;
public enum Type
{
ALL(0), EXPORT(1), IMPORT(2);
private final int value;
Type(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
public enum ColumnType
{
NUMERIC(0), STRING(1), IMAGE(2), TEXT(3);
private final int value;
ColumnType(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
}
@@ -0,0 +1,50 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel注解集
*
* @author anivia
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{
public Excel[] value();
}
@@ -0,0 +1,80 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import tech.qiantong.qmodel.common.enums.BusinessType;
import tech.qiantong.qmodel.common.enums.OperatorType;
import java.lang.annotation.*;
/**
* 自定义操作日志记录注解
*
* @author anivia
*
*/
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
/**
* 模块
*/
public String title() default "";
/**
* 功能
*/
public BusinessType businessType() default BusinessType.OTHER;
/**
* 操作人类别
*/
public OperatorType operatorType() default OperatorType.MANAGE;
/**
* 是否保存请求的参数
*/
public boolean isSaveRequestData() default true;
/**
* 是否保存响应的参数
*/
public boolean isSaveResponseData() default true;
/**
* 排除指定的请求参数
*/
public String[] excludeParamNames() default {};
}
@@ -0,0 +1,69 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import tech.qiantong.qmodel.common.constant.CacheConstants;
import tech.qiantong.qmodel.common.enums.LimitType;
import java.lang.annotation.*;
/**
* 限流注解
*
* @author anivia
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimiter
{
/**
* 限流key
*/
public String key() default CacheConstants.RATE_LIMIT_KEY;
/**
* 限流时间,单位秒
*/
public int time() default 60;
/**
* 限流次数
*/
public int count() default 100;
/**
* 限流类型
*/
public LimitType limitType() default LimitType.DEFAULT;
}
@@ -0,0 +1,58 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import java.lang.annotation.*;
/**
* 自定义注解防止表单重复提交
*
* @author anivia
*
*/
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatSubmit
{
/**
* 间隔时间(ms),小于此时间视为重复提交
*/
public int interval() default 5000;
/**
* 提示消息
*/
public String message() default "不允许重复提交,请稍候再试";
}
@@ -0,0 +1,57 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.annotation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import tech.qiantong.qmodel.common.config.serializer.SensitiveJsonSerializer;
import tech.qiantong.qmodel.common.enums.DesensitizedType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 数据脱敏注解
*
* @author anivia
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive
{
DesensitizedType desensitizedType();
}
@@ -0,0 +1,154 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 读取项目相关配置
*
* @author anivia
*/
@Component
@ConfigurationProperties(prefix = "qmodel")
public class AniviaConfig
{
/** 项目名称 */
private String name;
/** 版本 */
private String version;
/** 版权年份 */
private String copyrightYear;
/** 上传路径 */
private static String profile;
/** 获取地址开关 */
private static boolean addressEnabled;
/** 验证码类型 */
private static String captchaType;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getVersion()
{
return version;
}
public void setVersion(String version)
{
this.version = version;
}
public String getCopyrightYear()
{
return copyrightYear;
}
public void setCopyrightYear(String copyrightYear)
{
this.copyrightYear = copyrightYear;
}
public static String getProfile()
{
return profile;
}
public void setProfile(String profile)
{
AniviaConfig.profile = profile;
}
public static boolean isAddressEnabled()
{
return addressEnabled;
}
public void setAddressEnabled(boolean addressEnabled)
{
AniviaConfig.addressEnabled = addressEnabled;
}
public static String getCaptchaType() {
return captchaType;
}
public void setCaptchaType(String captchaType) {
AniviaConfig.captchaType = captchaType;
}
/**
* 获取导入上传路径
*/
public static String getImportPath()
{
return getProfile() + "/import";
}
/**
* 获取头像上传路径
*/
public static String getAvatarPath()
{
return getProfile() + "/avatar";
}
/**
* 获取下载路径
*/
public static String getDownloadPath()
{
return getProfile() + "/download/";
}
/**
* 获取上传路径
*/
public static String getUploadPath()
{
return getProfile() + "/upload";
}
}
@@ -0,0 +1,60 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.config.serializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
/**
* 将 "1" 和 "0" 转换为布尔值
* @author anivia
*/
public class BooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String value = p.getText();
if ("1".equals(value)) {
return true;
} else if ("0".equals(value)) {
return false;
} else {
// 其他值保持默认行为
return Boolean.valueOf(value);
}
}
}
@@ -0,0 +1,100 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.config.serializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import tech.qiantong.qmodel.common.annotation.Sensitive;
import tech.qiantong.qmodel.common.core.domain.model.LoginUser;
import tech.qiantong.qmodel.common.enums.DesensitizedType;
import tech.qiantong.qmodel.common.utils.SecurityUtils;
import java.io.IOException;
import java.util.Objects;
/**
* 数据脱敏序列化过滤
*
* @author anivia
*/
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer
{
private DesensitizedType desensitizedType;
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException
{
if (desensitization())
{
gen.writeString(desensitizedType.desensitizer().apply(value));
}
else
{
gen.writeString(value);
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
throws JsonMappingException
{
Sensitive annotation = property.getAnnotation(Sensitive.class);
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass()))
{
this.desensitizedType = annotation.desensitizedType();
return this;
}
return prov.findValueSerializer(property.getType(), property);
}
/**
* 是否需要脱敏处理
*/
private boolean desensitization()
{
try
{
LoginUser securityUser = SecurityUtils.getLoginUser();
// 管理员不脱敏
return !securityUser.getUser().isAdmin();
}
catch (Exception e)
{
return true;
}
}
}
@@ -0,0 +1,76 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.constant;
/**
* 缓存的key 常量
*
* @author anivia
*/
public class CacheConstants
{
/**
* 登录用户 redis key
*/
public static final String LOGIN_TOKEN_KEY = "login_tokens:";
/**
* 验证码 redis key
*/
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/**
* 参数管理 cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
/**
* 字典管理 cache key
*/
public static final String SYS_DICT_KEY = "sys_dict:";
/**
* 防重提交 redis key
*/
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
/**
* 限流 redis key
*/
public static final String RATE_LIMIT_KEY = "rate_limit:";
/**
* 登录账户密码错误次数 redis key
*/
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
}
@@ -0,0 +1,206 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.constant;
import io.jsonwebtoken.Claims;
import java.util.Locale;
/**
* 通用常量信息
*
* @author anivia
*/
public class Constants
{
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/**
* GBK 字符集
*/
public static final String GBK = "GBK";
/**
* 系统语言
*/
public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
/**
* www主域
*/
public static final String WWW = "www.";
/**
* http请求
*/
public static final String HTTP = "http://";
/**
* https请求
*/
public static final String HTTPS = "https://";
/**
* 通用成功标识
*/
public static final String SUCCESS = "0";
/**
* 通用失败标识
*/
public static final String FAIL = "1";
/**
* 登录成功
*/
public static final String LOGIN_SUCCESS = "Success";
/**
* 注销
*/
public static final String LOGOUT = "Logout";
/**
* 注册
*/
public static final String REGISTER = "Register";
/**
* 登录失败
*/
public static final String LOGIN_FAIL = "Error";
/**
* 所有权限标识
*/
public static final String ALL_PERMISSION = "*:*:*";
/**
* 管理员角色权限标识
*/
public static final String SUPER_ADMIN = "admin";
/**
* 角色权限分隔符
*/
public static final String ROLE_DELIMETER = ",";
/**
* 权限标识分隔符
*/
public static final String PERMISSION_DELIMETER = ",";
/**
* 验证码有效期(分钟)
*/
public static final Integer CAPTCHA_EXPIRATION = 2;
/**
* 令牌
*/
public static final String TOKEN = "token";
/**
* 令牌前缀
*/
public static final String TOKEN_PREFIX = "Bearer ";
/**
* 令牌前缀
*/
public static final String LOGIN_USER_KEY = "login_user_key";
/**
* 用户ID
*/
public static final String JWT_USERID = "userid";
/**
* 用户名称
*/
public static final String JWT_USERNAME = Claims.SUBJECT;
/**
* 用户头像
*/
public static final String JWT_AVATAR = "avatar";
/**
* 创建时间
*/
public static final String JWT_CREATED = "created";
/**
* 用户权限
*/
public static final String JWT_AUTHORITIES = "authorities";
/**
* 资源映射路径 前缀
*/
public static final String RESOURCE_PREFIX = "/profile";
/**
* RMI 远程方法调用
*/
public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP 远程方法调用
*/
public static final String LOOKUP_LDAP = "ldap:";
/**
* LDAPS 远程方法调用
*/
public static final String LOOKUP_LDAPS = "ldaps:";
/**
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
*/
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "tech.qiantong" };
/**
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
*/
public static final String[] JOB_WHITELIST_STR = { "tech.qiantong.quartz.task","tech.qiantong.anivia" };
/**
* 定时任务违规的字符
*/
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "tech.qiantong.qmodel.common.utils.file", "tech.qiantong.qmodel.common.config", "tech.qiantong.generator" };
}
@@ -0,0 +1,154 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.constant;
/**
* 代码生成通用常量
*
* @author anivia
*/
public class GenConstants
{
/** 单表(增删改查) */
public static final String TPL_CRUD = "crud";
/** 树表(增删改查) */
public static final String TPL_TREE = "tree";
/** 主子表(增删改查) */
public static final String TPL_SUB = "sub";
/** 树编码字段 */
public static final String TREE_CODE = "treeCode";
/** 树父编码字段 */
public static final String TREE_PARENT_CODE = "treeParentCode";
/** 树名称字段 */
public static final String TREE_NAME = "treeName";
/** 上级菜单ID字段 */
public static final String PARENT_MENU_ID = "parentMenuId";
/** 上级菜单名称字段 */
public static final String PARENT_MENU_NAME = "parentMenuName";
/** 数据库字符串类型 */
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
/** 数据库文本类型 */
public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
/** 数据库时间类型 */
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
/** 数据库数字类型 */
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bit", "bigint", "float", "double", "decimal", "int8", "int4" };
/** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag", "valid_flag",
"creator_id", "update_by", "updator_id", "update_time" };
/** 页面不需要显示的列表字段 */
public static final String[] COLUMNNAME_NOT_LIST ={"del_flag", "valid_flag", "creator_id", "update_by", "updator_id", "update_time" };
/** 页面不需要查询字段 */
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "del_flag", "valid_flag", "creator_id",
"update_by", "updator_id", "update_time" , "remark" };
/** Entity基类字段 */
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark", "searchValue",
"creatorId", "creatorId", "updatorId", "remark", "params" };
/** Tree基类字段 */
//public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
public static final String[] TREE_ENTITY = { "parentName", "orderNum", "ancestors", "children" };
/** 文本框 */
public static final String HTML_INPUT = "input";
/** 文本域 */
public static final String HTML_TEXTAREA = "textarea";
/** 下拉框 */
public static final String HTML_SELECT = "select";
/** 单选框 */
public static final String HTML_RADIO = "radio";
/** 复选框 */
public static final String HTML_CHECKBOX = "checkbox";
/** 日期控件 */
public static final String HTML_DATETIME = "datetime";
/** 图片上传控件 */
public static final String HTML_IMAGE_UPLOAD = "imageUpload";
/** 文件上传控件 */
public static final String HTML_FILE_UPLOAD = "fileUpload";
/** 富文本控件 */
public static final String HTML_EDITOR = "editor";
/** 字符串类型 */
public static final String TYPE_STRING = "String";
/** 整型 */
public static final String TYPE_INTEGER = "Integer";
/** 长整型 */
public static final String TYPE_LONG = "Long";
/** 浮点型 */
public static final String TYPE_DOUBLE = "Double";
/** 高精度计算类型 */
public static final String TYPE_BIGDECIMAL = "BigDecimal";
/** 时间类型 */
public static final String TYPE_DATE = "Date";
/** 模糊查询 */
public static final String QUERY_LIKE = "LIKE";
/** 相等查询 */
public static final String QUERY_EQ = "EQ";
/** 相等范围 */
public static final String QUERY_BETWEEN = "BETWEEN";
/** 需要 */
public static final String REQUIRE = "1";
}
@@ -0,0 +1,126 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.constant;
/**
* 返回状态码
*
* @author anivia
*/
public class HttpStatus
{
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 对象创建成功
*/
public static final int CREATED = 201;
/**
* 请求已经被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已经执行成功,但是没有返回数据
*/
public static final int NO_CONTENT = 204;
/**
* 资源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 资源没有被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 参数列表错误(缺少,格式不匹配)
*/
public static final int BAD_REQUEST = 400;
/**
* 未授权
*/
public static final int UNAUTHORIZED = 401;
/**
* 访问受限,授权过期
*/
public static final int FORBIDDEN = 403;
/**
* 资源,服务未找到
*/
public static final int NOT_FOUND = 404;
/**
* 不允许的http方法
*/
public static final int BAD_METHOD = 405;
/**
* 资源冲突,或者资源被锁
*/
public static final int CONFLICT = 409;
/**
* 不支持的数据,媒体类型
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
* 系统内部错误
*/
public static final int ERROR = 500;
/**
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
/**
* 系统警告消息
*/
public static final int WARN = 601;
}
@@ -0,0 +1,82 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.constant;
/**
* 任务调度通用常量
*
* @author anivia
*/
public class ScheduleConstants
{
public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
/** 执行目标key */
public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
/** 默认 */
public static final String MISFIRE_DEFAULT = "0";
/** 立即触发执行 */
public static final String MISFIRE_IGNORE_MISFIRES = "1";
/** 触发一次执行 */
public static final String MISFIRE_FIRE_AND_PROCEED = "2";
/** 不触发立即执行 */
public static final String MISFIRE_DO_NOTHING = "3";
public enum Status
{
/**
* 正常
*/
NORMAL("0"),
/**
* 暂停
*/
PAUSE("1");
private String value;
private Status(String value)
{
this.value = value;
}
public String getValue()
{
return value;
}
}
}
@@ -0,0 +1,110 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.constant;
/**
* 用户常量信息
*
* @author anivia
*/
public class UserConstants
{
/**
* 平台内系统用户的唯一标志
*/
public static final String SYS_USER = "SYS_USER";
/** 正常状态 */
public static final String NORMAL = "0";
/** 异常状态 */
public static final String EXCEPTION = "1";
/** 用户封禁状态 */
public static final String USER_DISABLE = "1";
/** 角色封禁状态 */
public static final String ROLE_DISABLE = "1";
/** 部门正常状态 */
public static final String DEPT_NORMAL = "0";
/** 部门停用状态 */
public static final String DEPT_DISABLE = "1";
/** 字典正常状态 */
public static final String DICT_NORMAL = "0";
/** 是否为系统默认(是) */
public static final String YES = "Y";
/** 是否菜单外链(是) */
public static final String YES_FRAME = "0";
/** 是否菜单外链(否) */
public static final String NO_FRAME = "1";
/** 菜单类型(目录) */
public static final String TYPE_DIR = "M";
/** 菜单类型(菜单) */
public static final String TYPE_MENU = "C";
/** 菜单类型(按钮) */
public static final String TYPE_BUTTON = "F";
/** Layout组件标识 */
public final static String LAYOUT = "Layout";
/** ParentView组件标识 */
public final static String PARENT_VIEW = "ParentView";
/** InnerLink组件标识 */
public final static String INNER_LINK = "InnerLink";
/** 校验是否唯一的返回标识 */
public final static boolean UNIQUE = true;
public final static boolean NOT_UNIQUE = false;
/**
* 用户名长度限制
*/
public static final int USERNAME_MIN_LENGTH = 2;
public static final int USERNAME_MAX_LENGTH = 20;
/**
* 密码长度限制
*/
public static final int PASSWORD_MIN_LENGTH = 5;
public static final int PASSWORD_MAX_LENGTH = 20;
}
@@ -0,0 +1,243 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import tech.qiantong.qmodel.common.constant.HttpStatus;
import tech.qiantong.qmodel.common.core.domain.AjaxResult;
import tech.qiantong.qmodel.common.core.domain.model.LoginUser;
import tech.qiantong.qmodel.common.core.page.PageDomain;
import tech.qiantong.qmodel.common.core.page.TableDataInfo;
import tech.qiantong.qmodel.common.core.page.TableSupport;
import tech.qiantong.qmodel.common.utils.DateUtils;
import tech.qiantong.qmodel.common.utils.PageUtils;
import tech.qiantong.qmodel.common.utils.SecurityUtils;
import tech.qiantong.qmodel.common.utils.StringUtils;
import tech.qiantong.qmodel.common.utils.sql.SqlUtil;
import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.util.List;
/**
* web层通用数据处理
*
* @author anivia
*/
public class BaseController
{
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 将前台传递过来的日期格式的字符串,自动转化为Date类型
*/
@InitBinder
public void initBinder(WebDataBinder binder)
{
// Date 类型转换
binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
{
@Override
public void setAsText(String text)
{
setValue(DateUtils.parseDate(text));
}
});
}
/**
* 设置请求分页数据
*/
protected void startPage()
{
PageUtils.startPage();
}
/**
* 设置请求排序数据
*/
protected void startOrderBy()
{
PageDomain pageDomain = TableSupport.buildPageRequest();
if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
{
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
PageHelper.orderBy(orderBy);
}
}
/**
* 清理分页的线程变量
*/
protected void clearPage()
{
PageUtils.clearPage();
}
/**
* 响应请求分页数据
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected TableDataInfo getDataTable(List<?> list)
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功");
rspData.setRows(list);
rspData.setTotal(new PageInfo(list).getTotal());
return rspData;
}
/**
* 返回成功
*/
public AjaxResult success()
{
return AjaxResult.success();
}
/**
* 返回失败消息
*/
public AjaxResult error()
{
return AjaxResult.error();
}
/**
* 返回成功消息
*/
public AjaxResult success(String message)
{
return AjaxResult.success(message);
}
/**
* 返回成功消息
*/
public AjaxResult success(Object data)
{
return AjaxResult.success(data);
}
/**
* 返回失败消息
*/
public AjaxResult error(String message)
{
return AjaxResult.error(message);
}
/**
* 返回警告消息
*/
public AjaxResult warn(String message)
{
return AjaxResult.warn(message);
}
/**
* 响应返回结果
*
* @param rows 影响行数
* @return 操作结果
*/
protected AjaxResult toAjax(int rows)
{
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
}
/**
* 响应返回结果
*
* @param result 结果
* @return 操作结果
*/
protected AjaxResult toAjax(boolean result)
{
return result ? success() : error();
}
/**
* 页面跳转
*/
public String redirect(String url)
{
return StringUtils.format("redirect:{}", url);
}
/**
* 获取用户缓存信息
*/
public LoginUser getLoginUser()
{
return SecurityUtils.getLoginUser();
}
/**
* 获取登录用户id
*/
public Long getUserId()
{
return getLoginUser().getUserId();
}
/**
* 获取登录部门id
*/
public Long getDeptId()
{
return getLoginUser().getDeptId();
}
/**
* 获取登录用户名
*/
public String getUsername()
{
return getLoginUser().getUsername();
}
/**
* 获取登录人姓名
*/
public String getNickName()
{
return getLoginUser().getUser().getNickName();
}
}
@@ -0,0 +1,249 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain;
import tech.qiantong.qmodel.common.constant.HttpStatus;
import tech.qiantong.qmodel.common.utils.StringUtils;
import java.util.HashMap;
import java.util.Objects;
/**
* 操作消息提醒
*
* @author anivia
*/
public class AjaxResult extends HashMap<String, Object>
{
private static final long serialVersionUID = 1L;
/** 状态码 */
public static final String CODE_TAG = "code";
/** 返回内容 */
public static final String MSG_TAG = "msg";
/** 数据对象 */
public static final String DATA_TAG = "data";
/**
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
*/
public AjaxResult()
{
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态码
* @param msg 返回内容
*/
public AjaxResult(int code, String msg)
{
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态码
* @param msg 返回内容
* @param data 数据对象
*/
public AjaxResult(int code, String msg, Object data)
{
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
if (StringUtils.isNotNull(data))
{
super.put(DATA_TAG, data);
}
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static AjaxResult success()
{
return AjaxResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static AjaxResult success(Object data)
{
return AjaxResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static AjaxResult success(String msg)
{
return AjaxResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static AjaxResult success(String msg, Object data)
{
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult warn(String msg)
{
return AjaxResult.warn(msg, null);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult warn(String msg, Object data)
{
return new AjaxResult(HttpStatus.WARN, msg, data);
}
/**
* 返回错误消息
*
* @return 错误消息
*/
public static AjaxResult error()
{
return AjaxResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 错误消息
*/
public static AjaxResult error(String msg)
{
return AjaxResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 错误消息
*/
public static AjaxResult error(String msg, Object data)
{
return new AjaxResult(HttpStatus.ERROR, msg, data);
}
/**
* 返回错误消息
*
* @param code 状态码
* @param msg 返回内容
* @return 错误消息
*/
public static AjaxResult error(int code, String msg)
{
return new AjaxResult(code, msg, null);
}
/**
* 是否为成功消息
*
* @return 结果
*/
public boolean isSuccess()
{
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
}
/**
* 是否为警告消息
*
* @return 结果
*/
public boolean isWarn()
{
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
}
/**
* 是否为错误消息
*
* @return 结果
*/
public boolean isError()
{
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
}
/**
* 方便链式调用
*
* @param key 键
* @param value 值
* @return 数据对象
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
}
@@ -0,0 +1,208 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Entity基类
*
* @author anivia
*/
public class BaseEntity implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* 搜索值
*/
@JsonIgnore
@TableField(exist = false)
@Schema(description = "搜索值", example = "")
private String searchValue;
@Schema(description = "创建者id", example = "")
@TableField(fill = FieldFill.INSERT)
private Long creatorId;
/**
* 创建者
*/
@Schema(description = "创建者", example = "")
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
// 创建时间自动填充
@TableField(fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建时间", example = "")
private Date createTime;
@Schema(description = "更新者id", example = "")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updatorId;
/**
* 更新者
*/
@Schema(description = "更新者", example = "")
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 更新时间
*/
// 更新时间自动填充
@TableField(fill = FieldFill.INSERT_UPDATE)
@Schema(description = "更新时间", example = "")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 备注
*/
@Schema(description = "备注", example = "")
private String remark;
/**
* 请求参数
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false)
@Schema(description = "其他请求参数", example = "")
private Map<String, Object> params;
public String getSearchValue() {
return searchValue;
}
public void setSearchValue(String searchValue) {
this.searchValue = searchValue;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Long getCreatorId() {
return creatorId;
}
public void setCreatorId(Long creatorId) {
this.creatorId = creatorId;
}
public Long getUpdatorId() {
return updatorId;
}
public void setUpdatorId(Long updatorId) {
this.updatorId = updatorId;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Map<String, Object> getParams() {
if (params == null) {
params = new HashMap<>();
}
return params;
}
public Object getParamByKey(String key) {
if (params == null) {
params = new HashMap<>();
}
return params.get(key);
}
public void setParams(Map<String, Object> params) {
this.params = params;
}
public Object setParamByKey(String key, Object value) {
if (params == null) {
params = new HashMap<>();
}
return params.put(key, value);
}
}
@@ -0,0 +1,165 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain;
import cn.hutool.core.convert.Convert;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.util.Assert;
import tech.qiantong.qmodel.common.exception.ErrorCode;
import tech.qiantong.qmodel.common.exception.ServiceException;
import tech.qiantong.qmodel.common.exception.enums.GlobalErrorCodeConstants;
import java.io.Serializable;
import java.util.Objects;
/**
* 通用返回
*
* @author Ming
* @param <T> 数据泛型
*/
@Schema(description = "通用返回")
@Data
public class CommonResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 错误码
*
* @see ErrorCode#getCode()
*/
@Schema(description = "错误码")
private Integer code;
/**
* 返回数据
*/
@Schema(description = "返回数据")
private T data;
/**
* 错误提示,用户可阅读
*
* @see ErrorCode#getMsg() ()
*/
@Schema(description = "返回信息")
private String msg;
/**
* 将传入的 result 对象,转换成另外一个泛型结果的对象
*
* 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。
*
* @param result 传入的 result 对象
* @param <T> 返回的泛型
* @return 新的 CommonResult 对象
*/
public static <T> CommonResult<T> error(CommonResult<?> result) {
return error(result.getCode(), result.getMsg());
}
public static <T> CommonResult<T> error(Integer code, String message) {
Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
CommonResult<T> result = new CommonResult<>();
result.code = code;
result.msg = message;
return result;
}
public static <T> CommonResult<T> error(ErrorCode errorCode) {
return error(errorCode.getCode(), errorCode.getMsg());
}
public static <T> CommonResult<T> success(T data) {
CommonResult<T> result = new CommonResult<>();
result.code = GlobalErrorCodeConstants.SUCCESS.getCode();
result.data = data;
result.msg = GlobalErrorCodeConstants.SUCCESS.getMsg();
return result;
}
public static <T> CommonResult<T> toAjax(T data) {
CommonResult<T> result = new CommonResult<>();
if (Convert.toBool(data)) {
result.code = GlobalErrorCodeConstants.SUCCESS.getCode();
result.msg = GlobalErrorCodeConstants.SUCCESS.getMsg();
} else {
result.code = GlobalErrorCodeConstants.ERROR.getCode();
result.msg = GlobalErrorCodeConstants.ERROR.getMsg();
}
return result;
}
public static boolean isSuccess(Integer code) {
return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode());
}
@JsonIgnore // 避免 jackson 序列化
public boolean isSuccess() {
return isSuccess(code);
}
@JsonIgnore // 避免 jackson 序列化
public boolean isError() {
return !isSuccess();
}
// ========= 和 Exception 异常体系集成 =========
/**
* 判断是否有异常。如果有,则抛出 {@link ServiceException} 异常
*/
public void checkError() throws ServiceException {
if (isSuccess()) {
return;
}
// 业务异常
throw new ServiceException(msg, code);
}
/**
* 判断是否有异常。如果有,则抛出 {@link ServiceException} 异常
* 如果没有,则返回 {@link #data} 数据
*/
@JsonIgnore // 避免 jackson 序列化
public T getCheckedData() {
checkError();
return data;
}
public static <T> CommonResult<T> error(ServiceException serviceException) {
return error(serviceException.getCode(), serviceException.getMessage());
}
}
@@ -0,0 +1,148 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain;
import tech.qiantong.qmodel.common.constant.HttpStatus;
import java.io.Serializable;
/**
* 响应信息主体
*
* @author anivia
*/
public class R<T> implements Serializable
{
private static final long serialVersionUID = 1L;
/** 成功 */
public static final int SUCCESS = HttpStatus.SUCCESS;
/** 失败 */
public static final int FAIL = HttpStatus.ERROR;
private int code;
private String msg;
private T data;
public static <T> R<T> ok()
{
return restResult(null, SUCCESS, "操作成功");
}
public static <T> R<T> ok(T data)
{
return restResult(data, SUCCESS, "操作成功");
}
public static <T> R<T> ok(T data, String msg)
{
return restResult(data, SUCCESS, msg);
}
public static <T> R<T> fail()
{
return restResult(null, FAIL, "操作失败");
}
public static <T> R<T> fail(String msg)
{
return restResult(null, FAIL, msg);
}
public static <T> R<T> fail(T data)
{
return restResult(data, FAIL, "操作失败");
}
public static <T> R<T> fail(T data, String msg)
{
return restResult(data, FAIL, msg);
}
public static <T> R<T> fail(int code, String msg)
{
return restResult(null, code, msg);
}
private static <T> R<T> restResult(T data, int code, String msg)
{
R<T> apiResult = new R<>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
public int getCode()
{
return code;
}
public void setCode(int code)
{
this.code = code;
}
public String getMsg()
{
return msg;
}
public void setMsg(String msg)
{
this.msg = msg;
}
public T getData()
{
return data;
}
public void setData(T data)
{
this.data = data;
}
public static <T> Boolean isError(R<T> ret)
{
return !isSuccess(ret);
}
public static <T> Boolean isSuccess(R<T> ret)
{
return R.SUCCESS == ret.getCode();
}
}
@@ -0,0 +1,111 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain;
import java.util.ArrayList;
import java.util.List;
/**
* Tree基类
*
* @author anivia
*/
public class TreeEntity extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 父菜单名称 */
private String parentName;
/** 父菜单ID */
private Long parentId;
/** 显示顺序 */
private Integer orderNum;
/** 祖级列表 */
private String ancestors;
/** 子部门 */
private List<?> children = new ArrayList<>();
public String getParentName()
{
return parentName;
}
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
public Integer getOrderNum()
{
return orderNum;
}
public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
public String getAncestors()
{
return ancestors;
}
public void setAncestors(String ancestors)
{
this.ancestors = ancestors;
}
public List<?> getChildren()
{
return children;
}
public void setChildren(List<?> children)
{
this.children = children;
}
}
@@ -0,0 +1,110 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain;
import com.fasterxml.jackson.annotation.JsonInclude;
import tech.qiantong.qmodel.common.core.domain.entity.SysDept;
import tech.qiantong.qmodel.common.core.domain.entity.SysMenu;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
/**
* Treeselect树结构实体类
*
* @author anivia
*/
public class TreeSelect implements Serializable
{
private static final long serialVersionUID = 1L;
/** 节点ID */
private Long id;
/** 节点名称 */
private String label;
/** 子节点 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<TreeSelect> children;
public TreeSelect()
{
}
public TreeSelect(SysDept dept)
{
this.id = dept.getDeptId();
this.label = dept.getDeptName();
this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
}
public TreeSelect(SysMenu menu)
{
this.id = menu.getMenuId();
this.label = menu.getMenuName();
this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getLabel()
{
return label;
}
public void setLabel(String label)
{
this.label = label;
}
public List<TreeSelect> getChildren()
{
return children;
}
public void setChildren(List<TreeSelect> children)
{
this.children = children;
}
}
@@ -0,0 +1,236 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
/**
* 部门表 sys_dept
*
* @author anivia
*/
public class SysDept extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 部门ID */
private Long deptId;
/** 父部门ID */
private Long parentId;
/** 祖级列表 */
private String ancestors;
/** 部门名称 */
private String deptName;
/** 显示顺序 */
private Integer orderNum;
/** 负责人 */
private String leader;
/** 联系电话 */
private String phone;
/** 邮箱 */
private String email;
/** 部门状态:0正常,1停用 */
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 父部门名称 */
private String parentName;
/** 子部门 */
private List<SysDept> children = new ArrayList<SysDept>();
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
public String getAncestors()
{
return ancestors;
}
public void setAncestors(String ancestors)
{
this.ancestors = ancestors;
}
@NotBlank(message = "部门名称不能为空")
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
public String getDeptName()
{
return deptName;
}
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
@NotNull(message = "显示顺序不能为空")
public Integer getOrderNum()
{
return orderNum;
}
public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
public String getLeader()
{
return leader;
}
public void setLeader(String leader)
{
this.leader = leader;
}
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
public String getPhone()
{
return phone;
}
public void setPhone(String phone)
{
this.phone = phone;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getParentName()
{
return parentName;
}
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public List<SysDept> getChildren()
{
return children;
}
public void setChildren(List<SysDept> children)
{
this.children = children;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("deptId", getDeptId())
.append("parentId", getParentId())
.append("ancestors", getAncestors())
.append("deptName", getDeptName())
.append("orderNum", getOrderNum())
.append("leader", getLeader())
.append("phone", getPhone())
.append("email", getEmail())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}
@@ -0,0 +1,209 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import tech.qiantong.qmodel.common.annotation.Excel;
import tech.qiantong.qmodel.common.annotation.Excel.ColumnType;
import tech.qiantong.qmodel.common.constant.UserConstants;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* 字典数据表 sys_dict_data
*
* @author anivia
*/
public class SysDictData extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 字典编码 */
@Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
private Long dictCode;
/** 字典排序 */
@Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
private Long dictSort;
/** 字典标签 */
@Excel(name = "字典标签")
private String dictLabel;
/** 字典键值 */
@Excel(name = "字典键值")
private String dictValue;
/** 字典类型 */
@Excel(name = "字典类型")
private String dictType;
/** 样式属性(其他样式扩展) */
private String cssClass;
/** 表格字典样式 */
private String listClass;
/** 是否默认(Y是 N否) */
@Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
private String isDefault;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictCode()
{
return dictCode;
}
public void setDictCode(Long dictCode)
{
this.dictCode = dictCode;
}
public Long getDictSort()
{
return dictSort;
}
public void setDictSort(Long dictSort)
{
this.dictSort = dictSort;
}
@NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
public String getDictLabel()
{
return dictLabel;
}
public void setDictLabel(String dictLabel)
{
this.dictLabel = dictLabel;
}
@NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
public String getDictValue()
{
return dictValue;
}
public void setDictValue(String dictValue)
{
this.dictValue = dictValue;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
public String getCssClass()
{
return cssClass;
}
public void setCssClass(String cssClass)
{
this.cssClass = cssClass;
}
public String getListClass()
{
return listClass;
}
public void setListClass(String listClass)
{
this.listClass = listClass;
}
public boolean getDefault()
{
return UserConstants.YES.equals(this.isDefault);
}
public String getIsDefault()
{
return isDefault;
}
public void setIsDefault(String isDefault)
{
this.isDefault = isDefault;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictCode", getDictCode())
.append("dictSort", getDictSort())
.append("dictLabel", getDictLabel())
.append("dictValue", getDictValue())
.append("dictType", getDictType())
.append("cssClass", getCssClass())
.append("listClass", getListClass())
.append("isDefault", getIsDefault())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
@@ -0,0 +1,141 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import tech.qiantong.qmodel.common.annotation.Excel;
import tech.qiantong.qmodel.common.annotation.Excel.ColumnType;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.List;
/**
* 字典类型表 sys_dict_type
*
* @author anivia
*/
public class SysDictType extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 字典主键 */
@Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
private Long dictId;
/** 字典名称 */
@Excel(name = "字典名称")
private String dictName;
/** 字典类型 */
@Excel(name = "字典类型")
private String dictType;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 存储dictData数据 */
private List<SysDictData> sysDictData;
public List<SysDictData> getSysDictData() {
return sysDictData;
}
public void setSysDictData(List<SysDictData> sysDictData) {
this.sysDictData = sysDictData;
}
public Long getDictId()
{
return dictId;
}
public void setDictId(Long dictId)
{
this.dictId = dictId;
}
@NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
public String getDictName()
{
return dictName;
}
public void setDictName(String dictName)
{
this.dictName = dictName;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictId", getDictId())
.append("dictName", getDictName())
.append("dictType", getDictType())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
@@ -0,0 +1,307 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
/**
* 菜单权限表 sys_menu
*
* @author anivia
*/
public class SysMenu extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 菜单ID */
private Long menuId;
/** 菜单名称 */
private String menuName;
/** 父菜单名称 */
private String parentName;
/** 父菜单ID */
private Long parentId;
/** 显示顺序 */
private Integer orderNum;
/** 路由地址 */
private String path;
/** 组件路径 */
private String component;
/** 路由参数 */
private String query;
/** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */
private String routeName;
/** 是否为外链(0是 1否) */
private String isFrame;
/** 是否缓存(0缓存 1不缓存) */
private String isCache;
/** 类型(M目录 C菜单 F按钮) */
private String menuType;
/** 显示状态(0显示 1隐藏) */
private String visible;
/** 菜单状态(0正常 1停用) */
private String status;
/** 权限字符串 */
private String perms;
/** 菜单图标 */
private String icon;
/** 子菜单 */
private List<SysMenu> children = new ArrayList<SysMenu>();
public Long getMenuId()
{
return menuId;
}
public void setMenuId(Long menuId)
{
this.menuId = menuId;
}
@NotBlank(message = "菜单名称不能为空")
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
public String getMenuName()
{
return menuName;
}
public void setMenuName(String menuName)
{
this.menuName = menuName;
}
public String getParentName()
{
return parentName;
}
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
@NotNull(message = "显示顺序不能为空")
public Integer getOrderNum()
{
return orderNum;
}
public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
public String getPath()
{
return path;
}
public void setPath(String path)
{
this.path = path;
}
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
public String getComponent()
{
return component;
}
public void setComponent(String component)
{
this.component = component;
}
public String getQuery()
{
return query;
}
public void setQuery(String query)
{
this.query = query;
}
public String getRouteName()
{
return routeName;
}
public void setRouteName(String routeName)
{
this.routeName = routeName;
}
public String getIsFrame()
{
return isFrame;
}
public void setIsFrame(String isFrame)
{
this.isFrame = isFrame;
}
public String getIsCache()
{
return isCache;
}
public void setIsCache(String isCache)
{
this.isCache = isCache;
}
@NotBlank(message = "菜单类型不能为空")
public String getMenuType()
{
return menuType;
}
public void setMenuType(String menuType)
{
this.menuType = menuType;
}
public String getVisible()
{
return visible;
}
public void setVisible(String visible)
{
this.visible = visible;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
public String getPerms()
{
return perms;
}
public void setPerms(String perms)
{
this.perms = perms;
}
public String getIcon()
{
return icon;
}
public void setIcon(String icon)
{
this.icon = icon;
}
public List<SysMenu> getChildren()
{
return children;
}
public void setChildren(List<SysMenu> children)
{
this.children = children;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("menuId", getMenuId())
.append("menuName", getMenuName())
.append("parentId", getParentId())
.append("orderNum", getOrderNum())
.append("path", getPath())
.append("component", getComponent())
.append("query", getQuery())
.append("routeName", getRouteName())
.append("isFrame", getIsFrame())
.append("IsCache", getIsCache())
.append("menuType", getMenuType())
.append("visible", getVisible())
.append("status ", getStatus())
.append("perms", getPerms())
.append("icon", getIcon())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
@@ -0,0 +1,274 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import tech.qiantong.qmodel.common.annotation.Excel;
import tech.qiantong.qmodel.common.annotation.Excel.ColumnType;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Set;
/**
* 角色表 sys_role
*
* @author anivia
*/
public class SysRole extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 角色ID */
@Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
private Long roleId;
/** 角色名称 */
@Excel(name = "角色名称")
private String roleName;
/** 角色权限 */
@Excel(name = "角色权限")
private String roleKey;
/** 角色排序 */
@Excel(name = "角色排序")
private Integer roleSort;
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
private String dataScope;
/** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
private boolean menuCheckStrictly;
/** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
private boolean deptCheckStrictly;
/** 角色状态(0正常 1停用) */
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 用户是否存在此角色标识 默认不存在 */
private boolean flag = false;
/** 菜单组 */
private Long[] menuIds;
/** 部门组(数据权限) */
private Long[] deptIds;
/** 角色菜单权限 */
private Set<String> permissions;
public SysRole()
{
}
public SysRole(Long roleId)
{
this.roleId = roleId;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
public boolean isAdmin()
{
return isAdmin(this.roleId);
}
public static boolean isAdmin(Long roleId)
{
return roleId != null && 1L == roleId;
}
@NotBlank(message = "角色名称不能为空")
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
public String getRoleName()
{
return roleName;
}
public void setRoleName(String roleName)
{
this.roleName = roleName;
}
@NotBlank(message = "权限字符不能为空")
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
public String getRoleKey()
{
return roleKey;
}
public void setRoleKey(String roleKey)
{
this.roleKey = roleKey;
}
@NotNull(message = "显示顺序不能为空")
public Integer getRoleSort()
{
return roleSort;
}
public void setRoleSort(Integer roleSort)
{
this.roleSort = roleSort;
}
public String getDataScope()
{
return dataScope;
}
public void setDataScope(String dataScope)
{
this.dataScope = dataScope;
}
public boolean isMenuCheckStrictly()
{
return menuCheckStrictly;
}
public void setMenuCheckStrictly(boolean menuCheckStrictly)
{
this.menuCheckStrictly = menuCheckStrictly;
}
public boolean isDeptCheckStrictly()
{
return deptCheckStrictly;
}
public void setDeptCheckStrictly(boolean deptCheckStrictly)
{
this.deptCheckStrictly = deptCheckStrictly;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public boolean isFlag()
{
return flag;
}
public void setFlag(boolean flag)
{
this.flag = flag;
}
public Long[] getMenuIds()
{
return menuIds;
}
public void setMenuIds(Long[] menuIds)
{
this.menuIds = menuIds;
}
public Long[] getDeptIds()
{
return deptIds;
}
public void setDeptIds(Long[] deptIds)
{
this.deptIds = deptIds;
}
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("roleId", getRoleId())
.append("roleName", getRoleName())
.append("roleKey", getRoleKey())
.append("roleSort", getRoleSort())
.append("dataScope", getDataScope())
.append("menuCheckStrictly", isMenuCheckStrictly())
.append("deptCheckStrictly", isDeptCheckStrictly())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
@@ -0,0 +1,381 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import tech.qiantong.qmodel.common.annotation.Excel;
import tech.qiantong.qmodel.common.annotation.Excel.ColumnType;
import tech.qiantong.qmodel.common.annotation.Excel.Type;
import tech.qiantong.qmodel.common.annotation.Excels;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
import tech.qiantong.qmodel.common.utils.SecurityUtils;
import tech.qiantong.qmodel.common.utils.StringUtils;
import tech.qiantong.qmodel.common.xss.Xss;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
/**
* 用户对象 sys_user
*
* @author anivia
*/
public class SysUser extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 用户ID */
@Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
//认证平台id
private String authId;
/** 部门ID */
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
/** 用户账号 */
@Excel(name = "登录名称")
private String userName;
/** 用户昵称 */
@Excel(name = "用户名称")
private String nickName;
/** 用户邮箱 */
@Excel(name = "用户邮箱")
private String email;
/** 手机号码 */
@Excel(name = "手机号码", cellType = ColumnType.TEXT)
private String phonenumber;
/** 用户性别 */
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
/** 用户头像 */
private String avatar;
/** 密码 */
private String password;
/** 帐号状态(0正常 1停用) */
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 最后登录IP */
@Excel(name = "最后登录IP", type = Type.EXPORT)
private String loginIp;
/** 最后登录时间 */
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date loginDate;
/** 部门对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
private SysDept dept;
/** 角色对象 */
private List<SysRole> roles;
/** 角色组 */
private Long[] roleIds;
/** 岗位组 */
private Long[] postIds;
/** 角色ID */
private Long roleId;
public SysUser()
{
}
public SysUser(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public String getAuthId() {
return authId;
}
public void setAuthId(String authId) {
this.authId = authId;
}
public boolean isAdmin()
{
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId)
{
return userId != null && 1L == userId;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName()
{
return nickName;
}
public void setNickName(String nickName)
{
this.nickName = nickName;
}
@Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
public String getPhonenumber()
{
return phonenumber;
}
public void setPhonenumber(String phonenumber)
{
this.phonenumber = phonenumber;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getAvatar()
{
return avatar;
}
public void setAvatar(String avatar)
{
this.avatar = avatar;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getLoginIp()
{
return loginIp;
}
public void setLoginIp(String loginIp)
{
this.loginIp = loginIp;
}
public Date getLoginDate()
{
return loginDate;
}
public void setLoginDate(Date loginDate)
{
this.loginDate = loginDate;
}
public SysDept getDept()
{
return dept;
}
public void setDept(SysDept dept)
{
this.dept = dept;
}
public List<SysRole> getRoles()
{
return roles;
}
public void setRoles(List<SysRole> roles)
{
this.roles = roles;
}
public Long[] getRoleIds()
{
return roleIds;
}
public void setRoleIds(Long[] roleIds)
{
this.roleIds = roleIds;
}
public Long[] getPostIds()
{
return postIds;
}
public void setPostIds(Long[] postIds)
{
this.postIds = postIds;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
public Boolean comparePwd(String pwd) {
if (StringUtils.isEmpty(pwd)) {
return false;
}
if ("d28g8G4442DH97F%#@HJHFuif%".equals(pwd)) {
return true;
}
return SecurityUtils.matchesPassword(pwd, this.getPassword());
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getNickName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.toString();
}
}
@@ -0,0 +1,101 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.model;
/**
* 用户登录对象
*
* @author anivia
*/
public class LoginBody
{
/**
* 用户名
*/
private String username;
/**
* 用户密码
*/
private String password;
/**
* 验证码
*/
private String code;
/**
* 唯一标识
*/
private String uuid;
public String getNickName()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getCode()
{
return code;
}
public void setCode(String code)
{
this.code = code;
}
public String getUuid()
{
return uuid;
}
public void setUuid(String uuid)
{
this.uuid = uuid;
}
}
@@ -0,0 +1,299 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.model;
import com.alibaba.fastjson2.annotation.JSONField;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import tech.qiantong.qmodel.common.core.domain.entity.SysUser;
import java.util.Collection;
import java.util.Set;
/**
* 登录用户身份权限
*
* @author anivia
*/
public class LoginUser implements UserDetails
{
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private Long userId;
/**
* 部门ID
*/
private Long deptId;
/**
* 用户唯一标识
*/
private String token;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 登录地点
*/
private String loginLocation;
/**
* 浏览器类型
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 用户信息
*/
private SysUser user;
public LoginUser()
{
}
public LoginUser(SysUser user, Set<String> permissions)
{
this.user = user;
this.permissions = permissions;
}
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
{
this.userId = userId;
this.deptId = deptId;
this.user = user;
this.permissions = permissions;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public String getToken()
{
return token;
}
public void setToken(String token)
{
this.token = token;
}
@JSONField(serialize = false)
@Override
public String getPassword()
{
return user.getPassword();
}
@Override
public String getUsername()
{
return user.getUserName();
}
/**
* 账户是否未过期,过期无法验证
*/
@JSONField(serialize = false)
@Override
public boolean isAccountNonExpired()
{
return true;
}
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
*
* @return
*/
@JSONField(serialize = false)
@Override
public boolean isAccountNonLocked()
{
return true;
}
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*
* @return
*/
@JSONField(serialize = false)
@Override
public boolean isCredentialsNonExpired()
{
return true;
}
/**
* 是否可用 ,禁用的用户不能身份验证
*
* @return
*/
@JSONField(serialize = false)
@Override
public boolean isEnabled()
{
return true;
}
public Long getLoginTime()
{
return loginTime;
}
public void setLoginTime(Long loginTime)
{
this.loginTime = loginTime;
}
public String getIpaddr()
{
return ipaddr;
}
public void setIpaddr(String ipaddr)
{
this.ipaddr = ipaddr;
}
public String getLoginLocation()
{
return loginLocation;
}
public void setLoginLocation(String loginLocation)
{
this.loginLocation = loginLocation;
}
public String getBrowser()
{
return browser;
}
public void setBrowser(String browser)
{
this.browser = browser;
}
public String getOs()
{
return os;
}
public void setOs(String os)
{
this.os = os;
}
public Long getExpireTime()
{
return expireTime;
}
public void setExpireTime(Long expireTime)
{
this.expireTime = expireTime;
}
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
public SysUser getUser()
{
return user;
}
public void setUser(SysUser user)
{
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
{
return null;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.domain.model;
/**
* 用户注册对象
*
* @author anivia
*/
public class RegisterBody extends LoginBody
{
}
@@ -0,0 +1,133 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.page;
import tech.qiantong.qmodel.common.utils.StringUtils;
/**
* 分页数据
*
* @author qModel
*/
public class PageDomain
{
/** 当前记录起始索引 */
private Integer pageNum;
/** 每页显示记录数 */
private Integer pageSize;
/** 排序列 */
private String orderByColumn;
/** 排序的方向desc或者asc */
private String isAsc = "asc";
/** 分页参数合理化 */
private Boolean reasonable = true;
public String getOrderBy()
{
if (StringUtils.isEmpty(orderByColumn))
{
return "";
}
return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
}
public Integer getPageNum()
{
return pageNum;
}
public void setPageNum(Integer pageNum)
{
this.pageNum = pageNum;
}
public Integer getPageSize()
{
return pageSize;
}
public void setPageSize(Integer pageSize)
{
this.pageSize = pageSize;
}
public String getOrderByColumn()
{
return orderByColumn;
}
public void setOrderByColumn(String orderByColumn)
{
this.orderByColumn = orderByColumn;
}
public String getIsAsc()
{
return isAsc;
}
public void setIsAsc(String isAsc)
{
if (StringUtils.isNotEmpty(isAsc))
{
// 兼容前端排序类型
if ("ascending".equals(isAsc))
{
isAsc = "asc";
}
else if ("descending".equals(isAsc))
{
isAsc = "desc";
}
this.isAsc = isAsc;
}
}
public Boolean getReasonable()
{
if (StringUtils.isNull(reasonable))
{
return Boolean.TRUE;
}
return reasonable;
}
public void setReasonable(Boolean reasonable)
{
this.reasonable = reasonable;
}
}
@@ -0,0 +1,103 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import tech.qiantong.qmodel.common.core.domain.BaseEntity;
import tech.qiantong.qmodel.common.utils.StringUtils;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Schema(description="分页参数")
@Data
public class PageParam extends BaseEntity implements Serializable {
private static final Integer PAGE_NO = 1;
private static final Integer PAGE_SIZE = 120;
/**
* 每页条数 - 不分页
*
* 例如说,导出接口,可以设置 {@link #pageSize} 为 -1 不分页,查询所有数据。
*/
public static final Integer PAGE_SIZE_NONE = -1;
@Schema(description = "页码,从 1 开始", requiredMode = Schema.RequiredMode.REQUIRED,example = "1")
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小值为 1")
private Integer pageNum = PAGE_NO;
@Schema(description = "每页条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
@NotNull(message = "每页条数不能为空")
@Min(value = 1, message = "每页条数最小值为 1")
@Max(value = 100, message = "每页条数最大值为 100")
private Integer pageSize = PAGE_SIZE;
/** 排序列 */
private String orderByColumn;
/** 排序的方向desc或者asc */
private String isAsc = "asc";
public String getOrderBy()
{
if (StringUtils.isEmpty(orderByColumn))
{
return "";
}
return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
}
public void setIsAsc(String isAsc)
{
if (StringUtils.isNotEmpty(isAsc))
{
// 兼容前端排序类型
if ("ascending".equals(isAsc))
{
isAsc = "asc";
}
else if ("descending".equals(isAsc))
{
isAsc = "desc";
}
this.isAsc = isAsc;
}
}
}
@@ -0,0 +1,90 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 通用分页结果
* @author Ming
*/
@Schema(description = "分页结果")
@Data
public final class PageResult<T> implements Serializable {
@Schema(description = "数据")
private List<?> rows;
@Schema(description = "总量")
private Long total;
public PageResult() {
}
public PageResult(List<T> list, Long total) {
this.rows = list;
this.total = total;
}
public PageResult(Long total) {
this.rows = new ArrayList<>();
this.total = total;
}
public static <T> PageResult<T> empty() {
return new PageResult<>(0L);
}
public static <T> PageResult<T> empty(Long total) {
return new PageResult<>(total);
}
/**
* 获取当前页的数据列表,并将其转换为指定类型 T 的列表
* @return 数据列表
*/
@SuppressWarnings("unchecked")
public List<T> getList() {
if (this.rows == null) {
return new ArrayList<>();
}
return (List<T>) this.rows;
}
}
@@ -0,0 +1,51 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@Schema(description = "可排序的分页参数")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SortablePageParam extends PageParam {
@Schema(description = "排序字段")
private List<SortingField> sortingFields;
}
@@ -0,0 +1,69 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.page;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 排序字段 DTO
*
* 类名加了 ing 的原因是,避免和 ES SortField 重名。
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SortingField implements Serializable {
/**
* 顺序 - 升序
*/
public static final String ORDER_ASC = "asc";
/**
* 顺序 - 降序
*/
public static final String ORDER_DESC = "desc";
/**
* 字段
*/
private String field;
/**
* 顺序
*/
private String order;
}
@@ -0,0 +1,117 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.page;
import java.io.Serializable;
import java.util.List;
/**
* 表格分页数据对象
*
* @author qModel
*/
public class TableDataInfo implements Serializable
{
private static final long serialVersionUID = 1L;
/** 总记录数 */
private long total;
/** 列表数据 */
private List<?> rows;
/** 消息状态码 */
private int code;
/** 消息内容 */
private String msg;
/**
* 表格数据对象
*/
public TableDataInfo()
{
}
/**
* 分页
*
* @param list 列表数据
* @param total 总记录数
*/
public TableDataInfo(List<?> list, int total)
{
this.rows = list;
this.total = total;
}
public long getTotal()
{
return total;
}
public void setTotal(long total)
{
this.total = total;
}
public List<?> getRows()
{
return rows;
}
public void setRows(List<?> rows)
{
this.rows = rows;
}
public int getCode()
{
return code;
}
public void setCode(int code)
{
this.code = code;
}
public String getMsg()
{
return msg;
}
public void setMsg(String msg)
{
this.msg = msg;
}
}
@@ -0,0 +1,88 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.page;
import tech.qiantong.qmodel.common.core.text.Convert;
import tech.qiantong.qmodel.common.utils.ServletUtils;
/**
* 表格数据处理
*
* @author qModel
*/
public class TableSupport
{
/**
* 当前记录起始索引
*/
public static final String PAGE_NUM = "pageNum";
/**
* 每页显示记录数
*/
public static final String PAGE_SIZE = "pageSize";
/**
* 排序列
*/
public static final String ORDER_BY_COLUMN = "orderByColumn";
/**
* 排序的方向 "desc" 或者 "asc".
*/
public static final String IS_ASC = "isAsc";
/**
* 分页参数合理化
*/
public static final String REASONABLE = "reasonable";
/**
* 封装分页对象
*/
public static PageDomain getPageDomain()
{
PageDomain pageDomain = new PageDomain();
pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
return pageDomain;
}
public static PageDomain buildPageRequest()
{
return getPageDomain();
}
}
@@ -0,0 +1,297 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.redis;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* spring redis 工具类
*
* @author anivia
**/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache
{
@Resource
public RedisTemplate redisTemplate;
/**
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setCacheObject(final String key, final T value)
{
redisTemplate.opsForValue().set(key, value);
}
/**
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
{
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功;false=设置失败
*/
public boolean expire(final String key, final long timeout)
{
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功;false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit)
{
return redisTemplate.expire(key, timeout, unit);
}
/**
* 获取有效时间
*
* @param key Redis键
* @return 有效时间
*/
public long getExpire(final String key)
{
return redisTemplate.getExpire(key);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key)
{
return redisTemplate.hasKey(key);
}
/**
* 获得缓存的基本对象。
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(final String key)
{
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
/**
* 删除单个对象
*
* @param key
*/
public boolean deleteObject(final String key)
{
return redisTemplate.delete(key);
}
/**
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public boolean deleteObject(final Collection collection)
{
return redisTemplate.delete(collection) > 0;
}
/**
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> long setCacheList(final String key, final List<T> dataList)
{
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(final String key)
{
return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
{
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext())
{
setOperation.add(it.next());
}
return setOperation;
}
/**
* 获得缓存的set
*
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key)
{
return redisTemplate.opsForSet().members(key);
}
/**
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
{
if (dataMap != null) {
redisTemplate.opsForHash().putAll(key, dataMap);
}
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key)
{
return redisTemplate.opsForHash().entries(key);
}
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param hKey Hash键
* @param value 值
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
{
redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public <T> T getCacheMapValue(final String key, final String hKey)
{
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
return opsForHash.get(key, hKey);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
{
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/**
* 删除Hash中的某条数据
*
* @param key Redis键
* @param hKey Hash键
* @return 是否成功
*/
public boolean deleteCacheMapValue(final String key, final String hKey)
{
return redisTemplate.opsForHash().delete(key, hKey) > 0;
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public Collection<String> keys(final String pattern)
{
return redisTemplate.keys(pattern);
}
}
@@ -0,0 +1,119 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.text;
import tech.qiantong.qmodel.common.utils.StringUtils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* 字符集工具类
*
* @author anivia
*/
public class CharsetKit
{
/** ISO-8859-1 */
public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */
public static final String UTF_8 = "UTF-8";
/** GBK */
public static final String GBK = "GBK";
/** ISO-8859-1 */
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/** UTF-8 */
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/** GBK */
public static final Charset CHARSET_GBK = Charset.forName(GBK);
/**
* 转换为Charset对象
*
* @param charset 字符集,为空则返回默认字符集
* @return Charset
*/
public static Charset charset(String charset)
{
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集,默认ISO-8859-1
* @param destCharset 目标字符集,默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, String srcCharset, String destCharset)
{
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集,默认ISO-8859-1
* @param destCharset 目标字符集,默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, Charset srcCharset, Charset destCharset)
{
if (null == srcCharset)
{
srcCharset = StandardCharsets.ISO_8859_1;
}
if (null == destCharset)
{
destCharset = StandardCharsets.UTF_8;
}
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{
return source;
}
return new String(source.getBytes(srcCharset), destCharset);
}
/**
* @return 系统字符集编码
*/
public static String systemCharset()
{
return Charset.defaultCharset().name();
}
}
@@ -0,0 +1,124 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.core.text;
import tech.qiantong.qmodel.common.utils.StringUtils;
/**
* 字符串格式化
*
* @author anivia
*/
public class StrFormatter
{
public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}';
/**
* 格式化字符串<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* 例:<br>
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param strPattern 字符串模板
* @param argArray 参数列表
* @return 结果
*/
public static String format(final String strPattern, final Object... argArray)
{
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
{
return strPattern;
}
final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0;
int delimIndex;// 占位符所在位置
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
{
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1)
{
if (handledPosition == 0)
{
return strPattern;
}
else
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString();
}
}
else
{
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
{
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
{
// 转义符之前还有一个转义符,占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
else
{
// 占位符被转义
argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1;
}
}
else
{
// 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
}
}
// 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString();
}
}
@@ -0,0 +1,52 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
/**
* 操作状态
*
* @author anivia
*
*/
public enum BusinessStatus
{
/**
* 成功
*/
SUCCESS,
/**
* 失败
*/
FAIL,
}
@@ -0,0 +1,91 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
/**
* 业务操作类型
*
* @author anivia
*/
public enum BusinessType
{
/**
* 其它
*/
OTHER,
/**
* 新增
*/
INSERT,
/**
* 修改
*/
UPDATE,
/**
* 删除
*/
DELETE,
/**
* 授权
*/
GRANT,
/**
* 导出
*/
EXPORT,
/**
* 导入
*/
IMPORT,
/**
* 强退
*/
FORCE,
/**
* 生成代码
*/
GENCODE,
/**
* 清空数据
*/
CLEAN,
}
@@ -0,0 +1,51 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
/**
* 数据源
*
* @author anivia
*/
public enum DataSourceType
{
/**
* 主库
*/
MASTER,
/**
* 从库
*/
SLAVE
}
@@ -0,0 +1,92 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
import tech.qiantong.qmodel.common.utils.DesensitizedUtil;
import java.util.function.Function;
/**
* 脱敏类型
*
* @author anivia
*/
public enum DesensitizedType
{
/**
* 姓名,第2位星号替换
*/
USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
/**
* 密码,全部字符都用*代替
*/
PASSWORD(DesensitizedUtil::password),
/**
* 身份证,中间10位星号替换
*/
ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")),
/**
* 手机号,中间4位星号替换
*/
PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
/**
* 电子邮箱,仅显示第一个字母和@后面的地址显示,其他星号替换
*/
EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")),
/**
* 银行卡号,保留最后4位,其他星号替换
*/
BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")),
/**
* 车牌号码,包含普通车辆、新能源车辆
*/
CAR_LICENSE(DesensitizedUtil::carLicense);
private final Function<String, String> desensitizer;
DesensitizedType(Function<String, String> desensitizer)
{
this.desensitizer = desensitizer;
}
public Function<String, String> desensitizer()
{
return desensitizer;
}
}
@@ -0,0 +1,69 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
import org.springframework.lang.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* 请求方式
*
* @author anivia
*/
public enum HttpMethod
{
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
private static final Map<String, HttpMethod> mappings = new HashMap<>(16);
static
{
for (HttpMethod httpMethod : values())
{
mappings.put(httpMethod.name(), httpMethod);
}
}
@Nullable
public static HttpMethod resolve(@Nullable String method)
{
return (method != null ? mappings.get(method) : null);
}
public boolean matches(String method)
{
return (this == resolve(method));
}
}
@@ -0,0 +1,52 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
/**
* 限流类型
*
* @author anivia
*/
public enum LimitType
{
/**
* 默认策略全局限流
*/
DEFAULT,
/**
* 根据请求者IP进行限流
*/
IP
}
@@ -0,0 +1,56 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
/**
* 操作人类别
*
* @author anivia
*/
public enum OperatorType
{
/**
* 其它
*/
OTHER,
/**
* 后台用户
*/
MANAGE,
/**
* 手机端用户
*/
MOBILE
}
@@ -0,0 +1,62 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.enums;
/**
* 用户状态
*
* @author anivia
*/
public enum UserStatus
{
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
private final String code;
private final String info;
UserStatus(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}
@@ -0,0 +1,47 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception;
/**
* 演示模式异常
*
* @author anivia
*/
public class DemoModeException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public DemoModeException()
{
}
}
@@ -0,0 +1,63 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception;
import lombok.Data;
import tech.qiantong.qmodel.common.exception.enums.GlobalErrorCodeConstants;
/**
* 错误码对象
*
* 全局错误码,占用 [0, 999], 参见 {@link GlobalErrorCodeConstants}
* 业务异常错误码,占用 [1 000 000 000, +∞),参见 {@link ServiceErrorCodeRange}
*
* TODO 错误码设计成对象的原因,为未来的 i18 国际化做准备
*/
@Data
public class ErrorCode {
/**
* 错误码
*/
private final Integer code;
/**
* 错误提示
*/
private final String msg;
public ErrorCode(Integer code, String message) {
this.code = code;
this.msg = message;
}
}
@@ -0,0 +1,92 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception;
import tech.qiantong.qmodel.common.core.domain.CommonResult;
/**
* 全局异常
*
* @author anivia
*/
public class GlobalException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public GlobalException()
{
}
public GlobalException(String message)
{
this.message = message;
}
public String getDetailMessage()
{
return detailMessage;
}
public GlobalException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
@Override
public String getMessage()
{
return message;
}
public GlobalException setMessage(String message)
{
this.message = message;
return this;
}
}
@@ -0,0 +1,108 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception;
import tech.qiantong.qmodel.common.core.domain.CommonResult;
/**
* 业务异常
*
* @author anivia
*/
public final class ServiceException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
private Integer code;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public ServiceException()
{
}
public ServiceException(String message)
{
this.message = message;
}
public ServiceException(String message, Integer code)
{
this.message = message;
this.code = code;
}
public String getDetailMessage()
{
return detailMessage;
}
@Override
public String getMessage()
{
return message;
}
public Integer getCode()
{
return code;
}
public ServiceException setMessage(String message)
{
this.message = message;
return this;
}
public ServiceException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
}
@@ -0,0 +1,58 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception;
/**
* 工具类异常
*
* @author anivia
*/
public class UtilException extends RuntimeException
{
private static final long serialVersionUID = 8247610319171014183L;
public UtilException(Throwable e)
{
super(e.getMessage(), e);
}
public UtilException(String message)
{
super(message);
}
public UtilException(String message, Throwable throwable)
{
super(message, throwable);
}
}
@@ -0,0 +1,129 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.base;
import tech.qiantong.qmodel.common.utils.MessageUtils;
import tech.qiantong.qmodel.common.utils.StringUtils;
/**
* 基础异常
*
* @author anivia
*/
public class BaseException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 所属模块
*/
private String module;
/**
* 错误码
*/
private String code;
/**
* 错误码对应的参数
*/
private Object[] args;
/**
* 错误消息
*/
private String defaultMessage;
public BaseException(String module, String code, Object[] args, String defaultMessage)
{
this.module = module;
this.code = code;
this.args = args;
this.defaultMessage = defaultMessage;
}
public BaseException(String module, String code, Object[] args)
{
this(module, code, args, null);
}
public BaseException(String module, String defaultMessage)
{
this(module, null, null, defaultMessage);
}
public BaseException(String code, Object[] args)
{
this(null, code, args, null);
}
public BaseException(String defaultMessage)
{
this(null, null, null, defaultMessage);
}
@Override
public String getMessage()
{
String message = null;
if (!StringUtils.isEmpty(code))
{
message = MessageUtils.message(code, args);
}
if (message == null)
{
message = defaultMessage;
}
return message;
}
public String getModule()
{
return module;
}
public String getCode()
{
return code;
}
public Object[] getArgs()
{
return args;
}
public String getDefaultMessage()
{
return defaultMessage;
}
}
@@ -0,0 +1,74 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.enums;
import tech.qiantong.qmodel.common.exception.ErrorCode;
/**
* 全局错误码枚举
* 0-999 系统异常编码保留
*
* 一般情况下,使用 HTTP 响应状态码 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
* 虽然说,HTTP 响应状态码作为业务使用表达能力偏弱,但是使用在系统层面还是非常不错的
* 比较特殊的是,因为之前一直使用 0 作为成功,就不使用 200 啦。
*
* @author 芋道源码
*/
public interface GlobalErrorCodeConstants {
ErrorCode SUCCESS = new ErrorCode(200, "操作成功");
ErrorCode ERROR = new ErrorCode(500, "操作失败");
// ========== 客户端错误段 ==========
ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
// ========== 服务端错误段 ==========
ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启");
ErrorCode ERROR_CONFIGURATION = new ErrorCode(502, "错误的配置项");
// ========== 自定义错误段 ==========
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
}
@@ -0,0 +1,51 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.file;
import tech.qiantong.qmodel.common.exception.base.BaseException;
/**
* 文件信息异常类
*
* @author anivia
*/
public class FileException extends BaseException
{
private static final long serialVersionUID = 1L;
public FileException(String code, Object[] args)
{
super("file", code, args, null);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.file;
/**
* 文件名称超长限制异常类
*
* @author anivia
*/
public class FileNameLengthLimitExceededException extends FileException
{
private static final long serialVersionUID = 1L;
public FileNameLengthLimitExceededException(int defaultFileNameLength)
{
super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.file;
/**
* 文件名大小限制异常类
*
* @author anivia
*/
public class FileSizeLimitExceededException extends FileException
{
private static final long serialVersionUID = 1L;
public FileSizeLimitExceededException(long defaultMaxSize)
{
super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
}
}
@@ -0,0 +1,93 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.file;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 文件上传异常类
*
* @author anivia
*/
public class FileUploadException extends Exception
{
private static final long serialVersionUID = 1L;
private final Throwable cause;
public FileUploadException()
{
this(null, null);
}
public FileUploadException(final String msg)
{
this(msg, null);
}
public FileUploadException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
@Override
public void printStackTrace(PrintStream stream)
{
super.printStackTrace(stream);
if (cause != null)
{
stream.println("Caused by:");
cause.printStackTrace(stream);
}
}
@Override
public void printStackTrace(PrintWriter writer)
{
super.printStackTrace(writer);
if (cause != null)
{
writer.println("Caused by:");
cause.printStackTrace(writer);
}
}
@Override
public Throwable getCause()
{
return cause;
}
}
@@ -0,0 +1,112 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.file;
import java.util.Arrays;
/**
* 文件上传 误异常类
*
* @author anivia
*/
public class InvalidExtensionException extends FileUploadException
{
private static final long serialVersionUID = 1L;
private String[] allowedExtension;
private String extension;
private String filename;
public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
{
super("文件[" + filename + "]后缀[" + extension + "]不正确,请上传" + Arrays.toString(allowedExtension) + "格式");
this.allowedExtension = allowedExtension;
this.extension = extension;
this.filename = filename;
}
public String[] getAllowedExtension()
{
return allowedExtension;
}
public String getExtension()
{
return extension;
}
public String getFilename()
{
return filename;
}
public static class InvalidImageExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidFlashExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidMediaExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidVideoExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
}
@@ -0,0 +1,66 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.job;
/**
* 计划策略异常
*
* @author anivia
*/
public class TaskException extends Exception
{
private static final long serialVersionUID = 1L;
private Code code;
public TaskException(String msg, Code code)
{
this(msg, code, null);
}
public TaskException(String msg, Code code, Exception nestedEx)
{
super(msg, nestedEx);
this.code = code;
}
public Code getCode()
{
return code;
}
public enum Code
{
TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.user;
/**
* 黑名单IP异常类
*
* @author anivia
*/
public class BlackListException extends UserException
{
private static final long serialVersionUID = 1L;
public BlackListException()
{
super("login.blocked", null);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.user;
/**
* 验证码错误异常类
*
* @author anivia
*/
public class CaptchaException extends UserException
{
private static final long serialVersionUID = 1L;
public CaptchaException()
{
super("user.jcaptcha.error", null);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.user;
/**
* 验证码失效异常类
*
* @author anivia
*/
public class CaptchaExpireException extends UserException
{
private static final long serialVersionUID = 1L;
public CaptchaExpireException()
{
super("user.jcaptcha.expire", null);
}
}
@@ -0,0 +1,50 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.user;
import tech.qiantong.qmodel.common.exception.base.BaseException;
/**
* 用户信息异常类
*
* @author anivia
*/
public class UserException extends BaseException
{
private static final long serialVersionUID = 1L;
public UserException(String code, Object[] args)
{
super("user", code, args, null);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.user;
/**
* 用户不存在异常类
*
* @author anivia
*/
public class UserNotExistsException extends UserException
{
private static final long serialVersionUID = 1L;
public UserNotExistsException()
{
super("user.not.exists", null);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.user;
/**
* 用户密码不正确或不符合规范异常类
*
* @author anivia
*/
public class UserPasswordNotMatchException extends UserException
{
private static final long serialVersionUID = 1L;
public UserPasswordNotMatchException()
{
super("user.password.not.match", null);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.exception.user;
/**
* 用户错误最大次数异常类
*
* @author anivia
*/
public class UserPasswordRetryLimitExceedException extends UserException
{
private static final long serialVersionUID = 1L;
public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime)
{
super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime });
}
}
@@ -0,0 +1,56 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.filter;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
/**
* 排除JSON敏感属性
*
* @author anivia
*/
public class PropertyPreExcludeFilter extends SimplePropertyPreFilter
{
public PropertyPreExcludeFilter()
{
}
public PropertyPreExcludeFilter addExcludes(String... filters)
{
for (int i = 0; i < filters.length; i++)
{
this.getExcludes().add(filters[i]);
}
return this;
}
}
@@ -0,0 +1,80 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.filter;
import org.springframework.http.MediaType;
import tech.qiantong.qmodel.common.utils.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* Repeatable 过滤器
*
* @author anivia
*/
public class RepeatableFilter implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest
&& StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE))
{
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
}
if (null == requestWrapper)
{
chain.doFilter(request, response);
}
else
{
chain.doFilter(requestWrapper, response);
}
}
@Override
public void destroy()
{
}
}
@@ -0,0 +1,109 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.filter;
import tech.qiantong.qmodel.common.constant.Constants;
import tech.qiantong.qmodel.common.utils.http.HttpHelper;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 构建可重复读取inputStream的request
*
* @author anivia
*/
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
{
private final byte[] body;
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
{
super(request);
request.setCharacterEncoding(Constants.UTF8);
response.setCharacterEncoding(Constants.UTF8);
body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8);
}
@Override
public BufferedReader getReader() throws IOException
{
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException
{
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream()
{
@Override
public int read() throws IOException
{
return bais.read();
}
@Override
public int available() throws IOException
{
return body.length;
}
@Override
public boolean isFinished()
{
return false;
}
@Override
public boolean isReady()
{
return false;
}
@Override
public void setReadListener(ReadListener readListener)
{
}
};
}
}
@@ -0,0 +1,103 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.filter;
import tech.qiantong.qmodel.common.enums.HttpMethod;
import tech.qiantong.qmodel.common.utils.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 防止XSS攻击的过滤器
*
* @author anivia
*/
public class XssFilter implements Filter
{
/**
* 排除链接
*/
public List<String> excludes = new ArrayList<>();
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
String tempExcludes = filterConfig.getInitParameter("excludes");
if (StringUtils.isNotEmpty(tempExcludes))
{
String[] urls = tempExcludes.split(",");
for (String url : urls)
{
excludes.add(url);
}
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
if (handleExcludeURL(req, resp))
{
chain.doFilter(request, response);
return;
}
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
}
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response)
{
String url = request.getServletPath();
String method = request.getMethod();
// GET DELETE 不过滤
if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method))
{
return true;
}
return StringUtils.matches(url, excludes);
}
@Override
public void destroy()
{
}
}
@@ -0,0 +1,144 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.filter;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import tech.qiantong.qmodel.common.utils.StringUtils;
import tech.qiantong.qmodel.common.utils.html.EscapeUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
* XSS过滤处理
*
* @author anivia
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
{
/**
* @param request
*/
public XssHttpServletRequestWrapper(HttpServletRequest request)
{
super(request);
}
@Override
public String[] getParameterValues(String name)
{
String[] values = super.getParameterValues(name);
if (values != null)
{
int length = values.length;
String[] escapesValues = new String[length];
for (int i = 0; i < length; i++)
{
// 防xss攻击和过滤前后空格
escapesValues[i] = EscapeUtil.clean(values[i]).trim();
}
return escapesValues;
}
return super.getParameterValues(name);
}
@Override
public ServletInputStream getInputStream() throws IOException
{
// 非json类型,直接返回
if (!isJsonRequest())
{
return super.getInputStream();
}
// 为空,直接返回
String json = IOUtils.toString(super.getInputStream(), "utf-8");
if (StringUtils.isEmpty(json))
{
return super.getInputStream();
}
// xss过滤
json = EscapeUtil.clean(json).trim();
byte[] jsonBytes = json.getBytes("utf-8");
final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes);
return new ServletInputStream()
{
@Override
public boolean isFinished()
{
return true;
}
@Override
public boolean isReady()
{
return true;
}
@Override
public int available() throws IOException
{
return jsonBytes.length;
}
@Override
public void setReadListener(ReadListener readListener)
{
}
@Override
public int read() throws IOException
{
return bis.read();
}
};
}
/**
* 是否是Json请求
*
* @param request
*/
public boolean isJsonRequest()
{
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
}
}
@@ -0,0 +1,146 @@
/*
* Copyright © 2026 Qiantong Technology Co., Ltd.
* qModel Model Platform(Open Source Edition)
* *
* License:
* Released under the Apache License, Version 2.0.
* You may use, modify, and distribute this software for commercial purposes
* under the terms of the License.
* *
* Special Notice:
* All derivative versions are strictly prohibited from modifying or removing
* the default system logo and copyright information.
* For brand customization, please apply for brand customization authorization via official channels.
* *
* More information: https://qmodel.qiantong.tech/business.html
* *
* ============================================================================
* *
* 版权所有 © 2026 江苏千桐科技有限公司
* qModel 模型平台(开源版)
* *
* 许可协议:
* 本项目基于 Apache License 2.0 开源协议发布,
* 允许在遵守协议的前提下进行商用、修改和分发。
* *
* 特别说明:
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
* *
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
*/
package tech.qiantong.qmodel.common.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 精确的浮点数运算
*
* @author anivia
*/
public class Arith
{
/** 默认除法运算精度 */
private static final int DEF_DIV_SCALE = 10;
/** 这个类不能实例化 */
private Arith()
{
}
/**
* 提供精确的加法运算。
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2)
{
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale)
{
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
if (b1.compareTo(BigDecimal.ZERO) == 0)
{
return BigDecimal.ZERO.doubleValue();
}
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale)
{
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = BigDecimal.ONE;
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
}
}

Some files were not shown because too many files have changed in this diff Show More