同步工作目录变更:移除已删除的 qModel 等目录

This commit is contained in:
zdh
2026-05-14 18:21:17 +08:00
parent acca2041f0
commit 61999dd416
1627 changed files with 0 additions and 262487 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 672 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 KiB

-61
View File
@@ -1,61 +0,0 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
/.idea/
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
!*/qmodel-ui/dist/
!*/qmodel-ui/node_modules/
/qmodel-ui/dist/
/qmodel-ui/node_modules/
!*/resources/static
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml
### 组件库编译后的文件 ###
storybook-static/
### Mac ###
.DS_Store
# 忽略 upload 目录下的所有内容
/upload/
-18
View File
@@ -1,18 +0,0 @@
# Open Source License
qModel is licensed under a modified version of the Apache License 2.0, with the following additional conditions:
1. qModel may be utilized commercially, including as a backend service for other applications or as an application development platform for enterprises. Should the conditions below be met, a commercial license must be obtained from the producer:
a. LOGO and copyright information: In the process of using qModel's frontend, you may not remove or modify the LOGO or copyright information in the qModel console or applications.
2. As a contributor, you should agree that:
a. The producer can adjust the open-source agreement to be more strict or relaxed as deemed necessary.
b. Your contributed code may be used for commercial purposes, including but not limited to its cloud business operations.
Apart from the specific conditions mentioned above, all other rights and restrictions follow the Apache License 2.0. Detailed information about the Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0.
The interactive design of this product is protected by appearance patent.
© 2025 Jiangsu Qiantong Technology Co., Ltd
-208
View File
@@ -1,208 +0,0 @@
# 🚀 qModel模型管理平台 快速开始指南
---
## 一、准备工作 <small>(必备环境)</small>
在运行系统之前,请确保您已安装以下环境:
| 软件/工具 | 版本要求 | 推荐版本 |
|:---------------------------------------------------------------------------------------------------------------------:|:--------:|:------:|
| <img src="https://img.icons8.com/color/48/000000/java-coffee-cup-logo.png" width="24"/> JDK | >= 1.8 | 1.8 |
| <img src="https://img.icons8.com/color/48/000000/mysql-logo.png" width="24"/> MySQL | >= 5.7.0 | 5.7 |
| <img src="https://dist.neo4j.com/wp-content/uploads/20230926084108/Logo_FullColor_RGB_TransBG.svg" width="24"/> Neo4j | 4.x | 4.4.40 |
| <img src="https://img.icons8.com/color/48/000000/redis.png" width="24"/> Redis | >= 5.0 | 5.0 |
| <img src="https://img.icons8.com/?size=100&id=jfjmkTUFX5Vf&format=png" width="24"/> Maven | >= 3.6 | 3.6 |
| <img src="https://img.icons8.com/color/48/000000/nodejs.png" width="24"/> Node.js | >= 16 | 16 |
> **提示**: 前端安装完 `Node.js` 后,建议设置淘宝镜像源以提升依赖包下载速度。不推荐使用 `cnpm`,可能会引入一些不可预知的问题。
>
> ```bash
> npm config set registry https://registry.npmmirror.com
> ```
---
## 二、获取项目代码 <small>(下载与解压)</small>
前往 【[qKnow Gitee 下载页面](https://gitee.com/qiantongtech/qModel)】 下载项目并解压到您的工作目录。
---
## 三、目录结构
### 2.1 项目结构;
```
├─qmodel-framework # 公共配置模块
├─ ├─qmodel-auth # oauth2模块
├─ ├─qmodel-common # 共通模块
├─ ├─qmodel-config # 配置模块
├─ ├─qmodel-es # es模块
├─ ├─qmodel-file # 文件管理模块
├─ ├─qmodel-generator # 代码生成器
├─ ├─qmodel-mybatis # mybatis配置
├─ ├─qmodel-pay # 支付模块
├─ ├─qmodel-quartz # 定时任务模块
├─ ├─qmodel-redis # redis模块
├─ ├─qmodel-security # security模块
├─ ├─qmodel-websocket # websocket模块
├─qmodel-module-model # 模型管理模块
├─qmodel-module-system # 系统管理模块
├─qmodel-server # 启动项目
├─qmodel-ui # 前端模块
├─sql # sql脚本
├─README.md # 相关介绍
├─QUICKSTART.md # 快速启动
```
### 2.2 前端结构;
```
├─qmodel-ui # 前端模块
├─ ├─public # 静态资源目录
├─ ├─src
├─ | ├─api # 接口
├─ | ├─assets # 图片、样式等资源
├─ | ├─components # 通用组件
├─ | ├─layout # 布局
├─ | ├─plugins # 插件
├─ | ├─router # 路由
├─ | ├─store # 状态管理
├─ | ├─utils # 工具类
├─ | ├─views # 页面视图
├─ | | ├─example # 示例模块(未使用)
├─ | | ├─flyflow # 工作流模块(未使用)
├─ | | ├─model # 模型管理模块
├─ | | ├─system # 系统管理模块
├─ ├─.env.development # 开发环境配置
├─ ├─.env.production # 生产环境配置
├─ ├─vite.config.js # Vite配置文件
```
---
## 四、必要配置 <small>(数据库与服务配置)</small>
### 1. 创建达梦数据库并导入数据
- 创建 达梦 数据库:`QMODEL_DEV`
- 导入数据脚本:`qModel-2025-12-30.sql`
### 2. 修改达梦数据库连接配置
路径:`qModel/qmodel-server/src/main/resources/application-dev.yml`
```yaml
datasource:
type: dm8
dm8:
# JDBC驱动类名
driver-class-name: dm.jdbc.driver.DmDriver
# 主库JDBC连接URL
url: 数据库地址
# 主库用户名
username: 数据库账号
# 主库密码
password: 数据库密码
```
### 3. 配置服务端口和访问路径
路径:`qModel/qmodel-server/src/main/resources/application.yml`
```yaml
server:
port: 端口 # 默认为8090
servlet:
context-path: /应用路径 # 应用访问路径,默认为空
```
---
## 五、后端运行 <small>(启动服务器)</small>
1. 使用 IntelliJ IDEA 或 Eclipse 导入项目。
2. IDE 将自动加载 Maven 依赖,初次加载可能较慢。
3. 运行 `tech.qiantong.qmodel.server.QModelApplication.java`。启动成功后,可通过 `http://localhost:8090` 访问后端服务。
4. 出现以下提示,表示后端服务启动成功:
```
(♥◠‿◠)ノ゙ 千知平台启动成功 ლ(´ڡ`ლ)゙
_ __
__ _| |/ /_ __ _____ __
/ _` | ' /| '_ \ / _ \ \ /\ / /
| (_| | . \| | | | (_) \ V V /
\__, |_|\_\_| |_|\___/ \_/\_/
|_|
```
> **注意**: 仅启动后端服务不会显示静态页面,请继续部署前端服务。
---
## 七、前端运行 <small>(启动前端服务)</small>
### 1. 根据需要修改后台服务端口配置
```javascript
// vite 相关配置
server: {
port: 80,
host: true,
open: true,
proxy: {
"/dev-api": {
target: "http://localhost:8090",
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, ""),
},
}
}
```
### 2. 启动前端服务
#### 步骤 1: 进入项目目录
首先,导航到 `qmodel-ui` 目录下:
```bash
# 进入项目目录
cd qmodel-ui
```
#### 步骤 2: 安装依赖
接下来,安装项目的依赖包。这里我们使用淘宝镜像源以加速下载速度:
```bash
# 安装依赖(推荐使用淘宝镜像)
npm install --registry=https://registry.npmmirror.com
```
#### 步骤 3: 本地开发并启动项目
最后,运行以下命令来启动前端开发服务器:
```bash
# 本地开发 启动项目
npm run dev
```
### 3. 测试前端服务
打开浏览器,输入 `http://localhost`。默认账户/密码为 `qModel/qModel123`。若能正确展示登录页面,并能成功登录,菜单及页面展示正常,则表明环境搭建成功。
> **提示**: 因为本项目是前后端完全分离的,所以需要前后端都单独启动好,才能进行访问。
---
希望这个文档能够帮助您更好地理解和操作 **qModel模型管理平台** 项目!
---
<p align="center">
<img src="https://img.icons8.com/fluent/48/000000/checkmark.png" width="36"/>
<strong>完成!</strong>
</p>
-209
View File
@@ -1,209 +0,0 @@
[banner.png](.gitee/banner.png)
<p align="center">
<img src="https://img.shields.io/badge/JDK-1.8+-brightgreen.svg" alt="JDK">
<img src="https://img.shields.io/badge/Spring%20Boot-2.5.15-blue.svg" alt="Spring Boot">
<img src="https://img.shields.io/badge/Vue-3.4.31-blue.svg" alt="Vue">
<img src="https://img.shields.io/badge/license-Apache--2.0-green" alt="License"/>
<img src="https://img.shields.io/badge/qModel-v1.0.0-blue.svg" alt="qModel"/>
<img src="https://gitee.com/qiantongtech/qModel/badge/star.svg" alt="Gitee Stars"/>
<img src="https://img.shields.io/github/stars/qiantongtech/qModel?label=Github%20Stars" alt="GitHub Stars"/>
</p>
<p align="center">
<a href="README.md">📖简体中文</a> | 📖English
</p>
## 🌈 Introduction
**qModel** is an open-source model management platform centered around **full lifecycle management of AI models**. It provides capabilities including model ingestion, registration, testing, deployment, computation, fusion, orchestration, and service exposure—helping enterprises and research institutions transform algorithmic assets into intelligent services that are operable, reusable, and governable.
The platform supports multiple model formats such as Python scripts, Java JARs, and executable binaries (`exe`), bridging the engineering gap from experimentation to production, and serving as a robust foundation for collaborative applications involving traditional algorithms.
✨✨✨**Live Demo**✨✨✨
<a href="demo.qmodel.tech" target="_blank">demo.qmodel.tech</a>
(Username: `qModel`, Password: `qModel123`)
> **qModel — Empowering models throughout their full lifecycle, driving continuous value through intelligence.**
## 🍱 Typical Use Cases
| Scenario | Description |
|----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
| **AI Model Asset Management** | Centralized governance of scattered models across teams, with version control, categorization, tagging, and permission management |
| **Engineering Lab-to-Production Transition** | Rapidly package research algorithms into callable services to accelerate technology transfer |
| **Multi-Model Fusion Inference** | Supports strategies like weighted averaging, voting, and stacking to enhance prediction robustness |
| **Intelligent Workflow Orchestration** | Visually drag-and-drop to build AI workflows combining multiple models for complex business logic |
| **Private Model Marketplace** | Establish internal model sharing and trading mechanisms to promote knowledge reuse and innovation |
## 🚀 Key Advantages
- **Full lifecycle coverage**: From upload, testing, and release to monitoring and retirement—fully traceable
- **Multi-language support**: Compatible with Python, Java, executables, and more
- **Lightweight architecture**: Ready-to-run out of the box; supports one-click Docker deployment
- **Modular design**: Core features are decoupled for easy integration and secondary development
- **Open from day one**: Community-driven and continuously evolving
## ✨ Core Features
| Module | Description | Open Source Status |
|-------------------------------------|---------------------------------------------------------------------------------------------------------------------------|--------------------|
| **System Management** | Unified governance of users, roles, departments, menus, dictionaries, parameters, announcements, and logs | ✅ Implemented |
| **Model Categories** | Create and manage hierarchical model categories and tag groups | ✅ Implemented |
| **Model Management** | Register, categorize, tag, approve, publish/retire, and version-control models | ✅ Implemented |
| **Model Computation** | Manage tasks, configure parameters, visualize results, and download outputs (input data binding required manually in OSS) | ✅ Implemented |
| **Computation History** | View historical tasks; filter by model, time, status; and revisit results | ✅ Implemented |
| **Model Ingestion & Execution** | Upload multi-language models, auto-parse metadata, and perform compatibility checks | ❌ Planned |
| **Model Packaging** | Standardized packaging guidelines and documentation | ❌ Planned |
| **Service Governance & Scheduling** | Auto-generate RESTful APIs with authentication, rate limiting, concurrency control, call tracing, and watermarking | ❌ Planned |
| **Documentation Center** | Integrated developer documentation management | ❌ Planned |
> 💡 Note: Advanced features such as automated containerization, online debugging, model fusion, workflow orchestration, and training loop integration will be available in the commercial edition. Community contributions to extend the open-source version are warmly welcomed!
## 🛠️ Tech Stack
qModel adopts a frontend-backend separated architecture: Spring Boot on the backend and Vue 3 on the frontend, integrated with mainstream middleware for enterprise-grade model management.
<table>
<tr>
<th>Tech Layer</th><th>Framework</th><th>Description</th>
</tr>
<tr>
<td rowspan="6">Backend</td><td>Spring Boot</td><td>Main application framework</td>
</tr>
<tr>
<td>MyBatis-Plus</td><td>ORM for simplified database operations</td>
</tr>
<tr>
<td>Spring Security</td><td>Authentication and authorization</td>
</tr>
<tr>
<td>Quartz</td><td>Scheduled task execution (e.g., batch computations)</td>
</tr>
<tr>
<td>Alibaba Druid</td><td>High-performance database connection pool</td>
</tr>
<tr>
<td>Swagger</td><td>Auto-generated API documentation</td>
</tr>
<tr>
<td rowspan="7">Frontend</td><td>Vue 3</td><td>Reactive UI framework</td>
</tr>
<tr>
<td>Vite</td><td>Ultra-fast build tool</td>
</tr>
<tr>
<td>Element Plus</td><td>Modern UI component library</td>
</tr>
<tr>
<td>Pinia</td><td>Lightweight state management</td>
</tr>
<tr>
<td>Vue Router</td><td>Client-side routing</td>
</tr>
<tr>
<td>Axios</td><td>HTTP client for API calls</td>
</tr>
<tr>
<td>ECharts</td><td>Visualization of computation results and system metrics</td>
</tr>
<tr>
<td rowspan="4">Third-party Dependencies</td><td>MySQL</td><td>Metadata storage</td>
</tr>
<tr>
<td>Redis</td><td>Task queue and caching</td>
</tr>
<tr>
<td>Docker (optional)</td><td>Containerized deployment (auto-image building in commercial edition)</td>
</tr>
<tr>
<td>Local Storage</td><td>Store model files and computation outputs</td>
</tr>
</table>
## 🏗️ Deployment Requirements
Ensure the following environment is ready before deploying qModel:
<table>
<tr>
<th>Environment</th><th>Component</th><th>Recommended Version</th><th>Note</th>
</tr>
<tr>
<td rowspan="5">Backend</td><td>JDK</td><td>1.8+</td><td>Runtime environment</td>
</tr>
<tr>
<td>Maven</td><td>3.6+</td><td>Project build tool</td>
</tr>
<tr>
<td>MySQL</td><td>5.7 / 8.0</td><td>Metadata database</td>
</tr>
<tr>
<td>Redis</td><td>5.0+</td><td>For task queues and caching</td>
</tr>
<tr>
<td>OS</td><td>Linux / Windows / macOS</td><td>Fully supported</td>
</tr>
<tr>
<td rowspan="3">Frontend</td><td>Node.js</td><td>16+</td><td>Build dependency</td>
</tr>
<tr>
<td>pnpm / npm</td><td>Latest</td><td>Package manager</td>
</tr>
<tr>
<td>Vite</td><td>≥4.0</td><td>Build tool</td>
</tr>
</table>
## 🚨 Commercial Licensing
qModel offers both **open-source** and **commercial** editions:
- The **open-source edition** is ideal for learning, evaluation, and lightweight production use, licensed under Apache 2.0 (commercial use allowed with logo retention).
- The **commercial edition** targets enterprise and government clients, offering advanced capabilities such as **automated containerization, model fusion, visual workflow orchestration, training-in-loop, and private model marketplace**, along with dedicated technical support and private repository access.
👉 For **custom branding licensing** or **commercial trial requests**, please
<a href="https://qmodel.qiantong.tech/discuss.html">join our official QQ group for consultation</a>.
## 🚀 Quick Start
👉 <a href="./QUICKSTART.md">View Quick Deployment Guide</a>
## 👥 Community Support
Join the official qModel QQ group to stay updated, ask questions, and share experiences!
👉 <a href="https://qmodel.qiantong.tech/discuss.html">Join the QQ Group</a>
## 🖼️ Screenshots
<table>
<tr>
<td><img alt="Login Page" src=".gitee/system/login.png"/></td>
<td><img alt="Dashboard" src=".gitee/system/workbench.png"/></td>
</tr>
<tr>
<td><img alt="Model List" src=".gitee/system/modelList.png"/></td>
<td><img alt="Model Detail" src=".gitee/system/modelDetail.png"/></td>
</tr>
<tr>
<td><img alt="Compute Tasks" src=".gitee/system/taskList.png"/></td>
<td><img alt="Task History" src=".gitee/system/taskHistory.png"/></td>
</tr>
</table>
<table>
<tr>
<td><img alt="Login Page" src=".gitee/system/login.png"/></td>
<td><img alt="Dashboard" src=".gitee/system/workbench.png"/></td>
</tr>
<tr>
<td><img alt="Model Category" src=".gitee/system/modelCategory.png"/></td>
<td><img alt="Model Input" src=".gitee/system/input.png"/></td>
</tr>
<tr>
<td><img alt="Model List" src=".gitee/system/modelList.png"/></td>
<td><img alt="Compute Tasks" src=".gitee/system/taskList.png"/></td>
</tr>
</table>
-201
View File
@@ -1,201 +0,0 @@
![banner.png](.gitee/banner.png)
<p align="center">
<img src="https://img.shields.io/badge/JDK-1.8+-brightgreen.svg" alt="JDK">
<img src="https://img.shields.io/badge/Spring%20Boot-2.5.15-blue.svg" alt="Spring Boot">
<img src="https://img.shields.io/badge/Vue-3.4.31-blue.svg" alt="Vue">
<img src="https://img.shields.io/badge/license-Apache--2.0-green" alt="License"/>
<img src="https://img.shields.io/badge/qModel-v1.0.0-blue.svg" alt="qModel"/>
<img src="https://gitee.com/qiantongtech/qModel/badge/star.svg" alt="Gitee Stars"/>
<img src="https://img.shields.io/github/stars/qiantongtech/qModel?label=Github%20Stars" alt="GitHub Stars"/>
</p>
<p align="center">
📖简体中文 | <a href="README.en.md">📖English</a>
</p>
## 🌈平台简介
大模型很火,但真正支撑业务落地的,往往是小模型。qModel 模型平台,正是为了解决企业“小模型混乱症”而生。未来的竞争,不只是数据的竞争,更是模型资产的竞争——谁能把算法沉淀为**可管理、可迭代、可复用、可交易**的服务,谁就能掌握智能化的主动权。
**qModel** 是一个以 **模型全生命周期管理** 为核心的开源模型平台,提供行业算法模型接入、注册、测试、部署、计算、融合、编排与服务化等能力,帮助企业与科研机构将算法资产转化为可运维、可复用、可治理的智能服务。
平台支持 Python、Java、exe 等多语言模型格式,打通从实验到生产的工程链路,为传统算法的协同应用提供坚实底座。
[//]: # (✨✨✨**在线文档**✨✨✨ <a href="https://qmodel.qiantong.tech" target="_blank">https://qmodel.qiantong.tech</a>)
✨✨✨**演示地址**✨✨✨ <a href="https://demo.qmodel.tech" target="_blank">https://demo.qmodel.tech</a> (账号:`qModel`,密码:`qModel123`
> **qModel模型管理平台,让模型贯穿全生命周期,让智能持续创造价值。**
## 🍱 典型应用场景
| 场景 | 说明 |
|----------------|--------------------------------|
| **AI 模型资产化管理** | 统一纳管散落在各团队的模型,实现版本控制、分类标签与权限治理 |
| **科研成果工程化落地** | 将实验室中的算法快速封装为可调用服务,加速成果转化 |
| **多模型融合推理** | 支持加权融合、投票、Stacking 等策略,提升预测鲁棒性 |
| **智能工作流编排** | 可视化拖拽构建包含多个模型的 AI 工作流,支撑复杂业务逻辑 |
| **私有模型市场建设** | 构建企业内部模型共享与交易机制,促进知识复用与创新协作 |
## 🚀 核心优势
- 覆盖模型 **全生命周期**:从上传、测试、发布到监控、下线,全程可追溯
- **多语言兼容**,支持 Python 脚本、Java JAR、可执行程序等多种模型形态
- **轻量级架构**,开箱即用,支持 Docker 一键部署
- **模块化设计**,核心功能解耦,便于二次开发与集成
- **初生即开源**,社区共建,持续演进
## ✨ 核心功能
| 功能模块 | 描述 | 开源版 |
|-------------|--------------------------------------------|--------|
| **系统管理** | 用户、角色、部门、菜单、字典、参数、公告、日志等统一治理 | ✅ 已完成 |
| **模型分类** | 支持创建与管理模型分类体系,包括分类层级、标签分组等 | ✅ 已完成 |
| **模型管理** | 注册、分类、标签、审批、发布/下线、版本控制 | ✅ 已完成 |
| **模型计算** | 任务管理、参数配置、结果可视化、下载;开源版需手动绑定输入数据 | ✅ 已完成 |
| **计算历史** | 查看历史计算任务记录,支持按模型、时间、状态等条件筛选与结果回溯 | ✅ 已完成 |
| **模型接入与运行** | 支持多语言模型上传、自动解析、兼容性检测;开源版支持 Python/Java/exe | ⏳ 计划中 |
| **模型封装** | 提供标准化打包规范;提供文档指导 | ⏳ 计划中 |
| **服务治理与调度** | 自动生成 RESTful API;支持鉴权、限流、并发控制、调用链监控、水印等 | ⏳ 计划中 |
| **综合管理** | 开发文档管理 | ⏳ 计划中 |
> 注:自动化容器化、在线调试、融合编排、训练闭环等高级功能将在商业版中提供,欢迎社区共建开源版能力!
## 🛠️ 技术栈
qModel 采用前后端分离架构,后端基于 Spring Boot,前端基于 Vue 3,整合主流中间件,构建企业级模型管理解决方案。
<table>
<tr>
<th>技术栈</th><th>技术框架</th><th>描述</th>
</tr>
<tr>
<td rowspan="6">后端技术栈</td><td>Spring Boot</td><td>主体框架,简化配置与开发</td>
</tr>
<tr>
<td>MyBatis-Plus</td><td>ORM 框架,简化数据库操作</td>
</tr>
<tr>
<td>Spring Security</td><td>认证授权与安全控制</td>
</tr>
<tr>
<td>Quartz</td><td>定时任务调度(用于计算任务)</td>
</tr>
<tr>
<td>Alibaba Druid</td><td>高性能数据库连接池</td>
</tr>
<tr>
<td>Swagger</td><td>自动生成 API 文档</td>
</tr>
<tr>
<td rowspan="7">前端技术栈</td><td>Vue 3</td><td>响应式前端框架</td>
</tr>
<tr>
<td>Vite</td><td>极速构建工具</td>
</tr>
<tr>
<td>Element Plus</td><td>现代化 UI 组件库</td>
</tr>
<tr>
<td>Pinia</td><td>轻量级状态管理</td>
</tr>
<tr>
<td>Vue Router</td><td>前端路由管理</td>
</tr>
<tr>
<td>Axios</td><td>HTTP 请求封装</td>
</tr>
<tr>
<td>ECharts</td><td>计算结果与资源监控可视化</td>
</tr>
<tr>
<td rowspan="5">第三方依赖</td><td>MySQL</td><td>模型元数据存储</td>
</tr>
<tr>
<td>Redis</td><td>任务队列与缓存</td>
</tr>
<tr>
<td>Docker(可选)</td><td>容器化部署支持(商业版自动构建镜像)</td>
</tr>
<tr>
<td>本地存储</td><td>模型文件与计算结果存储</td>
</tr>
</table>
## 🏗️ 部署要求
在部署 qModel 之前,请确保以下环境已准备就绪:
<table>
<tr>
<th>环境</th><th>项目</th><th>推荐版本</th><th>说明</th>
</tr>
<tr>
<td rowspan="5">后端</td><td>JDK</td><td>1.8+</td><td>运行环境</td>
</tr>
<tr>
<td>Maven</td><td>3.6+</td><td>项目构建</td>
</tr>
<tr>
<td>MySQL</td><td>5.7 / 8.0</td><td>元数据库</td>
</tr>
<tr>
<td>Redis</td><td>5.0+</td><td>任务队列与缓存</td>
</tr>
<tr>
<td>操作系统</td><td>Linux / Windows / macOS</td><td>通用支持</td>
</tr>
<tr>
<td rowspan="3">前端</td><td>Node.js</td><td>16+</td><td>构建依赖</td>
</tr>
<tr>
<td>pnpm / npm</td><td>最新版</td><td>包管理器</td>
</tr>
<tr>
<td>Vite</td><td>≥4.0</td><td>构建工具</td>
</tr>
</table>
## 🚨 商用授权
qModel 提供 **开源版****商业版** 双轨模式:
- **开源版** 适合学习、评估与轻量级生产,遵循 Apache 2.0 协议(可商用,保留 Logo);
- **商业版** 面向政企客户,提供 **自动化容器化、模型融合、工作流编排、训练闭环、模型市场** 等高阶能力,并包含专属技术支持与私有仓库访问权限。
[//]: # (👉 如需 **品牌定制授权****申请商业版试用**,请访问:[💼 了解授权详情]&#40;https://qmodel.qiantong.tech/business.html&#41;)
👉 如需 **品牌定制授权****申请商业版试用**,请加入 QQ 交流群咨询
[![加入QQ群](https://img.shields.io/badge/QQ群-1064842367-blue.svg)](https://qm.qq.com/q/Ph8rhmZBQY)
## 🚀 快速开始
[//]: # (👉 <a href="https://qmodel.qiantong.tech/discuss.html">点击查看快速部署手册</a>)
👉 <a href="./QUICKSTART.md">点击查看快速部署手册</a>
## 👥 QQ交流群
欢迎加入 qModel 官方 QQ 交流群,获取最新动态、技术答疑与使用经验分享!
[![加入QQ群](https://img.shields.io/badge/QQ群-1064842367-blue.svg)](https://qm.qq.com/q/Ph8rhmZBQY)
[//]: # (👉 <a href="https://qmodel.qiantong.tech/discuss.html">点击加入 QQ 交流群</a>)
## 🖼️ 系统配图
<table>
<tr>
<td><img alt="登录页" src=".gitee/system/login.png"/></td>
<td><img alt="工作台" src=".gitee/system/workbench.png"/></td>
</tr>
<tr>
<td><img alt="模型分类" src=".gitee/system/modelCategory.png"/></td>
<td><img alt="模型输入" src=".gitee/system/input.png"/></td>
</tr>
<tr>
<td><img alt="模型列表" src=".gitee/system/modelList.png"/></td>
<td><img alt="计算任务" src=".gitee/system/taskList.png"/></td>
</tr>
</table>
-84
View File
@@ -1,84 +0,0 @@
package tech.qiantong.qmodel.server.project;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
/**
* 一键修改包名
* * @author anivia
*/
public class ProjectRenamer {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入修改前的工程路径
System.out.print("请输入修改前的工程路径: ");
String originalDirectory = scanner.nextLine();
// 输入修改后的工程路径
System.out.print("请输入修改后的工程路径: ");
String newDirectory = scanner.nextLine();
// 输入修改前的工程名称
System.out.print("请输入修改前的工程名称: ");
String oldProjectName = scanner.nextLine().toLowerCase();
// 输入修改后的工程名称
System.out.print("请输入修改后的工程名称: ");
String newProjectName = scanner.nextLine().toLowerCase();
try {
// 创建新的功能目录
File newDir = new File(newDirectory);
if (!newDir.exists()) {
newDir.mkdirs(); // 创建新目录
}
// 复制原工程内容到新目录并重命名
copyAndRename(new File(originalDirectory), newDir, oldProjectName, newProjectName);
// 替换文件内容中的原工程名称
replaceInFiles(newDir, oldProjectName, newProjectName);
System.out.println("工程已成功从 " + originalDirectory + " 修改为 " + newDirectory);
} catch (IOException e) {
e.printStackTrace();
} finally {
scanner.close();
}
}
private static void copyAndRename(File srcDir, File destDir, String oldName, String newName) throws IOException {
if (srcDir.isDirectory()) {
for (File file : srcDir.listFiles()) {
File newFile = new File(destDir, file.getName().replace(oldName, newName));
if (file.isDirectory()) {
newFile.mkdirs();
copyAndRename(file, newFile, oldName, newName);
} else {
Files.copy(file.toPath(), newFile.toPath());
}
}
}
}
private static void replaceInFiles(File dir, String oldString, String newString) throws IOException {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
replaceInFiles(file, oldString, newString);
} else {
Path path = Paths.get(file.getPath());
String content = new String(Files.readAllBytes(path));
// 替换包路径和工程名称
content = content.replace(oldString, newString);
Files.write(path, content.getBytes());
}
}
}
}
}
@@ -1,36 +0,0 @@
# ProjectRenamer 使用说明
## 功能概述
`ProjectRenamer` 是一个 Java 程序,用于根据用户输入修改工程名称及包路径,并将修改后的文件结构输出到指定的新路径。程序会保持文件结构的一致性,并替换文件中的原工程名称。
## 使用说明
0. **前提工作**
- 拷贝一份 Anivia-Plus 并且只保留后端代码
- Anivia-Plus 名称重命名为 Anivia
- 创建新工程目录如:Surge
1. **编译和运行**
2. **输入信息**
按照提示输入以下信息:
- **修改前的工程路径**C:\Users\Ming\Desktop\Anivia
- **修改后的工程路径**C:\Users\Ming\Desktop\Surge
- **修改前的工程名称**:Anivia(代码中将转为小写)。
- **修改后的工程名称**:Surge(代码中将转为小写)。
3. **执行过程**
- 程序会复制原工程内容到新路径,并重命名相关目录和文件。
- 所有文件中的原工程名称和包路径将被替换为新的名称。
## 注意事项
- **备份**:在运行程序之前,请确保对原工程进行备份,以防数据丢失或意外修改。
- **路径有效性**:确保输入的修改前工程路径存在且有效。
- **权限**:确保你对目标路径有写入权限,否则程序可能无法创建新目录或文件。
- **文件内容**:程序会扫描所有文件并进行替换,请确认文件中内容的准确性,特别是对于代码中的包路径。
- **环境要求**:需要安装 JDK 并设置好环境变量,确保能够使用 `javac``java` 命令。
## 联系方式
如有问题,请联系开发者以获取支持。
-20
View File
@@ -1,20 +0,0 @@
!/bin/sh
#filename: restart.sh
echo "stoping ..."
pid=`jps -l | grep 'qModel-server*' | awk '{print $1}'`
if [ ! $pid ]; then
echo "no such service."
else
echo "find service. pid=$pid"
kill -9 $pid
echo "stop success."
fi
echo "starting ..."
nohup java -Xms256m -Xmx1024m -server -jar -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=prod qModel-server.jar >>/dev/null &
# nohup java -Xms64m -Xmx128m -jar -Djava.security.egd=file:/dev/./urandom anivia-server.jar >>/dev/null &
pid=`jps -l | grep 'qModel-server*' | awk '{print $1}'`
echo "start success. pid=$pid"
-26
View File
@@ -1,26 +0,0 @@
# ==================================== qModel 以及相关中间件 ====================================
QMODEL_HUB=crpi-kf13onfj0v8f6jax.cn-shanghai.personal.cr.aliyuncs.com/qiantongkeji
QMODEL_VERSION=1.0.1
# 数据库类型,可选值:dm8 或 mysql
DB_TYPE=dm8
# 数据库
CASE_SENSITIVE=0
INSTANCE_NAME=QMODEL_DEV
# admin 密码
SYSDBA_PWD=o5KjnPYxswsiURZHCPwd
SYSAUDITOR_PWD=o5KjnPYxswsiURZHCPwd
# 表空间名称、密码
QMODEL_USER=QMODEL_DEV
QMODEL_PWD=s2LKr6LMQxVDTQx
# redis
REDIS_PASSWORD='J98%FHF#9h@e88h9fre9'
EXPOSE_REDIS_PORT=6379
# nginx
EXPOSE_NGINX_PORT=80
NGINX_PORT=80
-26
View File
@@ -1,26 +0,0 @@
# ==================================== qModel 以及相关中间件 ====================================
QMODEL_HUB=crpi-kf13onfj0v8f6jax.cn-shanghai.personal.cr.aliyuncs.com/qiantongkeji
QMODEL_VERSION=1.0.1
# 数据库类型,可选值:dm8 或 mysql
DB_TYPE=dm8
# 数据库
CASE_SENSITIVE=0
INSTANCE_NAME=QMODEL
# admin 密码
SYSDBA_PWD=o5KjnPYxswsiURZHCPwd
SYSAUDITOR_PWD=o5KjnPYxswsiURZHCPwd
# 表空间名称、密码
QMODEL_USER=QMODEL
QMODEL_PWD=s2LKr6LMQxVDTQx
# redis
REDIS_PASSWORD='J98%FHF#9h@e88h9fre9'
EXPOSE_REDIS_PORT=6379
# nginx
EXPOSE_NGINX_PORT=80
NGINX_PORT=80
@@ -1,142 +0,0 @@
#!/bin/sh
set -e
DM_PATH=/home/dmdba/dmdbms
DM_DATA_DIR=/home/dmdba/data/DAMENG
INIT_SQL=/home/dmdba/initdata/init-qmodel.sql
FIRST_RUN_FLAG=/var/run/qmodel_init.done
PORT=${PORT_NUM:-5236}
# ---------- 检查是否已经初始化 ----------
check_is_init() {
if [ -d "${DM_DATA_DIR}" ]; then
DATABASE_ALREADY_EXISTS=true
fi
}
# ---------- 初始化数据库 ----------
db_init() {
echo "[dm8] init db ..."
mkdir -p "${DM_DATA_DIR}"
chown -R dmdba "${DM_DATA_DIR}"
cd "${DM_PATH}/bin"
# 初始化参数,参考你原来的需求
INIT_ARGS="PATH=/home/dmdba/data DB_NAME=DAMENG PORT_NUM=${PORT} PAGE_SIZE=16 CHARSET=1 LENGTH_IN_CHAR=1 CASE_SENSITIVE=${CASE_SENSITIVE:-0}"
if [ -n "${SYSDBA_PWD}" ]; then
INIT_ARGS="${INIT_ARGS} SYSDBA_PWD=${SYSDBA_PWD}"
fi
if [ -n "${SYSAUDITOR_PWD}" ]; then
INIT_ARGS="${INIT_ARGS} SYSAUDITOR_PWD=${SYSAUDITOR_PWD}"
fi
echo "[dm8] dminit ${INIT_ARGS}"
gosu dmdba "${DM_PATH}/bin/dminit" ${INIT_ARGS}
echo "[dm8] db init done."
}
# ---------- 等待 dmserver TCP 端口可用(参考老版本逻辑) ----------
wait_dm_ready() {
echo "[dm8] wait dmserver tcp on 127.0.0.1:${PORT} ..."
i=0
max=6000 # 最多等 6000 秒
while [ $i -lt $max ]; do
# 使用 /dev/tcp 检测端口是否可连
if (echo >"/dev/tcp/127.0.0.1/${PORT}") >/dev/null 2>&1; then
echo "[dm8] dmserver tcp ready."
return 0
fi
i=`expr $i + 1`
sleep 1
done
echo "[dm8] WARN: dmserver tcp not ready after ${max}s, continue anyway."
return 1
}
# ---------- 首次启动时导入 init-qmodel.sql ----------
run_init_sql_once() {
# 已经执行过了就直接跳过
if [ -f "${FIRST_RUN_FLAG}" ]; then
echo "[dm8] qModel init already done, skip."
return 0
fi
# 没有 SQL 文件就不导入,避免每次都尝试
if [ ! -f "${INIT_SQL}" ]; then
echo "[dm8] ${INIT_SQL} not found, skip qModel init."
mkdir -p "$(dirname "${FIRST_RUN_FLAG}")"
touch "${FIRST_RUN_FLAG}"
return 0
fi
# 必要环境变量没配也跳过
if [ -z "${QMODEL_USER}" ] || [ -z "${QMODEL_PWD}" ] || [ -z "${SYSDBA_PWD}" ]; then
echo "[dm8] QMODEL_USER / QMODEL_PWD / SYSDBA_PWD not set, skip qModel init."
mkdir -p "$(dirname "${FIRST_RUN_FLAG}")"
touch "${FIRST_RUN_FLAG}"
return 0
fi
# 仅用 TCP 端口检测等待服务就绪
wait_dm_ready
echo "[dm8] start create business user and import init-qmodel.sql ..."
# 为了防止“用户已存在”等导致整个容器退出,这里临时关掉 set -e
set +e
# 1) SYSDBA 创建业务用户并授权
gosu dmdba "${DM_PATH}/bin/disql" "SYSDBA/${SYSDBA_PWD}@127.0.0.1:${PORT}" <<EOF
create user "${QMODEL_USER}" identified by "${QMODEL_PWD}" hash with SHA512 salt;
grant "PUBLIC","SOI","DBA" to "${QMODEL_USER}";
commit;
EOF
# 2) 业务用户执行初始化脚本
gosu dmdba "${DM_PATH}/bin/disql" "${QMODEL_USER}/${QMODEL_PWD}@127.0.0.1:${PORT}" <<EOF
set define off;
set CHAR_CODE UTF8;
\`${INIT_SQL}
set define on;
EOF
# 恢复 set -e
set -e
mkdir -p "$(dirname "${FIRST_RUN_FLAG}")"
touch "${FIRST_RUN_FLAG}"
echo "[dm8] qModel init finished."
}
# ---------- 主流程 ----------
check_is_init
if [ -z "${DATABASE_ALREADY_EXISTS}" ]; then
db_init
else
echo "[dm8] db already exists, skip dminit."
fi
# 安装服务(修复你原脚本里的那一处 `DmAPService}` 的 bug
if [ ! -f "${DM_PATH}/bin/DmAPService" ]; then
"${DM_PATH}/script/root/dm_service_installer.sh" -s "${DM_PATH}/bin/DmAPService"
fi
if [ ! -f "${DM_PATH}/bin/DmServiceDMSERVER" ]; then
"${DM_PATH}/script/root/dm_service_installer.sh" -t dmserver -p "DMSERVER" -dm_ini "${DM_DATA_DIR}/dm.ini"
fi
# 启动服务
gosu dmdba "${DM_PATH}/bin/DmAPService" start
gosu dmdba "${DM_PATH}/bin/DmServiceDMSERVER" start
# 首次导入任务放到后台,不阻塞主进程
run_init_sql_once &
# 保持容器前台进程:沿用原脚本 tail 日志
exec gosu dmdba tail -f /home/dmdba/dmdbms/log/DmServiceDMSERVER.log
-157
View File
@@ -1,157 +0,0 @@
#!/bin/bash
set -e
DB_PATH=${DB_PATH:-"/home/dmdba/data"}
INSTANCE_NAME=${INSTANCE_NAME:-"DMSERVER"}
DB_NAME=${DB_NAME:-"DAMENG"}
DMDB_INSTALL_PATH=${DMDB_INSTALL_PATH:-"/home/dmdba/dmdb"}
INIT_PARAMS=""
PORT_NUM=${PORT_NUM:-"5236"}
TIME_ZONE=${TIME_ZONE:-"+08:00"}
BUFFER=${BUFFER:-"8000"}
PAGE_CHECK=${PAGE_CHECK:-"3"}
PAGE_SIZE=${PAGE_SIZE:-"8"}
LOG_SIZE=${LOG_SIZE:-"4096"}
EXTENT_SIZE=${EXTENT_SIZE:-"16"}
CHARSET=${CHARSET:-"0"}
USE_DB_NAME=${USE_DB_NAME:-"1"}
AUTO_OVERWRITE=${AUTO_OVERWRITE:-"0"}
BLANK_PAD_MODE=${BLANK_PAD_MODE:-"0"}
DPC_MODE=${DPC_MODE:-"0"}
CASE_SENSITIVE=${CASE_SENSITIVE:-"y"}
OTHER_PARAMS=${OTHER_PARAMS:-""}
SYSDBA_PWD=${SYSDBA_PWD:-""}
SYSAUDITOR_PWD=${SYSAUDITOR_PWD:-""}
# ===== 新增:一次性执行标记 & 日志路径 =====
FIRST_RUN_FLAG="/var/run/dm8_first_run.done" # 首次执行标记
INIT_LOG="/init.log" # 初始化日志文件
function init_db() {
if [ -z "$SYSDBA_PWD" ]; then
echo "SYSDBA_PWD is empty, please set it in environment variables"
exit 1
fi
if [ -z "$SYSAUDITOR_PWD" ]; then
echo "SYSAUDITOR_PWD is empty, please set it in environment variables"
exit 1
fi
# 判断DB_PATH文件夹内是否存在文件
if [ -d "$DB_PATH" ]; then
if [ "$(ls -A $DB_PATH)" ]; then
echo "DB_PATH is not empty, please check it"
exit 1
fi
else
echo "DB_PATH is not exist, create it"
mkdir -p $DB_PATH
chown -R dmdba $DB_PATH
fi
INIT_PARAMS="$INIT_PARAMS PATH=$DB_PATH SYSDBA_PWD=$SYSDBA_PWD SYSAUDITOR_PWD=$SYSAUDITOR_PWD INSTANCE_NAME=$INSTANCE_NAME"
INIT_PARAMS="$INIT_PARAMS PORT_NUM=$PORT_NUM DB_NAME=$DB_NAME TIME_ZONE=$TIME_ZONE BUFFER=$BUFFER PAGE_CHECK=$PAGE_CHECK PAGE_SIZE=$PAGE_SIZE"
INIT_PARAMS="$INIT_PARAMS LOG_SIZE=$LOG_SIZE EXTENT_SIZE=$EXTENT_SIZE CHARSET=$CHARSET USE_DB_NAME=$USE_DB_NAME"
INIT_PARAMS="$INIT_PARAMS AUTO_OVERWRITE=$AUTO_OVERWRITE BLANK_PAD_MODE=$BLANK_PAD_MODE DPC_MODE=$DPC_MODE CASE_SENSITIVE=$CASE_SENSITIVE"
INIT_PARAMS="$INIT_PARAMS $OTHER_PARAMS"
echo "Initializing database..."
echo "Initializing database with parameters:"
echo $INIT_PARAMS
sudo -u dmdba /home/dmdba/dmdb/bin/dminit $INIT_PARAMS
echo "Database initialized"
}
function start_dmap() {
echo "Starting DmAPService..."
sudo -u dmdba /home/dmdba/dmdb/bin/dmap dmap_ini=/home/dmdba/dmdb/bin/dmap.ini &
echo "DmAPService started"
}
# 创建一个函数,用来修改文件的权限
function modify_db_permissions() {
echo "Modifying $DB_PATH permissions..."
chown -R dmdba $DB_PATH
echo "$DB_PATH permissions modified"
}
function check_initialized() {
# 判断 $DB_PATH/$DB_NAME/dm.ini 是否存在
if [ -f "$DB_PATH/$DB_NAME/dm.ini" ]; then
echo "Database already initialized"
modify_db_permissions
else
echo "Database not initialized"
init_db
fi
}
# ===== 新增:等待 TCP 就绪的小函数 =====
wait_tcp_ready() {
local waited=0
local timeout=600
echo "Waiting for dmserver TCP on 127.0.0.1:${PORT_NUM} ..."
# /dev/tcp 存在即可用;若镜像不支持,可改用 nc -z
while ! (echo >"/dev/tcp/127.0.0.1/${PORT_NUM}") >/dev/null 2>&1; do
sleep 2
waited=$((waited+2))
if [ $waited -ge $timeout ]; then
echo "ERROR: TCP 127.0.0.1:${PORT_NUM} not ready in ${timeout}s"
return 1
fi
done
echo "TCP ready."
return 0
}
# ===== 新增:首次执行的后台任务(按你的两段 disql 顺序)=====
post_boot_first_run() {
# 已执行过则直接退出
if [ -f "$FIRST_RUN_FLAG" ]; then
return 0
fi
# 等 TCP 就绪(服务启动完成)
if ! wait_tcp_ready; then
echo "WARN: dmserver TCP not ready; skip first-run init."
return 0
fi
# 准备日志
if [ ! -f "$INIT_LOG" ]; then
echo "init database at $(date +'%Y-%m-%d %H:%M:%S')" > "$INIT_LOG"
fi
echo "Creating business user & grant ..." | tee -a "$INIT_LOG"
# 第一步:SYSDBA 执行建用户与授权
/home/dmdba/dmdb/bin/disql SYSDBA/${SYSDBA_PWD}@localhost:${PORT_NUM} <<EOF >> "$INIT_LOG" 2>&1
create user "${QMODEL_USER}" identified by "${QMODEL_PWD}" hash with SHA512 salt;
grant "PUBLIC","SOI","DBA" to "${QMODEL_USER}";
COMMIT;
EOF
echo "Importing initial data ..." | tee -a "$INIT_LOG"
# 第二步:业务用户导入数据(确保 /home/dmdba/initdata/init-qmodel.sql 可读)
/home/dmdba/dmdb/bin/disql ${QMODEL_USER}/${QMODEL_PWD}@localhost:${PORT_NUM} <<EOF >> "$INIT_LOG" 2>&1
set define off;
set CHAR_CODE UTF8;
\`/home/dmdba/initdata/init-qmodel.sql
set define on;
EOF
# 落标记:仅首次执行
touch "$FIRST_RUN_FLAG"
echo "First-run initialization finished." | tee -a "$INIT_LOG"
}
cd $DMDB_INSTALL_PATH/bin
# 检查DB是否初始化,如果没有初始化则执行初始化
check_initialized
# 启动 DmAPServer
start_dmap
# ===== 新增:后台启动首次执行任务(不阻塞主进程)=====
post_boot_first_run &
# 启动数据库实例(前台)
echo "Starting DmServer..."
exec sudo -u dmdba /home/dmdba/dmdb/bin/dmserver path=$DB_PATH/$DB_NAME/dm.ini
File diff suppressed because it is too large Load Diff
@@ -1,22 +0,0 @@
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#log-error = /var/log/mysql/error.log
#bind-address = 127.0.0.1
symbolic-links=0
character_set_server=utf8mb4
character_set_filesystem=utf8mb4
collation-server=utf8mb4_general_ci
init-connect='SET NAMES utf8mb4'
init_connect='SET collation_connection = utf8mb4_general_ci'
skip-character-set-client-handshake
lower_case_table_names=1
# 最大连接数
max_connections=500000
# 连接超时时间
connect_timeout=30
# 最大包大小 (16MB)
max_allowed_packet=16777216
-67
View File
@@ -1,67 +0,0 @@
version: "1.0.1"
services:
redis:
privileged: true
image: redis:6-alpine
profiles: ["all","local"]
env_file: .env
restart: always
environment:
REDISCLI_AUTH: ${REDIS_PASSWORD:-J98%FHF#9h@e88h9fre9}
# volumes:
# # Mount the redis data directory to the container.
# - ./redis/data:/data
# Set the redis password when startup redis server.
command: redis-server --requirepass ${REDIS_PASSWORD:-J98%FHF#9h@e88h9fre9}
ports:
- "${EXPOSE_REDIS_PORT:-6379}:6379"
healthcheck:
test: [ 'CMD', 'redis-cli', 'ping' ]
networks:
- qmodel_net
nginx:
privileged: true
image: nginx:1.24.0
restart: always
profiles: [ "all" ]
env_file: .env
ports:
- '${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}'
networks:
- qmodel_net
volumes:
- ./nginx/dist:/usr/share/nginx
- ./nginx/logs:/var/log/nginx
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/sites/:/etc/nginx/http_vhost/:ro
dm8:
image: ${QMODEL_HUB}/dm8:mixed
profiles: [ "all", "schema","local" ,"qmodel-db"]
env_file: .env
privileged: true
hostname: dm8
restart: always
ports:
- "35236:5236"
volumes:
- ./database/dm8/init-qmodel.sql:/home/dmdba/initdata/init-qmodel.sql
- ./database/dm8/entrypoint.sh:/entrypoint.sh
- ./database/dm8/entrypoint-arm64.sh:/usr/local/bin/docker-entrypoint.sh
environment:
- TZ=${TZ}
- CASE_SENSITIVE=${CASE_SENSITIVE}
- SYSDBA_PWD=${SYSDBA_PWD}
- SYSAUDITOR_PWD=${SYSAUDITOR_PWD}
- QMODEL_USER=${QMODEL_USER}
- QMODEL_PWD=${QMODEL_PWD}
healthcheck:
test: [ "CMD-SHELL", "echo > /dev/tcp/127.0.0.1/5236" ]
interval: 20s # 每 20 秒检测一次
timeout: 5s # 超过 5 秒算失败
retries: 10 # 连续 10 次失败算 unhealthy
start_period: 1200s # 容忍 20 分钟内失败
networks:
- qmodel_net
-28
View File
@@ -1,28 +0,0 @@
version: "1.0.1"
services:
# qmodel 后端服务
qmodel-api:
privileged: true
image: ${QMODEL_HUB}/qmodel-server-ce:${QMODEL_VERSION}
restart: always
profiles: [ "all" ]
env_file: .env
environment:
- TZ=Asia/Shanghai
ports:
- "18888:8080"
volumes:
- /etc/localtime:/etc/localtime:ro
- ./qmodel-server/logs:/usr/app/jar/logs
- ./qmodel-server/upload:/usr/app/jar/upload
- ./qmodel-server/application-prod.yml:/usr/app/jar/application-prod.yml
depends_on:
redis:
condition: service_healthy
dm8:
condition: service_healthy
networks:
- qmodel_net
extra_hosts:
- "host.docker.internal:host-gateway"
-12
View File
@@ -1,12 +0,0 @@
include:
- path: ./docker-compose-base.yml
- path: ./docker-compose-qmodel.yml
version: "1.0.1"
networks:
qmodel_net:
driver: bridge
ipam:
config:
- subnet: 172.52.0.0/16
-42
View File
@@ -1,42 +0,0 @@
user root;
worker_processes 8;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 3000;
}
http {
include /etc/nginx/mime.types;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 300;
keepalive_requests 1000;
client_header_timeout 60;
client_body_timeout 60;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
proxy_max_temp_file_size 0;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 1;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
include http_vhost/*.conf;
}
-30
View File
@@ -1,30 +0,0 @@
server {
listen 80;
server_name localhost;
client_max_body_size 500M;
add_header Strict-Transport-Security "max-age=31536000";
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;
keepalive_timeout 600s;
send_timeout 60s;
location / {
proxy_read_timeout 600;
charset utf-8;
root /usr/share/nginx;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location /prod-api {
add_header 'Access-Control-Allow-Methods' 'GET, POST,PUT,DELETE, OPTIONS';
proxy_read_timeout 6000;
rewrite ^/prod-api/(.*)$ /$1 break;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://qmodel-api:8080;
}
}
@@ -1,117 +0,0 @@
# 用户配置
user:
password:
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间(默认10分钟)
lockTime: 10
#万能密码 配置为空则不生效
universalPassword: qModel23@qtt0317.
# 主数据源选择
datasource:
type: dm8
# Spring配置
spring:
# redis 配置
redis:
# 地址
host: redis
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: J98%FHF#9h@e88h9fre9
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
datasource:
druid:
stat-view-servlet:
# 是否启用Druid的监控统计功能
enabled: false
# 访问Druid监控页面的用户名
loginUsername: qModel
# 访问Druid监控页面的密码
loginPassword: 123456
dynamic:
druid:
# 连接池初始化时创建的连接数量
initial-size: 5
# 连接池中最小空闲连接数
min-idle: 5
# 连接池中最大活动连接数
maxActive: 20
# 连接池等待连接的最长时间(毫秒)
maxWait: 60000
# 数据库连接超时时间(毫秒)
connectTimeout: 30000
# Socket超时时间(毫秒)
socketTimeout: 60000
# 空闲连接的检测周期(毫秒)
timeBetweenEvictionRunsMillis: 60000
# 最小空闲连接的存活时间(毫秒)
minEvictableIdleTimeMillis: 300000
# 用于检测连接是否有效的SQL语句
validationQuery: SELECT 1 FROM DUAL
# 是否在空闲时检测连接的有效性
testWhileIdle: true
# 借用连接时是否测试连接的有效性
testOnBorrow: false
# 归还连接时是否测试连接的有效性
testOnReturn: false
# 是否打开连接池的PreparedStatement缓存
poolPreparedStatements: true
# 每个连接池的PreparedStatement缓存上限
maxPoolPreparedStatementPerConnectionSize: 20
# 配置Druid的过滤器
filters: stat,slf4j
# Druid连接属性配置
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
# 主库数据源配置
master:
# 动态加载的配置属性
driver-class-name: ${${datasource.type}.driver-class-name}
url: ${${datasource.type}.url}
username: ${${datasource.type}.username}
password: ${${datasource.type}.password}
# 达梦配置文件
dm8:
# JDBC驱动类名
driver-class-name: dm.jdbc.driver.DmDriver
# 主库JDBC连接URL
url: jdbc:dm://dm8:5236/QMODEL_DEV?STU&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&schema=QMODEL_DEV&serverTimezone=Asia/Shanghai
# 主库用户名
username: QMODEL_DEV
# 主库密码
password: s2LKr6LMQxVDTQx
## 工作流模块的访问地址
flow:
enable: false
url: http://127.0.0.1:26859/
#模型
modelUrl: "http://192.168.200.206:8000"
modelUrl2: "http://192.168.200.182:8821"
model:
hydrodynamicModel: D:\model\chengxuhuizong11.5
newHydrodynamicModel: C:\Users\yuexin\Downloads\1.31exe\1.31exe
filePath: D:\nami\data\model
location: D:\nami\data\modelFile\
accessUrl: D:/nami/data/modelFile
Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

-17
View File
@@ -1,17 +0,0 @@
## 前端
建立 socket 连接,连接地址为/websocket/message/当前用户 id。
socket 可接收推送的消息数量,初始化时需主动获取消息数量。
离开时,务必关闭 socket 连接。
![前端连接过程](image/message/消息.png)
## 后端
使用方法:
消息模版操作:在系统管理中的消息模版进行增删改查。
消息发送:在messageService中的send方法进行发送(通过模版向某一用户发送消息)。
消息数量查询:在messageService中的getNum。
消息已读:在messageService中的read。
消息批量已读:在messageService中的readAll。
实现流程:读取指定模版生成对应的消息,添加到数据库中,添加完成后通过 websocket 通知对应的用户。
涉及数据库
message 消息通知
message_template 消息模版
-2
View File
@@ -1,2 +0,0 @@
#!/bin/sh
mvn -Dmaven.test.skip=true clean package
-258
View File
@@ -1,258 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>tech.qiantong</groupId>
<artifactId>qModel</artifactId>
<version>1.0.1</version>
<name>qModel</name>
<url>https://qiantong.tech</url>
<description>qModel模型平台</description>
<properties>
<anivia.version>1.0.1</anivia.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<spring-framework.version>5.3.33</spring-framework.version>
<spring-security.version>5.7.12</spring-security.version>
<druid.version>1.2.23</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<swagger.version>3.0.0</swagger.version>
<kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
<fastjson.version>2.0.43</fastjson.version>
<oshi.version>6.6.1</oshi.version>
<commons.io.version>2.13.0</commons.io.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
<!-- Docker 镜像构建配置 -->
<docker.hub>crpi-kf13onfj0v8f6jax.cn-shanghai.personal.cr.aliyuncs.com/qiantongkeji</docker.hub>
<!-- 镜像仓库名:默认使用模块名称(module name) -->
<docker.repo>${project.name}</docker.repo>
<!-- 镜像版本号:默认使用当前模块版本 -->
<docker.tag>${project.version}</docker.tag>
<!-- 是否打印构建命令(默认打印,便于调试,不执行实际构建) -->
<docker.print.skip>true</docker.print.skip>
<!-- 是否跳过镜像构建(默认跳过,避免在开发环境误构建镜像) -->
<docker.build.skip>true</docker.build.skip>
<!-- 是否跳过镜像推送(默认跳过,避免误将测试镜像推送至镜像仓库) -->
<docker.push.skip>true</docker.push.skip>
</properties>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
<!-- SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringSecurity的依赖配置-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>${spring-security.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.15</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${bitwalker.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>${oshi.version}</version>
</dependency>
<!-- Swagger3依赖 -->
<!-- <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>-->
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- Token生成与解析-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>tech.qiantong</groupId>
<artifactId>qmodel-quartz</artifactId>
<version>${anivia.version}</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>tech.qiantong</groupId>
<artifactId>qmodel-generator</artifactId>
<version>${anivia.version}</version>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>tech.qiantong</groupId>
<artifactId>qmodel-framework</artifactId>
<version>${anivia.version}</version>
</dependency>
<!-- 系统模块-->
<dependency>
<groupId>tech.qiantong</groupId>
<artifactId>qmodel-module-system</artifactId>
<version>${anivia.version}</version>
</dependency>
<!-- 通用工具-->
<dependency>
<groupId>tech.qiantong</groupId>
<artifactId>qmodel-common</artifactId>
<version>${anivia.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>qmodel-framework</module>
<module>qmodel-module-system</module>
<module>/qmodel-module-model</module>
<module>qmodel-server</module>
</modules>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>aliyun-public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
<repository>
<id>central</id>
<name>maven central</name>
<url>https://repo1.maven.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
-18
View File
@@ -1,18 +0,0 @@
#!/bin/sh
#filename: publish-server.sh
# 部署Whale系统项目
targetPath="/home/qtt/src/qModel/qmodel-server/target"
# 运行目录
runPath="/home/qtt/opt/qmodel-server"
# publish
echo "Publishing qModel admin ... The installation directory is $runPath"
cd $targetPath
cp qmodel-server.jar $runPath
echo "Publish qModel success! Now you can go to the installation directory($runPath) and restart the server."
cd $runPath
sh restart.sh
tail -f logs/info.log
-65
View File
@@ -1,65 +0,0 @@
<?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>
@@ -1,96 +0,0 @@
<?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>
@@ -1,135 +0,0 @@
/*
* 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)));
}
}
@@ -1,127 +0,0 @@
/*
* 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)));
}
}
@@ -1,225 +0,0 @@
/*
* 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();
// }
//}
@@ -1,105 +0,0 @@
/*
* 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;
}
@@ -1,70 +0,0 @@
/*
* 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;
}
@@ -1,46 +0,0 @@
/*
* 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> {
}
@@ -1,46 +0,0 @@
/*
* 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> {
}
@@ -1,46 +0,0 @@
/*
* 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> {
}
@@ -1,46 +0,0 @@
/*
* 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> {
}
@@ -1,58 +0,0 @@
/*
* 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;
}
@@ -1,58 +0,0 @@
/*
* 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;
}
@@ -1,119 +0,0 @@
/*
* 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();
}
}
@@ -1,49 +0,0 @@
/*
* 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);
}
@@ -1,76 +0,0 @@
# 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
@@ -1,76 +0,0 @@
# 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
@@ -1,76 +0,0 @@
# 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
@@ -1,169 +0,0 @@
<?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>
@@ -1,96 +0,0 @@
<?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>
@@ -1,244 +0,0 @@
<?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>
@@ -1,47 +0,0 @@
/*
* 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
{
}
@@ -1,61 +0,0 @@
/*
* 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 "";
}
@@ -1,56 +0,0 @@
/*
* 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;
}
@@ -1,225 +0,0 @@
/*
* 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;
}
}
}
@@ -1,50 +0,0 @@
/*
* 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();
}
@@ -1,80 +0,0 @@
/*
* 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 {};
}
@@ -1,69 +0,0 @@
/*
* 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;
}
@@ -1,58 +0,0 @@
/*
* 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 "不允许重复提交,请稍候再试";
}
@@ -1,57 +0,0 @@
/*
* 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();
}
@@ -1,154 +0,0 @@
/*
* 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";
}
}
@@ -1,60 +0,0 @@
/*
* 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);
}
}
}
@@ -1,100 +0,0 @@
/*
* 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;
}
}
}
@@ -1,76 +0,0 @@
/*
* 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:";
}
@@ -1,206 +0,0 @@
/*
* 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" };
}
@@ -1,154 +0,0 @@
/*
* 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";
}
@@ -1,126 +0,0 @@
/*
* 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;
}
@@ -1,82 +0,0 @@
/*
* 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;
}
}
}
@@ -1,110 +0,0 @@
/*
* 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;
}
@@ -1,243 +0,0 @@
/*
* 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();
}
}
@@ -1,249 +0,0 @@
/*
* 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;
}
}
@@ -1,208 +0,0 @@
/*
* 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);
}
}
@@ -1,165 +0,0 @@
/*
* 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());
}
}
@@ -1,148 +0,0 @@
/*
* 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();
}
}
@@ -1,111 +0,0 @@
/*
* 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;
}
}
@@ -1,110 +0,0 @@
/*
* 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;
}
}
@@ -1,236 +0,0 @@
/*
* 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();
}
}
@@ -1,209 +0,0 @@
/*
* 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();
}
}
@@ -1,141 +0,0 @@
/*
* 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();
}
}
@@ -1,307 +0,0 @@
/*
* 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();
}
}
@@ -1,274 +0,0 @@
/*
* 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();
}
}
@@ -1,381 +0,0 @@
/*
* 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();
}
}
@@ -1,101 +0,0 @@
/*
* 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;
}
}
@@ -1,299 +0,0 @@
/*
* 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;
}
}
@@ -1,43 +0,0 @@
/*
* 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
{
}
@@ -1,133 +0,0 @@
/*
* 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;
}
}
@@ -1,103 +0,0 @@
/*
* 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;
}
}
}
@@ -1,90 +0,0 @@
/*
* 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;
}
}
@@ -1,51 +0,0 @@
/*
* 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;
}
@@ -1,69 +0,0 @@
/*
* 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;
}
@@ -1,117 +0,0 @@
/*
* 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;
}
}
@@ -1,88 +0,0 @@
/*
* 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();
}
}
@@ -1,297 +0,0 @@
/*
* 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);
}
}
@@ -1,119 +0,0 @@
/*
* 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();
}
}
@@ -1,124 +0,0 @@
/*
* 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();
}
}
@@ -1,52 +0,0 @@
/*
* 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,
}

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