mirror of
https://github.com/chillzhuang/Sword
synced 2024-11-21 17:59:26 +08:00
🎉 init all
This commit is contained in:
parent
99e6dfee83
commit
9921323463
172
README.md
172
README.md
@ -1,70 +1,119 @@
|
|||||||
## 简介
|
<p align="center">
|
||||||
* Sword 是 [SpringBlade](https://gitee.com/smallc/SpringBlade)前端UI项目,基于react 、ant design、dva,用于快速构建系统中后台业务。
|
<img src="https://img.shields.io/badge/Release-V2.5.1-green.svg" alt="Downloads">
|
||||||
* Sword 已入选 ant design 官方脚手架市场,地址:[scaffolds.ant.design](http://scaffold.ant.design/#/scaffolds/Sword)
|
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status">
|
||||||
|
<img src="https://img.shields.io/badge/license-Apache%202-blue.svg" alt="Build Status">
|
||||||
|
<img src="https://img.shields.io/badge/Spring%20Cloud-Greenwich.SR3-blue.svg" alt="Coverage Status">
|
||||||
|
<img src="https://img.shields.io/badge/Spring%20Boot-2.1.8.RELEASE-blue.svg" alt="Downloads">
|
||||||
|
<a target="_blank" href="https://bladex.vip">
|
||||||
|
<img src="https://img.shields.io/badge/Author-Small%20Chill-ff69b4.svg" alt="Downloads">
|
||||||
|
</a>
|
||||||
|
<a target="_blank" href="https://bladex.vip">
|
||||||
|
<img src="https://img.shields.io/badge/Copyright%20-@BladeX-%23ff3f59.svg" alt="Downloads">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
## 文档
|
## SpringBlade微服务开发平台
|
||||||
* 文档地址:[Sword开发手册](https://www.kancloud.cn/smallchill/sword)
|
* 采用前后端分离的模式,前端开源两个框架:[Sword](https://gitee.com/smallc/Sword) (基于 React、Ant Design)、[Saber](https://gitee.com/smallc/Saber) (基于 Vue、Element-UI)
|
||||||
|
* 后端采用SpringCloud全家桶,并同时对其基础组件做了高度的封装,单独开源出一个框架:[BladeTool](https://github.com/chillzhuang/blade-tool)
|
||||||
|
* [BladeTool](https://github.com/chillzhuang/blade-tool)已推送至Maven中央库,直接引入即可,减少了工程的臃肿,也可更注重于业务开发
|
||||||
|
* 集成Sentinel从流量控制、熔断降级、系统负载等多个维度保护服务的稳定性。
|
||||||
|
* 注册中心、配置中心选型Nacos,为工程瘦身的同时加强各模块之间的联动。
|
||||||
|
* 使用Traefik进行反向代理,监听后台变化自动化应用新的配置文件。
|
||||||
|
* 极简封装了多租户底层,用更少的代码换来拓展性更强的SaaS多租户系统。
|
||||||
|
* 借鉴OAuth2,实现了多终端认证系统,可控制子系统的token权限互相隔离。
|
||||||
|
* 借鉴Security,封装了Secure模块,采用JWT做Token认证,可拓展集成Redis等细颗粒度控制方案。
|
||||||
|
* 稳定生产了一年,经历了从Camden -> Greenwich的技术架构,也经历了从fat jar -> docker -> k8s + jenkins的部署架构
|
||||||
|
* 项目分包明确,规范微服务的开发模式,使包与包之间的分工清晰。
|
||||||
|
|
||||||
|
## 架构图
|
||||||
|
<img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/springblade-framework.png"/>
|
||||||
|
|
||||||
|
## 工程结构
|
||||||
|
```
|
||||||
|
SpringBlade
|
||||||
|
├── blade-auth -- 授权服务提供
|
||||||
|
├── blade-common -- 常用工具封装包
|
||||||
|
├── blade-gateway -- Spring Cloud 网关
|
||||||
|
├── blade-ops -- 运维中心
|
||||||
|
├ ├── blade-admin -- spring-cloud后台管理
|
||||||
|
├ ├── blade-develop -- 代码生成
|
||||||
|
├ ├── blade-resource -- 资源管理
|
||||||
|
├ ├── blade-seata-order -- seata分布式事务demo
|
||||||
|
├ ├── blade-seata-storage -- seata分布式事务demo
|
||||||
|
├── blade-service -- 业务模块
|
||||||
|
├ ├── blade-desk -- 工作台模块
|
||||||
|
├ ├── blade-log -- 日志模块
|
||||||
|
├ ├── blade-system -- 系统模块
|
||||||
|
├ └── blade-user -- 用户模块
|
||||||
|
├── blade-service-api -- 业务模块api封装
|
||||||
|
├ ├── blade-desk-api -- 工作台api
|
||||||
|
├ ├── blade-dict-api -- 字典api
|
||||||
|
├ ├── blade-system-api -- 系统api
|
||||||
|
└── └── blade-user-api -- 用户api
|
||||||
|
```
|
||||||
|
|
||||||
## 官网
|
## 官网
|
||||||
* 官网地址:[https://bladex.vip](https://bladex.vip)
|
* 官网地址:[https://bladex.vip](https://bladex.vip)
|
||||||
|
* 问答社区:[https://sns.bladex.vip](https://sns.bladex.vip)
|
||||||
|
* 会员计划:[SpringBlade会员计划](https://gitee.com/smallc/SpringBlade/wikis/SpringBlade会员计划)
|
||||||
|
* 交流一群:`477853168`
|
||||||
|
* 交流二群:`751253339`
|
||||||
|
|
||||||
## 在线演示
|
## 在线演示
|
||||||
* Sword演示地址:[https://sword.bladex.vip](https://sword.bladex.vip)
|
* Saber-基于Vue:[https://saber.bladex.vip](https://saber.bladex.vip)
|
||||||
* Saber演示地址:[https://saber.bladex.vip](https://saber.bladex.vip)
|
* Sword-基于React:[https://sword.bladex.vip](https://sword.bladex.vip)
|
||||||
|
* Archer-全能代码生成系统:[https://archer.bladex.vip](https://archer.bladex.vip)
|
||||||
|
|
||||||
## 后端项目地址
|
## 技术文档
|
||||||
* [Gitee地址](https://gitee.com/smallc/SpringBlade)
|
* [开发手册一览](https://gitee.com/smallc/SpringBlade/wikis/SpringBlade开发手册)
|
||||||
* [Github地址](https://github.com/chillzhuang/SpringBlade)
|
* [常见问题集锦](https://sns.bladex.vip/article-14966.html)
|
||||||
|
|
||||||
## 前端项目地址
|
|
||||||
* [Sword--基于React](https://gitee.com/smallc/Sword)
|
|
||||||
* [Saber--基于Vue](https://gitee.com/smallc/Saber)
|
|
||||||
|
|
||||||
## 特性
|
|
||||||
|
|
||||||
- :gem: **优雅美观**:基于 Ant Design 体系精心设计
|
|
||||||
- :triangular_ruler: **常见设计模式**:提炼自中后台应用的典型页面和场景
|
|
||||||
- :rocket: **最新技术栈**:使用 React/umi/dva/antd 等前端前沿技术开发
|
|
||||||
- :iphone: **响应式**:针对不同屏幕大小设计
|
|
||||||
- :art: **主题**:可配置的主题满足多样化的品牌诉求
|
|
||||||
- :globe_with_meridians: **国际化**:内建业界通用的国际化方案
|
|
||||||
- :zap: **最佳实践**:良好的工程实践助您持续产出高质量代码
|
|
||||||
- :1234: **Mock 数据**:实用的本地数据调试方案
|
|
||||||
- :white_check_mark: **UI 测试**:自动化测试保障前端产品质量
|
|
||||||
|
|
||||||
## 支持环境
|
|
||||||
|
|
||||||
现代浏览器及 IE11。
|
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
|
|
||||||
| --------- | --------- | --------- | --------- | --------- |
|
|
||||||
| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions
|
|
||||||
|
|
||||||
|
## 项目地址
|
||||||
|
* 后端Gitee地址:[https://gitee.com/smallc/SpringBlade](https://gitee.com/smallc/SpringBlade)
|
||||||
|
* 后端Github地址:[https://github.com/chillzhuang/SpringBlade](https://github.com/chillzhuang/SpringBlade)
|
||||||
|
* 后端SpringBoot版:[https://gitee.com/smallc/SpringBlade/tree/2.0-boot/](https://gitee.com/smallc/SpringBlade/tree/2.0-boot/)
|
||||||
|
* 前端框架Sword(基于React):[https://gitee.com/smallc/Sword](https://gitee.com/smallc/Sword)
|
||||||
|
* 前端框架Saber(基于Vue):[https://gitee.com/smallc/Saber](https://gitee.com/smallc/Saber)
|
||||||
|
* 核心框架项目地址:[https://github.com/chillzhuang/blade-tool](https://github.com/chillzhuang/blade-tool)
|
||||||
|
|
||||||
## 用户权益
|
## 用户权益
|
||||||
* 允许免费用于学习、毕设、公司项目、私活等。
|
* 允许免费用于学习、毕设、公司项目、私活等。
|
||||||
* 代码文件需保留相关license信息。
|
* 代码文件需保留相关license信息。
|
||||||
|
* 禁止直接将本项目挂淘宝等商业平台出售。
|
||||||
## 禁止事项
|
* 非界面代码50%以上相似度的二次开源,二次开源需先联系作者。
|
||||||
* 直接将本项目挂淘宝等商业平台出售。
|
|
||||||
* 业务代码50%以上相似度的二次开源,二次开源需先联系作者。
|
|
||||||
|
|
||||||
注意:若禁止条款被发现有权追讨19999的授权费。
|
|
||||||
|
|
||||||
## 如何启动
|
## 如何启动
|
||||||
```
|
```
|
||||||
$ git clone https://gitee.com/smallc/Sword.git
|
$ git clone https://gitee.com/smallc/Sword.git
|
||||||
$ cd Sword
|
$ cd Sword
|
||||||
$ npm install
|
$ yarn install 或者 npm install
|
||||||
# mock模式
|
# mock模式
|
||||||
$ npm start
|
$ yarn start 或者 npm start
|
||||||
# 服务模式
|
# 服务模式
|
||||||
$ npm run start:no-mock
|
$ yarn run start:no-mock 或者 npm run start:no-mock
|
||||||
# 访问 http://localhost:88
|
# 访问 http://localhost:8888
|
||||||
|
# 推荐使用yarn
|
||||||
```
|
```
|
||||||
|
|
||||||
# 界面
|
# 界面
|
||||||
## Sword界面一览
|
|
||||||
|
## [BladeX](https://bladex.vip/#/vip) 工作流一览
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/bladex-flow1.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/bladex-flow2.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/bladex-flow3.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/bladex-flow4.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/bladex-flow5.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/bladex-flow6.png"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
## [Sword](https://gitee.com/smallc/Sword) 界面一览
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/sword-main.png"/></td>
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/sword-main.png"/></td>
|
||||||
@ -88,6 +137,22 @@ $ npm run start:no-mock
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
## [Saber](https://gitee.com/smallc/Saber) 界面一览
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-user.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-role.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-dict.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-dict-select.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-log.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-code.png"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
## 监控界面一览
|
## 监控界面一览
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@ -116,18 +181,5 @@ $ npm run start:no-mock
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
## Saber界面一览
|
## 关注我们
|
||||||
<table>
|
![](https://images.gitee.com/uploads/images/2019/0330/065148_f0ada806_410595.jpeg)
|
||||||
<tr>
|
|
||||||
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-user.png"/></td>
|
|
||||||
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-role.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-dict.png"/></td>
|
|
||||||
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-dict-select.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-log.png"/></td>
|
|
||||||
<td><img src="https://gitee.com/smallc/SpringBlade/raw/master/pic/saber-code.png"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
@ -52,18 +52,19 @@ export default [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/account/settings',
|
path: '/account/settings',
|
||||||
component: './Account/Settings/Info',
|
//component: './Account/Settings/Info',
|
||||||
routes: [
|
routes: [
|
||||||
{ path: '/account/settings', redirect: '/account/settings/base' },
|
{ path: '/account/settings', redirect: '/account/settings/base' },
|
||||||
{ path: '/account/settings/base', component: './Account/Settings/BaseView' },
|
{ path: '/account/settings/base', component: './Account/Settings/BaseView' },
|
||||||
{ path: '/account/settings/security', component: './Account/Settings/SecurityView' },
|
{ path: '/account/settings/password', component: './Account/Settings/PasswordView' },
|
||||||
{ path: '/account/settings/binding', component: './Account/Settings/BindingView' },
|
//{ path: '/account/settings/security', component: './Account/Settings/SecurityView' },
|
||||||
|
//{ path: '/account/settings/binding', component: './Account/Settings/BindingView' },
|
||||||
{
|
{
|
||||||
path: '/account/settings/notification',
|
path: '/account/settings/notification',
|
||||||
component: './Account/Settings/NotificationView',
|
component: './Account/Settings/NotificationView',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -226,6 +227,23 @@ export default [
|
|||||||
{ path: '/tool/code/view/:id', component: './System/Code/CodeView' },
|
{ path: '/tool/code/view/:id', component: './System/Code/CodeView' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/tool/datasource',
|
||||||
|
routes: [
|
||||||
|
{ path: '/tool/datasource', redirect: '/tool/datasource/list' },
|
||||||
|
{ path: '/tool/datasource/list', component: './System/DataSource/DataSource' },
|
||||||
|
{ path: '/tool/datasource/add', component: './System/DataSource/DataSourceAdd' },
|
||||||
|
{ path: '/tool/datasource/add/:id', component: './System/DataSource/DataSourceAdd' },
|
||||||
|
{
|
||||||
|
path: '/tool/datasource/edit/:id',
|
||||||
|
component: './System/DataSource/DataSourceEdit',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/tool/datasource/view/:id',
|
||||||
|
component: './System/DataSource/DataSourceView',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -6,21 +6,21 @@ function getFakeList(req, res) {
|
|||||||
data.push({
|
data.push({
|
||||||
id: '1',
|
id: '1',
|
||||||
deptName: '刀锋科技',
|
deptName: '刀锋科技',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
fullName: '江苏刀锋科技有限公司',
|
fullName: '江苏刀锋科技有限公司',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
deptName: '常州刀锋',
|
deptName: '常州刀锋',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
fullName: '常州刀锋科技有限公司',
|
fullName: '常州刀锋科技有限公司',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '3',
|
id: '3',
|
||||||
deptName: '南京刀锋',
|
deptName: '南京刀锋',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
fullName: '南京刀锋科技有限公司',
|
fullName: '南京刀锋科技有限公司',
|
||||||
sort: '2',
|
sort: '2',
|
||||||
},
|
},
|
||||||
@ -36,7 +36,7 @@ function getFakeDetail(req, res) {
|
|||||||
id: 2,
|
id: 2,
|
||||||
parentId: 1,
|
parentId: 1,
|
||||||
parentName: '江苏刀锋',
|
parentName: '江苏刀锋',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
deptName: '常州刀锋',
|
deptName: '常州刀锋',
|
||||||
fullName: '常州刀锋科技有限公司',
|
fullName: '常州刀锋科技有限公司',
|
||||||
sort: 1,
|
sort: 1,
|
||||||
|
12
mock/role.js
12
mock/role.js
@ -7,14 +7,14 @@ function getFakeList(req, res) {
|
|||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
roleName: '超级管理员',
|
roleName: '超级管理员',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
roleAlias: 'administrator',
|
roleAlias: 'administrator',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
roleName: '管理员',
|
roleName: '管理员',
|
||||||
tenantCode: '000001',
|
tenantId: '000001',
|
||||||
roleAlias: 'admin',
|
roleAlias: 'admin',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
},
|
},
|
||||||
@ -23,21 +23,21 @@ function getFakeList(req, res) {
|
|||||||
{
|
{
|
||||||
id: '3',
|
id: '3',
|
||||||
roleName: '用户',
|
roleName: '用户',
|
||||||
tenantCode: '000002',
|
tenantId: '000002',
|
||||||
roleAlias: 'user',
|
roleAlias: 'user',
|
||||||
sort: '2',
|
sort: '2',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: '4',
|
id: '4',
|
||||||
roleName: '普通用户',
|
roleName: '普通用户',
|
||||||
tenantCode: '000003',
|
tenantId: '000003',
|
||||||
roleAlias: 'user',
|
roleAlias: 'user',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '5',
|
id: '5',
|
||||||
roleName: '访客',
|
roleName: '访客',
|
||||||
tenantCode: '000004',
|
tenantId: '000004',
|
||||||
roleAlias: 'guest',
|
roleAlias: 'guest',
|
||||||
sort: '2',
|
sort: '2',
|
||||||
},
|
},
|
||||||
@ -54,7 +54,7 @@ function getFakeDetail(req, res) {
|
|||||||
id: 2,
|
id: 2,
|
||||||
parentId: 1,
|
parentId: 1,
|
||||||
parentName: '超级管理员',
|
parentName: '超级管理员',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
roleName: '用户',
|
roleName: '用户',
|
||||||
roleAlias: 'user',
|
roleAlias: 'user',
|
||||||
sort: 1,
|
sort: 1,
|
||||||
|
@ -6,7 +6,7 @@ function getFakeList(req, res) {
|
|||||||
list.push(
|
list.push(
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
tenantName: '管理组',
|
tenantName: '管理组',
|
||||||
linkman: 'Chill',
|
linkman: 'Chill',
|
||||||
contactNumber: '66666666666',
|
contactNumber: '66666666666',
|
||||||
@ -14,7 +14,7 @@ function getFakeList(req, res) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
tenantCode: '000001',
|
tenantId: '000001',
|
||||||
tenantName: '用户组',
|
tenantName: '用户组',
|
||||||
linkman: 'Bill',
|
linkman: 'Bill',
|
||||||
contactNumber: '23333333333',
|
contactNumber: '23333333333',
|
||||||
@ -36,7 +36,7 @@ function getFakeDetail(req, res) {
|
|||||||
const json = { code: 200, success: true, msg: '操作成功' };
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
json.data = {
|
json.data = {
|
||||||
id: '1',
|
id: '1',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
tenantName: '管理组',
|
tenantName: '管理组',
|
||||||
linkman: 'Chill',
|
linkman: 'Chill',
|
||||||
contactNumber: '66666666666',
|
contactNumber: '66666666666',
|
||||||
@ -54,11 +54,11 @@ function getFakeTenantSelect(req, res) {
|
|||||||
const json = { code: 200, success: true, msg: '操作成功' };
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
json.data = [
|
json.data = [
|
||||||
{
|
{
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
tenantName: '管理组',
|
tenantName: '管理组',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
tenantCode: '000001',
|
tenantId: '000001',
|
||||||
tenantName: '用户组',
|
tenantName: '用户组',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -6,7 +6,7 @@ function getFakeList(req, res) {
|
|||||||
list.push(
|
list.push(
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
account: 'admin',
|
account: 'admin',
|
||||||
name: '超级管理员',
|
name: '超级管理员',
|
||||||
realName: '管理员',
|
realName: '管理员',
|
||||||
@ -18,7 +18,7 @@ function getFakeList(req, res) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
tenantCode: '000001',
|
tenantId: '000001',
|
||||||
account: 'user',
|
account: 'user',
|
||||||
name: '系统用户',
|
name: '系统用户',
|
||||||
realName: '用户',
|
realName: '用户',
|
||||||
@ -44,7 +44,7 @@ function getFakeDetail(req, res) {
|
|||||||
const json = { code: 200, success: true, msg: '操作成功' };
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
json.data = {
|
json.data = {
|
||||||
id: '1',
|
id: '1',
|
||||||
tenantCode: '000000',
|
tenantId: '000000',
|
||||||
account: 'admin',
|
account: 'admin',
|
||||||
name: '超级管理员',
|
name: '超级管理员',
|
||||||
realName: '管理员',
|
realName: '管理员',
|
||||||
@ -74,6 +74,7 @@ const proxy = {
|
|||||||
'POST /api/blade-user/grant': fakeSuccess,
|
'POST /api/blade-user/grant': fakeSuccess,
|
||||||
'POST /api/blade-user/reset-password': fakeSuccess,
|
'POST /api/blade-user/reset-password': fakeSuccess,
|
||||||
'POST /api/blade-user/submit': fakeSuccess,
|
'POST /api/blade-user/submit': fakeSuccess,
|
||||||
|
'POST /api/blade-user/update': fakeSuccess,
|
||||||
'POST /api/blade-user/remove': fakeSuccess,
|
'POST /api/blade-user/remove': fakeSuccess,
|
||||||
|
|
||||||
// 支持值为 Object 和 Array
|
// 支持值为 Object 和 Array
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sword",
|
"name": "sword",
|
||||||
"version": "1.0.0",
|
"version": "2.5.4",
|
||||||
"description": "An out-of-box UI solution for enterprise applications",
|
"description": "An out-of-box UI solution for enterprise applications",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -7,6 +7,13 @@ export function CODE_LIST(payload) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function CODE_INIT() {
|
||||||
|
return {
|
||||||
|
type: `${CODE_NAMESPACE}/fetchInit`,
|
||||||
|
payload: { code: 'yes_no' },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function CODE_DETAIL(id) {
|
export function CODE_DETAIL(id) {
|
||||||
return {
|
return {
|
||||||
type: `${CODE_NAMESPACE}/fetchDetail`,
|
type: `${CODE_NAMESPACE}/fetchDetail`,
|
||||||
|
36
src/actions/datasource.js
Normal file
36
src/actions/datasource.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
export const DATASOURCE_NAMESPACE = 'datasource';
|
||||||
|
|
||||||
|
export function DATASOURCE_LIST(payload) {
|
||||||
|
return {
|
||||||
|
type: `${DATASOURCE_NAMESPACE}/fetchList`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DATASOURCE_DETAIL(id) {
|
||||||
|
return {
|
||||||
|
type: `${DATASOURCE_NAMESPACE}/fetchDetail`,
|
||||||
|
payload: { id },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DATASOURCE_CLEAR_DETAIL() {
|
||||||
|
return {
|
||||||
|
type: `${DATASOURCE_NAMESPACE}/clearDetail`,
|
||||||
|
payload: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DATASOURCE_SUBMIT(payload) {
|
||||||
|
return {
|
||||||
|
type: `${DATASOURCE_NAMESPACE}/submit`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DATASOURCE_REMOVE(payload) {
|
||||||
|
return {
|
||||||
|
type: `${DATASOURCE_NAMESPACE}/remove`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
@ -43,6 +43,13 @@ export function USER_SUBMIT(payload) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function USER_UPDATE(payload) {
|
||||||
|
return {
|
||||||
|
type: `${USER_NAMESPACE}/update`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function USER_REMOVE(payload) {
|
export function USER_REMOVE(payload) {
|
||||||
return {
|
return {
|
||||||
type: `${USER_NAMESPACE}/remove`,
|
type: `${USER_NAMESPACE}/remove`,
|
||||||
|
@ -96,14 +96,14 @@ export default class GlobalHeaderRight extends PureComponent {
|
|||||||
selectedKeys={[]}
|
selectedKeys={[]}
|
||||||
onClick={onMenuClick}
|
onClick={onMenuClick}
|
||||||
>
|
>
|
||||||
<Menu.Item key="userCenter">
|
|
||||||
<Icon type="user" />
|
|
||||||
<FormattedMessage id="menu.account.center" defaultMessage="account center" />
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Item key="userinfo">
|
<Menu.Item key="userinfo">
|
||||||
<Icon type="setting" />
|
<Icon type="setting" />
|
||||||
<FormattedMessage id="menu.account.settings" defaultMessage="account settings" />
|
<FormattedMessage id="menu.account.settings" defaultMessage="account settings" />
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
<Menu.Item key="password">
|
||||||
|
<Icon type="user" />
|
||||||
|
<FormattedMessage id="menu.account.password" defaultMessage="password settings" />
|
||||||
|
</Menu.Item>
|
||||||
<Menu.Divider />
|
<Menu.Divider />
|
||||||
<Menu.Item key="logout">
|
<Menu.Item key="logout">
|
||||||
<Icon type="logout" />
|
<Icon type="logout" />
|
||||||
|
2
src/components/Login/index.d.ts
vendored
2
src/components/Login/index.d.ts
vendored
@ -12,7 +12,7 @@ export interface ILoginProps {
|
|||||||
|
|
||||||
export default class Login extends React.Component<ILoginProps, any> {
|
export default class Login extends React.Component<ILoginProps, any> {
|
||||||
public static Tab: typeof LoginTab;
|
public static Tab: typeof LoginTab;
|
||||||
public static TenantCode: typeof LoginItem;
|
public static TenantId: typeof LoginItem;
|
||||||
public static UserName: typeof LoginItem;
|
public static UserName: typeof LoginItem;
|
||||||
public static Password: typeof LoginItem;
|
public static Password: typeof LoginItem;
|
||||||
public static Mobile: typeof LoginItem;
|
public static Mobile: typeof LoginItem;
|
||||||
|
@ -3,17 +3,17 @@ import { Icon } from 'antd';
|
|||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
TenantCode: {
|
TenantId: {
|
||||||
props: {
|
props: {
|
||||||
size: 'large',
|
size: 'large',
|
||||||
id: 'tenantCode',
|
id: 'tenantId',
|
||||||
prefix: <Icon type="home" className={styles.prefixIcon} />,
|
prefix: <Icon type="home" className={styles.prefixIcon} />,
|
||||||
placeholder: 'admin',
|
placeholder: 'admin',
|
||||||
},
|
},
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: 'Please enter tenantcode!',
|
message: 'Please enter tenantId!',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -52,10 +52,12 @@ export default class PageHeader extends PureComponent {
|
|||||||
<div className={styles.detail}>
|
<div className={styles.detail}>
|
||||||
{logo && <div className={styles.logo}>{logo}</div>}
|
{logo && <div className={styles.logo}>{logo}</div>}
|
||||||
<div className={styles.main}>
|
<div className={styles.main}>
|
||||||
<div className={styles.row}>
|
{title && (
|
||||||
{title && <h1 className={styles.title}>{title}</h1>}
|
<div className={styles.row}>
|
||||||
{action && <div className={styles.action}>{action}</div>}
|
<h1 className={styles.title}>{title}</h1>
|
||||||
</div>
|
{action && <div className={styles.action}>{action}</div>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
{content && <div className={styles.content}>{content}</div>}
|
{content && <div className={styles.content}>{content}</div>}
|
||||||
{extraContent && <div className={styles.extraContent}>{extraContent}</div>}
|
{extraContent && <div className={styles.extraContent}>{extraContent}</div>}
|
||||||
|
@ -34,7 +34,9 @@ export default class Grid extends PureComponent {
|
|||||||
const { form } = this.props;
|
const { form } = this.props;
|
||||||
|
|
||||||
form.validateFields(async (err, fieldsValue) => {
|
form.validateFields(async (err, fieldsValue) => {
|
||||||
if (err) return;
|
if (err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const values = {
|
const values = {
|
||||||
...fieldsValue,
|
...fieldsValue,
|
||||||
@ -57,7 +59,9 @@ export default class Grid extends PureComponent {
|
|||||||
formValues: {},
|
formValues: {},
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
});
|
});
|
||||||
if (onReset) onReset();
|
if (onReset) {
|
||||||
|
onReset();
|
||||||
|
}
|
||||||
this.refreshTable();
|
this.refreshTable();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,7 +83,9 @@ export default class Grid extends PureComponent {
|
|||||||
size,
|
size,
|
||||||
...formValues,
|
...formValues,
|
||||||
};
|
};
|
||||||
if (onSearch) onSearch(params);
|
if (onSearch) {
|
||||||
|
onSearch(params);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSelectRows = rows => {
|
handleSelectRows = rows => {
|
||||||
@ -105,12 +111,13 @@ export default class Grid extends PureComponent {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handelToolBarClick = btn => {
|
handleToolBarClick = btn => {
|
||||||
|
const { selectedRows } = this.state;
|
||||||
const keys = this.getSelectKeys();
|
const keys = this.getSelectKeys();
|
||||||
this.handelClick(btn, keys);
|
this.handleClick(btn, keys, selectedRows);
|
||||||
};
|
};
|
||||||
|
|
||||||
handelClick = (btn, keys = []) => {
|
handleClick = (btn, keys = [], rows) => {
|
||||||
const { path, alias } = btn;
|
const { path, alias } = btn;
|
||||||
const { btnCallBack } = this.props;
|
const { btnCallBack } = this.props;
|
||||||
const refresh = (temp = true) => this.refreshTable(temp);
|
const refresh = (temp = true) => this.refreshTable(temp);
|
||||||
@ -176,7 +183,7 @@ export default class Grid extends PureComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (btnCallBack) {
|
if (btnCallBack) {
|
||||||
btnCallBack({ btn, keys, refresh });
|
btnCallBack({ btn, keys, rows, refresh });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,12 +202,13 @@ export default class Grid extends PureComponent {
|
|||||||
renderSearchForm,
|
renderSearchForm,
|
||||||
renderLeftButton,
|
renderLeftButton,
|
||||||
renderRightButton,
|
renderRightButton,
|
||||||
|
renderActionButton,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let { columns } = this.props;
|
let { columns } = this.props;
|
||||||
|
|
||||||
const actionButtons = buttons.filter(button => button.action === 2 || button.action === 3);
|
const actionButtons = buttons.filter(button => button.action === 2 || button.action === 3);
|
||||||
|
|
||||||
if (columns && Array.isArray(columns) && actionButtons.length > 0) {
|
if (columns && Array.isArray(columns) && (actionButtons.length > 0 || renderActionButton)) {
|
||||||
const key = pkField || rowKey || 'id';
|
const key = pkField || rowKey || 'id';
|
||||||
columns = [
|
columns = [
|
||||||
...columns,
|
...columns,
|
||||||
@ -209,17 +217,24 @@ export default class Grid extends PureComponent {
|
|||||||
width: actionColumnWidth || 200,
|
width: actionColumnWidth || 200,
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{actionButtons.map((button, index) => (
|
<div style={{ textAlign: 'center' }}>
|
||||||
<Fragment key={button.code}>
|
{actionButtons.map((button, index) => (
|
||||||
{index > 0 ? <Divider type="vertical" /> : null}
|
<Fragment key={button.code}>
|
||||||
<a
|
{index > 0 ? <Divider type="vertical" /> : null}
|
||||||
title={formatMessage({ id: `button.${button.alias}.name` })}
|
<a
|
||||||
onClick={() => this.handelClick(button, [record[childPkField || key]])}
|
title={formatMessage({ id: `button.${button.alias}.name` })}
|
||||||
>
|
onClick={() =>
|
||||||
<FormattedMessage id={`button.${button.alias}.name`} />
|
this.handleClick(button, [record[childPkField || key]], [record])
|
||||||
</a>
|
}
|
||||||
</Fragment>
|
>
|
||||||
))}
|
<FormattedMessage id={`button.${button.alias}.name`} />
|
||||||
|
</a>
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
{renderActionButton
|
||||||
|
? renderActionButton([record[childPkField || key]], [record])
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -236,7 +251,7 @@ export default class Grid extends PureComponent {
|
|||||||
buttons={buttons}
|
buttons={buttons}
|
||||||
renderLeftButton={renderLeftButton}
|
renderLeftButton={renderLeftButton}
|
||||||
renderRightButton={renderRightButton}
|
renderRightButton={renderRightButton}
|
||||||
onClick={this.handelToolBarClick}
|
onClick={this.handleToolBarClick}
|
||||||
/>
|
/>
|
||||||
<StandardTable
|
<StandardTable
|
||||||
rowKey={rowKey || 'id'}
|
rowKey={rowKey || 'id'}
|
||||||
@ -249,6 +264,7 @@ export default class Grid extends PureComponent {
|
|||||||
scroll={scroll}
|
scroll={scroll}
|
||||||
tblProps={tblProps}
|
tblProps={tblProps}
|
||||||
size="middle"
|
size="middle"
|
||||||
|
bordered
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -62,8 +62,11 @@ class HeaderView extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'userinfo') {
|
if (key === 'userinfo') {
|
||||||
message.success('即将开放');
|
router.push('/account/settings/base');
|
||||||
// router.push('/account/settings/base');
|
return;
|
||||||
|
}
|
||||||
|
if (key === 'password') {
|
||||||
|
router.push('/account/settings/password');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'triggerError') {
|
if (key === 'triggerError') {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
'app.login.tenantCode': 'tenantCode',
|
'app.login.tenantId': 'tenantId',
|
||||||
'app.login.userName': 'userName',
|
'app.login.userName': 'userName',
|
||||||
'app.login.password': 'password',
|
'app.login.password': 'password',
|
||||||
'app.login.message-invalid-credentials': 'Invalid username or password(admin/ant.design)',
|
'app.login.message-invalid-credentials': 'Invalid username or password(admin/ant.design)',
|
||||||
@ -21,7 +21,7 @@ export default {
|
|||||||
'app.register-result.view-mailbox': 'View mailbox',
|
'app.register-result.view-mailbox': 'View mailbox',
|
||||||
'validation.email.required': 'Please enter your email!',
|
'validation.email.required': 'Please enter your email!',
|
||||||
'validation.email.wrong-format': 'The email address is in the wrong format!',
|
'validation.email.wrong-format': 'The email address is in the wrong format!',
|
||||||
'validation.userName.tenantCode': 'Please enter your tenantCode!',
|
'validation.userName.tenantId': 'Please enter your tenantId!',
|
||||||
'validation.userName.required': 'Please enter your userName!',
|
'validation.userName.required': 'Please enter your userName!',
|
||||||
'validation.password.required': 'Please enter your password!',
|
'validation.password.required': 'Please enter your password!',
|
||||||
'validation.password.twice': 'The passwords entered twice do not match!',
|
'validation.password.twice': 'The passwords entered twice do not match!',
|
||||||
|
@ -24,6 +24,7 @@ export default {
|
|||||||
'menu.monitor.doc': 'api doc',
|
'menu.monitor.doc': 'api doc',
|
||||||
'menu.tool': 'develop',
|
'menu.tool': 'develop',
|
||||||
'menu.tool.code': 'code generate',
|
'menu.tool.code': 'code generate',
|
||||||
|
'menu.tool.datasource': 'datasource',
|
||||||
'menu.result': 'Result',
|
'menu.result': 'Result',
|
||||||
'menu.result.success': 'Success',
|
'menu.result.success': 'Success',
|
||||||
'menu.result.fail': 'Fail',
|
'menu.result.fail': 'Fail',
|
||||||
@ -34,6 +35,7 @@ export default {
|
|||||||
'menu.exception.trigger': 'Trigger',
|
'menu.exception.trigger': 'Trigger',
|
||||||
'menu.account': 'Account',
|
'menu.account': 'Account',
|
||||||
'menu.account.center': 'Account Center',
|
'menu.account.center': 'Account Center',
|
||||||
|
'menu.account.password': 'Modify Password',
|
||||||
'menu.account.settings': 'Account Settings',
|
'menu.account.settings': 'Account Settings',
|
||||||
'menu.account.trigger': 'Trigger Error',
|
'menu.account.trigger': 'Trigger Error',
|
||||||
'menu.account.logout': 'Logout',
|
'menu.account.logout': 'Logout',
|
||||||
|
@ -9,6 +9,8 @@ export default {
|
|||||||
'app.settings.basic.email-message': 'Please input your email!',
|
'app.settings.basic.email-message': 'Please input your email!',
|
||||||
'app.settings.basic.nickname': 'Nickname',
|
'app.settings.basic.nickname': 'Nickname',
|
||||||
'app.settings.basic.nickname-message': 'Please input your Nickname!',
|
'app.settings.basic.nickname-message': 'Please input your Nickname!',
|
||||||
|
'app.settings.basic.realname': 'Realname',
|
||||||
|
'app.settings.basic.realname-message': 'Please input your Realname!',
|
||||||
'app.settings.basic.profile': 'Personal profile',
|
'app.settings.basic.profile': 'Personal profile',
|
||||||
'app.settings.basic.profile-message': 'Please input your personal profile!',
|
'app.settings.basic.profile-message': 'Please input your personal profile!',
|
||||||
'app.settings.basic.profile-placeholder': 'Brief introduction to yourself',
|
'app.settings.basic.profile-placeholder': 'Brief introduction to yourself',
|
||||||
@ -21,6 +23,12 @@ export default {
|
|||||||
'app.settings.basic.phone': 'Phone Number',
|
'app.settings.basic.phone': 'Phone Number',
|
||||||
'app.settings.basic.phone-message': 'Please input your phone!',
|
'app.settings.basic.phone-message': 'Please input your phone!',
|
||||||
'app.settings.basic.update': 'Update Information',
|
'app.settings.basic.update': 'Update Information',
|
||||||
|
'app.settings.password.old': 'Old Password',
|
||||||
|
'app.settings.password.old-message': 'Please input your Old Password!',
|
||||||
|
'app.settings.password.new': 'New Password',
|
||||||
|
'app.settings.password.new-message': 'Please input your new Password!',
|
||||||
|
'app.settings.password.new1': 'New Password1',
|
||||||
|
'app.settings.password.new1-message': 'Please comfirm your new Password!',
|
||||||
'app.settings.security.strong': 'Strong',
|
'app.settings.security.strong': 'Strong',
|
||||||
'app.settings.security.medium': 'Medium',
|
'app.settings.security.medium': 'Medium',
|
||||||
'app.settings.security.weak': 'Weak',
|
'app.settings.security.weak': 'Weak',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
'app.login.tenantCode': '租户编号',
|
'app.login.tenantId': '租户ID',
|
||||||
'app.login.userName': '用户名',
|
'app.login.userName': '用户名',
|
||||||
'app.login.password': '密码',
|
'app.login.password': '密码',
|
||||||
'app.login.message-invalid-credentials': '账户或密码错误(admin/ant.design)',
|
'app.login.message-invalid-credentials': '账户或密码错误(admin/ant.design)',
|
||||||
@ -21,7 +21,7 @@ export default {
|
|||||||
'app.register-result.view-mailbox': '查看邮箱',
|
'app.register-result.view-mailbox': '查看邮箱',
|
||||||
'validation.email.required': '请输入邮箱地址!',
|
'validation.email.required': '请输入邮箱地址!',
|
||||||
'validation.email.wrong-format': '邮箱地址格式错误!',
|
'validation.email.wrong-format': '邮箱地址格式错误!',
|
||||||
'validation.tenantCode.required': '请输入租户编号!',
|
'validation.tenantId.required': '请输入租户ID!',
|
||||||
'validation.userName.required': '请输入用户名!',
|
'validation.userName.required': '请输入用户名!',
|
||||||
'validation.password.required': '请输入密码!',
|
'validation.password.required': '请输入密码!',
|
||||||
'validation.password.twice': '两次输入的密码不匹配!',
|
'validation.password.twice': '两次输入的密码不匹配!',
|
||||||
|
@ -24,6 +24,7 @@ export default {
|
|||||||
'menu.monitor.doc': '接口文档',
|
'menu.monitor.doc': '接口文档',
|
||||||
'menu.tool': '研发工具',
|
'menu.tool': '研发工具',
|
||||||
'menu.tool.code': '代码生成',
|
'menu.tool.code': '代码生成',
|
||||||
|
'menu.tool.datasource': '数据源管理',
|
||||||
'menu.result': '结果页',
|
'menu.result': '结果页',
|
||||||
'menu.result.success': '成功页',
|
'menu.result.success': '成功页',
|
||||||
'menu.result.fail': '失败页',
|
'menu.result.fail': '失败页',
|
||||||
@ -34,6 +35,7 @@ export default {
|
|||||||
'menu.exception.trigger': '触发错误',
|
'menu.exception.trigger': '触发错误',
|
||||||
'menu.account': '个人页',
|
'menu.account': '个人页',
|
||||||
'menu.account.center': '个人中心',
|
'menu.account.center': '个人中心',
|
||||||
|
'menu.account.password': '密码修改',
|
||||||
'menu.account.settings': '个人设置',
|
'menu.account.settings': '个人设置',
|
||||||
'menu.account.trigger': '触发报错',
|
'menu.account.trigger': '触发报错',
|
||||||
'menu.account.logout': '退出登录',
|
'menu.account.logout': '退出登录',
|
||||||
|
@ -9,6 +9,8 @@ export default {
|
|||||||
'app.settings.basic.email-message': '请输入您的邮箱!',
|
'app.settings.basic.email-message': '请输入您的邮箱!',
|
||||||
'app.settings.basic.nickname': '昵称',
|
'app.settings.basic.nickname': '昵称',
|
||||||
'app.settings.basic.nickname-message': '请输入您的昵称!',
|
'app.settings.basic.nickname-message': '请输入您的昵称!',
|
||||||
|
'app.settings.basic.realname': '姓名',
|
||||||
|
'app.settings.basic.realname-message': '请输入您的姓名!',
|
||||||
'app.settings.basic.profile': '个人简介',
|
'app.settings.basic.profile': '个人简介',
|
||||||
'app.settings.basic.profile-message': '请输入个人简介!',
|
'app.settings.basic.profile-message': '请输入个人简介!',
|
||||||
'app.settings.basic.profile-placeholder': '个人简介',
|
'app.settings.basic.profile-placeholder': '个人简介',
|
||||||
@ -21,6 +23,12 @@ export default {
|
|||||||
'app.settings.basic.phone': '联系电话',
|
'app.settings.basic.phone': '联系电话',
|
||||||
'app.settings.basic.phone-message': '请输入您的联系电话!',
|
'app.settings.basic.phone-message': '请输入您的联系电话!',
|
||||||
'app.settings.basic.update': '更新基本信息',
|
'app.settings.basic.update': '更新基本信息',
|
||||||
|
'app.settings.password.old': '旧密码',
|
||||||
|
'app.settings.password.old-message': '请输入你的旧密码!',
|
||||||
|
'app.settings.password.new': '新密码',
|
||||||
|
'app.settings.password.new-message': '请输入你的新密码!',
|
||||||
|
'app.settings.password.new1': '确认密码',
|
||||||
|
'app.settings.password.new1-message': '请输入你的确认密码!',
|
||||||
'app.settings.security.strong': '强',
|
'app.settings.security.strong': '强',
|
||||||
'app.settings.security.medium': '中',
|
'app.settings.security.medium': '中',
|
||||||
'app.settings.security.weak': '弱',
|
'app.settings.security.weak': '弱',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
'app.login.tenantCode': '租戶編號',
|
'app.login.tenantId': '租戶編號',
|
||||||
'app.login.userName': '賬戶',
|
'app.login.userName': '賬戶',
|
||||||
'app.login.password': '密碼',
|
'app.login.password': '密碼',
|
||||||
'app.login.message-invalid-credentials': '賬戶或密碼錯誤(admin/ant.design)',
|
'app.login.message-invalid-credentials': '賬戶或密碼錯誤(admin/ant.design)',
|
||||||
@ -21,7 +21,7 @@ export default {
|
|||||||
'app.register-result.view-mailbox': '查看郵箱',
|
'app.register-result.view-mailbox': '查看郵箱',
|
||||||
'validation.email.required': '請輸入郵箱地址!',
|
'validation.email.required': '請輸入郵箱地址!',
|
||||||
'validation.email.wrong-format': '郵箱地址格式錯誤!',
|
'validation.email.wrong-format': '郵箱地址格式錯誤!',
|
||||||
'validation.tenantCode.required': '請輸入租戶編號!',
|
'validation.tenantId.required': '請輸入租戶編號!',
|
||||||
'validation.userName.required': '請輸入賬戶!',
|
'validation.userName.required': '請輸入賬戶!',
|
||||||
'validation.password.required': '請輸入密碼!',
|
'validation.password.required': '請輸入密碼!',
|
||||||
'validation.password.twice': '兩次輸入的密碼不匹配!',
|
'validation.password.twice': '兩次輸入的密碼不匹配!',
|
||||||
|
@ -24,6 +24,7 @@ export default {
|
|||||||
'menu.monitor.doc': '接口文檔',
|
'menu.monitor.doc': '接口文檔',
|
||||||
'menu.tool': '研發工具',
|
'menu.tool': '研發工具',
|
||||||
'menu.tool.code': '代碼生成',
|
'menu.tool.code': '代碼生成',
|
||||||
|
'menu.tool.datasource': '數據源管理',
|
||||||
'menu.result': '結果頁',
|
'menu.result': '結果頁',
|
||||||
'menu.result.success': '成功頁',
|
'menu.result.success': '成功頁',
|
||||||
'menu.result.fail': '失敗頁',
|
'menu.result.fail': '失敗頁',
|
||||||
@ -34,6 +35,7 @@ export default {
|
|||||||
'menu.exception.trigger': '觸發錯誤',
|
'menu.exception.trigger': '觸發錯誤',
|
||||||
'menu.account': '個人頁',
|
'menu.account': '個人頁',
|
||||||
'menu.account.center': '個人中心',
|
'menu.account.center': '個人中心',
|
||||||
|
'menu.account.password': '密碼修改',
|
||||||
'menu.account.settings': '個人設置',
|
'menu.account.settings': '個人設置',
|
||||||
'menu.account.trigger': '觸發報錯',
|
'menu.account.trigger': '觸發報錯',
|
||||||
'menu.account.logout': '退出登錄',
|
'menu.account.logout': '退出登錄',
|
||||||
|
@ -9,6 +9,8 @@ export default {
|
|||||||
'app.settings.basic.email-message': '請輸入您的郵箱!',
|
'app.settings.basic.email-message': '請輸入您的郵箱!',
|
||||||
'app.settings.basic.nickname': '昵稱',
|
'app.settings.basic.nickname': '昵稱',
|
||||||
'app.settings.basic.nickname-message': '請輸入您的昵稱!',
|
'app.settings.basic.nickname-message': '請輸入您的昵稱!',
|
||||||
|
'app.settings.basic.realname': '姓名',
|
||||||
|
'app.settings.basic.realname-message': '請輸入您的姓名!',
|
||||||
'app.settings.basic.profile': '個人簡介',
|
'app.settings.basic.profile': '個人簡介',
|
||||||
'app.settings.basic.profile-message': '請輸入個人簡介!',
|
'app.settings.basic.profile-message': '請輸入個人簡介!',
|
||||||
'app.settings.basic.profile-placeholder': '個人簡介',
|
'app.settings.basic.profile-placeholder': '個人簡介',
|
||||||
@ -21,6 +23,12 @@ export default {
|
|||||||
'app.settings.basic.phone': '聯系電話',
|
'app.settings.basic.phone': '聯系電話',
|
||||||
'app.settings.basic.phone-message': '請輸入您的聯系電話!',
|
'app.settings.basic.phone-message': '請輸入您的聯系電話!',
|
||||||
'app.settings.basic.update': '更新基本信息',
|
'app.settings.basic.update': '更新基本信息',
|
||||||
|
'app.settings.password.old': '舊密碼',
|
||||||
|
'app.settings.password.old-message': '請輸入妳的舊密碼!',
|
||||||
|
'app.settings.password.new': '新密碼',
|
||||||
|
'app.settings.password.new-message': '請輸入妳的新密碼!',
|
||||||
|
'app.settings.password.new1': '確認密碼',
|
||||||
|
'app.settings.password.new1-message': '請輸入妳的確認密碼!',
|
||||||
'app.settings.security.strong': '強',
|
'app.settings.security.strong': '強',
|
||||||
'app.settings.security.medium': '中',
|
'app.settings.security.medium': '中',
|
||||||
'app.settings.security.weak': '弱',
|
'app.settings.security.weak': '弱',
|
||||||
|
@ -2,6 +2,8 @@ import { message } from 'antd';
|
|||||||
import router from 'umi/router';
|
import router from 'umi/router';
|
||||||
import { CODE_NAMESPACE } from '../actions/code';
|
import { CODE_NAMESPACE } from '../actions/code';
|
||||||
import { list, submit, detail, remove } from '../services/code';
|
import { list, submit, detail, remove } from '../services/code';
|
||||||
|
import { select } from '../services/datasource';
|
||||||
|
import { dict } from '../services/dict';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespace: CODE_NAMESPACE,
|
namespace: CODE_NAMESPACE,
|
||||||
@ -10,6 +12,10 @@ export default {
|
|||||||
list: [],
|
list: [],
|
||||||
pagination: {},
|
pagination: {},
|
||||||
},
|
},
|
||||||
|
init: {
|
||||||
|
source: [],
|
||||||
|
category: [],
|
||||||
|
},
|
||||||
detail: {},
|
detail: {},
|
||||||
},
|
},
|
||||||
effects: {
|
effects: {
|
||||||
@ -29,6 +35,19 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
*fetchInit({ payload }, { call, put }) {
|
||||||
|
const responseS = yield call(select, payload);
|
||||||
|
const responseC = yield call(dict, payload);
|
||||||
|
if (responseS.success && responseC.success) {
|
||||||
|
yield put({
|
||||||
|
type: 'saveInit',
|
||||||
|
payload: {
|
||||||
|
source: responseS.data,
|
||||||
|
category: responseC.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
*fetchDetail({ payload }, { call, put }) {
|
*fetchDetail({ payload }, { call, put }) {
|
||||||
const response = yield call(detail, payload);
|
const response = yield call(detail, payload);
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@ -71,6 +90,12 @@ export default {
|
|||||||
data: action.payload,
|
data: action.payload,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
saveInit(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
init: action.payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
saveDetail(state, action) {
|
saveDetail(state, action) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
87
src/models/datasource.js
Normal file
87
src/models/datasource.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { message } from 'antd';
|
||||||
|
import router from 'umi/router';
|
||||||
|
import { DATASOURCE_NAMESPACE } from '../actions/datasource';
|
||||||
|
import { list, submit, detail, remove } from '../services/datasource';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespace: DATASOURCE_NAMESPACE,
|
||||||
|
state: {
|
||||||
|
data: {
|
||||||
|
list: [],
|
||||||
|
pagination: false,
|
||||||
|
},
|
||||||
|
detail: {},
|
||||||
|
},
|
||||||
|
effects: {
|
||||||
|
*fetchList({ payload }, { call, put }) {
|
||||||
|
const response = yield call(list, payload);
|
||||||
|
if (response.success) {
|
||||||
|
yield put({
|
||||||
|
type: 'saveList',
|
||||||
|
payload: {
|
||||||
|
list: response.data.records,
|
||||||
|
pagination: {
|
||||||
|
total: response.data.total,
|
||||||
|
current: response.data.current,
|
||||||
|
pageSize: response.data.size,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*fetchDetail({ payload }, { call, put }) {
|
||||||
|
const response = yield call(detail, payload);
|
||||||
|
if (response.success) {
|
||||||
|
yield put({
|
||||||
|
type: 'saveDetail',
|
||||||
|
payload: {
|
||||||
|
detail: response.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*clearDetail({ payload }, { put }) {
|
||||||
|
yield put({
|
||||||
|
type: 'removeDetail',
|
||||||
|
payload: { payload },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
*submit({ payload }, { call }) {
|
||||||
|
const response = yield call(submit, payload);
|
||||||
|
if (response.success) {
|
||||||
|
message.success('提交成功');
|
||||||
|
router.push('/tool/datasource');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*remove({ payload }, { call }) {
|
||||||
|
const {
|
||||||
|
data: { keys },
|
||||||
|
success,
|
||||||
|
} = payload;
|
||||||
|
const response = yield call(remove, { ids: keys });
|
||||||
|
if (response.success) {
|
||||||
|
success();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
saveList(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
data: action.payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
saveDetail(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
detail: action.payload.detail,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
removeDetail(state) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
detail: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
import router from 'umi/router';
|
import router from 'umi/router';
|
||||||
import { USER_NAMESPACE } from '../actions/user';
|
import { USER_NAMESPACE } from '../actions/user';
|
||||||
import { query as queryUsers, list, submit, detail, remove, grant } from '../services/user';
|
import { query as queryUsers, list, submit, update, detail, remove, grant } from '../services/user';
|
||||||
import { select as tenants } from '../services/tenant';
|
import { select as tenants } from '../services/tenant';
|
||||||
import { tree as roles } from '../services/role';
|
import { tree as roles } from '../services/role';
|
||||||
import { tree as depts } from '../services/dept';
|
import { tree as depts } from '../services/dept';
|
||||||
@ -116,6 +116,13 @@ export default {
|
|||||||
router.push('/system/user');
|
router.push('/system/user');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
*update({ payload }, { call }) {
|
||||||
|
const response = yield call(update, payload);
|
||||||
|
if (response.success) {
|
||||||
|
message.success('提交成功');
|
||||||
|
router.push('/system/user');
|
||||||
|
}
|
||||||
|
},
|
||||||
*remove({ payload }, { call }) {
|
*remove({ payload }, { call }) {
|
||||||
const {
|
const {
|
||||||
data: { keys },
|
data: { keys },
|
||||||
|
@ -1,106 +1,161 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { formatMessage, FormattedMessage } from 'umi/locale';
|
import { formatMessage } from 'umi/locale';
|
||||||
import { Form, Input, Upload, Select, Button } from 'antd';
|
import { Form, Input, Upload, Button, message, Icon, Card } from 'antd';
|
||||||
import { connect } from 'dva';
|
import Panel from '../../../components/Panel';
|
||||||
import styles from './BaseView.less';
|
import { getUserInfo, update } from '../../../services/user';
|
||||||
import GeographicView from './GeographicView';
|
import { getToken } from '../../../utils/authority';
|
||||||
import PhoneView from './PhoneView';
|
|
||||||
// import { getTimeDistance } from '@/utils/utils';
|
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
const { Option } = Select;
|
|
||||||
|
|
||||||
// 头像组件 方便以后独立,增加裁剪之类的功能
|
|
||||||
const AvatarView = ({ avatar }) => (
|
|
||||||
<Fragment>
|
|
||||||
<div className={styles.avatar_title}>
|
|
||||||
<FormattedMessage id="app.settings.basic.avatar" defaultMessage="Avatar" />
|
|
||||||
</div>
|
|
||||||
<div className={styles.avatar}>
|
|
||||||
<img src={avatar} alt="avatar" />
|
|
||||||
</div>
|
|
||||||
<Upload fileList={[]}>
|
|
||||||
<div className={styles.button_view}>
|
|
||||||
<Button icon="upload">
|
|
||||||
<FormattedMessage id="app.settings.basic.change-avatar" defaultMessage="Change avatar" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Upload>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
|
|
||||||
const validatorGeographic = (rule, value, callback) => {
|
|
||||||
const { province, city } = value;
|
|
||||||
if (!province.key) {
|
|
||||||
callback('Please input your province!');
|
|
||||||
}
|
|
||||||
if (!city.key) {
|
|
||||||
callback('Please input your city!');
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
|
|
||||||
const validatorPhone = (rule, value, callback) => {
|
|
||||||
const values = value.split('-');
|
|
||||||
if (!values[0]) {
|
|
||||||
callback('Please input your area code!');
|
|
||||||
}
|
|
||||||
if (!values[1]) {
|
|
||||||
callback('Please input your phone number!');
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
|
|
||||||
@connect(({ user }) => ({
|
|
||||||
currentUser: user.currentUser,
|
|
||||||
}))
|
|
||||||
@Form.create()
|
@Form.create()
|
||||||
class BaseView extends Component {
|
class BaseView extends Component {
|
||||||
|
state = {
|
||||||
|
userId: '',
|
||||||
|
avatar: '',
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setBaseInfo();
|
this.setBaseInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
setBaseInfo = () => {
|
setBaseInfo = () => {
|
||||||
const { currentUser, form } = this.props;
|
const { form } = this.props;
|
||||||
Object.keys(form.getFieldsValue()).forEach(key => {
|
getUserInfo().then(resp => {
|
||||||
const obj = {};
|
if (resp.success) {
|
||||||
obj[key] = currentUser[key] || null;
|
const userInfo = resp.data;
|
||||||
form.setFieldsValue(obj);
|
Object.keys(form.getFieldsValue()).forEach(key => {
|
||||||
|
const obj = {};
|
||||||
|
obj[key] = userInfo[key] || null;
|
||||||
|
form.setFieldsValue(obj);
|
||||||
|
});
|
||||||
|
this.setState({ userId: userInfo.id, avatar: userInfo.avatar });
|
||||||
|
} else {
|
||||||
|
message.error(resp.msg || '获取数据失败');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getAvatarURL() {
|
beforeUpload = file => {
|
||||||
const { currentUser } = this.props;
|
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
||||||
if (currentUser.avatar) {
|
if (!isJpgOrPng) {
|
||||||
return currentUser.avatar;
|
message.error('You can only upload JPG/PNG file!');
|
||||||
}
|
}
|
||||||
const url = 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png';
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||||
return url;
|
if (!isLt2M) {
|
||||||
}
|
message.error('Image must smaller than 2MB!');
|
||||||
|
}
|
||||||
|
return isJpgOrPng && isLt2M;
|
||||||
|
};
|
||||||
|
|
||||||
getViewDom = ref => {
|
handleChange = info => {
|
||||||
this.view = ref;
|
if (info.file.status === 'uploading') {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (info.file.status === 'done') {
|
||||||
|
this.setState({ loading: false, avatar: info.file.response.data.link });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const { form } = this.props;
|
||||||
|
const { userId, avatar } = this.state;
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
const params = {
|
||||||
|
id: userId,
|
||||||
|
...values,
|
||||||
|
avatar,
|
||||||
|
};
|
||||||
|
update(params).then(resp => {
|
||||||
|
if (resp.success) {
|
||||||
|
message.success(resp.msg);
|
||||||
|
} else {
|
||||||
|
message.error(resp.msg || '提交失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
form: { getFieldDecorator },
|
form: { getFieldDecorator },
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const { avatar, loading } = this.state;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 7 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
md: { span: 10 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadProp = {
|
||||||
|
action: '/api/blade-resource/oss/endpoint/put-file',
|
||||||
|
headers: {
|
||||||
|
'Blade-Auth': getToken(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadButton = (
|
||||||
|
<div>
|
||||||
|
<Icon type={loading ? 'loading' : 'plus'} />
|
||||||
|
<div className="ant-upload-text">上传头像</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleSubmit}>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.baseView} ref={this.getViewDom}>
|
<Panel title="个人设置" back="/" action={action}>
|
||||||
<div className={styles.left}>
|
<Form style={{ marginTop: 8 }} hideRequiredMark>
|
||||||
<Form layout="vertical" onSubmit={this.handleSubmit} hideRequiredMark>
|
<Card title="基本信息" bordered={false}>
|
||||||
<FormItem label={formatMessage({ id: 'app.settings.basic.email' })}>
|
<FormItem
|
||||||
{getFieldDecorator('email', {
|
{...formItemLayout}
|
||||||
|
label={formatMessage({ id: 'app.settings.basic.avatar' })}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('avatar', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: formatMessage({ id: 'app.settings.basic.email-message' }, {}),
|
message: formatMessage({ id: 'app.settings.basic.avatar' }, {}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})(<Input />)}
|
})(
|
||||||
|
<Upload
|
||||||
|
name="file"
|
||||||
|
listType="picture-card"
|
||||||
|
className="avatar-uploader"
|
||||||
|
showUploadList={false}
|
||||||
|
beforeUpload={this.beforeUpload}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
{...uploadProp}
|
||||||
|
>
|
||||||
|
{avatar ? (
|
||||||
|
<img src={avatar} alt="avatar" style={{ width: '100%' }} />
|
||||||
|
) : (
|
||||||
|
uploadButton
|
||||||
|
)}
|
||||||
|
</Upload>
|
||||||
|
)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label={formatMessage({ id: 'app.settings.basic.nickname' })}>
|
<FormItem
|
||||||
|
{...formItemLayout}
|
||||||
|
label={formatMessage({ id: 'app.settings.basic.nickname' })}
|
||||||
|
>
|
||||||
{getFieldDecorator('name', {
|
{getFieldDecorator('name', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
@ -110,81 +165,42 @@ class BaseView extends Component {
|
|||||||
],
|
],
|
||||||
})(<Input />)}
|
})(<Input />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label={formatMessage({ id: 'app.settings.basic.profile' })}>
|
<FormItem
|
||||||
{getFieldDecorator('profile', {
|
{...formItemLayout}
|
||||||
|
label={formatMessage({ id: 'app.settings.basic.realname' })}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('realName', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: formatMessage({ id: 'app.settings.basic.profile-message' }, {}),
|
message: formatMessage({ id: 'app.settings.basic.realname-message' }, {}),
|
||||||
},
|
|
||||||
],
|
|
||||||
})(
|
|
||||||
<Input.TextArea
|
|
||||||
placeholder={formatMessage({ id: 'app.settings.basic.profile-placeholder' })}
|
|
||||||
rows={4}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</FormItem>
|
|
||||||
<FormItem label={formatMessage({ id: 'app.settings.basic.country' })}>
|
|
||||||
{getFieldDecorator('country', {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: formatMessage({ id: 'app.settings.basic.country-message' }, {}),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})(
|
|
||||||
<Select style={{ maxWidth: 220 }}>
|
|
||||||
<Option value="China">中国</Option>
|
|
||||||
</Select>
|
|
||||||
)}
|
|
||||||
</FormItem>
|
|
||||||
<FormItem label={formatMessage({ id: 'app.settings.basic.geographic' })}>
|
|
||||||
{getFieldDecorator('geographic', {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: formatMessage({ id: 'app.settings.basic.geographic-message' }, {}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
validator: validatorGeographic,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})(<GeographicView />)}
|
|
||||||
</FormItem>
|
|
||||||
<FormItem label={formatMessage({ id: 'app.settings.basic.address' })}>
|
|
||||||
{getFieldDecorator('address', {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: formatMessage({ id: 'app.settings.basic.address-message' }, {}),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})(<Input />)}
|
})(<Input />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label={formatMessage({ id: 'app.settings.basic.phone' })}>
|
<FormItem {...formItemLayout} label={formatMessage({ id: 'app.settings.basic.phone' })}>
|
||||||
{getFieldDecorator('phone', {
|
{getFieldDecorator('phone', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: formatMessage({ id: 'app.settings.basic.phone-message' }, {}),
|
message: formatMessage({ id: 'app.settings.basic.phone-message' }, {}),
|
||||||
},
|
},
|
||||||
{ validator: validatorPhone },
|
|
||||||
],
|
],
|
||||||
})(<PhoneView />)}
|
})(<Input />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<Button type="primary">
|
<FormItem {...formItemLayout} label={formatMessage({ id: 'app.settings.basic.email' })}>
|
||||||
<FormattedMessage
|
{getFieldDecorator('email', {
|
||||||
id="app.settings.basic.update"
|
rules: [
|
||||||
defaultMessage="Update Information"
|
{
|
||||||
/>
|
required: true,
|
||||||
</Button>
|
message: formatMessage({ id: 'app.settings.basic.email-message' }, {}),
|
||||||
</Form>
|
},
|
||||||
</div>
|
],
|
||||||
<div className={styles.right}>
|
})(<Input />)}
|
||||||
<AvatarView avatar={this.getAvatarURL()} />
|
</FormItem>
|
||||||
</div>
|
</Card>
|
||||||
</div>
|
</Form>
|
||||||
|
</Panel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
98
src/pages/Account/Settings/PasswordView.js
Normal file
98
src/pages/Account/Settings/PasswordView.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import { formatMessage } from 'umi/locale';
|
||||||
|
import { Form, Input, Button, Card, message } from 'antd';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import { updatePassword } from '../../../services/user';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@Form.create()
|
||||||
|
class PasswordView extends Component {
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const { form } = this.props;
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
updatePassword(values).then(resp => {
|
||||||
|
if (resp.success) {
|
||||||
|
message.success(resp.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 7 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
md: { span: 10 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleSubmit}>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="密码修改" back="/" action={action}>
|
||||||
|
<Form style={{ marginTop: 8 }} hideRequiredMark>
|
||||||
|
<Card title="基本信息" bordered={false}>
|
||||||
|
<FormItem
|
||||||
|
{...formItemLayout}
|
||||||
|
label={formatMessage({ id: 'app.settings.password.old' })}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('oldPassword', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: formatMessage({ id: 'app.settings.password.old-message' }, {}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input type="password" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
{...formItemLayout}
|
||||||
|
label={formatMessage({ id: 'app.settings.password.new' })}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('newPassword', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: formatMessage({ id: 'app.settings.password.new-message' }, {}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input type="password" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
{...formItemLayout}
|
||||||
|
label={formatMessage({ id: 'app.settings.password.new1' })}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('newPassword1', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: formatMessage({ id: 'app.settings.password.new1-message' }, {}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input type="password" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PasswordView;
|
@ -1,286 +1,223 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import moment from 'moment';
|
import { Card, Col, Collapse, Row } from 'antd';
|
||||||
import { connect } from 'dva';
|
import styles from '../../layouts/Sword.less';
|
||||||
import Link from 'umi/link';
|
|
||||||
import { Row, Col, Card, List, Avatar } from 'antd';
|
|
||||||
|
|
||||||
import EditableLinkGroup from '@/components/EditableLinkGroup';
|
|
||||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||||
|
|
||||||
import styles from './Workplace.less';
|
const { Panel } = Collapse;
|
||||||
|
|
||||||
const links = [
|
|
||||||
{
|
|
||||||
title: '操作一',
|
|
||||||
href: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作二',
|
|
||||||
href: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作三',
|
|
||||||
href: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作四',
|
|
||||||
href: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作五',
|
|
||||||
href: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作六',
|
|
||||||
href: '',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
@connect(({ user, project, activities, loading }) => ({
|
|
||||||
currentUser: user.currentUser,
|
|
||||||
project,
|
|
||||||
activities,
|
|
||||||
currentUserLoading: loading.effects['user/fetchCurrent'],
|
|
||||||
projectLoading: loading.effects['project/fetchNotice'],
|
|
||||||
activitiesLoading: loading.effects['activities/fetchList'],
|
|
||||||
}))
|
|
||||||
class Workplace extends PureComponent {
|
class Workplace extends PureComponent {
|
||||||
componentDidMount() {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
dispatch({
|
|
||||||
type: 'user/fetchCurrent',
|
|
||||||
});
|
|
||||||
dispatch({
|
|
||||||
type: 'project/fetchNotice',
|
|
||||||
});
|
|
||||||
dispatch({
|
|
||||||
type: 'activities/fetchList',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderActivities() {
|
|
||||||
const {
|
|
||||||
activities: { list },
|
|
||||||
} = this.props;
|
|
||||||
return list.map(item => {
|
|
||||||
const events = item.template.split(/@\{([^{}]*)\}/gi).map(key => {
|
|
||||||
if (item[key]) {
|
|
||||||
return (
|
|
||||||
<a href={item[key].link} key={item[key].name}>
|
|
||||||
{item[key].name}
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
<List.Item key={item.id}>
|
|
||||||
<List.Item.Meta
|
|
||||||
avatar={<Avatar src={item.user.avatar} />}
|
|
||||||
title={
|
|
||||||
<span>
|
|
||||||
<a className={styles.username}>{item.user.name}</a>
|
|
||||||
|
|
||||||
<span className={styles.event}>{events}</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
description={
|
|
||||||
<span className={styles.datetime} title={item.updatedAt}>
|
|
||||||
{moment(item.updatedAt).fromNow()}
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
|
||||||
currentUser,
|
|
||||||
currentUserLoading,
|
|
||||||
project: { notice },
|
|
||||||
projectLoading,
|
|
||||||
activitiesLoading,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const pageHeaderContent =
|
|
||||||
currentUser && Object.keys(currentUser).length ? (
|
|
||||||
<div className={styles.pageHeaderContent}>
|
|
||||||
<div className={styles.avatar}>
|
|
||||||
<Avatar size="large" src={currentUser.avatar} />
|
|
||||||
</div>
|
|
||||||
<div className={styles.content}>
|
|
||||||
<div className={styles.contentTitle}>
|
|
||||||
您好,
|
|
||||||
{currentUser.name}
|
|
||||||
,祝您开心每一天!
|
|
||||||
</div>
|
|
||||||
<div>我们用代码编写梦想,用梦想改变世界。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null;
|
|
||||||
|
|
||||||
const extraContent = (
|
|
||||||
<div className={styles.extraContent}>
|
|
||||||
<div className={styles.statItem}>
|
|
||||||
<p>项目数</p>
|
|
||||||
<p>56</p>
|
|
||||||
</div>
|
|
||||||
<div className={styles.statItem}>
|
|
||||||
<p>团队内排名</p>
|
|
||||||
<p>
|
|
||||||
8<span> / 24</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className={styles.statItem}>
|
|
||||||
<p>项目访问</p>
|
|
||||||
<p>2,223</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageHeaderWrapper
|
<PageHeaderWrapper>
|
||||||
loading={currentUserLoading}
|
<Card className={styles.card} bordered={false}>
|
||||||
content={pageHeaderContent}
|
<Row gutter={24}>
|
||||||
extraContent={extraContent}
|
<Col span={24}>
|
||||||
>
|
<div style={{ textAlign: 'center' }}>
|
||||||
<Row gutter={24}>
|
<img src="https://img.shields.io/badge/Release-V2.5.4-green.svg" alt="Downloads" />
|
||||||
<Col xl={16} lg={24} md={24} sm={24} xs={24}>
|
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status" />
|
||||||
<Card
|
<img
|
||||||
style={{ marginBottom: 24 }}
|
src="https://img.shields.io/badge/Spring%20Cloud-Greenwich.SR3-blue.svg"
|
||||||
bodyStyle={{ padding: 0 }}
|
alt="Coverage Status"
|
||||||
bordered={false}
|
/>
|
||||||
className={styles.activeCard}
|
<img
|
||||||
title="简介"
|
src="https://img.shields.io/badge/Spring%20Boot-2.1.9.RELEASE-blue.svg"
|
||||||
loading={activitiesLoading}
|
alt="Downloads"
|
||||||
>
|
/>
|
||||||
<List loading={activitiesLoading} size="large">
|
<a href="https://bladex.vip">
|
||||||
<div className={styles.activitiesList}>
|
<img
|
||||||
<List.Item key="desc-1">
|
src="https://img.shields.io/badge/Sword%20Author-Small%20Chill-ff69b4.svg"
|
||||||
<List.Item.Meta
|
alt="Downloads"
|
||||||
title={
|
/>
|
||||||
<span>
|
</a>
|
||||||
<a className={styles.username}>SpringBlade 2.0 </a>
|
<a href="https://bladex.vip">
|
||||||
<span className={styles.event}>
|
<img
|
||||||
是一个基于 Spring Boot 2 & Spring Cloud Finchley & Mybatis
|
src="https://img.shields.io/badge/Copyright%20-@BladeX-%23ff3f59.svg"
|
||||||
等核心技术,用于快速构建中大型系统的基础框架。
|
alt="Downloads"
|
||||||
</span>
|
/>
|
||||||
</span>
|
</a>
|
||||||
}
|
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
<List.Item key="desc-2">
|
|
||||||
<List.Item.Meta
|
|
||||||
title={
|
|
||||||
<span>
|
|
||||||
<a className={styles.username}>SpringBlade 企业版系列 </a>
|
|
||||||
<span className={styles.event}>
|
|
||||||
已通过长时间生产环境的考验,现将其拆分出基础模块进行开源,当前版本为:2.0.0。
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
<List.Item key="desc-2">
|
|
||||||
<List.Item.Meta
|
|
||||||
title={
|
|
||||||
<span>
|
|
||||||
<a className={styles.username}>SpringBlade </a>
|
|
||||||
<span className={styles.event}>
|
|
||||||
技术交流群号:477853168。欢迎大家加入。
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
</div>
|
|
||||||
</List>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card
|
|
||||||
className={styles.projectList}
|
|
||||||
title="所使用技术"
|
|
||||||
bordered={false}
|
|
||||||
loading={projectLoading}
|
|
||||||
bodyStyle={{ padding: 0 }}
|
|
||||||
>
|
|
||||||
{notice.map(item => (
|
|
||||||
<Card.Grid className={styles.projectGrid} key={item.id}>
|
|
||||||
<Card bodyStyle={{ padding: 0 }} bordered={false}>
|
|
||||||
<Card.Meta
|
|
||||||
title={
|
|
||||||
<div className={styles.cardTitle}>
|
|
||||||
<Avatar size="small" src={item.logo} />
|
|
||||||
<Link to="/">{item.title}</Link>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
description={item.description}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
</Card.Grid>
|
|
||||||
))}
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
<Col xl={8} lg={24} md={24} sm={24} xs={24}>
|
|
||||||
<Card
|
|
||||||
style={{ marginBottom: 24 }}
|
|
||||||
title="快速开始 / 便捷导航"
|
|
||||||
bordered={false}
|
|
||||||
bodyStyle={{ padding: 0 }}
|
|
||||||
>
|
|
||||||
<EditableLinkGroup onAdd={() => {}} links={links} linkElement={Link} />
|
|
||||||
</Card>
|
|
||||||
<Card
|
|
||||||
bodyStyle={{ paddingTop: 12, paddingBottom: 12 }}
|
|
||||||
bordered={false}
|
|
||||||
title="团队"
|
|
||||||
loading={projectLoading}
|
|
||||||
>
|
|
||||||
<div className={styles.members}>
|
|
||||||
<Row gutter={48}>
|
|
||||||
<Col span={12} key="members-item-1">
|
|
||||||
<Link to="/">
|
|
||||||
<Avatar
|
|
||||||
src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
<span className={styles.member}>ChillZhuang</span>
|
|
||||||
</Link>
|
|
||||||
</Col>
|
|
||||||
<Col span={12} key="members-item-2">
|
|
||||||
<Link to="/">
|
|
||||||
<Avatar
|
|
||||||
src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
<span className={styles.member}>DreamLu</span>
|
|
||||||
</Link>
|
|
||||||
</Col>
|
|
||||||
<Col span={12} key="members-item-3">
|
|
||||||
<Link to="/">
|
|
||||||
<Avatar
|
|
||||||
src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
<span className={styles.member}>LengLeng</span>
|
|
||||||
</Link>
|
|
||||||
</Col>
|
|
||||||
<Col span={12} key="members-item-4">
|
|
||||||
<Link to="/">
|
|
||||||
<Avatar
|
|
||||||
src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
<span className={styles.member}>LiXunHuan</span>
|
|
||||||
</Link>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Col>
|
||||||
</Col>
|
</Row>
|
||||||
</Row>
|
<Row gutter={24}>
|
||||||
|
<Col span={16}>
|
||||||
|
<Collapse bordered={false} defaultActiveKey={['1','2','3','5']}>
|
||||||
|
<Panel header="欢迎使用Sword" key="1">
|
||||||
|
<div>1.Sword是SpringBlade前端UI系统</div>
|
||||||
|
<div>2.对现有的ant design pro库进行二次封装</div>
|
||||||
|
<div>3.100%兼容原生ant design pro库</div>
|
||||||
|
<div>4.配合后端代码生成系统可以快速搭建完整的功能模块</div>
|
||||||
|
<div>5.使用Sword可以大幅度提升开发效率,不再为重复工作发愁</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="什么是BladeX" key="2">
|
||||||
|
<div>1.BladeX是一款精心设计的微服务架构,提供 SpringCloud 全套解决方案</div>
|
||||||
|
<div>2.开源中国首批完美集成 SpringCloud Alibaba 系列组件的微服务架构</div>
|
||||||
|
<div>3.基于稳定生产的商业项目升级优化而来,更加贴近企业级的需求</div>
|
||||||
|
<div>4.追求企业开发更加高效,部署更加方便,生产更加稳定</div>
|
||||||
|
<div>5.GVP-码云最有价值开源项目</div>
|
||||||
|
<div>6.BladeX授权地址:<a href="https://bladex.vip/#/vip">点击授权</a></div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="为何需要BladeX" key="3">
|
||||||
|
<div>1.经历过较长的线上生产,积累了很多企业痛点的解决方案。</div>
|
||||||
|
<div>2.一套代码兼容MySql、Oracle、PostgreSQL,适应企业各种不同场景的需求。</div>
|
||||||
|
<div>3.集成了很多企业急切所需的例如多租户、Oauth2授权认证、工作流、分布式事务等等功能。</div>
|
||||||
|
<div>4.深度定制了Flowable工作流,完美支持SpringCloud分布式服务的场景,以远程调用的方式进行操作。</div>
|
||||||
|
<div>5.升级了核心驱动,新功能完全可以开箱即用,而开源版需要自己再花时间进行集成,需要花掉更多的时间成本。</div>
|
||||||
|
<div>6.拥抱微服务时代,很多企业由于项目转型或升级,传统的技术已然不能满足,反而会花更多成本,而BladeX就是为此而生。</div>
|
||||||
|
<div>7.同时提供SpringCloud版本和SpringBoot版本,两个版本的api可以与Sword和Saber无缝对接,为小型项目至大型项目保驾护航。</div>
|
||||||
|
<div>8.授权购买即永久,源码没有混淆,后续升级完全免费。企业只需花很少的钱即可获得一整套成熟的解决方案,你还在等什么?</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="拥有的核心功能" key="4">
|
||||||
|
<div>1.前后端分离-采用前后端分离模式,前端提供两套架构,Sword基于React,Saber基于Vue</div>
|
||||||
|
<div>2. 分布式单体式后端架构-提供两套后端架构,基于SpringCloud的分布式架构以及基于SpringBoot的单体式架构</div>
|
||||||
|
<div>3.API完全兼容-两套后端架构与两套前端架构,共四套架构可以任意组合,所有API完全兼容</div>
|
||||||
|
<div>4.前后端代码生成-定制针对两套前端与后端的代码生成模板,轻松生成整个模块的前后端代码,减少重复工作量</div>
|
||||||
|
<div>5.组件化、插件化架构-针对功能深度定制各个starter,引入开箱即用,为整个架构解耦,提升效率</div>
|
||||||
|
<div>6.Nacos-集成阿里巴巴的Nacos完成统一的服务注册与配置</div>
|
||||||
|
<div>7.Sentinel-集成Sentinel从流量控制、熔断降级、系统负载等多个维度保护服务的稳定性</div>
|
||||||
|
<div>8.Dubbo-完美集成Dubbo最新版,支持远程RPC调用</div>
|
||||||
|
<div>9.多租户系统-完整的SaaS多租户架构</div>
|
||||||
|
<div>10.Oauth2-集成Oauth2协议,完美支持多终端的接入与认证授权</div>
|
||||||
|
<div>11.工作流-深度定制SpringCloud分布式场景的Flowable工作流,为复杂流程保驾护航。同时提供SpringBoot集成版本</div>
|
||||||
|
<div>12.独立流程设计器-提供独立的完全汉化的流程设计器,轻松定制流程模型</div>
|
||||||
|
<div>13.动态网关-集成基于Nacos的轻量级、高拓展性动态网关</div>
|
||||||
|
<div>14.动态聚合文档-实现基于Nacos的Swagger SpringCloud聚合文档</div>
|
||||||
|
<div>15.分布式文件服务-集成minio、qiniu、alioss等优秀的第三方,提供便捷的文件上传与管理</div>
|
||||||
|
<div>16.多租户对象存储系统-在SaaS系统中,各租户可自行配置文件上传至自己的私有OSS</div>
|
||||||
|
<div>17.权限管理-精心设计的权限管理方案,角色权限精确到按钮</div>
|
||||||
|
<div>18.动态数据权限-高度灵活的动态数据权限,提供注解+Web可视化两种配置方式,Web配置无需重启直接生效</div>
|
||||||
|
<div>19.动态接口权限-高度灵活的动态接口权限,提供注解+Web可视化两种配置方式,Web配置无需重启直接生效</div>
|
||||||
|
<div>20.多租户顶部菜单配置-提供给每个租户独立的顶部菜单配置模块,可以自定义顶部菜单切换</div>
|
||||||
|
<div>21.主流数据库兼容-一套代码完全兼容Mysql、Postgresql、Oracle三大主流数据库</div>
|
||||||
|
<div>22.动态网关鉴权-基于Nacos的动态网关鉴权,可在线配置,实时生效</div>
|
||||||
|
<div>23.全能代码生成器-支持自定义模型、模版 、业务建模,支持多种模板引擎,在线配置。大幅度提升开发效率,不再为重复工作发愁。</div>
|
||||||
|
<div>24.Seata分布式事务-定制集成Seata,支持分布式事务,无代码侵入,不失灵活与简洁</div>
|
||||||
|
<div>25.未完待续...</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="软件定制开发合作" key="5">
|
||||||
|
<div>1.接BladeX系列架构的定制服务</div>
|
||||||
|
<div>2.接3个月以内工期的react、vue、springboot、springcloud、app、小程序等软件定制服务</div>
|
||||||
|
<div>3.有意向请联系唯一指定QQ:85088620</div>
|
||||||
|
</Panel>
|
||||||
|
</Collapse>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Collapse bordered={false} defaultActiveKey={['13']}>
|
||||||
|
<Panel header="2.5.4发布 增加多数据源示例工程" key="13">
|
||||||
|
<div>1.增加示例工程,增加多种常见场景的解决方案</div>
|
||||||
|
<div>2.增加不同包名运行的示例</div>
|
||||||
|
<div>3.增加多数据源调用运行的示例</div>
|
||||||
|
<div>4.增加自定义加载Naocs配置文件的示例</div>
|
||||||
|
<div>5.增加根据Nacos命名空间读取配置、注册服务的示例</div>
|
||||||
|
<div>6.修复Condition类没有过滤分页字段的问题</div>
|
||||||
|
<div>7.拆分CommonConstant出LauncherConstant</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.5.3发布 集成分布式链路追踪" key="12">
|
||||||
|
<div>1.封装集成zipkin,支持分布式链路追踪</div>
|
||||||
|
<div>2.seata升级至0.9.0,解决部分分布式事务遇到的bug</div>
|
||||||
|
<div>3.springboot版本升级至2.1.9</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.5.2发布 增加个人中心" key="11">
|
||||||
|
<div>1.增加个人中心,支持用户信息自定义修改</div>
|
||||||
|
<div>2.增加网关鉴权配置示例</div>
|
||||||
|
<div>3.token的SIGN_KEY修改为一致</div>
|
||||||
|
<div>4.admin模块增加对seata服务的过滤</div>
|
||||||
|
<div>5.blade-tool增加部分工具类方法</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.5.1发布 增加网关动态鉴权" key="10">
|
||||||
|
<div>1.增加网关动态鉴权</div>
|
||||||
|
<div>2.secure安全模块token校验默认关闭,交由网关处理</div>
|
||||||
|
<div>3.boot版本开启secure token校验功能</div>
|
||||||
|
<div>4.优化blade-gateway代码逻辑</div>
|
||||||
|
<div>5.修复blade-resource无法启动的问题</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.5.0发布 集成seata支持分布式事务" key="9">
|
||||||
|
<div>1.封装集成seata,支持分布式事务</div>
|
||||||
|
<div>2.重写blade-core-cloud模块,增强cloud场景支持</div>
|
||||||
|
<div>3.增加hystrix自动fallback功能</div>
|
||||||
|
<div>4.升级springboot至2.1.8.RELEASE</div>
|
||||||
|
<div>5.升级springcloud至Greenwich.SR3</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.4.1发布 代码生成增加多数据源,强化代码生成功能" key="8">
|
||||||
|
<div>1.升级SpringBoot至2.1.7</div>
|
||||||
|
<div>2.代码生成增加多数据源配置</div>
|
||||||
|
<div>3.增强代码生成功能,支持可选基础业务、包装器配置</div>
|
||||||
|
<div>4.优化代码生成模板</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.4.0发布 升级AlibabaCloud毕业版本" key="7">
|
||||||
|
<div>1.升级AlibabaCloud毕业版本</div>
|
||||||
|
<div>2.升级支持Naocs 1.1.0、Sentinel 1.6.3</div>
|
||||||
|
<div>3.租户系统的tenantCode统一更改为tenantId</div>
|
||||||
|
<div>4.优化代码生成模板</div>
|
||||||
|
<div>5.优化mybatis-plus新版配置</div>
|
||||||
|
<div>6.修复排序字段sql注入问题</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.3.3发布 重构令牌逻辑, 增强令牌功能" key="6">
|
||||||
|
<div>1.重构令牌发放逻辑,可自定义令牌类型,增强可拓展性</div>
|
||||||
|
<div>2.增加动态配置token过期时间、令牌续期功能</div>
|
||||||
|
<div>3.增加GateWay动态聚合文档功能,简化配置</div>
|
||||||
|
<div>4.优化Wrapper定义,代码更加简洁</div>
|
||||||
|
<div>5.Swagger增加多包扫描</div>
|
||||||
|
<div>6.使用 Swagger-Bootstrap-UI 最新版排序注解</div>
|
||||||
|
<div>7.升级 SpringBoot 2.1.6,SpringCloud Greenwich.SR2</div>
|
||||||
|
<div>8.升级 Mybatis-Plus 3.1.2</div>
|
||||||
|
<div>9.修复排序字段可能导致的sql注入问题</div>
|
||||||
|
<div>10.修复部分缓存清除失效的问题</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.3.2发布 增加 OSS 封装及单元测试封装" key="5">
|
||||||
|
<div>1.增加七牛云oss-starter</div>
|
||||||
|
<div>2.增加blade-resource模块,对外提供服务,支持分布式下的oss场景</div>
|
||||||
|
<div>3.LauncherService增加排序功能</div>
|
||||||
|
<div>4.增加单元测试starter,可在启动过程中便捷地指定profile以及启动参数</div>
|
||||||
|
<div>5.增加指定启动参数的单元测试demo</div>
|
||||||
|
<div>6.优化docker脚本配置</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.3.1发布 升级业务架构" key="4">
|
||||||
|
<div>1.升级 SpringBoot 2.1.5</div>
|
||||||
|
<div>2.前端框架Saber升级 element-ui 2.8.2</div>
|
||||||
|
<div>3.Saber业务代码升级</div>
|
||||||
|
<div>4.优化Saber代码生成模板</div>
|
||||||
|
<div>5.统一日志业务表基础字段</div>
|
||||||
|
<div>6.优化租户过滤逻辑</div>
|
||||||
|
<div>7.BaseEntity放开主键限制,子类可自定义主键类型</div>
|
||||||
|
<div>8.XssFilter增加放行配置,可配置放行微信api接口</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.3.0发布 升级SpringCloud Greenwich与SpringBoot" key="3">
|
||||||
|
<div>1.升级 SpringCloud Greenwich</div>
|
||||||
|
<div>2.升级 SpringCloud Alibaba 组件版本为0.9.0.RELEASE,支持最新版本的nacos与sentinel</div>
|
||||||
|
<div>3.升级 SpringBoot 2.1.4</div>
|
||||||
|
<div>4.升级 mysql 驱动版本</div>
|
||||||
|
<div>5.优化 LauncherService 关于环境的判断逻辑</div>
|
||||||
|
<div>6.修复 blade-core-log 在部分情况下获取request为空的问题</div>
|
||||||
|
<div>7.修复多租户插件判断租户过滤的逻辑</div>
|
||||||
|
<div>8.修复请求日志打印插件部分格式空指针的问题</div>
|
||||||
|
<div>9.降低nacos心跳日志等级,关闭心跳日志显示</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.2.0发布 升级为多终端令牌认证系统" key="2">
|
||||||
|
<div>1.增加多终端令牌认证系统</div>
|
||||||
|
<div>2.增加多租户开关</div>
|
||||||
|
<div>3.修复部分模块没有筛选已删除的问题</div>
|
||||||
|
<div>4.调整角色分配会越权的问题</div>
|
||||||
|
<div>5.优化部署脚本</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.1.0发布 升级为SaaS多租户系统" key="1">
|
||||||
|
<div>1.升级为SaaS多租户系统</div>
|
||||||
|
<div>2.优化代码生成逻辑</div>
|
||||||
|
<div>3.代码生成增加菜单sql</div>
|
||||||
|
<div>4.增加SysClient,提供系统信息远程调用</div>
|
||||||
|
<div>5.优化部署脚本,增加前端部署实例</div>
|
||||||
|
<div>6.增加父子角色过滤,使得角色无法越权配置</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="2.0.0发布 全面升级为SpringCloud微服务架构" key="0">
|
||||||
|
<div>1.SpringBlade 2.0 是由一个商业级项目升级优化而来的SpringCloud微服务架构,采用Java8 API重构了业务代码,完全遵循阿里巴巴编码规范</div>
|
||||||
|
<div>2.采用Spring Boot 2 、Spring Cloud Greenwich 、Mybatis 等核心技术,用于快速搭建企业级的微服务系统平台</div>
|
||||||
|
<div>3.SpringBlade 致力于创造新颖的开发模式,将开发中遇到的痛点、生产中所踩的坑整理归纳,并将解决方案都融合到框架中</div>
|
||||||
|
</Panel>
|
||||||
|
</Collapse>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
</PageHeaderWrapper>
|
</PageHeaderWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import { formatMessage, FormattedMessage } from 'umi/locale';
|
import { formatMessage, FormattedMessage } from 'umi/locale';
|
||||||
import { Checkbox, Alert } from 'antd';
|
import { Checkbox, Alert, notification, Icon } from 'antd';
|
||||||
import Login from '../../components/Login';
|
import Login from '../../components/Login';
|
||||||
import styles from './Login.less';
|
import styles from './Login.less';
|
||||||
import { tenantMode } from '../../defaultSettings';
|
import { tenantMode } from '../../defaultSettings';
|
||||||
|
|
||||||
const { Tab, TenantCode, UserName, Password, Submit } = Login;
|
const { Tab, TenantId, UserName, Password, Submit } = Login;
|
||||||
|
|
||||||
@connect(({ login, loading }) => ({
|
@connect(({ login, loading }) => ({
|
||||||
login,
|
login,
|
||||||
@ -18,6 +18,44 @@ class LoginPage extends Component {
|
|||||||
autoLogin: true,
|
autoLogin: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
notification.config({
|
||||||
|
placement: 'bottomRight',
|
||||||
|
});
|
||||||
|
notification.destroy();
|
||||||
|
notification.open({
|
||||||
|
message: '手册信息',
|
||||||
|
description: (
|
||||||
|
<div>
|
||||||
|
<p>Sword开发手册:<a target="_blank" href="https://www.kancloud.cn/smallchill/sword">点击查看</a></p>
|
||||||
|
<p>SpringBlade开发手册:<a target="_blank" href="https://www.kancloud.cn/smallchill/blade">点击查看</a></p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
icon: <Icon type="smile" style={{ color: '#108ee9' }} />,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.open({
|
||||||
|
message: '授权信息',
|
||||||
|
description: (
|
||||||
|
<div>
|
||||||
|
<p>欢迎使用Sword!</p>
|
||||||
|
<p>该系统可用BladeX增强开发,</p>
|
||||||
|
<p>若要商用强烈推荐高度定制的商业化框架,具体授权信息请访问如下地址。</p>
|
||||||
|
<p>
|
||||||
|
BladeX 授权地址:
|
||||||
|
<a target="_blank" href="https://bladex.vip/#/vip">
|
||||||
|
点击授权
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
icon: <Icon type="smile" style={{ color: '#108ee9' }} />,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
onTabChange = type => {
|
onTabChange = type => {
|
||||||
this.setState({ type });
|
this.setState({ type });
|
||||||
};
|
};
|
||||||
@ -82,19 +120,21 @@ class LoginPage extends Component {
|
|||||||
!submitting &&
|
!submitting &&
|
||||||
this.renderMessage(formatMessage({ id: 'app.login.message-invalid-credentials' }))}
|
this.renderMessage(formatMessage({ id: 'app.login.message-invalid-credentials' }))}
|
||||||
{tenantMode ? (
|
{tenantMode ? (
|
||||||
<TenantCode
|
<TenantId
|
||||||
name="tenantCode"
|
name="tenantId"
|
||||||
placeholder={`${formatMessage({ id: 'app.login.tenantCode' })}: 000000`}
|
defaultValue="000000"
|
||||||
|
placeholder={`${formatMessage({ id: 'app.login.tenantId' })}: 000000`}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: formatMessage({ id: 'validation.tenantCode.required' }),
|
message: formatMessage({ id: 'validation.tenantId.required' }),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<UserName
|
<UserName
|
||||||
name="account"
|
name="account"
|
||||||
|
defaultValue="admin"
|
||||||
placeholder={`${formatMessage({ id: 'app.login.userName' })}: admin`}
|
placeholder={`${formatMessage({ id: 'app.login.userName' })}: admin`}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
@ -105,6 +145,7 @@ class LoginPage extends Component {
|
|||||||
/>
|
/>
|
||||||
<Password
|
<Password
|
||||||
name="password"
|
name="password"
|
||||||
|
defaultValue="admin"
|
||||||
placeholder={`${formatMessage({ id: 'app.login.password' })}: admin`}
|
placeholder={`${formatMessage({ id: 'app.login.password' })}: admin`}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { Fragment, PureComponent } from 'react';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import { Button, Col, Form, Input, message, Modal, Row } from 'antd';
|
import { Button, Col, Divider, Form, Input, message, Modal, Row } from "antd";
|
||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import Grid from '../../../components/Sword/Grid';
|
import Grid from '../../../components/Sword/Grid';
|
||||||
import { CODE_LIST } from '../../../actions/code';
|
import { CODE_LIST } from '../../../actions/code';
|
||||||
import { genCodes } from '../../../services/code';
|
import { genCodes, copyCodes } from '../../../services/code';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@ -16,12 +16,14 @@ const FormItem = Form.Item;
|
|||||||
class Code extends PureComponent {
|
class Code extends PureComponent {
|
||||||
state = {
|
state = {
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
|
params: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============ 查询 ===============
|
// ============ 查询 ===============
|
||||||
handleSearch = params => {
|
handleSearch = params => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch(CODE_LIST(params));
|
dispatch(CODE_LIST(params));
|
||||||
|
this.setState({ params });
|
||||||
};
|
};
|
||||||
|
|
||||||
onSelectRow = rows => {
|
onSelectRow = rows => {
|
||||||
@ -60,6 +62,36 @@ class Code extends PureComponent {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
copyCode = keys => {
|
||||||
|
const { params } = this.state;
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
if (keys.length === 0) {
|
||||||
|
message.warn('请先选择一条数据!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (keys.length > 1) {
|
||||||
|
message.warn('只能选择一条数据!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Modal.confirm({
|
||||||
|
title: '代码配置复制确认',
|
||||||
|
content: '是否复制选中模块的配置?',
|
||||||
|
okText: '确定',
|
||||||
|
okType: 'danger',
|
||||||
|
cancelText: '取消',
|
||||||
|
async onOk() {
|
||||||
|
const response = await copyCodes({ id: keys[0] });
|
||||||
|
if (response.success) {
|
||||||
|
message.success(response.msg);
|
||||||
|
dispatch(CODE_LIST(params));
|
||||||
|
} else {
|
||||||
|
message.error(response.msg || '复制失败');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCancel() {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// ============ 查询表单 ===============
|
// ============ 查询表单 ===============
|
||||||
renderSearchForm = onReset => {
|
renderSearchForm = onReset => {
|
||||||
const { form } = this.props;
|
const { form } = this.props;
|
||||||
@ -102,6 +134,19 @@ class Code extends PureComponent {
|
|||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
renderActionButton = (keys, rows) => (
|
||||||
|
<Fragment key="copy">
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<a
|
||||||
|
onClick={() => {
|
||||||
|
this.copyCode(keys, rows);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
复制
|
||||||
|
</a>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const code = 'code';
|
const code = 'code';
|
||||||
|
|
||||||
@ -147,6 +192,7 @@ class Code extends PureComponent {
|
|||||||
onSearch={this.handleSearch}
|
onSearch={this.handleSearch}
|
||||||
renderSearchForm={this.renderSearchForm}
|
renderSearchForm={this.renderSearchForm}
|
||||||
renderLeftButton={this.renderLeftButton}
|
renderLeftButton={this.renderLeftButton}
|
||||||
|
renderActionButton={this.renderActionButton}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
data={data}
|
data={data}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Form, Input, Card, Button } from 'antd';
|
import { Form, Input, Card, Button, Row, Col, Radio, Select } from 'antd';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import styles from '../../../layouts/Sword.less';
|
import styles from '../../../layouts/Sword.less';
|
||||||
import { CODE_SUBMIT } from '../../../actions/code';
|
import { CODE_INIT, CODE_SUBMIT } from '../../../actions/code';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
const RadioGroup = Radio.Group;
|
||||||
|
|
||||||
@connect(({ loading }) => ({
|
@connect(({ code, loading }) => ({
|
||||||
|
code,
|
||||||
submitting: loading.effects['code/submit'],
|
submitting: loading.effects['code/submit'],
|
||||||
}))
|
}))
|
||||||
@Form.create()
|
@Form.create()
|
||||||
class CodeAdd extends PureComponent {
|
class CodeAdd extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch(CODE_INIT());
|
||||||
|
}
|
||||||
|
|
||||||
handleSubmit = e => {
|
handleSubmit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const { dispatch, form } = this.props;
|
const { dispatch, form } = this.props;
|
||||||
@ -25,18 +32,27 @@ class CodeAdd extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
form: { getFieldDecorator },
|
form: { getFieldDecorator },
|
||||||
|
code: { init },
|
||||||
submitting,
|
submitting,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const { source, category } = init;
|
||||||
|
|
||||||
const formItemLayout = {
|
const formItemLayout = {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
xs: { span: 24 },
|
span: 8,
|
||||||
sm: { span: 7 },
|
|
||||||
},
|
},
|
||||||
wrapperCol: {
|
wrapperCol: {
|
||||||
xs: { span: 24 },
|
span: 16,
|
||||||
sm: { span: 12 },
|
},
|
||||||
md: { span: 10 },
|
};
|
||||||
|
|
||||||
|
const formAllItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
span: 4,
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
span: 20,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,88 +64,178 @@ class CodeAdd extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel title="新增" back="/tool/code" action={action}>
|
<Panel title="新增" back="/tool/code" action={action}>
|
||||||
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
<Form style={{ marginTop: 8 }}>
|
||||||
<Card className={styles.card} bordered={false}>
|
<Card className={styles.card} bordered={false}>
|
||||||
<FormItem {...formItemLayout} label="模块名">
|
<Row gutter={24}>
|
||||||
{getFieldDecorator('codeName', {
|
<Col span={20}>
|
||||||
rules: [
|
<FormItem {...formAllItemLayout} label="数据源">
|
||||||
{
|
{getFieldDecorator('datasourceId', {
|
||||||
required: true,
|
rules: [
|
||||||
message: '请输入模块名',
|
{
|
||||||
},
|
required: true,
|
||||||
],
|
message: '请选择数据源',
|
||||||
})(<Input placeholder="请输入模块名" />)}
|
},
|
||||||
</FormItem>
|
],
|
||||||
<FormItem {...formItemLayout} label="服务名">
|
})(
|
||||||
{getFieldDecorator('serviceName', {
|
<Select placeholder="请选择数据源">
|
||||||
rules: [
|
{source.map(d => (
|
||||||
{
|
<Select.Option key={d.id} value={d.id}>
|
||||||
required: true,
|
{d.name}
|
||||||
message: '请输入服务名',
|
</Select.Option>
|
||||||
},
|
))}
|
||||||
],
|
</Select>
|
||||||
})(<Input placeholder="请输入服务名" />)}
|
)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label="表名">
|
</Col>
|
||||||
{getFieldDecorator('tableName', {
|
</Row>
|
||||||
rules: [
|
<Row gutter={24}>
|
||||||
{
|
<Col span={10}>
|
||||||
required: true,
|
<FormItem {...formItemLayout} label="模块名">
|
||||||
message: '请输入表名',
|
{getFieldDecorator('codeName', {
|
||||||
},
|
rules: [
|
||||||
],
|
{
|
||||||
})(<Input placeholder="请输入表名" />)}
|
required: true,
|
||||||
</FormItem>
|
message: '请输入模块名',
|
||||||
<FormItem {...formItemLayout} label="表前缀名">
|
},
|
||||||
{getFieldDecorator('tablePrefix', {
|
],
|
||||||
rules: [
|
})(<Input placeholder="请输入模块名" />)}
|
||||||
{
|
</FormItem>
|
||||||
required: true,
|
</Col>
|
||||||
message: '请输入表前缀名',
|
<Col span={10}>
|
||||||
},
|
<FormItem {...formItemLayout} label="服务名">
|
||||||
],
|
{getFieldDecorator('serviceName', {
|
||||||
})(<Input placeholder="请输入表前缀名" />)}
|
rules: [
|
||||||
</FormItem>
|
{
|
||||||
<FormItem {...formItemLayout} label="主键名">
|
required: true,
|
||||||
{getFieldDecorator('pkName', {
|
message: '请输入服务名',
|
||||||
rules: [
|
},
|
||||||
{
|
],
|
||||||
required: true,
|
})(<Input placeholder="请输入服务名" />)}
|
||||||
message: '请输入主键名',
|
</FormItem>
|
||||||
},
|
</Col>
|
||||||
],
|
</Row>
|
||||||
})(<Input placeholder="请输入主键名" />)}
|
<Row gutter={24}>
|
||||||
</FormItem>
|
<Col span={10}>
|
||||||
<FormItem {...formItemLayout} label="包名">
|
<FormItem {...formItemLayout} label="表名">
|
||||||
{getFieldDecorator('packageName', {
|
{getFieldDecorator('tableName', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入包名',
|
message: '请输入表名',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})(<Input placeholder="请输入包名" />)}
|
})(<Input placeholder="请输入表名" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label="后端生成路径">
|
</Col>
|
||||||
{getFieldDecorator('apiPath', {
|
<Col span={10}>
|
||||||
rules: [
|
<FormItem {...formItemLayout} label="表前缀名">
|
||||||
{
|
{getFieldDecorator('tablePrefix', {
|
||||||
required: true,
|
rules: [
|
||||||
message: '请输入后端生成路径',
|
{
|
||||||
},
|
required: true,
|
||||||
],
|
message: '请输入表前缀名',
|
||||||
})(<Input placeholder="请输入后端生成路径" />)}
|
},
|
||||||
</FormItem>
|
],
|
||||||
<FormItem {...formItemLayout} label="前端生成路径">
|
})(<Input placeholder="请输入表前缀名" />)}
|
||||||
{getFieldDecorator('webPath', {
|
</FormItem>
|
||||||
rules: [
|
</Col>
|
||||||
{
|
</Row>
|
||||||
required: true,
|
<Row gutter={24}>
|
||||||
message: '请输入前端生成路径',
|
<Col span={10}>
|
||||||
},
|
<FormItem {...formItemLayout} label="主键名">
|
||||||
],
|
{getFieldDecorator('pkName', {
|
||||||
})(<Input placeholder="请输入前端生成路径" />)}
|
rules: [
|
||||||
</FormItem>
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入主键名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入主键名" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="包名">
|
||||||
|
{getFieldDecorator('packageName', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入包名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入包名" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="基础业务">
|
||||||
|
{getFieldDecorator('baseMode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请配置基础业务',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(
|
||||||
|
<RadioGroup name="baseMode">
|
||||||
|
{category.map(d => (
|
||||||
|
<Radio key={d.dictKey} value={d.dictKey}>
|
||||||
|
{d.dictValue}
|
||||||
|
</Radio>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="包装器">
|
||||||
|
{getFieldDecorator('wrapMode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请配置包装器',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(
|
||||||
|
<RadioGroup name="wrapMode">
|
||||||
|
{category.map(d => (
|
||||||
|
<Radio key={d.dictKey} value={d.dictKey}>
|
||||||
|
{d.dictValue}
|
||||||
|
</Radio>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="后端生成路径">
|
||||||
|
{getFieldDecorator('apiPath', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入后端生成路径',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入后端生成路径" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="前端生成路径">
|
||||||
|
{getFieldDecorator('webPath', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入前端生成路径',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入前端生成路径" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
</Card>
|
</Card>
|
||||||
</Form>
|
</Form>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Form, Input, Card, Button } from 'antd';
|
import { Form, Input, Card, Button, Col, Row, Select, Radio } from 'antd';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import styles from '../../../layouts/Sword.less';
|
import styles from '../../../layouts/Sword.less';
|
||||||
import { CODE_DETAIL, CODE_SUBMIT } from '../../../actions/code';
|
import { CODE_DETAIL, CODE_INIT, CODE_SUBMIT } from '../../../actions/code';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
const RadioGroup = Radio.Group;
|
||||||
|
|
||||||
@connect(({ code, loading }) => ({
|
@connect(({ code, loading }) => ({
|
||||||
code,
|
code,
|
||||||
@ -21,6 +22,7 @@ class CodeEdit extends PureComponent {
|
|||||||
},
|
},
|
||||||
} = this.props;
|
} = this.props;
|
||||||
dispatch(CODE_DETAIL(id));
|
dispatch(CODE_DETAIL(id));
|
||||||
|
dispatch(CODE_INIT());
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit = e => {
|
handleSubmit = e => {
|
||||||
@ -38,7 +40,6 @@ class CodeEdit extends PureComponent {
|
|||||||
id,
|
id,
|
||||||
...values,
|
...values,
|
||||||
};
|
};
|
||||||
console.log(params);
|
|
||||||
dispatch(CODE_SUBMIT(params));
|
dispatch(CODE_SUBMIT(params));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -47,19 +48,27 @@ class CodeEdit extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
form: { getFieldDecorator },
|
form: { getFieldDecorator },
|
||||||
code: { detail },
|
code: { detail, init },
|
||||||
submitting,
|
submitting,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const { source, category } = init;
|
||||||
|
|
||||||
const formItemLayout = {
|
const formItemLayout = {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
xs: { span: 24 },
|
span: 8,
|
||||||
sm: { span: 7 },
|
|
||||||
},
|
},
|
||||||
wrapperCol: {
|
wrapperCol: {
|
||||||
xs: { span: 24 },
|
span: 16,
|
||||||
sm: { span: 12 },
|
},
|
||||||
md: { span: 10 },
|
};
|
||||||
|
|
||||||
|
const formAllItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
span: 4,
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
span: 20,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,96 +80,190 @@ class CodeEdit extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel title="修改" back="/tool/code" action={action}>
|
<Panel title="修改" back="/tool/code" action={action}>
|
||||||
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
<Form style={{ marginTop: 8 }}>
|
||||||
<Card className={styles.card} bordered={false}>
|
<Card className={styles.card} bordered={false}>
|
||||||
<FormItem {...formItemLayout} label="模块名">
|
<Row gutter={24}>
|
||||||
{getFieldDecorator('codeName', {
|
<Col span={20}>
|
||||||
rules: [
|
<FormItem {...formAllItemLayout} label="数据源">
|
||||||
{
|
{getFieldDecorator('datasourceId', {
|
||||||
required: true,
|
rules: [
|
||||||
message: '请输入模块名',
|
{
|
||||||
},
|
required: true,
|
||||||
],
|
message: '请选择数据源',
|
||||||
initialValue: detail.codeName,
|
},
|
||||||
})(<Input placeholder="请输入模块名" />)}
|
],
|
||||||
</FormItem>
|
initialValue: detail.datasourceId,
|
||||||
<FormItem {...formItemLayout} label="服务名">
|
})(
|
||||||
{getFieldDecorator('serviceName', {
|
<Select placeholder="请选择数据源">
|
||||||
rules: [
|
{source.map(d => (
|
||||||
{
|
<Select.Option key={d.id} value={d.id}>
|
||||||
required: true,
|
{d.name}
|
||||||
message: '请输入服务名',
|
</Select.Option>
|
||||||
},
|
))}
|
||||||
],
|
</Select>
|
||||||
initialValue: detail.serviceName,
|
)}
|
||||||
})(<Input placeholder="请输入服务名" />)}
|
</FormItem>
|
||||||
</FormItem>
|
</Col>
|
||||||
<FormItem {...formItemLayout} label="表名">
|
</Row>
|
||||||
{getFieldDecorator('tableName', {
|
<Row gutter={24}>
|
||||||
rules: [
|
<Col span={10}>
|
||||||
{
|
<FormItem {...formItemLayout} label="模块名">
|
||||||
required: true,
|
{getFieldDecorator('codeName', {
|
||||||
message: '请输入表名',
|
rules: [
|
||||||
},
|
{
|
||||||
],
|
required: true,
|
||||||
initialValue: detail.tableName,
|
message: '请输入模块名',
|
||||||
})(<Input placeholder="请输入表名" />)}
|
},
|
||||||
</FormItem>
|
],
|
||||||
<FormItem {...formItemLayout} label="表前缀名">
|
initialValue: detail.codeName,
|
||||||
{getFieldDecorator('tablePrefix', {
|
})(<Input placeholder="请输入模块名" />)}
|
||||||
rules: [
|
</FormItem>
|
||||||
{
|
</Col>
|
||||||
required: true,
|
<Col span={10}>
|
||||||
message: '请输入表前缀名',
|
<FormItem {...formItemLayout} label="服务名">
|
||||||
},
|
{getFieldDecorator('serviceName', {
|
||||||
],
|
rules: [
|
||||||
initialValue: detail.tablePrefix,
|
{
|
||||||
})(<Input placeholder="请输入表前缀名" />)}
|
required: true,
|
||||||
</FormItem>
|
message: '请输入服务名',
|
||||||
<FormItem {...formItemLayout} label="主键名">
|
},
|
||||||
{getFieldDecorator('pkName', {
|
],
|
||||||
rules: [
|
initialValue: detail.serviceName,
|
||||||
{
|
})(<Input placeholder="请输入服务名" />)}
|
||||||
required: true,
|
</FormItem>
|
||||||
message: '请输入主键名',
|
</Col>
|
||||||
},
|
</Row>
|
||||||
],
|
<Row gutter={24}>
|
||||||
initialValue: detail.pkName,
|
<Col span={10}>
|
||||||
})(<Input placeholder="请输入主键名" />)}
|
<FormItem {...formItemLayout} label="表名">
|
||||||
</FormItem>
|
{getFieldDecorator('tableName', {
|
||||||
<FormItem {...formItemLayout} label="包名">
|
rules: [
|
||||||
{getFieldDecorator('packageName', {
|
{
|
||||||
rules: [
|
required: true,
|
||||||
{
|
message: '请输入表名',
|
||||||
required: true,
|
},
|
||||||
message: '请输入包名',
|
],
|
||||||
},
|
initialValue: detail.tableName,
|
||||||
],
|
})(<Input placeholder="请输入表名" />)}
|
||||||
initialValue: detail.packageName,
|
</FormItem>
|
||||||
})(<Input placeholder="请输入包名" />)}
|
</Col>
|
||||||
</FormItem>
|
<Col span={10}>
|
||||||
<FormItem {...formItemLayout} label="后端生成路径">
|
<FormItem {...formItemLayout} label="表前缀名">
|
||||||
{getFieldDecorator('apiPath', {
|
{getFieldDecorator('tablePrefix', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入后端生成路径',
|
message: '请输入表前缀名',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
initialValue: detail.apiPath,
|
initialValue: detail.tablePrefix,
|
||||||
})(<Input placeholder="请输入后端生成路径" />)}
|
})(<Input placeholder="请输入表前缀名" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label="前端生成路径">
|
</Col>
|
||||||
{getFieldDecorator('webPath', {
|
</Row>
|
||||||
rules: [
|
<Row gutter={24}>
|
||||||
{
|
<Col span={10}>
|
||||||
required: true,
|
<FormItem {...formItemLayout} label="主键名">
|
||||||
message: '请输入前端生成路径',
|
{getFieldDecorator('pkName', {
|
||||||
},
|
rules: [
|
||||||
],
|
{
|
||||||
initialValue: detail.webPath,
|
required: true,
|
||||||
})(<Input placeholder="请输入前端生成路径" />)}
|
message: '请输入主键名',
|
||||||
</FormItem>
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.pkName,
|
||||||
|
})(<Input placeholder="请输入主键名" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="包名">
|
||||||
|
{getFieldDecorator('packageName', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入包名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.packageName,
|
||||||
|
})(<Input placeholder="请输入包名" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="基础业务">
|
||||||
|
{getFieldDecorator('baseMode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请配置基础业务',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.baseMode,
|
||||||
|
})(
|
||||||
|
<RadioGroup name="baseMode">
|
||||||
|
{category.map(d => (
|
||||||
|
<Radio key={d.dictKey} value={d.dictKey}>
|
||||||
|
{d.dictValue}
|
||||||
|
</Radio>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="包装器">
|
||||||
|
{getFieldDecorator('wrapMode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请配置包装器',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.wrapMode,
|
||||||
|
})(
|
||||||
|
<RadioGroup name="wrapMode">
|
||||||
|
{category.map(d => (
|
||||||
|
<Radio key={d.dictKey} value={d.dictKey}>
|
||||||
|
{d.dictValue}
|
||||||
|
</Radio>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="后端生成路径">
|
||||||
|
{getFieldDecorator('apiPath', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入后端生成路径',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.apiPath,
|
||||||
|
})(<Input placeholder="请输入后端生成路径" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="前端生成路径">
|
||||||
|
{getFieldDecorator('webPath', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入前端生成路径',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.webPath,
|
||||||
|
})(<Input placeholder="请输入前端生成路径" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
</Card>
|
</Card>
|
||||||
</Form>
|
</Form>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import router from 'umi/router';
|
import router from 'umi/router';
|
||||||
import { Form, Card, Button } from 'antd';
|
import { Form, Card, Button, Row, Col } from 'antd';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import styles from '../../../layouts/Sword.less';
|
import styles from '../../../layouts/Sword.less';
|
||||||
@ -39,13 +39,19 @@ class CodeView extends PureComponent {
|
|||||||
|
|
||||||
const formItemLayout = {
|
const formItemLayout = {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
xs: { span: 24 },
|
span: 8,
|
||||||
sm: { span: 7 },
|
|
||||||
},
|
},
|
||||||
wrapperCol: {
|
wrapperCol: {
|
||||||
xs: { span: 24 },
|
span: 16,
|
||||||
sm: { span: 12 },
|
},
|
||||||
md: { span: 10 },
|
};
|
||||||
|
|
||||||
|
const formAllItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
span: 4,
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
span: 20,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,32 +63,58 @@ class CodeView extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel title="查看" back="/tool/code" action={action}>
|
<Panel title="查看" back="/tool/code" action={action}>
|
||||||
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
<Form style={{ marginTop: 8 }}>
|
||||||
<Card className={styles.card} bordered={false}>
|
<Card className={styles.card} bordered={false}>
|
||||||
<FormItem {...formItemLayout} label="模块名">
|
<Row gutter={24}>
|
||||||
<span>{detail.codeName}</span>
|
<Col span={10}>
|
||||||
</FormItem>
|
<FormItem {...formItemLayout} label="模块名">
|
||||||
<FormItem {...formItemLayout} label="服务名">
|
<span>{detail.codeName}</span>
|
||||||
<span>{detail.serviceName}</span>
|
</FormItem>
|
||||||
</FormItem>
|
</Col>
|
||||||
<FormItem {...formItemLayout} label="表名">
|
<Col span={10}>
|
||||||
<span>{detail.tableName}</span>
|
<FormItem {...formItemLayout} label="服务名">
|
||||||
</FormItem>
|
<span>{detail.serviceName}</span>
|
||||||
<FormItem {...formItemLayout} label="表前缀名">
|
</FormItem>
|
||||||
<span>{detail.tablePrefix}</span>
|
</Col>
|
||||||
</FormItem>
|
</Row>
|
||||||
<FormItem {...formItemLayout} label="主键名">
|
<Row gutter={24}>
|
||||||
<span>{detail.pkName}</span>
|
<Col span={10}>
|
||||||
</FormItem>
|
<FormItem {...formItemLayout} label="表名">
|
||||||
<FormItem {...formItemLayout} label="包名">
|
<span>{detail.tableName}</span>
|
||||||
<span>{detail.packageName}</span>
|
</FormItem>
|
||||||
</FormItem>
|
</Col>
|
||||||
<FormItem {...formItemLayout} label="后端生成路径">
|
<Col span={10}>
|
||||||
<span>{detail.apiPath}</span>
|
<FormItem {...formItemLayout} label="表前缀名">
|
||||||
</FormItem>
|
<span>{detail.tablePrefix}</span>
|
||||||
<FormItem {...formItemLayout} label="前端生成路径">
|
</FormItem>
|
||||||
<span>{detail.webPath}</span>
|
</Col>
|
||||||
</FormItem>
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="主键名">
|
||||||
|
<span>{detail.pkName}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="包名">
|
||||||
|
<span>{detail.packageName}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="后端生成路径">
|
||||||
|
<span>{detail.apiPath}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="前端生成路径">
|
||||||
|
<span>{detail.webPath}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
</Card>
|
</Card>
|
||||||
</Form>
|
</Form>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
91
src/pages/System/DataSource/DataSource.js
Normal file
91
src/pages/System/DataSource/DataSource.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import { Button, Col, Form, Input, Row } from 'antd';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import { DATASOURCE_LIST } from '../../../actions/datasource';
|
||||||
|
import Grid from '../../../components/Sword/Grid';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ datasource, loading }) => ({
|
||||||
|
datasource,
|
||||||
|
loading: loading.models.datasource,
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class DataSource extends PureComponent {
|
||||||
|
// ============ 查询 ===============
|
||||||
|
handleSearch = params => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch(DATASOURCE_LIST(params));
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============ 查询表单 ===============
|
||||||
|
renderSearchForm = onReset => {
|
||||||
|
const { form } = this.props;
|
||||||
|
const { getFieldDecorator } = form;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
|
<Col md={6} sm={24}>
|
||||||
|
<FormItem label="查询名称">
|
||||||
|
{getFieldDecorator('name')(<Input placeholder="查询名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<div style={{ float: 'right' }}>
|
||||||
|
<Button type="primary" htmlType="submit">
|
||||||
|
查询
|
||||||
|
</Button>
|
||||||
|
<Button style={{ marginLeft: 8 }} onClick={onReset}>
|
||||||
|
重置
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const code = 'datasource';
|
||||||
|
|
||||||
|
const {
|
||||||
|
form,
|
||||||
|
loading,
|
||||||
|
datasource: { data },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '驱动类',
|
||||||
|
dataIndex: 'driverClass',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户名',
|
||||||
|
dataIndex: 'username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
dataIndex: 'remark',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel>
|
||||||
|
<Grid
|
||||||
|
code={code}
|
||||||
|
form={form}
|
||||||
|
onSearch={this.handleSearch}
|
||||||
|
renderSearchForm={this.renderSearchForm}
|
||||||
|
loading={loading}
|
||||||
|
data={data}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default DataSource;
|
132
src/pages/System/DataSource/DataSourceAdd.js
Normal file
132
src/pages/System/DataSource/DataSourceAdd.js
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Form, Input, Card, Button, Select } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { DATASOURCE_SUBMIT } from '../../../actions/datasource';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ loading }) => ({
|
||||||
|
submitting: loading.effects['datasource/submit'],
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class DataSourceAdd extends PureComponent {
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const { dispatch, form } = this.props;
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
dispatch(DATASOURCE_SUBMIT(values));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
submitting,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 7 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
md: { span: 10 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="新增" back="/tool/datasource" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="名称">
|
||||||
|
{getFieldDecorator('name', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入名称',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="驱动类">
|
||||||
|
{getFieldDecorator('driverClass', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入驱动类',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(
|
||||||
|
<Select placeholder="请选择驱动类">
|
||||||
|
<Select.Option key={1} value="com.mysql.cj.jdbc.Driver">
|
||||||
|
com.mysql.cj.jdbc.Driver
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option key={2} value="org.postgresql.Driver">
|
||||||
|
org.postgresql.Driver
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option key={3} value="oracle.jdbc.OracleDriver">
|
||||||
|
oracle.jdbc.OracleDriver
|
||||||
|
</Select.Option>
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="连接地址">
|
||||||
|
{getFieldDecorator('url', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入连接地址',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入连接地址" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="用户名">
|
||||||
|
{getFieldDecorator('username', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入用户名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入用户名" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="密码">
|
||||||
|
{getFieldDecorator('password', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入密码',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入密码" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="备注">
|
||||||
|
{getFieldDecorator('remark', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入备注',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入备注" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DataSourceAdd;
|
161
src/pages/System/DataSource/DataSourceEdit.js
Normal file
161
src/pages/System/DataSource/DataSourceEdit.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Form, Input, Card, Button, Select } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { DATASOURCE_DETAIL, DATASOURCE_SUBMIT } from '../../../actions/datasource';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ datasource, loading }) => ({
|
||||||
|
datasource,
|
||||||
|
submitting: loading.effects['datasource/submit'],
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class DataSourceEdit extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
dispatch(DATASOURCE_DETAIL(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
form,
|
||||||
|
} = this.props;
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
const params = {
|
||||||
|
id,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
console.log(params);
|
||||||
|
dispatch(DATASOURCE_SUBMIT(params));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
datasource: { detail },
|
||||||
|
submitting,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 7 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
md: { span: 10 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="修改" back="/tool/datasource" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="名称">
|
||||||
|
{getFieldDecorator('name', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入名称',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.name,
|
||||||
|
})(<Input placeholder="请输入名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="驱动类">
|
||||||
|
{getFieldDecorator('driverClass', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入驱动类',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.driverClass,
|
||||||
|
})(
|
||||||
|
<Select placeholder="请选择驱动类">
|
||||||
|
<Select.Option key={1} value="com.mysql.cj.jdbc.Driver">
|
||||||
|
com.mysql.cj.jdbc.Driver
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option key={2} value="org.postgresql.Driver">
|
||||||
|
org.postgresql.Driver
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option key={3} value="oracle.jdbc.OracleDriver">
|
||||||
|
oracle.jdbc.OracleDriver
|
||||||
|
</Select.Option>
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="连接地址">
|
||||||
|
{getFieldDecorator('url', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入连接地址',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.url,
|
||||||
|
})(<Input placeholder="请输入连接地址" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="用户名">
|
||||||
|
{getFieldDecorator('username', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入用户名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.username,
|
||||||
|
})(<Input placeholder="请输入用户名" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="密码">
|
||||||
|
{getFieldDecorator('password', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入密码',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.password,
|
||||||
|
})(<Input placeholder="请输入密码" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="备注">
|
||||||
|
{getFieldDecorator('remark', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入备注',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.remark,
|
||||||
|
})(<Input placeholder="请输入备注" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DataSourceEdit;
|
86
src/pages/System/DataSource/DataSourceView.js
Normal file
86
src/pages/System/DataSource/DataSourceView.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import router from 'umi/router';
|
||||||
|
import { Form, Card, Button } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { DATASOURCE_DETAIL } from '../../../actions/datasource';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ datasource }) => ({
|
||||||
|
datasource,
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class DataSourceView extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
dispatch(DATASOURCE_DETAIL(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEdit = () => {
|
||||||
|
const {
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
router.push(`/tool/datasource/edit/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
datasource: { detail },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 7 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
md: { span: 10 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleEdit}>
|
||||||
|
修改
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="查看" back="/tool/datasource" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="名称">
|
||||||
|
<span>{detail.name}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="驱动类">
|
||||||
|
<span>{detail.driverClass}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="连接地址">
|
||||||
|
<span>{detail.url}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="用户名">
|
||||||
|
<span>{detail.username}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="密码">
|
||||||
|
<span>{detail.password}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="备注">
|
||||||
|
<span>{detail.remark}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default DataSourceView;
|
@ -33,8 +33,8 @@ class Dept extends PureComponent {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={6} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
<FormItem label="租户编号">
|
<FormItem label="租户ID">
|
||||||
{getFieldDecorator('tenantCode')(<Input placeholder="请输入角色名称" />)}
|
{getFieldDecorator('tenantId')(<Input placeholder="请输入角色名称" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={6} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
@ -67,8 +67,8 @@ class Dept extends PureComponent {
|
|||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '租户编号',
|
title: '租户ID',
|
||||||
dataIndex: 'tenantCode',
|
dataIndex: 'tenantId',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '部门名称',
|
title: '部门名称',
|
||||||
|
@ -124,8 +124,8 @@ class Role extends PureComponent {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={6} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
<FormItem label="租户编号">
|
<FormItem label="租户ID">
|
||||||
{getFieldDecorator('tenantCode')(<Input placeholder="请输入角色名称" />)}
|
{getFieldDecorator('tenantId')(<Input placeholder="请输入角色名称" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={6} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
@ -178,8 +178,8 @@ class Role extends PureComponent {
|
|||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '租户编号',
|
title: '租户ID',
|
||||||
dataIndex: 'tenantCode',
|
dataIndex: 'tenantId',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '角色名称',
|
title: '角色名称',
|
||||||
|
@ -27,8 +27,8 @@ class Tenant extends PureComponent {
|
|||||||
return (
|
return (
|
||||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
<Col md={6} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
<FormItem label="租户编号">
|
<FormItem label="租户ID">
|
||||||
{getFieldDecorator('tenantCode')(<Input placeholder="请输入租户编号" />)}
|
{getFieldDecorator('tenantId')(<Input placeholder="请输入租户ID" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={6} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
@ -66,8 +66,8 @@ class Tenant extends PureComponent {
|
|||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '租户编号',
|
title: '租户ID',
|
||||||
dataIndex: 'tenantCode',
|
dataIndex: 'tenantId',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '租户名称',
|
title: '租户名称',
|
||||||
|
@ -59,8 +59,8 @@ class TenantView extends PureComponent {
|
|||||||
<Panel title="查看" back="/system/tenant" action={action}>
|
<Panel title="查看" back="/system/tenant" action={action}>
|
||||||
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
<Card className={styles.card} bordered={false}>
|
<Card className={styles.card} bordered={false}>
|
||||||
<FormItem {...formItemLayout} label="租户编号">
|
<FormItem {...formItemLayout} label="租户ID">
|
||||||
<span>{detail.tenantCode}</span>
|
<span>{detail.tenantId}</span>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label="租户名称">
|
<FormItem {...formItemLayout} label="租户名称">
|
||||||
<span>{detail.tenantName}</span>
|
<span>{detail.tenantName}</span>
|
||||||
|
@ -175,8 +175,8 @@ class User extends PureComponent {
|
|||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '租户编号',
|
title: '租户ID',
|
||||||
dataIndex: 'tenantCode',
|
dataIndex: 'tenantId',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '登录账号',
|
title: '登录账号',
|
||||||
|
@ -46,7 +46,7 @@ class UserAdd extends PureComponent {
|
|||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
const { dispatch, form } = this.props;
|
const { dispatch, form } = this.props;
|
||||||
form.resetFields(['roleId', 'deptId']);
|
form.resetFields(['roleId', 'deptId']);
|
||||||
dispatch(USER_CHANGE_INIT({ tenantCode: value }));
|
dispatch(USER_CHANGE_INIT({ tenantId: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -104,7 +104,7 @@ class UserAdd extends PureComponent {
|
|||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={20}>
|
<Col span={20}>
|
||||||
<FormItem {...formAllItemLayout} label="所属租户">
|
<FormItem {...formAllItemLayout} label="所属租户">
|
||||||
{getFieldDecorator('tenantCode', {
|
{getFieldDecorator('tenantId', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
@ -122,7 +122,7 @@ class UserAdd extends PureComponent {
|
|||||||
placeholder="请选择所属租户"
|
placeholder="请选择所属租户"
|
||||||
>
|
>
|
||||||
{tenantList.map(d => (
|
{tenantList.map(d => (
|
||||||
<Select.Option key={d.tenantCode} value={d.tenantCode}>
|
<Select.Option key={d.tenantId} value={d.tenantId}>
|
||||||
{d.tenantName}
|
{d.tenantName}
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
|
@ -5,7 +5,7 @@ import { connect } from 'dva';
|
|||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import func from '../../../utils/Func';
|
import func from '../../../utils/Func';
|
||||||
import styles from '../../../layouts/Sword.less';
|
import styles from '../../../layouts/Sword.less';
|
||||||
import { USER_CHANGE_INIT, USER_DETAIL, USER_INIT, USER_SUBMIT } from '../../../actions/user';
|
import { USER_CHANGE_INIT, USER_DETAIL, USER_INIT, USER_UPDATE } from '../../../actions/user';
|
||||||
import { tenantMode } from '../../../defaultSettings';
|
import { tenantMode } from '../../../defaultSettings';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
@ -45,7 +45,7 @@ class UserEdit extends PureComponent {
|
|||||||
deptId: func.join(values.deptId),
|
deptId: func.join(values.deptId),
|
||||||
birthday: func.format(values.birthday),
|
birthday: func.format(values.birthday),
|
||||||
};
|
};
|
||||||
dispatch(USER_SUBMIT(params));
|
dispatch(USER_UPDATE(params));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -53,7 +53,7 @@ class UserEdit extends PureComponent {
|
|||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
const { dispatch, form } = this.props;
|
const { dispatch, form } = this.props;
|
||||||
form.resetFields(['roleId', 'deptId']);
|
form.resetFields(['roleId', 'deptId']);
|
||||||
dispatch(USER_CHANGE_INIT({ tenantCode: value }));
|
dispatch(USER_CHANGE_INIT({ tenantId: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -113,14 +113,14 @@ class UserEdit extends PureComponent {
|
|||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={20}>
|
<Col span={20}>
|
||||||
<FormItem {...formAllItemLayout} label="所属租户">
|
<FormItem {...formAllItemLayout} label="所属租户">
|
||||||
{getFieldDecorator('tenantCode', {
|
{getFieldDecorator('tenantId', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请选择所属租户',
|
message: '请选择所属租户',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
initialValue: detail.tenantCode,
|
initialValue: detail.tenantId,
|
||||||
})(
|
})(
|
||||||
<Select
|
<Select
|
||||||
showSearch
|
showSearch
|
||||||
@ -132,7 +132,7 @@ class UserEdit extends PureComponent {
|
|||||||
placeholder="请选择所属租户"
|
placeholder="请选择所属租户"
|
||||||
>
|
>
|
||||||
{tenantList.map(d => (
|
{tenantList.map(d => (
|
||||||
<Select.Option key={d.tenantCode} value={d.tenantCode}>
|
<Select.Option key={d.tenantId} value={d.tenantId}>
|
||||||
{d.tenantName}
|
{d.tenantName}
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
|
@ -77,7 +77,7 @@ class UserView extends PureComponent {
|
|||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={20}>
|
<Col span={20}>
|
||||||
<FormItem {...formAllItemLayout} label="所属租户">
|
<FormItem {...formAllItemLayout} label="所属租户">
|
||||||
<span>{detail.tenantCode}</span>
|
<span>{detail.tenantId}</span>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -32,3 +32,10 @@ export async function genCodes(params) {
|
|||||||
body: func.toFormData(params),
|
body: func.toFormData(params),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function copyCodes(params) {
|
||||||
|
return request('/api/blade-develop/code/copy', {
|
||||||
|
method: 'POST',
|
||||||
|
body: func.toFormData(params),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
29
src/services/datasource.js
Normal file
29
src/services/datasource.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { stringify } from 'qs';
|
||||||
|
import func from '../utils/Func';
|
||||||
|
import request from '../utils/request';
|
||||||
|
|
||||||
|
export async function list(params) {
|
||||||
|
return request(`/api/blade-develop/datasource/list?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function select(params) {
|
||||||
|
return request(`/api/blade-develop/datasource/select?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function submit(params) {
|
||||||
|
return request('/api/blade-develop/datasource/submit', {
|
||||||
|
method: 'POST',
|
||||||
|
body: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function detail(params) {
|
||||||
|
return request(`/api/blade-develop/datasource/detail?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function remove(params) {
|
||||||
|
return request('/api/blade-develop/datasource/remove', {
|
||||||
|
method: 'POST',
|
||||||
|
body: func.toFormData(params),
|
||||||
|
});
|
||||||
|
}
|
@ -51,6 +51,24 @@ export async function submit(params) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function update(params) {
|
||||||
|
return request('/api/blade-user/update', {
|
||||||
|
method: 'POST',
|
||||||
|
body: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function detail(params) {
|
export async function detail(params) {
|
||||||
return request(`/api/blade-user/detail?${stringify(params)}`);
|
return request(`/api/blade-user/detail?${stringify(params)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getUserInfo() {
|
||||||
|
return request('/api/blade-user/info');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updatePassword(params) {
|
||||||
|
return request('/api/blade-user/update-password', {
|
||||||
|
method: 'POST',
|
||||||
|
body: func.toFormData(params),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user