mirror of
https://github.com/chillzhuang/Sword
synced 2024-11-22 02:09:26 +08:00
🎉 升级为多租户系统
This commit is contained in:
parent
39baec4b69
commit
0c3b807ea4
@ -1,12 +1,15 @@
|
|||||||
## 简介
|
## 简介
|
||||||
Sword 是 [SpringBlade](https://gitee.com/smallc/SpringBlade)前端UI项目,基于react 、ant design、dva,用于快速构建系统中后台业务。
|
Sword 是 [SpringBlade](https://gitee.com/smallc/SpringBlade)前端UI项目,基于react 、ant design、dva,用于快速构建系统中后台业务。
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
* 文档地址:[Sword开发手册](https://www.kancloud.cn/smallchill/sword)
|
||||||
|
|
||||||
## 官网
|
## 官网
|
||||||
* 官网地址:[https://bladex.vip](https://bladex.vip)
|
* 官网地址:[https://bladex.vip](https://bladex.vip)
|
||||||
|
|
||||||
## 在线演示
|
## 在线演示
|
||||||
* Sword演示地址:[https://sword.bladex.vip](https://sword.bladex.vip)
|
* Sword演示地址:[https://sword.bladex.vip](https://sword.bladex.vip)
|
||||||
* Saber演示地址:[https://saber.avue.top](https://saber.avue.top)
|
* Saber演示地址:[https://saber.bladex.vip](https://saber.bladex.vip)
|
||||||
|
|
||||||
## 后端项目地址
|
## 后端项目地址
|
||||||
* [Gitee地址](https://gitee.com/smallc/SpringBlade)
|
* [Gitee地址](https://gitee.com/smallc/SpringBlade)
|
||||||
|
@ -15,7 +15,7 @@ export default [
|
|||||||
path: '/',
|
path: '/',
|
||||||
component: '../layouts/BasicLayout',
|
component: '../layouts/BasicLayout',
|
||||||
Routes: ['src/pages/Authorized'],
|
Routes: ['src/pages/Authorized'],
|
||||||
authority: ['admin', 'user'],
|
authority: ['administrator', 'admin', 'user', 'test'],
|
||||||
routes: [
|
routes: [
|
||||||
// dashboard
|
// dashboard
|
||||||
{ path: '/', redirect: '/dashboard/workplace' },
|
{ path: '/', redirect: '/dashboard/workplace' },
|
||||||
@ -156,6 +156,16 @@ export default [
|
|||||||
{ path: '/system/param/view/:id', component: './System/Param/ParamView' },
|
{ path: '/system/param/view/:id', component: './System/Param/ParamView' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/system/tenant',
|
||||||
|
routes: [
|
||||||
|
{ path: '/system/tenant', redirect: '/system/tenant/list' },
|
||||||
|
{ path: '/system/tenant/list', component: './System/Tenant/Tenant' },
|
||||||
|
{ path: '/system/tenant/add', component: './System/Tenant/TenantAdd' },
|
||||||
|
{ path: '/system/tenant/edit/:id', component: './System/Tenant/TenantEdit' },
|
||||||
|
{ path: '/system/tenant/view/:id', component: './System/Tenant/TenantView' },
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -6,18 +6,21 @@ function getFakeList(req, res) {
|
|||||||
data.push({
|
data.push({
|
||||||
id: '1',
|
id: '1',
|
||||||
deptName: '刀锋科技',
|
deptName: '刀锋科技',
|
||||||
|
tenantCode: '000000',
|
||||||
fullName: '江苏刀锋科技有限公司',
|
fullName: '江苏刀锋科技有限公司',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
deptName: '常州刀锋',
|
deptName: '常州刀锋',
|
||||||
|
tenantCode: '000000',
|
||||||
fullName: '常州刀锋科技有限公司',
|
fullName: '常州刀锋科技有限公司',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '3',
|
id: '3',
|
||||||
deptName: '南京刀锋',
|
deptName: '南京刀锋',
|
||||||
|
tenantCode: '000000',
|
||||||
fullName: '南京刀锋科技有限公司',
|
fullName: '南京刀锋科技有限公司',
|
||||||
sort: '2',
|
sort: '2',
|
||||||
},
|
},
|
||||||
@ -33,6 +36,7 @@ function getFakeDetail(req, res) {
|
|||||||
id: 2,
|
id: 2,
|
||||||
parentId: 1,
|
parentId: 1,
|
||||||
parentName: '江苏刀锋',
|
parentName: '江苏刀锋',
|
||||||
|
tenantCode: '000000',
|
||||||
deptName: '常州刀锋',
|
deptName: '常州刀锋',
|
||||||
fullName: '常州刀锋科技有限公司',
|
fullName: '常州刀锋科技有限公司',
|
||||||
sort: 1,
|
sort: 1,
|
||||||
|
42
mock/menu.js
42
mock/menu.js
@ -54,6 +54,11 @@ function getFakeRoutes(req, res) {
|
|||||||
code: 'param',
|
code: 'param',
|
||||||
name: '参数管理',
|
name: '参数管理',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/system/tenant',
|
||||||
|
code: 'tenant',
|
||||||
|
name: '租户管理',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -397,6 +402,43 @@ function getFakeButtons(req, res) {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
code: 'tenant',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
code: 'tenant_add',
|
||||||
|
name: '新增',
|
||||||
|
path: '/system/tenant/add',
|
||||||
|
source: 'plus',
|
||||||
|
action: 1,
|
||||||
|
alias: 'add',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'tenant_edit',
|
||||||
|
name: '修改',
|
||||||
|
path: '/system/tenant/edit',
|
||||||
|
source: 'form',
|
||||||
|
action: 2,
|
||||||
|
alias: 'edit',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'tenant_delete',
|
||||||
|
name: '删除',
|
||||||
|
path: '/api/blade-system/tenant/remove',
|
||||||
|
source: 'delete',
|
||||||
|
action: 3,
|
||||||
|
alias: 'delete',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'tenant_view',
|
||||||
|
name: '查看',
|
||||||
|
path: '/system/tenant/view',
|
||||||
|
source: 'file-text',
|
||||||
|
action: 2,
|
||||||
|
alias: 'view',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
code: 'log_usual',
|
code: 'log_usual',
|
||||||
children: [
|
children: [
|
||||||
|
@ -15,105 +15,105 @@ const proxy = {
|
|||||||
title: '博客标题1',
|
title: '博客标题1',
|
||||||
categoryName: '批转通知',
|
categoryName: '批转通知',
|
||||||
content: '博客内容1',
|
content: '博客内容1',
|
||||||
date: '2018-05-08 12:00:00',
|
releaseTime: '2018-05-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
title: '博客标题2',
|
title: '博客标题2',
|
||||||
categoryName: '发布通知',
|
categoryName: '发布通知',
|
||||||
content: '博客内容2',
|
content: '博客内容2',
|
||||||
date: '2018-06-08 12:00:00',
|
releaseTime: '2018-06-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '3',
|
id: '3',
|
||||||
title: '博客标题3',
|
title: '博客标题3',
|
||||||
categoryName: '任免通知',
|
categoryName: '任免通知',
|
||||||
content: '博客内容3',
|
content: '博客内容3',
|
||||||
date: '2018-07-08 12:00:00',
|
releaseTime: '2018-07-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '4',
|
id: '4',
|
||||||
title: '博客标题4',
|
title: '博客标题4',
|
||||||
categoryName: '指示通知',
|
categoryName: '指示通知',
|
||||||
content: '博客内容4',
|
content: '博客内容4',
|
||||||
date: '2018-08-08 12:00:00',
|
releaseTime: '2018-08-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '5',
|
id: '5',
|
||||||
title: '博客标题5',
|
title: '博客标题5',
|
||||||
categoryName: '转发通知',
|
categoryName: '转发通知',
|
||||||
content: '博客内容5',
|
content: '博客内容5',
|
||||||
date: '2018-09-08 12:00:00',
|
releaseTime: '2018-09-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '6',
|
id: '6',
|
||||||
title: '博客标题1',
|
title: '博客标题1',
|
||||||
categoryName: '批转通知',
|
categoryName: '批转通知',
|
||||||
content: '博客内容1',
|
content: '博客内容1',
|
||||||
date: '2018-05-08 12:00:00',
|
releaseTime: '2018-05-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '7',
|
id: '7',
|
||||||
title: '博客标题2',
|
title: '博客标题2',
|
||||||
categoryName: '发布通知',
|
categoryName: '发布通知',
|
||||||
content: '博客内容2',
|
content: '博客内容2',
|
||||||
date: '2018-06-08 12:00:00',
|
releaseTime: '2018-06-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '8',
|
id: '8',
|
||||||
title: '博客标题3',
|
title: '博客标题3',
|
||||||
categoryName: '任免通知',
|
categoryName: '任免通知',
|
||||||
content: '博客内容3',
|
content: '博客内容3',
|
||||||
date: '2018-07-08 12:00:00',
|
releaseTime: '2018-07-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '9',
|
id: '9',
|
||||||
title: '博客标题4',
|
title: '博客标题4',
|
||||||
categoryName: '指示通知',
|
categoryName: '指示通知',
|
||||||
content: '博客内容4',
|
content: '博客内容4',
|
||||||
date: '2018-08-08 12:00:00',
|
releaseTime: '2018-08-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '10',
|
id: '10',
|
||||||
title: '博客标题5',
|
title: '博客标题5',
|
||||||
categoryName: '转发通知',
|
categoryName: '转发通知',
|
||||||
content: '博客内容5',
|
content: '博客内容5',
|
||||||
date: '2018-09-08 12:00:00',
|
releaseTime: '2018-09-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '11',
|
id: '11',
|
||||||
title: '博客标题1',
|
title: '博客标题1',
|
||||||
categoryName: '批转通知',
|
categoryName: '批转通知',
|
||||||
content: '博客内容1',
|
content: '博客内容1',
|
||||||
date: '2018-05-08 12:00:00',
|
releaseTime: '2018-05-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '12',
|
id: '12',
|
||||||
title: '博客标题2',
|
title: '博客标题2',
|
||||||
categoryName: '发布通知',
|
categoryName: '发布通知',
|
||||||
content: '博客内容2',
|
content: '博客内容2',
|
||||||
date: '2018-06-08 12:00:00',
|
releaseTime: '2018-06-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '13',
|
id: '13',
|
||||||
title: '博客标题3',
|
title: '博客标题3',
|
||||||
categoryName: '任免通知',
|
categoryName: '任免通知',
|
||||||
content: '博客内容3',
|
content: '博客内容3',
|
||||||
date: '2018-07-08 12:00:00',
|
releaseTime: '2018-07-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '14',
|
id: '14',
|
||||||
title: '博客标题4',
|
title: '博客标题4',
|
||||||
categoryName: '指示通知',
|
categoryName: '指示通知',
|
||||||
content: '博客内容4',
|
content: '博客内容4',
|
||||||
date: '2018-08-08 12:00:00',
|
releaseTime: '2018-08-08 12:00:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '15',
|
id: '15',
|
||||||
title: '博客标题5',
|
title: '博客标题5',
|
||||||
categoryName: '转发通知',
|
categoryName: '转发通知',
|
||||||
content: '博客内容5',
|
content: '博客内容5',
|
||||||
date: '2018-09-08 12:00:00',
|
releaseTime: '2018-09-08 12:00:00',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -138,7 +138,7 @@ const proxy = {
|
|||||||
title: '通知标题详情',
|
title: '通知标题详情',
|
||||||
category: '3',
|
category: '3',
|
||||||
categoryName: '转发通知',
|
categoryName: '转发通知',
|
||||||
date: '2018-12-31 23:33:33',
|
releaseTime: '2018-12-31 23:33:33',
|
||||||
content: '通知公告内容详情',
|
content: '通知公告内容详情',
|
||||||
},
|
},
|
||||||
message: 'success',
|
message: 'success',
|
||||||
|
@ -7,12 +7,14 @@ function getFakeList(req, res) {
|
|||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
roleName: '超级管理员',
|
roleName: '超级管理员',
|
||||||
|
tenantCode: '000000',
|
||||||
roleAlias: 'administrator',
|
roleAlias: 'administrator',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
roleName: '管理员',
|
roleName: '管理员',
|
||||||
|
tenantCode: '000001',
|
||||||
roleAlias: 'admin',
|
roleAlias: 'admin',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
},
|
},
|
||||||
@ -21,18 +23,21 @@ function getFakeList(req, res) {
|
|||||||
{
|
{
|
||||||
id: '3',
|
id: '3',
|
||||||
roleName: '用户',
|
roleName: '用户',
|
||||||
|
tenantCode: '000002',
|
||||||
roleAlias: 'user',
|
roleAlias: 'user',
|
||||||
sort: '2',
|
sort: '2',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: '4',
|
id: '4',
|
||||||
roleName: '普通用户',
|
roleName: '普通用户',
|
||||||
|
tenantCode: '000003',
|
||||||
roleAlias: 'user',
|
roleAlias: 'user',
|
||||||
sort: '1',
|
sort: '1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '5',
|
id: '5',
|
||||||
roleName: '访客',
|
roleName: '访客',
|
||||||
|
tenantCode: '000004',
|
||||||
roleAlias: 'guest',
|
roleAlias: 'guest',
|
||||||
sort: '2',
|
sort: '2',
|
||||||
},
|
},
|
||||||
@ -49,6 +54,7 @@ function getFakeDetail(req, res) {
|
|||||||
id: 2,
|
id: 2,
|
||||||
parentId: 1,
|
parentId: 1,
|
||||||
parentName: '超级管理员',
|
parentName: '超级管理员',
|
||||||
|
tenantCode: '000000',
|
||||||
roleName: '用户',
|
roleName: '用户',
|
||||||
roleAlias: 'user',
|
roleAlias: 'user',
|
||||||
sort: 1,
|
sort: 1,
|
||||||
|
75
mock/tenant.js
Normal file
75
mock/tenant.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { delay } from 'roadhog-api-doc';
|
||||||
|
|
||||||
|
function getFakeList(req, res) {
|
||||||
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
|
const list = [];
|
||||||
|
list.push(
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
tenantCode: '000000',
|
||||||
|
tenantName: '管理组',
|
||||||
|
linkman: 'Chill',
|
||||||
|
contactNumber: '66666666666',
|
||||||
|
address: '管理组地址',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
tenantCode: '000001',
|
||||||
|
tenantName: '用户组',
|
||||||
|
linkman: 'Bill',
|
||||||
|
contactNumber: '23333333333',
|
||||||
|
address: '用户组地址',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
json.data = {
|
||||||
|
total: 10,
|
||||||
|
size: 10,
|
||||||
|
current: 2,
|
||||||
|
searchCount: true,
|
||||||
|
pages: 1,
|
||||||
|
records: list,
|
||||||
|
};
|
||||||
|
return res.json(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFakeDetail(req, res) {
|
||||||
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
|
json.data = {
|
||||||
|
id: '1',
|
||||||
|
tenantCode: '000000',
|
||||||
|
tenantName: '管理组',
|
||||||
|
linkman: 'Chill',
|
||||||
|
contactNumber: '66666666666',
|
||||||
|
address: '管理组地址',
|
||||||
|
};
|
||||||
|
return res.json(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fakeSuccess(req, res) {
|
||||||
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
|
return res.json(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFakeTenantSelect(req, res) {
|
||||||
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
|
json.data = [
|
||||||
|
{
|
||||||
|
tenantCode: '000000',
|
||||||
|
tenantName: '管理组',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tenantCode: '000001',
|
||||||
|
tenantName: '用户组',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return res.json(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxy = {
|
||||||
|
'GET /api/blade-system/tenant/list': getFakeList,
|
||||||
|
'GET /api/blade-system/tenant/select': getFakeTenantSelect,
|
||||||
|
'GET /api/blade-system/tenant/detail': getFakeDetail,
|
||||||
|
'POST /api/blade-system/tenant/submit': fakeSuccess,
|
||||||
|
'POST /api/blade-system/tenant/remove': fakeSuccess,
|
||||||
|
};
|
||||||
|
export default delay(proxy, 500);
|
@ -6,6 +6,7 @@ function getFakeList(req, res) {
|
|||||||
list.push(
|
list.push(
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
|
tenantCode: '000000',
|
||||||
account: 'admin',
|
account: 'admin',
|
||||||
name: '超级管理员',
|
name: '超级管理员',
|
||||||
realName: '管理员',
|
realName: '管理员',
|
||||||
@ -17,6 +18,7 @@ function getFakeList(req, res) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
|
tenantCode: '000001',
|
||||||
account: 'user',
|
account: 'user',
|
||||||
name: '系统用户',
|
name: '系统用户',
|
||||||
realName: '用户',
|
realName: '用户',
|
||||||
@ -40,8 +42,9 @@ function getFakeList(req, res) {
|
|||||||
|
|
||||||
function getFakeDetail(req, res) {
|
function getFakeDetail(req, res) {
|
||||||
const json = { code: 200, success: true, msg: '操作成功' };
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
const detail = {
|
json.data = {
|
||||||
id: '1',
|
id: '1',
|
||||||
|
tenantCode: '000000',
|
||||||
account: 'admin',
|
account: 'admin',
|
||||||
name: '超级管理员',
|
name: '超级管理员',
|
||||||
realName: '管理员',
|
realName: '管理员',
|
||||||
@ -56,7 +59,6 @@ function getFakeDetail(req, res) {
|
|||||||
birthday: '2018-12-31 23:33:33',
|
birthday: '2018-12-31 23:33:33',
|
||||||
statusName: '启用',
|
statusName: '启用',
|
||||||
};
|
};
|
||||||
json.data = detail;
|
|
||||||
return res.json(json);
|
return res.json(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
src/actions/tenant.js
Normal file
36
src/actions/tenant.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
export const TENANT_NAMESPACE = 'tenant';
|
||||||
|
|
||||||
|
export function TENANT_LIST(payload) {
|
||||||
|
return {
|
||||||
|
type: `${TENANT_NAMESPACE}/fetchList`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TENANT_DETAIL(id) {
|
||||||
|
return {
|
||||||
|
type: `${TENANT_NAMESPACE}/fetchDetail`,
|
||||||
|
payload: { id },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TENANT_CLEAR_DETAIL() {
|
||||||
|
return {
|
||||||
|
type: `${TENANT_NAMESPACE}/clearDetail`,
|
||||||
|
payload: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TENANT_SUBMIT(payload) {
|
||||||
|
return {
|
||||||
|
type: `${TENANT_NAMESPACE}/submit`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TENANT_REMOVE(payload) {
|
||||||
|
return {
|
||||||
|
type: `${TENANT_NAMESPACE}/remove`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
@ -14,6 +14,13 @@ export function USER_INIT() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function USER_CHANGE_INIT(payload) {
|
||||||
|
return {
|
||||||
|
type: `${USER_NAMESPACE}/fetchChangeInit`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function USER_DETAIL(id) {
|
export function USER_DETAIL(id) {
|
||||||
return {
|
return {
|
||||||
type: `${USER_NAMESPACE}/fetchDetail`,
|
type: `${USER_NAMESPACE}/fetchDetail`,
|
||||||
|
1
src/components/Login/index.d.ts
vendored
1
src/components/Login/index.d.ts
vendored
@ -12,6 +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 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,6 +3,20 @@ import { Icon } from 'antd';
|
|||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
TenantCode: {
|
||||||
|
props: {
|
||||||
|
size: 'large',
|
||||||
|
id: 'tenantCode',
|
||||||
|
prefix: <Icon type="home" className={styles.prefixIcon} />,
|
||||||
|
placeholder: 'admin',
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: 'Please enter tenantcode!',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
UserName: {
|
UserName: {
|
||||||
props: {
|
props: {
|
||||||
size: 'large',
|
size: 'large',
|
||||||
|
@ -30,10 +30,10 @@ export default class ToolBar extends PureComponent {
|
|||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
{renderLeftButton ? renderLeftButton() : null}
|
{renderLeftButton ? renderLeftButton() : null}
|
||||||
|
{renderRightButton ? (
|
||||||
|
<div style={{ float: 'right', marginRight: '20px' }}>{renderRightButton()}</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
{renderRightButton ? (
|
|
||||||
<div style={{ float: 'right', marginRight: '20px' }}>renderRightButton()</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -51,10 +51,12 @@ const UserLayout = ({ children }) => (
|
|||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<img alt="logo" className={styles.logo} src={logo} />
|
<img alt="logo" className={styles.logo} src={logo} />
|
||||||
<span className={styles.title}>Ant Design</span>
|
<span className={styles.title}>Sword 企业级开发平台</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.desc}>Ant Design 是西湖区最具影响力的 Web 设计规范</div>
|
<div className={styles.desc}>
|
||||||
|
Sword是SpringBlade前端UI项目,基于react 、ant design、umi、dva等流行技术栈。
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
|
'app.login.tenantCode': 'tenantCode',
|
||||||
'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)',
|
||||||
@ -20,6 +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.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!',
|
||||||
|
@ -13,6 +13,7 @@ export default {
|
|||||||
'menu.system.menu': 'menu',
|
'menu.system.menu': 'menu',
|
||||||
'menu.system.role': 'role',
|
'menu.system.role': 'role',
|
||||||
'menu.system.param': 'parameter',
|
'menu.system.param': 'parameter',
|
||||||
|
'menu.system.tenant': 'tenant',
|
||||||
'menu.monitor': 'monitor',
|
'menu.monitor': 'monitor',
|
||||||
'menu.monitor.log': 'log',
|
'menu.monitor.log': 'log',
|
||||||
'menu.monitor.log.log_usual': 'usual log',
|
'menu.monitor.log.log_usual': 'usual log',
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
|
'app.login.tenantCode': '租户编号',
|
||||||
'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)',
|
||||||
@ -20,6 +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.userName.required': '请输入用户名!',
|
'validation.userName.required': '请输入用户名!',
|
||||||
'validation.password.required': '请输入密码!',
|
'validation.password.required': '请输入密码!',
|
||||||
'validation.password.twice': '两次输入的密码不匹配!',
|
'validation.password.twice': '两次输入的密码不匹配!',
|
||||||
|
@ -13,6 +13,7 @@ export default {
|
|||||||
'menu.system.menu': '菜单管理',
|
'menu.system.menu': '菜单管理',
|
||||||
'menu.system.role': '角色管理',
|
'menu.system.role': '角色管理',
|
||||||
'menu.system.param': '参数管理',
|
'menu.system.param': '参数管理',
|
||||||
|
'menu.system.tenant': '租户管理',
|
||||||
'menu.monitor': '系统监控',
|
'menu.monitor': '系统监控',
|
||||||
'menu.monitor.log': '日志管理',
|
'menu.monitor.log': '日志管理',
|
||||||
'menu.monitor.log.log_usual': '通用日志',
|
'menu.monitor.log.log_usual': '通用日志',
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
|
'app.login.tenantCode': '租戶編號',
|
||||||
'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)',
|
||||||
@ -20,6 +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.userName.required': '請輸入賬戶!',
|
'validation.userName.required': '請輸入賬戶!',
|
||||||
'validation.password.required': '請輸入密碼!',
|
'validation.password.required': '請輸入密碼!',
|
||||||
'validation.password.twice': '兩次輸入的密碼不匹配!',
|
'validation.password.twice': '兩次輸入的密碼不匹配!',
|
||||||
|
@ -13,6 +13,7 @@ export default {
|
|||||||
'menu.system.menu': '菜單管理',
|
'menu.system.menu': '菜單管理',
|
||||||
'menu.system.role': '角色管理',
|
'menu.system.role': '角色管理',
|
||||||
'menu.system.param': '參數管理',
|
'menu.system.param': '參數管理',
|
||||||
|
'menu.system.tenant': '租戶管理',
|
||||||
'menu.monitor': '系統監控',
|
'menu.monitor': '系統監控',
|
||||||
'menu.monitor.log': '日志管理',
|
'menu.monitor.log': '日志管理',
|
||||||
'menu.monitor.log.log_usual': '通用日志',
|
'menu.monitor.log.log_usual': '通用日志',
|
||||||
|
@ -18,6 +18,94 @@ import { getRoutes, setRoutes, getButtons, setButtons } from '../utils/authority
|
|||||||
import { MENU_NAMESPACE } from '../actions/menu';
|
import { MENU_NAMESPACE } from '../actions/menu';
|
||||||
import { formatRoutes, formatButtons } from '../utils/utils';
|
import { formatRoutes, formatButtons } from '../utils/utils';
|
||||||
|
|
||||||
|
const { check } = Authorized;
|
||||||
|
|
||||||
|
// Conversion router to menu.
|
||||||
|
function formatter(data, parentAuthority, parentName) {
|
||||||
|
return data
|
||||||
|
.map(item => {
|
||||||
|
if (!item.name || !item.path) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let locale = 'menu';
|
||||||
|
if (parentName) {
|
||||||
|
locale = `${parentName}.${item.name}`;
|
||||||
|
} else {
|
||||||
|
locale = `menu.${item.name}`;
|
||||||
|
}
|
||||||
|
// if enableMenuLocale use item.name,
|
||||||
|
// close menu international
|
||||||
|
const name = menu.disableLocal
|
||||||
|
? item.name
|
||||||
|
: formatMessage({ id: locale, defaultMessage: item.name });
|
||||||
|
const result = {
|
||||||
|
...item,
|
||||||
|
name,
|
||||||
|
locale,
|
||||||
|
authority: item.authority || parentAuthority,
|
||||||
|
};
|
||||||
|
if (item.routes) {
|
||||||
|
const children = formatter(item.routes, item.authority, locale);
|
||||||
|
// Reduce memory usage
|
||||||
|
result.children = children;
|
||||||
|
}
|
||||||
|
delete result.routes;
|
||||||
|
return result;
|
||||||
|
})
|
||||||
|
.filter(item => item);
|
||||||
|
}
|
||||||
|
|
||||||
|
const memoizeOneFormatter = memoizeOne(formatter, isEqual);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get SubMenu or Item
|
||||||
|
*/
|
||||||
|
const getSubMenu = item => {
|
||||||
|
// doc: add hideChildrenInMenu
|
||||||
|
if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
children: filterMenuData(item.children), // eslint-disable-line
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filter menuData
|
||||||
|
*/
|
||||||
|
const filterMenuData = menuData => {
|
||||||
|
if (!menuData) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return menuData
|
||||||
|
.filter(item => item.name && !item.hideInMenu)
|
||||||
|
.map(item => check(item.authority, getSubMenu(item)))
|
||||||
|
.filter(item => item);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取面包屑映射
|
||||||
|
* @param {Object} menuData 菜单配置
|
||||||
|
*/
|
||||||
|
const getBreadcrumbNameMap = menuData => {
|
||||||
|
const routerMap = {};
|
||||||
|
|
||||||
|
const flattenMenuData = data => {
|
||||||
|
data.forEach(menuItem => {
|
||||||
|
if (menuItem.children) {
|
||||||
|
flattenMenuData(menuItem.children);
|
||||||
|
}
|
||||||
|
// Reduce memory usage
|
||||||
|
routerMap[menuItem.path] = menuItem;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
flattenMenuData(menuData);
|
||||||
|
return routerMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespace: MENU_NAMESPACE,
|
namespace: MENU_NAMESPACE,
|
||||||
|
|
||||||
@ -165,91 +253,3 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const { check } = Authorized;
|
|
||||||
|
|
||||||
// Conversion router to menu.
|
|
||||||
function formatter(data, parentAuthority, parentName) {
|
|
||||||
return data
|
|
||||||
.map(item => {
|
|
||||||
if (!item.name || !item.path) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let locale = 'menu';
|
|
||||||
if (parentName) {
|
|
||||||
locale = `${parentName}.${item.name}`;
|
|
||||||
} else {
|
|
||||||
locale = `menu.${item.name}`;
|
|
||||||
}
|
|
||||||
// if enableMenuLocale use item.name,
|
|
||||||
// close menu international
|
|
||||||
const name = menu.disableLocal
|
|
||||||
? item.name
|
|
||||||
: formatMessage({ id: locale, defaultMessage: item.name });
|
|
||||||
const result = {
|
|
||||||
...item,
|
|
||||||
name,
|
|
||||||
locale,
|
|
||||||
authority: item.authority || parentAuthority,
|
|
||||||
};
|
|
||||||
if (item.routes) {
|
|
||||||
const children = formatter(item.routes, item.authority, locale);
|
|
||||||
// Reduce memory usage
|
|
||||||
result.children = children;
|
|
||||||
}
|
|
||||||
delete result.routes;
|
|
||||||
return result;
|
|
||||||
})
|
|
||||||
.filter(item => item);
|
|
||||||
}
|
|
||||||
|
|
||||||
const memoizeOneFormatter = memoizeOne(formatter, isEqual);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get SubMenu or Item
|
|
||||||
*/
|
|
||||||
const getSubMenu = item => {
|
|
||||||
// doc: add hideChildrenInMenu
|
|
||||||
if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
children: filterMenuData(item.children), // eslint-disable-line
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* filter menuData
|
|
||||||
*/
|
|
||||||
const filterMenuData = menuData => {
|
|
||||||
if (!menuData) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return menuData
|
|
||||||
.filter(item => item.name && !item.hideInMenu)
|
|
||||||
.map(item => check(item.authority, getSubMenu(item)))
|
|
||||||
.filter(item => item);
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* 获取面包屑映射
|
|
||||||
* @param {Object} menuData 菜单配置
|
|
||||||
*/
|
|
||||||
const getBreadcrumbNameMap = menuData => {
|
|
||||||
const routerMap = {};
|
|
||||||
|
|
||||||
const flattenMenuData = data => {
|
|
||||||
data.forEach(menuItem => {
|
|
||||||
if (menuItem.children) {
|
|
||||||
flattenMenuData(menuItem.children);
|
|
||||||
}
|
|
||||||
// Reduce memory usage
|
|
||||||
routerMap[menuItem.path] = menuItem;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
flattenMenuData(menuData);
|
|
||||||
return routerMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual);
|
|
||||||
|
87
src/models/tenant.js
Normal file
87
src/models/tenant.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { message } from 'antd';
|
||||||
|
import router from 'umi/router';
|
||||||
|
import { TENANT_NAMESPACE } from '../actions/tenant';
|
||||||
|
import { list, submit, detail, remove } from '../services/tenant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespace: TENANT_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('/system/tenant');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*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: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -2,6 +2,7 @@ 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, detail, remove, grant } from '../services/user';
|
||||||
|
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';
|
||||||
import { getCurrentUser } from '../utils/authority';
|
import { getCurrentUser } from '../utils/authority';
|
||||||
@ -19,6 +20,7 @@ export default {
|
|||||||
init: {
|
init: {
|
||||||
roleTree: [],
|
roleTree: [],
|
||||||
deptTree: [],
|
deptTree: [],
|
||||||
|
tenantList: [],
|
||||||
},
|
},
|
||||||
detail: {},
|
detail: {},
|
||||||
},
|
},
|
||||||
@ -57,9 +59,24 @@ export default {
|
|||||||
*fetchInit({ payload }, { call, put }) {
|
*fetchInit({ payload }, { call, put }) {
|
||||||
const responseRole = yield call(roles, payload);
|
const responseRole = yield call(roles, payload);
|
||||||
const responseDept = yield call(depts, payload);
|
const responseDept = yield call(depts, payload);
|
||||||
if (responseRole.success && responseDept.success) {
|
const responseTenant = yield call(tenants, payload);
|
||||||
|
if (responseRole.success && responseDept.success && responseTenant.success) {
|
||||||
yield put({
|
yield put({
|
||||||
type: 'saveInit',
|
type: 'saveInit',
|
||||||
|
payload: {
|
||||||
|
roleTree: responseRole.data,
|
||||||
|
deptTree: responseDept.data,
|
||||||
|
tenantList: responseTenant.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*fetchChangeInit({ payload }, { call, put }) {
|
||||||
|
const responseRole = yield call(roles, payload);
|
||||||
|
const responseDept = yield call(depts, payload);
|
||||||
|
if (responseRole.success && responseDept.success) {
|
||||||
|
yield put({
|
||||||
|
type: 'saveChangeInit',
|
||||||
payload: {
|
payload: {
|
||||||
roleTree: responseRole.data,
|
roleTree: responseRole.data,
|
||||||
deptTree: responseDept.data,
|
deptTree: responseDept.data,
|
||||||
@ -146,6 +163,14 @@ export default {
|
|||||||
init: action.payload,
|
init: action.payload,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
saveChangeInit(state, action) {
|
||||||
|
const newState = state;
|
||||||
|
newState.init.roleTree = action.payload.roleTree;
|
||||||
|
newState.init.deptTree = action.payload.deptTree;
|
||||||
|
return {
|
||||||
|
...newState,
|
||||||
|
};
|
||||||
|
},
|
||||||
saveDetail(state, action) {
|
saveDetail(state, action) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -122,7 +122,7 @@ class Notice extends PureComponent {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: formatMessage({ id: 'desk.notice.date' }),
|
title: formatMessage({ id: 'desk.notice.date' }),
|
||||||
dataIndex: 'date',
|
dataIndex: 'releaseTime',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class NoticeAdd extends PureComponent {
|
|||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
...values,
|
...values,
|
||||||
date: func.format(values.date),
|
releaseTime: func.format(values.releaseTime),
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatch(NOTICE_SUBMIT(params));
|
dispatch(NOTICE_SUBMIT(params));
|
||||||
@ -100,7 +100,7 @@ class NoticeAdd extends PureComponent {
|
|||||||
)}
|
)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.date" />}>
|
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.date" />}>
|
||||||
{getFieldDecorator('date', {
|
{getFieldDecorator('releaseTime', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -41,7 +41,7 @@ class NoticeAdd extends PureComponent {
|
|||||||
const params = {
|
const params = {
|
||||||
id,
|
id,
|
||||||
...values,
|
...values,
|
||||||
date: func.format(values.date),
|
releaseTime: func.format(values.releaseTime),
|
||||||
};
|
};
|
||||||
dispatch(NOTICE_SUBMIT(params));
|
dispatch(NOTICE_SUBMIT(params));
|
||||||
});
|
});
|
||||||
@ -113,14 +113,14 @@ class NoticeAdd extends PureComponent {
|
|||||||
)}
|
)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.date" />}>
|
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.date" />}>
|
||||||
{getFieldDecorator('date', {
|
{getFieldDecorator('releaseTime', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: formatMessage({ id: 'desk.notice.date.validation' }),
|
message: formatMessage({ id: 'desk.notice.date.validation' }),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
initialValue: moment(detail.date, 'YYYY-MM-DD HH:mm:ss'),
|
initialValue: moment(detail.releaseTime, 'YYYY-MM-DD HH:mm:ss'),
|
||||||
})(
|
})(
|
||||||
<DatePicker
|
<DatePicker
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
|
@ -66,7 +66,7 @@ class NoticeAdd extends PureComponent {
|
|||||||
<span>{detail.categoryName}</span>
|
<span>{detail.categoryName}</span>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.date" />}>
|
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.date" />}>
|
||||||
<span>{detail.date}</span>
|
<span>{detail.releaseTime}</span>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.content" />}>
|
<FormItem {...formItemLayout} label={<FormattedMessage id="desk.notice.content" />}>
|
||||||
<span>{detail.content}</span>
|
<span>{detail.content}</span>
|
||||||
|
@ -2,10 +2,10 @@ 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 } from 'antd';
|
||||||
import Login from '@/components/Login';
|
import Login from '../../components/Login';
|
||||||
import styles from './Login.less';
|
import styles from './Login.less';
|
||||||
|
|
||||||
const { Tab, UserName, Password, Submit } = Login;
|
const { Tab, TenantCode, UserName, Password, Submit } = Login;
|
||||||
|
|
||||||
@connect(({ login, loading }) => ({
|
@connect(({ login, loading }) => ({
|
||||||
login,
|
login,
|
||||||
@ -80,6 +80,16 @@ class LoginPage extends Component {
|
|||||||
login.type === 'account' &&
|
login.type === 'account' &&
|
||||||
!submitting &&
|
!submitting &&
|
||||||
this.renderMessage(formatMessage({ id: 'app.login.message-invalid-credentials' }))}
|
this.renderMessage(formatMessage({ id: 'app.login.message-invalid-credentials' }))}
|
||||||
|
<TenantCode
|
||||||
|
name="tenantCode"
|
||||||
|
placeholder={`${formatMessage({ id: 'app.login.tenantCode' })}: 000000`}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: formatMessage({ id: 'validation.tenantCode.required' }),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<UserName
|
<UserName
|
||||||
name="account"
|
name="account"
|
||||||
placeholder={`${formatMessage({ id: 'app.login.userName' })}: admin`}
|
placeholder={`${formatMessage({ id: 'app.login.userName' })}: admin`}
|
||||||
|
@ -26,12 +26,17 @@ class Dept extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
<Col md={8} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
<FormItem label="部门名称">
|
<FormItem label="部门名称">
|
||||||
{getFieldDecorator('deptName')(<Input placeholder="请输入部门名称" />)}
|
{getFieldDecorator('deptName')(<Input placeholder="请输入部门名称" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={8} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
|
<FormItem label="租户编号">
|
||||||
|
{getFieldDecorator('tenantCode')(<Input placeholder="请输入角色名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col md={6} sm={24}>
|
||||||
<FormItem label="部门全称">
|
<FormItem label="部门全称">
|
||||||
{getFieldDecorator('fullName')(<Input placeholder="请输入部门全称" />)}
|
{getFieldDecorator('fullName')(<Input placeholder="请输入部门全称" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@ -64,6 +69,10 @@ class Dept extends PureComponent {
|
|||||||
title: '部门名称',
|
title: '部门名称',
|
||||||
dataIndex: 'deptName',
|
dataIndex: 'deptName',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '租户编号',
|
||||||
|
dataIndex: 'tenantCode',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '部门全称',
|
title: '部门全称',
|
||||||
dataIndex: 'fullName',
|
dataIndex: 'fullName',
|
||||||
|
@ -109,12 +109,6 @@ class DeptAdd extends PureComponent {
|
|||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
<FormItem {...formItemLayout} label="上级部门">
|
<FormItem {...formItemLayout} label="上级部门">
|
||||||
{getFieldDecorator('parentId', {
|
{getFieldDecorator('parentId', {
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择上级部门',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
initialValue: detail.id,
|
initialValue: detail.id,
|
||||||
})(
|
})(
|
||||||
<TreeSelect
|
<TreeSelect
|
||||||
|
@ -121,12 +121,6 @@ class DeptEdit extends PureComponent {
|
|||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
<FormItem {...formItemLayout} label="上级部门">
|
<FormItem {...formItemLayout} label="上级部门">
|
||||||
{getFieldDecorator('parentId', {
|
{getFieldDecorator('parentId', {
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择上级部门',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
initialValue: detail.parentId,
|
initialValue: detail.parentId,
|
||||||
})(
|
})(
|
||||||
<TreeSelect
|
<TreeSelect
|
||||||
|
@ -117,12 +117,17 @@ class Role extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
<Col md={8} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
<FormItem label="角色名称">
|
<FormItem label="角色名称">
|
||||||
{getFieldDecorator('roleName')(<Input placeholder="请输入角色名称" />)}
|
{getFieldDecorator('roleName')(<Input placeholder="请输入角色名称" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={8} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
|
<FormItem label="租户编号">
|
||||||
|
{getFieldDecorator('tenantCode')(<Input placeholder="请输入角色名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col md={6} sm={24}>
|
||||||
<FormItem label="角色别名">
|
<FormItem label="角色别名">
|
||||||
{getFieldDecorator('roleAlias')(<Input placeholder="请输入角色别名" />)}
|
{getFieldDecorator('roleAlias')(<Input placeholder="请输入角色别名" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@ -175,6 +180,10 @@ class Role extends PureComponent {
|
|||||||
title: '角色名称',
|
title: '角色名称',
|
||||||
dataIndex: 'roleName',
|
dataIndex: 'roleName',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '租户编号',
|
||||||
|
dataIndex: 'tenantCode',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '角色别名',
|
title: '角色别名',
|
||||||
dataIndex: 'roleAlias',
|
dataIndex: 'roleAlias',
|
||||||
|
105
src/pages/System/Tenant/Tenant.js
Normal file
105
src/pages/System/Tenant/Tenant.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import { Button, Col, Form, Input, Row } from 'antd';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import { TENANT_LIST } from '../../../actions/tenant';
|
||||||
|
import Grid from '../../../components/Sword/Grid';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ tenant, loading }) => ({
|
||||||
|
tenant,
|
||||||
|
loading: loading.models.tenant,
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class Tenant extends PureComponent {
|
||||||
|
// ============ 查询 ===============
|
||||||
|
handleSearch = params => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch(TENANT_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('tenantCode')(<Input placeholder="请输入租户编号" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col md={6} sm={24}>
|
||||||
|
<FormItem label="租户名称">
|
||||||
|
{getFieldDecorator('tenantName')(<Input placeholder="请输入租户名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col md={6} sm={24}>
|
||||||
|
<FormItem label="联系电话">
|
||||||
|
{getFieldDecorator('contactNumber')(<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 = 'tenant';
|
||||||
|
|
||||||
|
const {
|
||||||
|
form,
|
||||||
|
loading,
|
||||||
|
tenant: { data },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '租户编号',
|
||||||
|
dataIndex: 'tenantCode',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '租户名称',
|
||||||
|
dataIndex: 'tenantName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系人',
|
||||||
|
dataIndex: 'linkman',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系电话',
|
||||||
|
dataIndex: 'contactNumber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系地址',
|
||||||
|
dataIndex: 'address',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel>
|
||||||
|
<Grid
|
||||||
|
code={code}
|
||||||
|
form={form}
|
||||||
|
onSearch={this.handleSearch}
|
||||||
|
renderSearchForm={this.renderSearchForm}
|
||||||
|
loading={loading}
|
||||||
|
data={data}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Tenant;
|
96
src/pages/System/Tenant/TenantAdd.js
Normal file
96
src/pages/System/Tenant/TenantAdd.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Form, Input, Card, Button } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { TENANT_SUBMIT } from '../../../actions/tenant';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
@connect(({ loading }) => ({
|
||||||
|
submitting: loading.effects['tenant/submit'],
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class TenantAdd extends PureComponent {
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const { dispatch, form } = this.props;
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
dispatch(TENANT_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="/system/tenant" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="租户名称">
|
||||||
|
{getFieldDecorator('tenantName', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入租户名称',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入租户名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系人">
|
||||||
|
{getFieldDecorator('linkman', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入联系人',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入联系人" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系电话">
|
||||||
|
{getFieldDecorator('contactNumber', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入联系电话',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入联系电话" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系地址">
|
||||||
|
{getFieldDecorator('address')(
|
||||||
|
<TextArea style={{ minHeight: 32 }} rows={3} placeholder="请输入联系地址" />
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TenantAdd;
|
122
src/pages/System/Tenant/TenantEdit.js
Normal file
122
src/pages/System/Tenant/TenantEdit.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Form, Input, Card, Button } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { TENANT_DETAIL, TENANT_SUBMIT } from '../../../actions/tenant';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
@connect(({ tenant, loading }) => ({
|
||||||
|
tenant,
|
||||||
|
submitting: loading.effects['tenant/submit'],
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class TenantEdit extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
dispatch(TENANT_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(TENANT_SUBMIT(params));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
tenant: { 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="/system/tenant" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="租户名称">
|
||||||
|
{getFieldDecorator('tenantName', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入租户名称',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.tenantName,
|
||||||
|
})(<Input placeholder="请输入租户名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系人">
|
||||||
|
{getFieldDecorator('linkman', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入联系人',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.linkman,
|
||||||
|
})(<Input placeholder="请输入联系人" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系电话">
|
||||||
|
{getFieldDecorator('contactNumber', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入联系电话',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.contactNumber,
|
||||||
|
})(<Input placeholder="请输入联系电话" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系地址">
|
||||||
|
{getFieldDecorator('address', {
|
||||||
|
initialValue: detail.address,
|
||||||
|
})(<TextArea style={{ minHeight: 32 }} rows={3} placeholder="请输入联系地址" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TenantEdit;
|
83
src/pages/System/Tenant/TenantView.js
Normal file
83
src/pages/System/Tenant/TenantView.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
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 { TENANT_DETAIL } from '../../../actions/tenant';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ tenant }) => ({
|
||||||
|
tenant,
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class TenantView extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
dispatch(TENANT_DETAIL(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEdit = () => {
|
||||||
|
const {
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
router.push(`/system/tenant/edit/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
tenant: { 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="/system/tenant" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="租户编号">
|
||||||
|
<span>{detail.tenantCode}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="租户名称">
|
||||||
|
<span>{detail.tenantName}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系人">
|
||||||
|
<span>{detail.linkman}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系电话">
|
||||||
|
<span>{detail.contactNumber}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="联系地址">
|
||||||
|
<span>{detail.address}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default TenantView;
|
@ -173,6 +173,10 @@ class User extends PureComponent {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '租户编号',
|
||||||
|
dataIndex: 'tenantCode',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '登录账号',
|
title: '登录账号',
|
||||||
dataIndex: 'account',
|
dataIndex: 'account',
|
||||||
|
@ -4,7 +4,7 @@ import { connect } from 'dva';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import styles from '../../../layouts/Sword.less';
|
import styles from '../../../layouts/Sword.less';
|
||||||
import { USER_INIT, USER_SUBMIT } from '../../../actions/user';
|
import { USER_INIT, USER_CHANGE_INIT, USER_SUBMIT } from '../../../actions/user';
|
||||||
import func from '../../../utils/Func';
|
import func from '../../../utils/Func';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
@ -42,11 +42,17 @@ class UserAdd extends PureComponent {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleChange = value => {
|
||||||
|
const { dispatch, form } = this.props;
|
||||||
|
form.resetFields(['roleId', 'deptId']);
|
||||||
|
dispatch(USER_CHANGE_INIT({ tenantCode: value }));
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
form: { getFieldDecorator },
|
form: { getFieldDecorator },
|
||||||
user: {
|
user: {
|
||||||
init: { roleTree, deptTree },
|
init: { roleTree, deptTree, tenantList },
|
||||||
},
|
},
|
||||||
submitting,
|
submitting,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
@ -60,15 +66,6 @@ class UserAdd extends PureComponent {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const formAllItemLayout = {
|
|
||||||
labelCol: {
|
|
||||||
span: 4,
|
|
||||||
},
|
|
||||||
wrapperCol: {
|
|
||||||
span: 20,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const action = (
|
const action = (
|
||||||
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
||||||
提交
|
提交
|
||||||
@ -80,8 +77,8 @@ class UserAdd extends PureComponent {
|
|||||||
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
<Card title="基本信息" className={styles.card} bordered={false}>
|
<Card title="基本信息" className={styles.card} bordered={false}>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={20}>
|
<Col span={10}>
|
||||||
<FormItem {...formAllItemLayout} label="登录账号">
|
<FormItem {...formItemLayout} label="登录账号">
|
||||||
{getFieldDecorator('account', {
|
{getFieldDecorator('account', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
@ -92,6 +89,34 @@ class UserAdd extends PureComponent {
|
|||||||
})(<Input placeholder="请输入登录账号" />)}
|
})(<Input placeholder="请输入登录账号" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="所属租户">
|
||||||
|
{getFieldDecorator('tenantCode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择所属租户',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(
|
||||||
|
<Select
|
||||||
|
showSearch
|
||||||
|
onChange={this.handleChange}
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
|
allowClear
|
||||||
|
placeholder="请选择所属租户"
|
||||||
|
>
|
||||||
|
{tenantList.map(d => (
|
||||||
|
<Select.Option key={d.tenantCode} value={d.tenantCode}>
|
||||||
|
{d.tenantName}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
|
@ -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_DETAIL, USER_INIT, USER_SUBMIT } from '../../../actions/user';
|
import { USER_CHANGE_INIT, USER_DETAIL, USER_INIT, USER_SUBMIT } from '../../../actions/user';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@ -49,12 +49,18 @@ class UserEdit extends PureComponent {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleChange = value => {
|
||||||
|
const { dispatch, form } = this.props;
|
||||||
|
form.resetFields(['roleId', 'deptId']);
|
||||||
|
dispatch(USER_CHANGE_INIT({ tenantCode: value }));
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
form: { getFieldDecorator },
|
form: { getFieldDecorator },
|
||||||
user: {
|
user: {
|
||||||
detail,
|
detail,
|
||||||
init: { roleTree, deptTree },
|
init: { roleTree, deptTree, tenantList },
|
||||||
},
|
},
|
||||||
submitting,
|
submitting,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
@ -70,15 +76,6 @@ class UserEdit extends PureComponent {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const formAllItemLayout = {
|
|
||||||
labelCol: {
|
|
||||||
span: 4,
|
|
||||||
},
|
|
||||||
wrapperCol: {
|
|
||||||
span: 20,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const action = (
|
const action = (
|
||||||
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
||||||
提交
|
提交
|
||||||
@ -90,8 +87,8 @@ class UserEdit extends PureComponent {
|
|||||||
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
<Card title="基本信息" className={styles.card} bordered={false}>
|
<Card title="基本信息" className={styles.card} bordered={false}>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={20}>
|
<Col span={10}>
|
||||||
<FormItem {...formAllItemLayout} label="登录账号">
|
<FormItem {...formItemLayout} label="登录账号">
|
||||||
{getFieldDecorator('account', {
|
{getFieldDecorator('account', {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
@ -103,6 +100,35 @@ class UserEdit extends PureComponent {
|
|||||||
})(<Input placeholder="请输入登录账号" />)}
|
})(<Input placeholder="请输入登录账号" />)}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="所属租户">
|
||||||
|
{getFieldDecorator('tenantCode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择所属租户',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.tenantCode,
|
||||||
|
})(
|
||||||
|
<Select
|
||||||
|
showSearch
|
||||||
|
onChange={this.handleChange}
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
|
allowClear
|
||||||
|
placeholder="请选择所属租户"
|
||||||
|
>
|
||||||
|
{tenantList.map(d => (
|
||||||
|
<Select.Option key={d.tenantCode} value={d.tenantCode}>
|
||||||
|
{d.tenantName}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
|
@ -46,15 +46,6 @@ class UserView extends PureComponent {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const formAllItemLayout = {
|
|
||||||
labelCol: {
|
|
||||||
span: 4,
|
|
||||||
},
|
|
||||||
wrapperCol: {
|
|
||||||
span: 20,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const action = (
|
const action = (
|
||||||
<Button type="primary" onClick={this.handleEdit}>
|
<Button type="primary" onClick={this.handleEdit}>
|
||||||
修改
|
修改
|
||||||
@ -66,11 +57,16 @@ class UserView extends PureComponent {
|
|||||||
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
<Card title="基本信息" className={styles.card} bordered={false}>
|
<Card title="基本信息" className={styles.card} bordered={false}>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={20}>
|
<Col span={10}>
|
||||||
<FormItem {...formAllItemLayout} label="登录账号">
|
<FormItem {...formItemLayout} label="登录账号">
|
||||||
<span>{detail.account}</span>
|
<span>{detail.account}</span>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="所属租户">
|
||||||
|
<span>{detail.tenantCode}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
|
29
src/services/tenant.js
Normal file
29
src/services/tenant.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-system/tenant/list?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function select(params) {
|
||||||
|
return request(`/api/blade-system/tenant/select?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function submit(params) {
|
||||||
|
return request('/api/blade-system/tenant/submit', {
|
||||||
|
method: 'POST',
|
||||||
|
body: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function detail(params) {
|
||||||
|
return request(`/api/blade-system/tenant/detail?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function remove(params) {
|
||||||
|
return request('/api/blade-system/tenant/remove', {
|
||||||
|
method: 'POST',
|
||||||
|
body: func.toFormData(params),
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user