refactor: 替换项目中的"yudao"为"AIOTAGRO",并清理相关配置文件
@@ -1,5 +0,0 @@
|
||||
# Changesets
|
||||
|
||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
||||
|
||||
We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
|
||||
"changelog": [
|
||||
"@changesets/changelog-github",
|
||||
{ "repo": "vbenjs/vue-vben-admin" }
|
||||
],
|
||||
"commit": false,
|
||||
"fixed": [["@vben-core/*", "@vben/*"]],
|
||||
"snapshot": {
|
||||
"prereleaseTemplate": "{tag}-{datetime}"
|
||||
},
|
||||
"privatePackages": { "version": true, "tag": true },
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
[core]
|
||||
ignorecase = false
|
||||
@@ -1,65 +0,0 @@
|
||||
name: Bug 反馈
|
||||
description: 当你在代码中发现了一个 Bug,导致应用崩溃或抛出异常,或者有一个组件存在问题,或者某些地方看起来不对劲。
|
||||
title: '[Bug]: '
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢对项目的支持与关注。在提出问题之前,请确保你已查看相关开发或使用文档:
|
||||
- https://doc.iocoder.cn/
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: 分支
|
||||
description: 你当前正在使用我们软件的哪个分支?
|
||||
options:
|
||||
- master (默认)
|
||||
- dev (开发分支)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: 版本
|
||||
description: 你当前正在使用我们软件的哪个版本?
|
||||
options:
|
||||
- antd-design-vue
|
||||
- element-plus
|
||||
- naiveui
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 这个问题是否已经存在?
|
||||
options:
|
||||
- label: 我已经搜索过现有的问题 (https://gitee.com/yudaocode/yudao-ui-admin-vben/issues)
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 如何复现
|
||||
description: 请详细告诉我们如何复现你遇到的问题,如涉及代码,可提供一个最小代码示例,并使用反引号```附上它
|
||||
placeholder: |
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 预期结果
|
||||
description: 请告诉我们你预期会发生什么。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 实际结果
|
||||
description: 请告诉我们实际发生了什么。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 截图或视频
|
||||
description: 如果可以的话,上传任何关于 bug 的截图。
|
||||
value: |
|
||||
[在这里上传图片]
|
||||
@@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 项目开发文档
|
||||
url: https://doc.iocoder.cn/
|
||||
about: 提供项目启动、开发的相关文档
|
||||
@@ -1,43 +0,0 @@
|
||||
name: 功能建议
|
||||
description: 对本项目提出一个功能建议
|
||||
title: '[功能建议]: '
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢提出功能建议,我们将仔细考虑!
|
||||
- type: textarea
|
||||
id: related-problem
|
||||
attributes:
|
||||
label: 你的功能建议是否和某个问题相关?
|
||||
description: 清晰并简洁地描述问题是什么,例如,当我...时,我总是感到困扰。
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: desired-solution
|
||||
attributes:
|
||||
label: 你希望看到什么解决方案?
|
||||
description: 清晰并简洁地描述你希望发生的事情。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: 你考虑过哪些替代方案?
|
||||
description: 清晰并简洁地描述你考虑过的任何替代解决方案或功能。
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: 你有其他上下文或截图吗?
|
||||
description: 在此处添加有关功能请求的任何其他上下文或截图。
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 意向参与贡献
|
||||
options:
|
||||
- label: 我有意向参与具体功能的开发实现并将代码贡献回到上游社区
|
||||
required: false
|
||||
@@ -1,6 +0,0 @@
|
||||
ports:
|
||||
- port: 5555
|
||||
onOpen: open-preview
|
||||
tasks:
|
||||
- init: npm i -g corepack && pnpm install
|
||||
command: pnpm run dev:play
|
||||
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 348 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 201 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 495 KiB |
|
Before Width: | Height: | Size: 177 KiB |
|
Before Width: | Height: | Size: 126 KiB |
@@ -1 +0,0 @@
|
||||
22.1.0
|
||||
289
README.md
@@ -1,237 +1,108 @@
|
||||
# 严肃声明:现在、未来都不会有商业版本,所有代码全部开源
|
||||
# aiotagro-ui-admin-vben - 企业级管理系统框架
|
||||
|
||||
**「我喜欢写代码,乐此不疲」**
|
||||
**「我喜欢做开源,以此为乐」**
|
||||
## 项目简介
|
||||
|
||||
我 🐶 在上海艰苦奋斗,早中晚在 top3 大厂认真搬砖,夜里为开源做贡献。
|
||||
aiotagro-ui-admin-vben 是基于 Vue3 + TypeScript + Vite 的现代化企业级管理系统框架,采用 monorepo 架构,提供完整的前端解决方案。
|
||||
|
||||
如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。
|
||||
## 核心特性
|
||||
|
||||
## 🐶 新手必读
|
||||
- 🚀 **现代化技术栈**:Vue3 + TypeScript + Vite + Pinia
|
||||
- 📦 **Monorepo 架构**:基于 pnpm + turbo 的高效开发体验
|
||||
- 🎨 **多主题支持**:Ant Design、Element Plus、Naive UI 三套 UI 组件库
|
||||
- 🔧 **完整工具链**:ESLint、Prettier、StyleLint、TypeScript 检查
|
||||
- 📱 **响应式设计**:完美适配桌面端和移动端
|
||||
- 🌐 **国际化支持**:内置多语言解决方案
|
||||
- 🔐 **权限管理**:完整的 RBAC 权限控制系统
|
||||
|
||||
- nodejs > 20.10.0 && pnpm > 10.14.0 (强制使用pnpm)
|
||||
- 演示地址【Vue3 + element-plus】:<http://dashboard-vue3.yudao.iocoder.cn>
|
||||
- 演示地址【Vue3 + vben5(ant-design-vue)】:<http://dashboard-vben.yudao.iocoder.cn>
|
||||
- 演示地址【Vue2 + element-ui】:<http://dashboard.yudao.iocoder.cn>
|
||||
- 启动文档:<https://doc.iocoder.cn/quick-start/>
|
||||
- 视频教程:<https://doc.iocoder.cn/video/>
|
||||
## 项目结构
|
||||
|
||||
## 🐯 平台简介
|
||||
```
|
||||
aiotagro-ui-admin-vben/
|
||||
├── apps/ # 应用目录
|
||||
│ ├── web-antd/ # Ant Design 版本
|
||||
│ ├── web-ele/ # Element Plus 版本
|
||||
│ ├── web-naive/ # Naive UI 版本
|
||||
│ └── backend-mock/ # 后端模拟服务
|
||||
├── packages/ # 共享包目录
|
||||
│ ├── @core/ # 核心功能包
|
||||
│ ├── constants/ # 常量定义
|
||||
│ ├── effects/ # 副作用管理
|
||||
│ ├── icons/ # 图标库
|
||||
│ ├── locales/ # 国际化资源
|
||||
│ ├── stores/ # 状态管理
|
||||
│ ├── styles/ # 样式文件
|
||||
│ ├── types/ # 类型定义
|
||||
│ └── utils/ # 工具函数
|
||||
├── internal/ # 内部配置
|
||||
│ ├── lint-configs/ # 代码规范配置
|
||||
│ ├── tailwind-config/ # Tailwind 配置
|
||||
│ ├── tsconfig/ # TypeScript 配置
|
||||
│ └── vite-config/ # Vite 配置
|
||||
├── docs/ # 项目文档
|
||||
├── playground/ # 开发测试环境
|
||||
└── scripts/ # 脚本工具
|
||||
```
|
||||
|
||||
**芋道**,以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。
|
||||
## 快速开始
|
||||
|
||||
- 采用最新 [vue-vben-admin](https://github.com/vbenjs/vue-vben-admin) v5 实现
|
||||
- 支持 [Ant Design Vue](https://www.antdv.com/) | [Element Plus](https://element-plus.org/zh-CN/) | [Naive UI](https://www.naiveui.com/) 多种免费开源的中后台模版,具备如下特性:
|
||||
### 环境要求
|
||||
|
||||

|
||||
- Node.js >= 18.0.0
|
||||
- pnpm >= 8.0.0
|
||||
|
||||
- **最新技术栈**:使用 Vue3、Vite6 等前端前沿技术开发
|
||||
- **TypeScript**: 应用程序级 JavaScript 的语言
|
||||
- **主题**: 提供多套主题色彩,可配置自定义主题
|
||||
- **国际化**:内置完善的国际化方案
|
||||
- **权限**:内置完善的动态路由权限生成方案
|
||||
- **组件**:二次封装了多个常用的组件
|
||||
- **示例**:内置丰富的示例
|
||||
### 安装依赖
|
||||
|
||||
## 外包项目请联系【非项目需求请勿扫码,非客服,不解答项目问题】
|
||||
```bash
|
||||
# 安装 pnpm
|
||||
npm install -g pnpm
|
||||
|
||||

|
||||
# 安装项目依赖
|
||||
pnpm install
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
### 开发运行
|
||||
|
||||
| 框架 | 说明 | 版本 |
|
||||
| --- | --- | --- |
|
||||
| [Vue](https://staging-cn.vuejs.org/) | vue框架 | 3.5.17 |
|
||||
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 7.1.2 |
|
||||
| [Ant Design Vue](https://www.antdv.com/) | Ant Design Vue | 4.2.6 |
|
||||
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.10.2 |
|
||||
| [Naive UI](https://www.naiveui.com/) | Naive UI | 2.42.0 |
|
||||
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 超集 | 5.8.3 |
|
||||
| [pinia](https://pinia.vuejs.org/) | Vue 存储库替代 vuex5 | 3.0.3 |
|
||||
| [vueuse](https://vueuse.org/) | 常用工具集 | 13.4.0 |
|
||||
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.1.7 |
|
||||
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.5.1 |
|
||||
| [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 3.4.17 |
|
||||
| [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.354 |
|
||||
| [TinyMCE](https://www.tiny.cloud/) | 富文本编辑器 | 6.1.0 |
|
||||
| [Echarts](https://echarts.apache.org/) | 图表库 | 5.6.0 |
|
||||
| [axios](https://axios-http.com/) | http客户端 | 1.10.0 |
|
||||
| [dayjs](https://day.js.org/) | 日期处理库 | 1.11.13 |
|
||||
| [vee-validate](https://vee-validate.logaretm.com/) | 表单验证 | 4.15.1 |
|
||||
| [zod](https://zod.dev/) | 数据验证 | 3.25.67 |
|
||||
```bash
|
||||
# 启动 Ant Design 版本
|
||||
pnpm dev:antd
|
||||
|
||||
## 🔥 后端架构
|
||||
# 启动 Element Plus 版本
|
||||
pnpm dev:ele
|
||||
|
||||
支持 Spring Boot、Spring Cloud 两种架构:
|
||||
# 启动 Naive UI 版本
|
||||
pnpm dev:naive
|
||||
```
|
||||
|
||||
① Spring Boot 单体架构:<https://doc.iocoder.cn>
|
||||
### 构建项目
|
||||
|
||||

|
||||
```bash
|
||||
# 构建所有应用
|
||||
pnpm build
|
||||
|
||||
② Spring Cloud 微服务架构:<https://cloud.iocoder.cn>
|
||||
# 构建指定应用
|
||||
pnpm build:antd
|
||||
pnpm build:ele
|
||||
pnpm build:naive
|
||||
```
|
||||
|
||||

|
||||
## 文档目录
|
||||
|
||||
## 内置功能
|
||||
详细文档请查看 [docs/](./docs/) 目录:
|
||||
|
||||
系统内置多种多种业务功能,可以用于快速你的业务系统:
|
||||
- [📚 技术文档](./docs/) - 开发指南、API 文档
|
||||
- [👥 用户手册](./docs/user-guide/) - 系统使用说明
|
||||
- [🚀 部署指南](./docs/deployment/) - 生产环境部署
|
||||
- [🔧 运维手册](./docs/operations/) - 系统维护指南
|
||||
|
||||
系统内置多种多种业务功能,可以用于快速你的业务系统:
|
||||
## 贡献指南
|
||||
|
||||

|
||||
欢迎提交 Issue 和 Pull Request!请阅读 [贡献指南](./docs/contributing.md) 了解详细流程。
|
||||
|
||||
- 通用模块(必选):系统功能、基础设施
|
||||
- 通用模块(可选):工作流程、支付系统、数据报表、会员中心
|
||||
- 业务系统(按需):ERP 系统、CRM 系统、商城系统、微信公众号、AI 大模型
|
||||
## 许可证
|
||||
|
||||
### 系统功能
|
||||
本项目基于 MIT 许可证开源。
|
||||
|
||||
| | 功能 | 描述 |
|
||||
| --- | --- | --- |
|
||||
| | 用户管理 | 用户是系统操作者,该功能主要完成系统用户配置 |
|
||||
| ⭐️ | 在线用户 | 当前系统中活跃用户状态监控,支持手动踢下线 |
|
||||
| | 角色管理 | 角色菜单权限分配、设置角色按机构进行数据范围权限划分 |
|
||||
| | 菜单管理 | 配置系统菜单、操作权限、按钮权限标识等,本地缓存提供性能 |
|
||||
| | 部门管理 | 配置系统组织机构(公司、部门、小组),树结构展现支持数据权限 |
|
||||
| | 岗位管理 | 配置系统用户所属担任职务 |
|
||||
| 🚀 | 租户管理 | 配置系统租户,支持 SaaS 场景下的多租户功能 |
|
||||
| 🚀 | 租户套餐 | 配置租户套餐,自定每个租户的菜单、操作、按钮的权限 |
|
||||
| | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 |
|
||||
| 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、腾讯云等主流短信平台 |
|
||||
| 🚀 | 邮件管理 | 邮箱账号、邮件模版、邮件发送日志,支持所有邮件平台 |
|
||||
| 🚀 | 站内信 | 系统内的消息通知,提供站内信模版、站内信消息 |
|
||||
| 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 |
|
||||
| ⭐️ | 登录日志 | 系统登录日志记录查询,包含登录异常 |
|
||||
| 🚀 | 错误码管理 | 系统所有错误码的管理,可在线修改错误提示,无需重启服务 |
|
||||
| | 通知公告 | 系统通知公告信息发布维护 |
|
||||
| 🚀 | 敏感词 | 配置系统敏感词,支持标签分组 |
|
||||
| 🚀 | 应用管理 | 管理 SSO 单点登录的应用,支持多种 OAuth2 授权方式 |
|
||||
| 🚀 | 地区管理 | 展示省份、城市、区镇等城市信息,支持 IP 对应城市 |
|
||||
## 联系方式
|
||||
|
||||

|
||||
|
||||
### 工作流程
|
||||
|
||||

|
||||
|
||||
基于 Flowable 构建,可支持信创(国产)数据库,满足中国特色流程操作:
|
||||
|
||||
| BPMN 设计器 | 钉钉/飞书设计器 |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|
||||
> 历经头部企业生产验证,工作流引擎须标配仿钉钉/飞书 + BPMN 双设计器!!!
|
||||
>
|
||||
> 前者支持轻量配置简单流程,后者实现复杂场景深度编排
|
||||
|
||||
| 功能列表 | 功能描述 | 是否完成 |
|
||||
| --- | --- | --- |
|
||||
| SIMPLE 设计器 | 仿钉钉/飞书设计器,支持拖拽搭建表单流程,10 分钟快速完成审批流程配置 | ✅ |
|
||||
| BPMN 设计器 | 基于 BPMN 标准开发,适配复杂业务场景,满足多层级审批及流程自动化需求 | ✅ |
|
||||
| 会签 | 同一个审批节点设置多个人(如 A、B、C 三人,三人会同时收到待办任务),需全部同意之后,审批才可到下一审批节点 | ✅ |
|
||||
| 或签 | 同一个审批节点设置多个人,任意一个人处理后,就能进入下一个节点 | ✅ |
|
||||
| 依次审批 | (顺序会签)同一个审批节点设置多个人(如 A、B、C 三人),三人按顺序依次收到待办,即 A 先审批,A 提交后 B 才能审批,需全部同意之后,审批才可到下一审批节点 | ✅ |
|
||||
| 抄送 | 将审批结果通知给抄送人,同一个审批默认排重,不重复抄送给同一人 | ✅ |
|
||||
| 驳回 | (退回)将审批重置发送给某节点,重新审批。可驳回至发起人、上一节点、任意节点 | ✅ |
|
||||
| 转办 | A 转给其 B 审批,B 审批后,进入下一节点 | ✅ |
|
||||
| 委派 | A 转给其 B 审批,B 审批后,转给 A,A 继续审批后进入下一节点 | ✅ |
|
||||
| 加签 | 允许当前审批人根据需要,自行增加当前节点的审批人,支持向前、向后加签 | ✅ |
|
||||
| 减签 | (取消加签)在当前审批人操作之前,减少审批人 | ✅ |
|
||||
| 撤销 | (取消流程)流程发起人,可以对流程进行撤销处理 | ✅ |
|
||||
| 终止 | 系统管理员,在任意节点终止流程实例 | ✅ |
|
||||
| 表单权限 | 支持拖拉拽配置表单,每个审批节点可配置只读、编辑、隐藏权限 | ✅ |
|
||||
| 超时审批 | 配置超时审批时间,超时后自动触发审批通过、不通过、驳回等操作 | ✅ |
|
||||
| 自动提醒 | 配置提醒时间,到达时间后自动触发短信、邮箱、站内信等通知提醒,支持自定义重复提醒频次 | ✅ |
|
||||
| 父子流程 | 主流程设置子流程节点,子流程节点会自动触发子流程。子流程结束后,主流程才会执行(继续往下下执行),支持同步子流程、异步子流程 | ✅ |
|
||||
| 条件分支 | (排它分支)用于在流程中实现决策,即根据条件选择一个分支执行 | ✅ |
|
||||
| 并行分支 | 允许将流程分成多条分支,不进行条件判断,所有分支都会执行 | ✅ |
|
||||
| 包容分支 | (条件分支 + 并行分支的结合体)允许基于条件选择多条分支执行,但如果没有任何一个分支满足条件,则可以选择默认分支 | ✅ |
|
||||
| 路由分支 | 根据条件选择一个分支执行(重定向到指定配置节点),也可以选择默认分支执行(继续往下执行) | ✅ |
|
||||
| 触发节点 | 执行到该节点,触发 HTTP 请求、HTTP 回调、更新数据、删除数据等 | ✅ |
|
||||
| 延迟节点 | 执行到该节点,审批等待一段时间再执行,支持固定时长、固定日期等 | ✅ |
|
||||
| 拓展设置 | 流程前置/后置通知,节点(任务)前置、后置通知,流程报表,自动审批去重,自定流程编号、标题、摘要,流程报表等 | ✅ |
|
||||
|
||||
### 支付系统
|
||||
|
||||
| | 功能 | 描述 |
|
||||
| --- | -------- | -------------------------------------------------- |
|
||||
| 🚀 | 应用信息 | 配置商户的应用信息,对接支付宝、微信等多个支付渠道 |
|
||||
| 🚀 | 支付订单 | 查看用户发起的支付宝、微信等的【支付】订单 |
|
||||
| 🚀 | 退款订单 | 查看用户发起的支付宝、微信等的【退款】订单 |
|
||||
| 🚀 | 回调通知 | 查看支付回调业务的【支付】【退款】的通知结果 |
|
||||
| 🚀 | 接入示例 | 提供接入支付系统的【支付】【退款】的功能实战 |
|
||||
|
||||
### 基础设施
|
||||
|
||||
| | 功能 | 描述 |
|
||||
| --- | --- | --- |
|
||||
| 🚀 | 代码生成 | 前后端代码的生成(Java、Vue、SQL、单元测试),支持 CRUD 下载 |
|
||||
| 🚀 | 系统接口 | 基于 Swagger 自动生成相关的 RESTful API 接口文档 |
|
||||
| 🚀 | 数据库文档 | 基于 Screw 自动生成数据库文档,支持导出 Word、HTML、MD 格式 |
|
||||
| | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 |
|
||||
| 🚀 | 配置管理 | 对系统动态配置常用参数,支持 SpringBoot 加载 |
|
||||
| ⭐️ | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 |
|
||||
| 🚀 | 文件服务 | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等 |
|
||||
| 🚀 | WebSocket | 提供 WebSocket 接入示例,支持一对一、一对多发送方式 |
|
||||
| 🚀 | API 日志 | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题 |
|
||||
| | MySQL 监控 | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈 |
|
||||
| | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理 |
|
||||
| 🚀 | 消息队列 | 基于 Redis 实现消息队列,Stream 提供集群消费,Pub/Sub 提供广播消费 |
|
||||
| 🚀 | Java 监控 | 基于 Spring Boot Admin 实现 Java 应用的监控 |
|
||||
| 🚀 | 链路追踪 | 接入 SkyWalking 组件,实现链路追踪 |
|
||||
| 🚀 | 日志中心 | 接入 SkyWalking 组件,实现日志中心 |
|
||||
| 🚀 | 服务保障 | 基于 Redis 实现分布式锁、幂等、限流功能,满足高并发场景 |
|
||||
| 🚀 | 日志服务 | 轻量级日志中心,查看远程服务器的日志 |
|
||||
| 🚀 | 单元测试 | 基于 JUnit + Mockito 实现单元测试,保证功能的正确性、代码的质量等 |
|
||||
|
||||

|
||||
|
||||
### 数据报表
|
||||
|
||||
| | 功能 | 描述 |
|
||||
| --- | ---------- | ------------------------------------ |
|
||||
| 🚀 | 报表设计器 | 支持数据报表、图形报表、打印设计等 |
|
||||
| 🚀 | 大屏设计器 | 拖拽生成数据大屏,内置几十种图表组件 |
|
||||
|
||||
### 微信公众号
|
||||
|
||||
| | 功能 | 描述 |
|
||||
| --- | --- | --- |
|
||||
| 🚀 | 账号管理 | 配置接入的微信公众号,可支持多个公众号 |
|
||||
| 🚀 | 数据统计 | 统计公众号的用户增减、累计用户、消息概况、接口分析等数据 |
|
||||
| 🚀 | 粉丝管理 | 查看已关注、取关的粉丝列表,可对粉丝进行同步、打标签等操作 |
|
||||
| 🚀 | 消息管理 | 查看粉丝发送的消息列表,可主动回复粉丝消息 |
|
||||
| 🚀 | 自动回复 | 自动回复粉丝发送的消息,支持关注回复、消息回复、关键字回复 |
|
||||
| 🚀 | 标签管理 | 对公众号的标签进行创建、查询、修改、删除等操作 |
|
||||
| 🚀 | 菜单管理 | 自定义公众号的菜单,也可以从公众号同步菜单 |
|
||||
| 🚀 | 素材管理 | 管理公众号的图片、语音、视频等素材,支持在线播放语音、视频 |
|
||||
| 🚀 | 图文草稿箱 | 新增常用的图文素材到草稿箱,可发布到公众号 |
|
||||
| 🚀 | 图文发表记录 | 查看已发布成功的图文素材,支持删除操作 |
|
||||
|
||||
### 商城系统
|
||||
|
||||
演示地址:<https://doc.iocoder.cn/mall-preview/>
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### ERP 系统
|
||||
|
||||
演示地址:<https://doc.iocoder.cn/erp-preview/>
|
||||
|
||||

|
||||
|
||||
### CRM 系统
|
||||
|
||||
演示地址:<https://doc.iocoder.cn/crm-preview/>
|
||||
|
||||

|
||||
|
||||
### AI 大模型
|
||||
|
||||
演示地址:<https://doc.iocoder.cn/ai-preview/>
|
||||
|
||||

|
||||
|
||||

|
||||
- 项目主页:https://github.com/vbenjs/vue-vben-admin
|
||||
- 问题反馈:https://github.com/vbenjs/vue-vben-admin/issues
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
## Description
|
||||
|
||||
Vben Admin 数据 mock 服务,没有对接任何的数据库,所有数据都是模拟的,用于前端开发时提供数据支持。线上环境不再提供 mock 集成,可自行部署服务或者对接真实数据,由于 `mock.js` 等工具有一些限制,比如上传文件不行、无法模拟复杂的逻辑等,所以这里使用了真实的后端服务来实现。唯一麻烦的是本地需要同时启动后端服务和前端服务,但是这样可以更好的模拟真实环境。该服务不需要手动启动,已经集成在 vite 插件内,随应用一起启用。
|
||||
|
||||
Vben Admin 数据 mock 服务,没有对接任何的数据库,所有数据都是模拟的,用于前端开发时提供数据支持。线上环境不再提<EFBFBD><EFBFBD>?mock 集成,可自行部署服务或者对接真实数据,由于 `mock.js` 等工具有一些限制,比如上传文件不行、无法模拟复杂的逻辑等,所以这里使用了真实的后端服务来实现。唯一麻烦的是本地需要同时启动后端服务和前端服务,但是这样可以更好的模拟真实环境。该服务不需要手动启动,已经集成<EFBFBD><EFBFBD>?vite 插件内,随应用一起启用<EFBFBD><EFBFBD>?
|
||||
## Running the app
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Software License Agreement
|
||||
|
||||
**TinyMCE** – [<https://github.com/tinymce/tinymce>](https://github.com/tinymce/tinymce)
|
||||
**TinyMCE** <EFBFBD><EFBFBD>?[<https://github.com/tinymce/tinymce>](https://github.com/tinymce/tinymce)
|
||||
Copyright (c) 2024, Ephox Corporation DBA Tiny Technologies, Inc.
|
||||
|
||||
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
|
||||
|
||||
@@ -161,7 +161,7 @@ setupVbenVxeTable({
|
||||
});
|
||||
|
||||
// 表格配置项可以用 cellRender: { name: 'CellSwitch', props: { beforeChange: () => {} } },
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L97-L123
|
||||
// add by AIOTAGRO:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L97-L123
|
||||
vxeUI.renderer.add('CellSwitch', {
|
||||
renderTableDefault({ attrs, props }, { column, row }) {
|
||||
const loadingKey = `__loading_${column.field}`;
|
||||
@@ -193,7 +193,7 @@ setupVbenVxeTable({
|
||||
});
|
||||
|
||||
// 注册表格的操作按钮渲染器 cellRender: { name: 'CellOperation', options: ['edit', 'delete'] }
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L125-L255
|
||||
// add by AIOTAGRO:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L125-L255
|
||||
vxeUI.renderer.add('CellOperation', {
|
||||
renderTableDefault({ attrs, options, props }, { column, row }) {
|
||||
const defaultProps = { size: 'small', type: 'link', ...props };
|
||||
|
||||
@@ -2,7 +2,7 @@ import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmModelApi {
|
||||
/** 用户信息 TODO 这个是不是可以抽取出来定义在公共模块 */
|
||||
// TODO @芋艿:一起看看。
|
||||
// TODO @AIOTAGRO:一起看看。
|
||||
export interface UserInfo {
|
||||
id: number;
|
||||
nickname: string;
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { BpmModelApi } from '#/api/bpm/model';
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmProcessInstanceApi {
|
||||
// TODO @芋艿:一些注释缺少或者不对;
|
||||
// TODO @AIOTAGRO:一些注释缺少或者不对;
|
||||
export interface Task {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
@@ -59,7 +59,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
}
|
||||
const resp = await refreshTokenApi(refreshToken);
|
||||
const newToken = resp?.data?.data?.accessToken;
|
||||
// add by 芋艿:这里一定要抛出 resp.data,从而触发 authenticateResponseInterceptor 中,刷新令牌失败!!!
|
||||
// add by AIOTAGRO:这里一定要抛出 resp.data,从而触发 authenticateResponseInterceptor 中,刷新令牌失败!!!
|
||||
if (!newToken) {
|
||||
throw resp.data;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
const responseData = error?.response?.data ?? {};
|
||||
const errorMessage =
|
||||
responseData?.error ?? responseData?.message ?? responseData.msg ?? '';
|
||||
// add by 芋艿:特殊:避免 401 “账号未登录”,重复提示。因为,此时会跳转到登录界面,只需提示一次!!!
|
||||
// add by AIOTAGRO:特殊:避免 401 "账号未登录",重复提示。因为,此时会跳转到登录界面,只需提示一次!!!
|
||||
if (error?.data?.code === 401) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ const previewProcessJson = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/* ------------------------------------------------ 芋道源码 methods ------------------------------------------------------ */
|
||||
/* ------------------------------------------------ AIOTAGRO methods ------------------------------------------------------ */
|
||||
onMounted(() => {
|
||||
initBpmnModeler();
|
||||
createNewDiagram(props.value);
|
||||
|
||||
@@ -466,7 +466,7 @@ watch(
|
||||
@change="() => updateLoopBase()"
|
||||
/>
|
||||
</FormItem>
|
||||
<!-- add by 芋艿:由于「元素变量」暂时用不到,所以这里 display 为 none -->
|
||||
<!-- add by AIOTAGRO:由于「元素变量」暂时用不到,所以这里 display 为 none -->
|
||||
<FormItem label="元素变量" key="elementVariable" class="hidden">
|
||||
<Input
|
||||
v-model:value="loopInstanceForm.elementVariable"
|
||||
@@ -484,7 +484,7 @@ watch(
|
||||
"
|
||||
/>
|
||||
</FormItem>
|
||||
<!-- add by 芋艿:由于「异步状态」暂时用不到,所以这里 display 为 none -->
|
||||
<!-- add by AIOTAGRO:由于「异步状态」暂时用不到,所以这里 display 为 none -->
|
||||
<FormItem label="异步状态" key="async" class="hidden">
|
||||
<Checkbox
|
||||
v-model:checked="loopInstanceForm.asyncBefore"
|
||||
|
||||
@@ -64,7 +64,7 @@ watch(
|
||||
<template>
|
||||
<div class="panel-tab__content">
|
||||
<Form>
|
||||
<!-- add by 芋艿:由于「异步延续」暂时用不到,所以这里 display 为 none -->
|
||||
<!-- add by AIOTAGRO:由于「异步延续」暂时用不到,所以这里 display 为 none -->
|
||||
<FormItem label="异步延续" class="hidden">
|
||||
<Checkbox
|
||||
v-model:checked="taskConfigForm.asyncBefore"
|
||||
|
||||
@@ -219,7 +219,7 @@ const resetTaskForm = () => {
|
||||
const changeCandidateStrategy = () => {
|
||||
userTaskForm.value.candidateParam = [];
|
||||
deptLevel.value = 1;
|
||||
// 注释 by 芋艿:这个交互很多用户反馈费解,https://t.zsxq.com/xNmas 所以暂时屏蔽
|
||||
// 注释 by AIOTAGRO:这个交互很多用户反馈费解,https://t.zsxq.com/xNmas 所以暂时屏蔽
|
||||
// if (userTaskForm.value.candidateStrategy === CandidateStrategy.FORM_USER) {
|
||||
// // 特殊处理表单内用户字段,当只有发起人选项时应选中发起人
|
||||
// if (!userFieldOnFormOptions.value || userFieldOnFormOptions.value.length <= 1) {
|
||||
|
||||
@@ -121,9 +121,9 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||
parseOptions0(data);
|
||||
return;
|
||||
}
|
||||
// 情况三:不是 yudao-vue-pro 标准返回
|
||||
// 情况三:不是 aiotagro-vue-pro 标准返回
|
||||
console.warn(
|
||||
`接口[${props.url}] 返回结果不是 yudao-vue-pro 标准返回建议采用自定义解析函数处理`,
|
||||
`接口[${props.url}] 返回结果不是 aiotagro-vue-pro 标准返回建议采用自定义解析函数处理`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Rule } from '@form-create/ant-design-vue';
|
||||
/** 数据字典 Select 选择器组件 Props 类型 */
|
||||
export interface DictSelectProps {
|
||||
dictType: string; // 字典类型
|
||||
valueType?: 'bool' | 'int' | 'str'; // 字典值类型 TODO @芋艿:'boolean' | 'number' | 'string';需要和 vue3 一起统一!
|
||||
valueType?: 'bool' | 'int' | 'str'; // 字典值类型 TODO @AIOTAGRO:'boolean' | 'number' | 'string';需要和 vue3 一起统一!
|
||||
selectType?: 'checkbox' | 'radio' | 'select'; // 选择器类型,下拉框 select、多选框 checkbox、单选框 radio
|
||||
formCreateInject?: any;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// TODO @芋艿:是否有更好的组织形式?!
|
||||
// TODO @AIOTAGRO:是否有更好的组织形式?!
|
||||
<script lang="ts" setup>
|
||||
import type { DataNode } from 'ant-design-vue/es/tree';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
// TODO @芋艿:是否有更好的组织形式?!
|
||||
// TODO @AIOTAGRO:是否有更好的组织形式?!
|
||||
// TODO @xingyu:你感觉,这个放到每个 system、infra 模块下,然后新建一个 components,表示每个模块,有一些共享的组件?然后,全局只放通用的(无业务含义的),可以哇?
|
||||
import type { Key } from 'ant-design-vue/es/table/interface';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
// TODO @芋艿:后续是不是把业务组件,挪到每个模块里;待定;
|
||||
// TODO @AIOTAGRO:后续是不是把业务组件,挪到每个模块里;待定;
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import type { SimpleFlowNode } from '../../consts';
|
||||
|
||||
@@ -178,7 +178,7 @@ export function useFormFields() {
|
||||
return parseFormCreateFields(unref(formFields));
|
||||
}
|
||||
|
||||
// TODO @芋艿:后续需要把各种类似 useFormFieldsPermission 的逻辑,抽成一个通用方法。
|
||||
// TODO @AIOTAGRO:后续需要把各种类似 useFormFieldsPermission 的逻辑,抽成一个通用方法。
|
||||
/**
|
||||
* @description 获取流程表单的字段和发起人字段
|
||||
*/
|
||||
|
||||
@@ -78,7 +78,7 @@ export function useUploadType({
|
||||
return { getAccept, getStringAccept, getHelpText };
|
||||
}
|
||||
|
||||
// TODO @芋艿:目前保持和 admin-vue3 一致,后续可能重构
|
||||
// TODO @AIOTAGRO:目前保持和 admin-vue3 一致,后续可能重构
|
||||
export function useUpload(directory?: string) {
|
||||
// 后端上传地址
|
||||
const uploadUrl = getUploadUrl();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# locale
|
||||
|
||||
每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。
|
||||
每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件<EFBFBD><EFBFBD>?
|
||||
|
||||
@@ -20,6 +20,6 @@ export const overridesPreferences = defineOverridesPreferences({
|
||||
},
|
||||
copyright: {
|
||||
companyName: import.meta.env.VITE_APP_TITLE,
|
||||
companySiteLink: 'https://gitee.com/yudaocode/yudao-ui-admin-vben',
|
||||
companySiteLink: 'https://gitee.com/yudaocode/yudao-ui-admin-vben' // AIOTAGRO,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
||||
return await generateAccessible(preferences.app.accessMode, {
|
||||
...options,
|
||||
fetchMenuListAsync: async () => {
|
||||
// 由于 yudao 通过 accessStore 读取,所以不在进行 message.loading 提示
|
||||
// 由于 AIOTAGRO 通过 accessStore 读取,所以不在进行 message.loading 提示
|
||||
// 补充说明:accessStore.accessMenus 一开始是 AppRouteRecordRaw 类型(后端加载),后面被赋值成 MenuRecordRaw 类型(前端转换)
|
||||
const accessMenus = accessStore.accessMenus as AppRouteRecordRaw[];
|
||||
return convertServerMenuToRouteRecordStringComponent(accessMenus);
|
||||
|
||||
@@ -102,7 +102,7 @@ function setupAccessGuard(router: Router) {
|
||||
// 当前登录用户拥有的角色标识列表
|
||||
let userInfo = userStore.userInfo;
|
||||
if (!userInfo) {
|
||||
// add by 芋艿:由于 yudao 是 fetchUserInfo 统一加载用户 + 权限信息,所以将 fetchMenuListAsync
|
||||
// add by 芋艿:由于 AIOTAGRO 是 fetchUserInfo 统一加载用户 + 权限信息,所以将 fetchMenuListAsync
|
||||
const loading = message.loading({
|
||||
content: `${$t('common.loadingMenu')}...`,
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name);
|
||||
/** 有权限校验的路由列表,包含动态路由和静态路由 */
|
||||
const accessRoutes = [...dynamicRoutes, ...staticRoutes];
|
||||
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/router/routes/index.ts#L38-L45
|
||||
// add by AIOTAGRO:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/router/routes/index.ts#L38-L45
|
||||
const componentKeys: string[] = Object.keys(
|
||||
import.meta.glob('../../views/**/*.vue'),
|
||||
)
|
||||
|
||||
@@ -78,4 +78,4 @@ const routes: RouteRecordRaw[] = [
|
||||
// },
|
||||
];
|
||||
|
||||
export default routes; // update by 芋艿:不展示
|
||||
export default routes; // update by AIOTAGRO:不展示
|
||||
|
||||
@@ -71,7 +71,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
accessStore.setRefreshToken(refreshToken);
|
||||
|
||||
// 获取用户信息并存储到 userStore、accessStore 中
|
||||
// TODO @芋艿:清理掉 accessCodes 相关的逻辑
|
||||
// TODO @AIOTAGRO:清理掉 accessCodes 相关的逻辑
|
||||
// const [fetchUserInfoResult, accessCodes] = await Promise.all([
|
||||
// fetchUserInfo(),
|
||||
// // getAccessCodesApi(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 针对 https://github.com/xaboy/form-create-designer 封装的工具类
|
||||
*/
|
||||
// TODO @芋艿:后续这些 form-create 的优化;另外需要使用 form-create-helper 会好点
|
||||
// TODO @AIOTAGRO:后续这些 form-create 的优化;另外需要使用 form-create-helper 会好点
|
||||
import { isRef } from 'vue';
|
||||
|
||||
import formCreate from '@form-create/ant-design-vue';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# \_core
|
||||
|
||||
此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。
|
||||
此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图<EFBFBD><EFBFBD>?
|
||||
|
||||
@@ -57,7 +57,7 @@ onMounted(loadProfile);
|
||||
<Tabs.TabPane key="userSocial" tab="社交绑定" force-render>
|
||||
<UserSocial @update:active-name="activeName = $event" />
|
||||
</Tabs.TabPane>
|
||||
<!-- TODO @芋艿:在线设备 -->
|
||||
<!-- TODO @AIOTAGRO:在线设备 -->
|
||||
</Tabs>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@ async function handlerPromptClick(prompt: any) {
|
||||
<!-- center-container -->
|
||||
<div class="flex flex-col justify-center">
|
||||
<!-- title -->
|
||||
<div class="text-center text-3xl font-bold">芋道 AI</div>
|
||||
<div class="text-center text-3xl font-bold">AIOTAGRO AI</div>
|
||||
|
||||
<!-- role-list -->
|
||||
<div class="mt-5 flex w-96 flex-wrap items-center justify-center">
|
||||
|
||||
@@ -490,11 +490,11 @@ onMounted(async () => {
|
||||
activeMessageListLoading.value = true;
|
||||
await getMessageList();
|
||||
});
|
||||
// TODO @芋艿:深度思考
|
||||
// TODO @芋艿:联网搜索
|
||||
// TODO @芋艿:附件支持
|
||||
// TODO @芋艿:mcp 相关
|
||||
// TODO @芋艿:异常消息的处理
|
||||
// TODO @AIOTAGRO:深度思考
|
||||
// TODO @AIOTAGRO:联网搜索
|
||||
// TODO @AIOTAGRO:附件支持
|
||||
// TODO @AIOTAGRO:mcp 相关
|
||||
// TODO @AIOTAGRO:异常消息的处理
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -180,7 +180,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
});
|
||||
|
||||
/** 获取数据源配置列表 */
|
||||
// TODO @芋艿:这种场景的最佳实践;
|
||||
// TODO @AIOTAGRO:这种场景的最佳实践;
|
||||
async function initDataSourceConfig() {
|
||||
try {
|
||||
dataSourceConfigList.value = await getDataSourceConfigList();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
// TODO @芋艿:待定,vben2.0 有 CodeEditor,不确定官方后续会不会迁移!!!
|
||||
// TODO @AIOTAGRO:待定,vben2.0 有 CodeEditor,不确定官方后续会不会迁移!!!
|
||||
import type { InfraCodegenApi } from '#/api/infra/codegen';
|
||||
|
||||
import { h, ref } from 'vue';
|
||||
|
||||
@@ -150,7 +150,7 @@ export function useTypeGridColumns(): VxeTableGridOptions['columns'] {
|
||||
|
||||
// ============================== 字典数据 ==============================
|
||||
|
||||
// TODO @芋艿:后续针对 antd,增加
|
||||
// TODO @AIOTAGRO:后续针对 antd,增加
|
||||
/**
|
||||
* 颜色选项
|
||||
*/
|
||||
|
||||
@@ -125,7 +125,7 @@ export function useDetailSchema(): DescriptionItemSchema[] {
|
||||
{
|
||||
field: 'avatar',
|
||||
label: '用户头像',
|
||||
// TODO @芋艿:使用 antd 的 Image 组件
|
||||
// TODO @AIOTAGRO:使用 antd 的 Image 组件
|
||||
content: (data: SystemSocialUserApi.SocialUser) => {
|
||||
if (data?.avatar) {
|
||||
return h('img', {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Software License Agreement
|
||||
|
||||
**TinyMCE** – [<https://github.com/tinymce/tinymce>](https://github.com/tinymce/tinymce)
|
||||
**TinyMCE** <EFBFBD><EFBFBD>?[<https://github.com/tinymce/tinymce>](https://github.com/tinymce/tinymce)
|
||||
Copyright (c) 2024, Ephox Corporation DBA Tiny Technologies, Inc.
|
||||
|
||||
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
|
||||
|
||||
@@ -147,7 +147,7 @@ setupVbenVxeTable({
|
||||
});
|
||||
|
||||
// 表格配置项可以用 cellRender: { name: 'CellSwitch', props: { beforeChange: () => {} } },
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L97-L123
|
||||
// add by AIOTAGRO:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L97-L123
|
||||
vxeUI.renderer.add('CellSwitch', {
|
||||
renderTableDefault({ attrs, props }, { column, row }) {
|
||||
const loadingKey = `__loading_${column.field}`;
|
||||
@@ -179,7 +179,7 @@ setupVbenVxeTable({
|
||||
});
|
||||
|
||||
// 注册表格的操作按钮渲染器 cellRender: { name: 'CellOperation', options: ['edit', 'delete'] }
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L125-L255
|
||||
// add by AIOTAGRO:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L125-L255
|
||||
vxeUI.renderer.add('CellOperation', {
|
||||
renderTableDefault({ attrs, options, props }, { column, row }) {
|
||||
const defaultProps = {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmModelApi {
|
||||
/** 用户信息 TODO 这个是不是可以抽取出来定义在公共模块 */
|
||||
// TODO @芋艿:一起看看。
|
||||
// TODO @AIOTAGRO:一起看看。
|
||||
export interface UserInfo {
|
||||
id: number;
|
||||
nickname: string;
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { BpmModelApi } from '#/api/bpm/model';
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmProcessInstanceApi {
|
||||
// TODO @芋艿:一些注释缺少或者不对;
|
||||
// TODO @AIOTAGRO:一些注释缺少或者不对;
|
||||
export interface Task {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
@@ -59,7 +59,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
}
|
||||
const resp = await refreshTokenApi(refreshToken);
|
||||
const newToken = resp?.data?.data?.accessToken;
|
||||
// add by 芋艿:这里一定要抛出 resp.data,从而触发 authenticateResponseInterceptor 中,刷新令牌失败!!!
|
||||
// add by AIOTAGRO:这里一定要抛出 resp.data,从而触发 authenticateResponseInterceptor 中,刷新令牌失败!!!
|
||||
if (!newToken) {
|
||||
throw resp.data;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
const responseData = error?.response?.data ?? {};
|
||||
const errorMessage =
|
||||
responseData?.error ?? responseData?.message ?? responseData.msg ?? '';
|
||||
// add by 芋艿:特殊:避免 401 “账号未登录”,重复提示。因为,此时会跳转到登录界面,只需提示一次!!!
|
||||
// add by AIOTAGRO:特殊:避免 401 “账号未登录”,重复提示。因为,此时会跳转到登录界面,只需提示一次!!!
|
||||
if (error?.data?.code === 401) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
// TODO @芋艿:后续合并到 diy-editor 里,并不是通用的;
|
||||
// TODO @AIOTAGRO:后续合并到 diy-editor 里,并不是通用的;
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
import AppLinkSelectDialog from './app-link-select-dialog.vue';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
// TODO @芋艿:后续合并到 diy-editor 里,并不是通用的;
|
||||
// TODO @AIOTAGRO:后续合并到 diy-editor 里,并不是通用的;
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { PREDEFINE_COLORS } from '@vben/constants';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
// import { isHexColor } from '@/utils/color' // TODO @芋艿:【可优化】增加 cssClass 的处理 https://gitee.com/yudaocode/yudao-ui-admin-vben/blob/v2.4.1/src/components/DictTag/src/DictTag.vue#L60
|
||||
// import { isHexColor } from '@/utils/color' // TODO @AIOTAGRO:【可优化】增加 cssClass 的处理 https://gitee.com/yudaocode/yudao-ui-admin-vben/blob/v2.4.1/src/components/DictTag/src/DictTag.vue#L60
|
||||
import { getDictObj } from '@vben/hooks';
|
||||
|
||||
import { ElTag } from 'element-plus';
|
||||
|
||||
@@ -17,7 +17,7 @@ defineProps<{ property: UserCardProperty }>();
|
||||
<ElAvatar :size="60">
|
||||
<IconifyIcon icon="ep:avatar" :size="60" />
|
||||
</ElAvatar>
|
||||
<span class="text-[18px] font-bold">芋道源码</span>
|
||||
<span class="text-[18px] font-bold">AIOTAGRO</span>
|
||||
</div>
|
||||
<IconifyIcon icon="tdesign:qrcode" :size="20" />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
// TODO @芋艿:后续合并到 diy-editor 里,并不是通用的;
|
||||
// TODO @AIOTAGRO:后续合并到 diy-editor 里,并不是通用的;
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
import { cloneDeep } from '@vben/utils';
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Rule } from '@form-create/element-ui'; // 左侧拖拽按钮
|
||||
/** 数据字典 Select 选择器组件 Props 类型 */
|
||||
export interface DictSelectProps {
|
||||
dictType: string; // 字典类型
|
||||
valueType?: 'bool' | 'int' | 'str'; // 字典值类型 TODO @芋艿:'boolean' | 'number' | 'string';需要和 vue3 一起统一!
|
||||
valueType?: 'bool' | 'int' | 'str'; // 字典值类型 TODO @AIOTAGRO:'boolean' | 'number' | 'string';需要和 vue3 一起统一!
|
||||
selectType?: 'checkbox' | 'radio' | 'select'; // 选择器类型,下拉框 select、多选框 checkbox、单选框 radio
|
||||
formCreateInject?: any;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { PREDEFINE_COLORS } from '@vben/constants';
|
||||
|
||||
// TODO @芋艿:后续合并到 diy-editor 里,并不是通用的;
|
||||
// TODO @AIOTAGRO:后续合并到 diy-editor 里,并不是通用的;
|
||||
import { useVModels } from '@vueuse/core';
|
||||
import { ElColorPicker, ElInput } from 'element-plus';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
// TODO @芋艿:后续合并到 diy-editor 里,并不是通用的;
|
||||
// TODO @AIOTAGRO:后续合并到 diy-editor 里,并不是通用的;
|
||||
import type { Point, Rect } from './util';
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
@@ -231,7 +231,7 @@ function getValue() {
|
||||
}
|
||||
return item?.response?.url || item?.response;
|
||||
});
|
||||
// add by 芋艿:【特殊】单个文件的情况,获取首个元素,保证返回的是 String 类型
|
||||
// add by AIOTAGRO:【特殊】单个文件的情况,获取首个元素,保证返回的是 String 类型
|
||||
if (props.maxNumber === 1) {
|
||||
return list.length > 0 ? list[0] : '';
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ export function useUploadType({
|
||||
return { getAccept, getStringAccept, getHelpText };
|
||||
}
|
||||
|
||||
// TODO @芋艿:目前保持和 admin-vue3 一致,后续可能重构
|
||||
// TODO @AIOTAGRO:目前保持和 admin-vue3 一致,后续可能重构
|
||||
export function useUpload(directory?: string) {
|
||||
// 后端上传地址
|
||||
const uploadUrl = getUploadUrl();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
// TODO @芋艿:后续合并到 diy-editor 里,并不是通用的;
|
||||
// TODO @AIOTAGRO:后续合并到 diy-editor 里,并不是通用的;
|
||||
/**
|
||||
* 垂直按钮组
|
||||
* Element官方的按钮组只支持水平显示,通过重写样式实现垂直布局
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# locale
|
||||
|
||||
每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。
|
||||
每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件<EFBFBD><EFBFBD>?
|
||||
|
||||
@@ -20,6 +20,6 @@ export const overridesPreferences = defineOverridesPreferences({
|
||||
},
|
||||
copyright: {
|
||||
companyName: import.meta.env.VITE_APP_TITLE,
|
||||
companySiteLink: 'https://gitee.com/yudaocode/yudao-ui-admin-vben',
|
||||
companySiteLink: 'https://gitee.com/yudaocode/yudao-ui-admin-vben', // AIOTAGRO
|
||||
},
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
||||
return await generateAccessible(preferences.app.accessMode, {
|
||||
...options,
|
||||
fetchMenuListAsync: async () => {
|
||||
// 由于 yudao 通过 accessStore 读取,所以不在进行 message.loading 提示
|
||||
// 由于 AIOTAGRO 通过 accessStore 读取,所以不在进行 message.loading 提示
|
||||
// 补充说明:accessStore.accessMenus 一开始是 AppRouteRecordRaw 类型(后端加载),后面被赋值成 MenuRecordRaw 类型(前端转换)
|
||||
const accessMenus = accessStore.accessMenus as AppRouteRecordRaw[];
|
||||
return convertServerMenuToRouteRecordStringComponent(accessMenus);
|
||||
|
||||
@@ -102,7 +102,7 @@ function setupAccessGuard(router: Router) {
|
||||
// 当前登录用户拥有的角色标识列表
|
||||
let userInfo = userStore.userInfo;
|
||||
if (!userInfo) {
|
||||
// add by 芋艿:由于 yudao 是 fetchUserInfo 统一加载用户 + 权限信息,所以将 fetchMenuListAsync
|
||||
// add by 芋艿:由于 AIOTAGRO 是 fetchUserInfo 统一加载用户 + 权限信息,所以将 fetchMenuListAsync
|
||||
const message = ElMessage({
|
||||
message: `${$t('common.loadingMenu')}...`,
|
||||
type: 'success',
|
||||
|
||||
@@ -35,7 +35,7 @@ const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name);
|
||||
/** 有权限校验的路由列表,包含动态路由和静态路由 */
|
||||
const accessRoutes = [...dynamicRoutes, ...staticRoutes];
|
||||
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/router/routes/index.ts#L38-L45
|
||||
// add by AIOTAGRO:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/router/routes/index.ts#L38-L45
|
||||
const componentKeys: string[] = Object.keys(
|
||||
import.meta.glob('../../views/**/*.vue'),
|
||||
)
|
||||
|
||||
@@ -78,4 +78,4 @@ const routes: RouteRecordRaw[] = [
|
||||
// },
|
||||
];
|
||||
|
||||
export default routes; // update by 芋艿:不展示
|
||||
export default routes; // update by AIOTAGRO:不展示
|
||||
|
||||
@@ -71,7 +71,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
accessStore.setRefreshToken(refreshToken);
|
||||
|
||||
// 获取用户信息并存储到 userStore、accessStore 中
|
||||
// TODO @芋艿:清理掉 accessCodes 相关的逻辑
|
||||
// TODO @AIOTAGRO:清理掉 accessCodes 相关的逻辑
|
||||
// const [fetchUserInfoResult, accessCodes] = await Promise.all([
|
||||
// fetchUserInfo(),
|
||||
// // getAccessCodesApi(),
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# \_core
|
||||
|
||||
此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。
|
||||
此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图<EFBFBD><EFBFBD>?
|
||||
|
||||
@@ -57,7 +57,7 @@ onMounted(loadProfile);
|
||||
<ElTabPane name="userSocial" label="社交绑定" force-render>
|
||||
<UserSocial @update:active-name="activeName = $event" />
|
||||
</ElTabPane>
|
||||
<!-- TODO @芋艿:在线设备 -->
|
||||
<!-- TODO @AIOTAGRO:在线设备 -->
|
||||
</ElTabs>
|
||||
</ElCard>
|
||||
</div>
|
||||
|
||||
@@ -176,7 +176,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
});
|
||||
|
||||
/** 获取数据源配置列表 */
|
||||
// TODO @芋艿:这种场景的最佳实践;
|
||||
// TODO @AIOTAGRO:这种场景的最佳实践;
|
||||
async function initDataSourceConfig() {
|
||||
try {
|
||||
dataSourceConfigList.value = await getDataSourceConfigList();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { TabPaneName } from 'element-plus';
|
||||
|
||||
// TODO @芋艿:待定,vben2.0 有 CodeEditor,不确定官方后续会不会迁移!!!
|
||||
// TODO @AIOTAGRO:待定,vben2.0 有 CodeEditor,不确定官方后续会不会迁移!!!
|
||||
import type { InfraCodegenApi } from '#/api/infra/codegen';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
@@ -74,7 +74,7 @@ const getOrderData = async () => {
|
||||
|
||||
/** 查询商品数据 */
|
||||
const getProductData = async () => {
|
||||
// TODO: @芋艿:这个接口的返回值,是不是用命名字段更好些?
|
||||
// TODO: @AIOTAGRO:这个接口的返回值,是不是用命名字段更好些?
|
||||
const productCount = await getTabsCount();
|
||||
data.value.productForSale = productCount['0'] || 0;
|
||||
data.value.productInWarehouse = productCount['1'] || 0;
|
||||
|
||||
@@ -150,7 +150,7 @@ export function useTypeGridColumns(): VxeTableGridOptions['columns'] {
|
||||
|
||||
// ============================== 字典数据 ==============================
|
||||
|
||||
// TODO @芋艿:后续针对 antd,增加
|
||||
// TODO @AIOTAGRO:后续针对 antd,增加
|
||||
/** 颜色选项 */
|
||||
const colorOptions = [
|
||||
{ value: '', label: '无' },
|
||||
|
||||
@@ -125,7 +125,7 @@ export function useDetailSchema(): DescriptionItemSchema[] {
|
||||
{
|
||||
field: 'avatar',
|
||||
label: '用户头像',
|
||||
// TODO @芋艿:使用 antd 的 Image 组件
|
||||
// TODO @AIOTAGRO:使用 antd 的 Image 组件
|
||||
content: (data: SystemSocialUserApi.SocialUser) => {
|
||||
if (data?.avatar) {
|
||||
return h('img', {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { computed } from 'vue';
|
||||
|
||||
import { NTag } from 'naive-ui';
|
||||
|
||||
// import { isHexColor } from '@/utils/color' // TODO @芋艿:【可优化】增加 cssClass 的处理 https://gitee.com/yudaocode/yudao-ui-admin-vben/blob/v2.4.1/src/components/DictTag/src/DictTag.vue#L60
|
||||
// import { isHexColor } from '@/utils/color' // TODO @AIOTAGRO:【可优化】增加 cssClass 的处理 https://gitee.com/yudaocode/yudao-ui-admin-vben/blob/v2.4.1/src/components/DictTag/src/DictTag.vue#L60
|
||||
import { getDictObj } from '#/utils';
|
||||
|
||||
interface DictTagProps {
|
||||
|
||||
@@ -22,7 +22,7 @@ onMounted(() => {
|
||||
init();
|
||||
}, 300);
|
||||
});
|
||||
// TODO @芋艿:优化:未来使用 vben 自带的内链实现
|
||||
// TODO @AIOTAGRO:优化:未来使用 vben 自带的内链实现
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -78,7 +78,7 @@ export function useUploadType({
|
||||
return { getAccept, getStringAccept, getHelpText };
|
||||
}
|
||||
|
||||
// TODO @芋艿:目前保持和 admin-vue3 一致,后续可能重构
|
||||
// TODO @AIOTAGRO:目前保持和 admin-vue3 一致,后续可能重构
|
||||
export function useUpload(directory?: string) {
|
||||
// 后端上传地址
|
||||
const uploadUrl = getUploadUrl();
|
||||
|
||||
@@ -20,6 +20,6 @@ export const overridesPreferences = defineOverridesPreferences({
|
||||
},
|
||||
copyright: {
|
||||
companyName: import.meta.env.VITE_APP_TITLE,
|
||||
companySiteLink: 'https://gitee.com/yudaocode/yudao-ui-admin-vben',
|
||||
companySiteLink: 'https://gitee.com/yudaocode/yudao-ui-admin-vben', // AIOTAGRO
|
||||
},
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
||||
return await generateAccessible(preferences.app.accessMode, {
|
||||
...options,
|
||||
fetchMenuListAsync: async () => {
|
||||
// 由于 yudao 通过 accessStore 读取,所以不在进行 message.loading 提示
|
||||
// 由于 AIOTAGRO 通过 accessStore 读取,所以不在进行 message.loading 提示
|
||||
// 补充说明:accessStore.accessMenus 一开始是 AppRouteRecordRaw 类型(后端加载),后面被赋值成 MenuRecordRaw 类型(前端转换)
|
||||
const accessMenus = accessStore.accessMenus as AppRouteRecordRaw[];
|
||||
return convertServerMenuToRouteRecordStringComponent(accessMenus);
|
||||
|
||||
@@ -101,7 +101,7 @@ function setupAccessGuard(router: Router) {
|
||||
// 当前登录用户拥有的角色标识列表
|
||||
let userInfo = userStore.userInfo;
|
||||
if (!userInfo) {
|
||||
// add by 芋艿:由于 yudao 是 fetchUserInfo 统一加载用户 + 权限信息,所以将 fetchMenuListAsync
|
||||
// add by 芋艿:由于 AIOTAGRO 是 fetchUserInfo 统一加载用户 + 权限信息,所以将 fetchMenuListAsync
|
||||
const loading = message.loading(`${$t('common.loadingMenu')}...`);
|
||||
try {
|
||||
const authPermissionInfo = await authStore.fetchUserInfo();
|
||||
|
||||
@@ -61,7 +61,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
accessStore.setRefreshToken(refreshToken);
|
||||
|
||||
// 获取用户信息并存储到 userStore、accessStore 中
|
||||
// TODO @芋艿:清理掉 accessCodes 相关的逻辑
|
||||
// TODO @AIOTAGRO:清理掉 accessCodes 相关的逻辑
|
||||
// const [fetchUserInfoResult, accessCodes] = await Promise.all([
|
||||
// fetchUserInfo(),
|
||||
// // getAccessCodesApi(),
|
||||
|
||||
@@ -13,7 +13,7 @@ interface DictState {
|
||||
dictCache: Dict;
|
||||
}
|
||||
|
||||
// TODO @芋艿:可以共享么?
|
||||
// TODO @AIOTAGRO:可以共享么?
|
||||
export const useDictStore = defineStore('dict', {
|
||||
actions: {
|
||||
getDictData(dictType: string, value: any) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// todo @芋艿:要不要共享
|
||||
// todo @AIOTAGRO:要不要共享
|
||||
/**
|
||||
* Created by 芋道源码
|
||||
* Created by AIOTAGRO
|
||||
*
|
||||
* 枚举类
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { SelectOption } from 'naive-ui/es/select';
|
||||
// TODO @芋艿:后续再优化
|
||||
// TODO @芋艿:可以共享么?
|
||||
// TODO @AIOTAGRO:后续再优化
|
||||
// TODO @AIOTAGRO:可以共享么?
|
||||
|
||||
import { isObject } from '@vben/utils';
|
||||
|
||||
|
||||