先上个预览地址
账号:admin 密码:123456
Ai流程编排
通过拖放操作,可以实现利用AI技术来优化和自动化各种工作流程。
前端是基于 @vue-flow
Ai极速编码
来试试:show.cool-admin.com/helper/ai-c…
根据简要的描述生成完整的前后端代码,尊嘟假嘟??
7.14 支持 Java 版本,生成
Mapper
、Entity
、Service 实现/接口类
、Controller
有啥不一样??
路人甲:有一说一这种后台模版一抓一大把
路人乙:不就是UI组件套一套凑出来壳子的玩意
路人丙:代码结构肯定又是复制 vue-admin-template
那一套
...
虽然...,但是...,请跟着我往下看看
模块化开发
除了看得见的UI界面,背后的目录结构、代码设计都是几年来的总结和提炼。模块化开发也助于我们代码复用,降低耦合度。
src
├── cool 核心文件:权限、路由、模块插件的加载、Eps的生成
├── plugins
│ ├── crud CRUD组件
│ ├── editor 代码编辑器、符文布编辑器
│ ├── upload 文件上传
│ ├── excel 表格导入导出
│ └── view 视图组件
├── modules
│ ├── base 基础模块:用户、菜单、角色等
│ ├── chat 聊天通讯模块
│ ├── dict 字典模块
│ ├── helper 快速开发辅助模块
│ ├── space 文件管理模块
│ ├── task 任务模块
│ ├── theme 主题模块
│ └── user 用户模块
使用的方式极为清爽
import { useBase } from '/$/base';
import { useDict } from '/$/dict';
const { user } = useBase();
const { dict } = useDict();
// 使用
user.token
user.info.nickName
dict.get('userTag');
Eps扩展
Eps是什么?这个大家想必很陌生。它是扫描服务端的 Api 和 Entity,自动在前端生成 service、dts 文件,提高开发效率。
以往的开发流程:
- 后端创建表,写API接口;
- 编写API接口文档;
- 前端根据API接口文档,编写对应的调用接口的方法;
- 前端使用到的地方调用接口;
- 最后加上一堆恶心的 any;
这样的流程似乎有些冗余,我们在下面做了一些对比:
1. 在服务请求中
使用前:
// /api/user.ts
import { request } from "/@/utils"
export function userPage(data: any) {
return request({
url: "/admin/user/page",
method: "POST",
data
})
}
export function userInfo() { ... };
export function userUpdate() { ... };
export function userAdd() { ... };
export function userDelete() { ... };
// user.vue
import { userInfo } from "/@/api/user.ts"
userInfo({ id: 1 }); // 获取用户详情
使用后:
自动同步生成 Service
对象,层级与请求路径一致。嗯... 都忘了 axios 怎么写了
2. 在类型描述中
使用前:
// 定义一个list
const list = ref([])
// 在页面中渲染,你猜这时候 item 是不是一个any
<ul>
<li v-for="(item) in list">{{ item.nickName }}</li>
</ul>
// 那给他加个类型吧
interface User {
nickName: string;
avatarUrl: string;
status: number;
createTime: Date;
...
}
// 指定类型后有提示了
const list = ref<User[]>([])
使用后:
const list = ref<Eps.UserInfoEntity>([])
Eps.UserInfoEntity
根据后端 Entity
解析而来。那为什么不自己定义类型呢?
- 后端有很多的
Entity
,老板说给你的时间不多 - 后端是
MidwayJs
,还能蛮复制一下。那要是Java
、Python
咋办 - 新需求要添加字段的时候,又要每个类型对一遍
Crud组件
做后台管理系统最离不开的就是表的增删改查
,俗称CRUD
。解决的方案也非常多:
- 最常见的是 Mixin 混入(这种方式灵活性不够)
- 封装一个
<crud />
然后文档写一堆的参数,是否要新增按钮、是否能删除、某列能不能搜索加上 n 多插槽的命名table-after
table-before
header
footer
等等(相信使用的人也很累,满头问号??) - 低代码平台,直接生成几百行代码。(谁用谁难受)
- 复制黏贴(直接起飞)
那我们的优势又是什么??以下是我们基础代码的示例:
<template>
<cl-crud ref="Crud">
<cl-row>
<!-- 刷新按钮 -->
<cl-refresh-btn />
<!-- 新增按钮 -->
<cl-add-btn />
<!-- 删除按钮 -->
<cl-multi-delete-btn />
<!-- 筛选状态 -->
<cl-filter label="状态">
<cl-select prop="status" :options="options.status" />
</cl-filter>
<cl-flex1 />
<!-- 关键字搜索 -->
<cl-search-key placeholder="搜索名称、品牌" />
</cl-row>
<cl-row>
<!-- 数据表格 -->
<cl-table ref="Table">
<template #column-specification="{ scope }"> 自定义规格展示 </template>
</cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<!-- 分页控件 -->
<cl-pagination />
</cl-row>
<!-- 新增、编辑 -->
<cl-upsert ref="Upsert">
<template #slot-specification="{ scope }"> 自定义规格输入 </template>
</cl-upsert>
</cl-crud>
</template>
<script lang="ts" name="goods-info" setup>
import { useCrud, useTable, useUpsert } from '@cool-vue/crud';
import { useCool } from '/@/cool';
const { service } = useCool();
// 选择项
const options = reactive({
status: [
{ label: '下架', value: 0, type: 'danger' },
{ label: '上架', value: 1, type: 'success' }
]
});
// 新增、编辑配置
const Upsert = useUpsert({
items: [
{
label: '名称',
prop: 'name',
component: { name: 'el-input', props: { clearable: true } },
required: true
},
{
label: '价格',
prop: 'price',
hook: 'number',
component: { name: 'el-input-number' },
required: true
},
{
label: '库存',
prop: 'stock',
hook: 'number',
component: { name: 'el-input-number' },
required: true
},
{
label: '品牌',
prop: 'brand',
component: { name: 'el-input', props: { clearable: true } },
required: true
},
{
label: '规格',
prop: 'specification',
component: {
name: 'slot-specification'
}
},
{
label: '描述',
prop: 'description',
component: { name: 'el-input', props: { type: 'textarea', rows: 4 } }
},
{
label: '图片',
prop: 'images',
component: { name: 'cl-upload', props: { multiple: true } }
},
{
label: '状态',
prop: 'status',
component: {
name: 'el-radio-group',
options: options.status
},
value: 0,
required: true
},
{
label: '销量',
prop: 'sales',
hook: 'number',
component: { name: 'el-input-number' },
required: true
}
]
});
// 表格配置
const Table = useTable({
columns: [
{ type: 'selection' },
{ label: '名称', prop: 'name', minWidth: 140 },
{ label: '价格', prop: 'price', minWidth: 140 },
{ label: '库存', prop: 'stock', minWidth: 140 },
{ label: '品牌', prop: 'brand', minWidth: 140 },
{ label: '规格', prop: 'specification', minWidth: 140 },
{ label: '描述', prop: 'description', showOverflowTooltip: true, minWidth: 200 },
{
label: '图片',
prop: 'images',
minWidth: 100,
component: { name: 'cl-image', props: { size: 60 } }
},
{
label: '状态',
prop: 'status',
component: {
name: 'cl-switch'
},
minWidth: 120
},
{ label: '销量', prop: 'sales', minWidth: 140 },
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
},
{ type: 'op', buttons: ['edit', 'delete'] }
]
});
// CRUD配置
const Crud = useCrud(
{
service: service.goods.info // 绑定某个 service,驱动整个CRUD
},
(app) => {
app.refresh();
}
);
// 刷新数据
function refresh(params?: any) {
Crud.value?.refresh(params);
}
</script>
代码清晰易懂,也有很多人性化的设计(不一一举例):
- 使用
useTable<Eps.GoodsInfoEntity>
后,items.prop
就能提示当前表有那些可选字段值 - 继承
elm
的组件,如cl-table
组件可直接使用el-table
的border
stripe
row-class-name
等属性 - 支持插件模式,如输入框自动聚焦插件、字段权限校验插件
更多示例请移步:show.cool-admin.com/demo/crud
最后
闺蜜喊ct了,后续叫大哥们把 MidwayJs
Java
的一起补上,未完待续~~
另外 Go
和 Python
的版本也在铁粉的帮助下显露端倪
贴个官网链接:cool-js.com/
再贴个Github链接:github.com/cool-team-o…
完全开源,好用点个 Star 撒~~